blob: 1520c508e10c03ff378dca31383ea0ec13a07ada [file] [log] [blame]
Jason Evansc0cc5db2017-01-19 21:41:41 -08001#define JEMALLOC_CTL_C_
David Goldblatt743d9402017-04-10 18:17:55 -07002#include "jemalloc/internal/jemalloc_preamble.h"
3#include "jemalloc/internal/jemalloc_internal_includes.h"
Jason Evans3c234352010-01-27 13:10:55 -08004
David Goldblattd9ec36e2017-04-11 14:43:12 -07005#include "jemalloc/internal/assert.h"
David Goldblatt89e2d3c2017-04-24 17:09:56 -07006#include "jemalloc/internal/ctl.h"
David Goldblatt93284bb2017-05-23 14:36:09 -07007#include "jemalloc/internal/extent_dss.h"
David Goldblatt98774e62017-05-23 14:42:32 -07008#include "jemalloc/internal/extent_mmap.h"
David Goldblatt18ecbfa2017-05-23 12:28:19 -07009#include "jemalloc/internal/mutex.h"
David Goldblatt418d96a2017-04-17 16:17:02 -070010#include "jemalloc/internal/nstime.h"
David Goldblatt31b43212017-04-19 15:09:01 -070011#include "jemalloc/internal/size_classes.h"
David Goldblattf692e6c2017-04-11 13:31:16 -070012#include "jemalloc/internal/util.h"
13
Jason Evans3c234352010-01-27 13:10:55 -080014/******************************************************************************/
15/* Data. */
16
Jason Evansfc4dcfa2010-11-24 15:44:21 -080017/*
18 * ctl_mtx protects the following:
Jason Evansd778dd22017-01-03 12:40:54 -080019 * - ctl_stats->*
Jason Evansfc4dcfa2010-11-24 15:44:21 -080020 */
Jason Evans3c234352010-01-27 13:10:55 -080021static malloc_mutex_t ctl_mtx;
22static bool ctl_initialized;
Jason Evansd778dd22017-01-03 12:40:54 -080023static ctl_stats_t *ctl_stats;
Jason Evans9eb1b1c2017-01-18 23:03:37 -080024static ctl_arenas_t *ctl_arenas;
Jason Evans3c234352010-01-27 13:10:55 -080025
26/******************************************************************************/
Mike Hommey461ad5c2012-04-20 08:38:42 +020027/* Helpers for named and indexed nodes. */
28
David Goldblatt4d2e4bf2017-04-21 09:37:34 -070029static const ctl_named_node_t *
Jason Evansc4c25922017-01-15 16:56:30 -080030ctl_named_node(const ctl_node_t *node) {
Mike Hommey461ad5c2012-04-20 08:38:42 +020031 return ((node->named) ? (const ctl_named_node_t *)node : NULL);
32}
33
David Goldblatt4d2e4bf2017-04-21 09:37:34 -070034static const ctl_named_node_t *
Jason Evansc4c25922017-01-15 16:56:30 -080035ctl_named_children(const ctl_named_node_t *node, size_t index) {
Mike Hommey461ad5c2012-04-20 08:38:42 +020036 const ctl_named_node_t *children = ctl_named_node(node->children);
37
38 return (children ? &children[index] : NULL);
39}
40
David Goldblatt4d2e4bf2017-04-21 09:37:34 -070041static const ctl_indexed_node_t *
Jason Evansc4c25922017-01-15 16:56:30 -080042ctl_indexed_node(const ctl_node_t *node) {
Jason Evans551ebc42014-10-03 10:16:09 -070043 return (!node->named ? (const ctl_indexed_node_t *)node : NULL);
Mike Hommey461ad5c2012-04-20 08:38:42 +020044}
45
46/******************************************************************************/
Jason Evans3c234352010-01-27 13:10:55 -080047/* Function prototypes for non-inline static functions. */
48
Jason Evansc0cc5db2017-01-19 21:41:41 -080049#define CTL_PROTO(n) \
Jason Evansb2c0d632016-04-13 23:36:15 -070050static int n##_ctl(tsd_t *tsd, const size_t *mib, size_t miblen, \
51 void *oldp, size_t *oldlenp, void *newp, size_t newlen);
Jason Evans3c234352010-01-27 13:10:55 -080052
Jason Evansc0cc5db2017-01-19 21:41:41 -080053#define INDEX_PROTO(n) \
Jason Evansc1e00ef2016-05-10 22:21:10 -070054static const ctl_named_node_t *n##_index(tsdn_t *tsdn, \
Jason Evansb2c0d632016-04-13 23:36:15 -070055 const size_t *mib, size_t miblen, size_t i);
Jason Evans3c234352010-01-27 13:10:55 -080056
Jason Evansa40bc7a2010-03-02 13:01:16 -080057CTL_PROTO(version)
Jason Evans3c234352010-01-27 13:10:55 -080058CTL_PROTO(epoch)
Qi Wangb693c782017-03-17 12:42:33 -070059CTL_PROTO(background_thread)
Jason Evansd4be8b72012-03-26 18:54:44 -070060CTL_PROTO(thread_tcache_enabled)
Jason Evanse7b8fa12012-03-16 17:09:32 -070061CTL_PROTO(thread_tcache_flush)
Jason Evans602c8e02014-08-18 16:22:13 -070062CTL_PROTO(thread_prof_name)
63CTL_PROTO(thread_prof_active)
Jason Evansb267d0f2010-08-13 15:42:29 -070064CTL_PROTO(thread_arena)
Jason Evans93443682010-10-20 17:39:18 -070065CTL_PROTO(thread_allocated)
Jason Evansecf229a2010-12-03 15:55:47 -080066CTL_PROTO(thread_allocatedp)
Jason Evans93443682010-10-20 17:39:18 -070067CTL_PROTO(thread_deallocated)
Jason Evansecf229a2010-12-03 15:55:47 -080068CTL_PROTO(thread_deallocatedp)
Jason Evansf2bc8522015-07-17 16:38:25 -070069CTL_PROTO(config_cache_oblivious)
Jason Evans3c234352010-01-27 13:10:55 -080070CTL_PROTO(config_debug)
Jason Evans3c234352010-01-27 13:10:55 -080071CTL_PROTO(config_fill)
72CTL_PROTO(config_lazy_lock)
Jason Evansf8290092016-02-07 14:23:22 -080073CTL_PROTO(config_malloc_conf)
Jason Evansd34f9e72010-02-11 13:19:21 -080074CTL_PROTO(config_prof)
75CTL_PROTO(config_prof_libgcc)
76CTL_PROTO(config_prof_libunwind)
Jason Evans3c234352010-01-27 13:10:55 -080077CTL_PROTO(config_stats)
Jason Evansc606a872017-05-30 09:54:49 -070078CTL_PROTO(config_thp)
Jason Evansb1476112012-04-05 13:36:17 -070079CTL_PROTO(config_utrace)
Jason Evans3c234352010-01-27 13:10:55 -080080CTL_PROTO(config_xmalloc)
81CTL_PROTO(opt_abort)
Qi Wangb86d2712017-05-25 15:30:11 -070082CTL_PROTO(opt_abort_conf)
Jason Evansb9ab04a2017-04-26 16:26:12 -070083CTL_PROTO(opt_retain)
Jason Evans609ae592012-10-11 13:53:15 -070084CTL_PROTO(opt_dss)
Jason Evanse7339702010-10-23 18:37:06 -070085CTL_PROTO(opt_narenas)
Qi Wangec532e22017-02-02 17:02:05 -080086CTL_PROTO(opt_percpu_arena)
Qi Wangb693c782017-03-17 12:42:33 -070087CTL_PROTO(opt_background_thread)
Jason Evans6e62c622017-05-17 10:47:00 -070088CTL_PROTO(opt_dirty_decay_ms)
89CTL_PROTO(opt_muzzy_decay_ms)
Jason Evanse7339702010-10-23 18:37:06 -070090CTL_PROTO(opt_stats_print)
Qi Wangd5ef5ae2017-05-27 15:35:36 -070091CTL_PROTO(opt_stats_print_opts)
Jason Evans3c234352010-01-27 13:10:55 -080092CTL_PROTO(opt_junk)
Jason Evanse7339702010-10-23 18:37:06 -070093CTL_PROTO(opt_zero)
Jason Evansb1476112012-04-05 13:36:17 -070094CTL_PROTO(opt_utrace)
Jason Evans3c234352010-01-27 13:10:55 -080095CTL_PROTO(opt_xmalloc)
Jason Evans3fa9a2f2010-03-07 15:34:14 -080096CTL_PROTO(opt_tcache)
Jason Evansf3ca7c82012-04-04 16:16:09 -070097CTL_PROTO(opt_lg_tcache_max)
Jason Evansd34f9e72010-02-11 13:19:21 -080098CTL_PROTO(opt_prof)
Jason Evanse7339702010-10-23 18:37:06 -070099CTL_PROTO(opt_prof_prefix)
Jason Evansf18c9822010-03-31 18:43:24 -0700100CTL_PROTO(opt_prof_active)
Jason Evansfc12c0b2014-10-03 23:25:30 -0700101CTL_PROTO(opt_prof_thread_active_init)
Jason Evansb9477e72010-03-01 20:15:26 -0800102CTL_PROTO(opt_lg_prof_sample)
Jason Evansd34f9e72010-02-11 13:19:21 -0800103CTL_PROTO(opt_lg_prof_interval)
Jason Evanse7339702010-10-23 18:37:06 -0700104CTL_PROTO(opt_prof_gdump)
Jason Evans0b25fe72012-04-17 16:39:33 -0700105CTL_PROTO(opt_prof_final)
Jason Evansd34f9e72010-02-11 13:19:21 -0800106CTL_PROTO(opt_prof_leak)
Jason Evansa881cd22010-10-02 15:18:50 -0700107CTL_PROTO(opt_prof_accum)
Jason Evans1cb181e2015-01-29 15:30:47 -0800108CTL_PROTO(tcache_create)
109CTL_PROTO(tcache_flush)
110CTL_PROTO(tcache_destroy)
Jason Evansdc2125c2017-01-04 10:21:53 -0800111CTL_PROTO(arena_i_initialized)
Jason Evans243f7a02016-02-19 20:09:31 -0800112CTL_PROTO(arena_i_decay)
Jason Evans64e458f2017-03-08 22:42:57 -0800113CTL_PROTO(arena_i_purge)
Jason Evans19ff2ce2016-04-22 14:37:17 -0700114CTL_PROTO(arena_i_reset)
Jason Evansedf1baf2017-01-03 17:21:59 -0800115CTL_PROTO(arena_i_destroy)
Jason Evans609ae592012-10-11 13:53:15 -0700116CTL_PROTO(arena_i_dss)
Jason Evans6e62c622017-05-17 10:47:00 -0700117CTL_PROTO(arena_i_dirty_decay_ms)
118CTL_PROTO(arena_i_muzzy_decay_ms)
Jason Evans9c305c92016-05-31 15:03:51 -0700119CTL_PROTO(arena_i_extent_hooks)
Jason Evans609ae592012-10-11 13:53:15 -0700120INDEX_PROTO(arena_i)
Jason Evans3c234352010-01-27 13:10:55 -0800121CTL_PROTO(arenas_bin_i_size)
122CTL_PROTO(arenas_bin_i_nregs)
Jason Evans498856f2016-05-29 18:34:50 -0700123CTL_PROTO(arenas_bin_i_slab_size)
Jason Evans3c234352010-01-27 13:10:55 -0800124INDEX_PROTO(arenas_bin_i)
Jason Evans7d63fed2016-05-31 14:50:21 -0700125CTL_PROTO(arenas_lextent_i_size)
126INDEX_PROTO(arenas_lextent_i)
Jason Evans3c234352010-01-27 13:10:55 -0800127CTL_PROTO(arenas_narenas)
Jason Evans6e62c622017-05-17 10:47:00 -0700128CTL_PROTO(arenas_dirty_decay_ms)
129CTL_PROTO(arenas_muzzy_decay_ms)
Jason Evans3c234352010-01-27 13:10:55 -0800130CTL_PROTO(arenas_quantum)
Jason Evansae4c7b42012-04-02 07:04:34 -0700131CTL_PROTO(arenas_page)
Jason Evansdafde142010-03-17 16:27:39 -0700132CTL_PROTO(arenas_tcache_max)
Jason Evans3c234352010-01-27 13:10:55 -0800133CTL_PROTO(arenas_nbins)
Jason Evansdafde142010-03-17 16:27:39 -0700134CTL_PROTO(arenas_nhbins)
Jason Evans7d63fed2016-05-31 14:50:21 -0700135CTL_PROTO(arenas_nlextents)
Jason Evans0f04bb12017-01-03 08:21:29 -0800136CTL_PROTO(arenas_create)
Jason Evansfc12c0b2014-10-03 23:25:30 -0700137CTL_PROTO(prof_thread_active_init)
Jason Evansf18c9822010-03-31 18:43:24 -0700138CTL_PROTO(prof_active)
Jason Evansd34f9e72010-02-11 13:19:21 -0800139CTL_PROTO(prof_dump)
Jason Evans5b8ed5b2015-01-25 21:16:57 -0800140CTL_PROTO(prof_gdump)
Jason Evans602c8e02014-08-18 16:22:13 -0700141CTL_PROTO(prof_reset)
Jason Evansd34f9e72010-02-11 13:19:21 -0800142CTL_PROTO(prof_interval)
Jason Evans602c8e02014-08-18 16:22:13 -0700143CTL_PROTO(lg_prof_sample)
Jason Evans3c234352010-01-27 13:10:55 -0800144CTL_PROTO(stats_arenas_i_small_allocated)
145CTL_PROTO(stats_arenas_i_small_nmalloc)
146CTL_PROTO(stats_arenas_i_small_ndalloc)
Jason Evans86815df2010-03-13 20:32:56 -0800147CTL_PROTO(stats_arenas_i_small_nrequests)
Jason Evans7d63fed2016-05-31 14:50:21 -0700148CTL_PROTO(stats_arenas_i_large_allocated)
149CTL_PROTO(stats_arenas_i_large_nmalloc)
150CTL_PROTO(stats_arenas_i_large_ndalloc)
151CTL_PROTO(stats_arenas_i_large_nrequests)
Jason Evans86815df2010-03-13 20:32:56 -0800152CTL_PROTO(stats_arenas_i_bins_j_nmalloc)
153CTL_PROTO(stats_arenas_i_bins_j_ndalloc)
Jason Evans3c234352010-01-27 13:10:55 -0800154CTL_PROTO(stats_arenas_i_bins_j_nrequests)
Jason Evans3c4d92e2014-10-12 22:53:59 -0700155CTL_PROTO(stats_arenas_i_bins_j_curregs)
Jason Evans3c234352010-01-27 13:10:55 -0800156CTL_PROTO(stats_arenas_i_bins_j_nfills)
157CTL_PROTO(stats_arenas_i_bins_j_nflushes)
Jason Evans498856f2016-05-29 18:34:50 -0700158CTL_PROTO(stats_arenas_i_bins_j_nslabs)
159CTL_PROTO(stats_arenas_i_bins_j_nreslabs)
160CTL_PROTO(stats_arenas_i_bins_j_curslabs)
Jason Evans3c234352010-01-27 13:10:55 -0800161INDEX_PROTO(stats_arenas_i_bins_j)
Jason Evans7d63fed2016-05-31 14:50:21 -0700162CTL_PROTO(stats_arenas_i_lextents_j_nmalloc)
163CTL_PROTO(stats_arenas_i_lextents_j_ndalloc)
164CTL_PROTO(stats_arenas_i_lextents_j_nrequests)
165CTL_PROTO(stats_arenas_i_lextents_j_curlextents)
166INDEX_PROTO(stats_arenas_i_lextents_j)
Jason Evans597632b2011-03-18 13:41:33 -0700167CTL_PROTO(stats_arenas_i_nthreads)
Qi Wangbaf3e292017-05-16 13:56:00 -0700168CTL_PROTO(stats_arenas_i_uptime)
Jason Evans609ae592012-10-11 13:53:15 -0700169CTL_PROTO(stats_arenas_i_dss)
Jason Evans6e62c622017-05-17 10:47:00 -0700170CTL_PROTO(stats_arenas_i_dirty_decay_ms)
171CTL_PROTO(stats_arenas_i_muzzy_decay_ms)
Jason Evans3c234352010-01-27 13:10:55 -0800172CTL_PROTO(stats_arenas_i_pactive)
173CTL_PROTO(stats_arenas_i_pdirty)
Jason Evans64e458f2017-03-08 22:42:57 -0800174CTL_PROTO(stats_arenas_i_pmuzzy)
Jason Evans3c234352010-01-27 13:10:55 -0800175CTL_PROTO(stats_arenas_i_mapped)
Jason Evans04c3c0f2016-05-03 22:11:35 -0700176CTL_PROTO(stats_arenas_i_retained)
Jason Evans64e458f2017-03-08 22:42:57 -0800177CTL_PROTO(stats_arenas_i_dirty_npurge)
178CTL_PROTO(stats_arenas_i_dirty_nmadvise)
179CTL_PROTO(stats_arenas_i_dirty_purged)
180CTL_PROTO(stats_arenas_i_muzzy_npurge)
181CTL_PROTO(stats_arenas_i_muzzy_nmadvise)
182CTL_PROTO(stats_arenas_i_muzzy_purged)
Jason Evansa0dd3a42016-12-22 16:39:10 -0600183CTL_PROTO(stats_arenas_i_base)
184CTL_PROTO(stats_arenas_i_internal)
Qi Wang58424e62016-04-22 18:37:44 -0700185CTL_PROTO(stats_arenas_i_tcache_bytes)
Jason Evansa0dd3a42016-12-22 16:39:10 -0600186CTL_PROTO(stats_arenas_i_resident)
Jason Evans3c234352010-01-27 13:10:55 -0800187INDEX_PROTO(stats_arenas_i)
Jason Evans3c234352010-01-27 13:10:55 -0800188CTL_PROTO(stats_allocated)
189CTL_PROTO(stats_active)
Qi Wang2bee0c62017-05-12 12:30:33 -0700190CTL_PROTO(stats_background_thread_num_threads)
191CTL_PROTO(stats_background_thread_num_runs)
192CTL_PROTO(stats_background_thread_run_interval)
Jason Evans4581b972014-11-27 17:22:36 -0200193CTL_PROTO(stats_metadata)
Jason Evans4acd75a2015-03-23 17:25:57 -0700194CTL_PROTO(stats_resident)
Jason Evans3c234352010-01-27 13:10:55 -0800195CTL_PROTO(stats_mapped)
Jason Evans04c3c0f2016-05-03 22:11:35 -0700196CTL_PROTO(stats_retained)
Jason Evans3c234352010-01-27 13:10:55 -0800197
Qi Wang64c5f5c2017-03-13 17:29:03 -0700198#define MUTEX_STATS_CTL_PROTO_GEN(n) \
Qi Wangca9074d2017-03-11 20:28:31 -0800199CTL_PROTO(stats_##n##_num_ops) \
200CTL_PROTO(stats_##n##_num_wait) \
201CTL_PROTO(stats_##n##_num_spin_acq) \
202CTL_PROTO(stats_##n##_num_owner_switch) \
203CTL_PROTO(stats_##n##_total_wait_time) \
204CTL_PROTO(stats_##n##_max_wait_time) \
205CTL_PROTO(stats_##n##_max_num_thds)
Qi Wang0fb5c0e2017-03-10 12:14:05 -0800206
Qi Wang64c5f5c2017-03-13 17:29:03 -0700207/* Global mutexes. */
Qi Wangd3fde1c2017-03-21 11:56:38 -0700208#define OP(mtx) MUTEX_STATS_CTL_PROTO_GEN(mutexes_##mtx)
David Goldblatt89e2d3c2017-04-24 17:09:56 -0700209MUTEX_PROF_GLOBAL_MUTEXES
Qi Wangd3fde1c2017-03-21 11:56:38 -0700210#undef OP
211
212/* Per arena mutexes. */
213#define OP(mtx) MUTEX_STATS_CTL_PROTO_GEN(arenas_i_mutexes_##mtx)
David Goldblatt89e2d3c2017-04-24 17:09:56 -0700214MUTEX_PROF_ARENA_MUTEXES
Qi Wangd3fde1c2017-03-21 11:56:38 -0700215#undef OP
Qi Wangca9074d2017-03-11 20:28:31 -0800216
Qi Wang64c5f5c2017-03-13 17:29:03 -0700217/* Arena bin mutexes. */
218MUTEX_STATS_CTL_PROTO_GEN(arenas_i_bins_j_mutex)
Qi Wang64c5f5c2017-03-13 17:29:03 -0700219#undef MUTEX_STATS_CTL_PROTO_GEN
220
221CTL_PROTO(stats_mutexes_reset)
Qi Wang0fb5c0e2017-03-10 12:14:05 -0800222
Jason Evans3c234352010-01-27 13:10:55 -0800223/******************************************************************************/
224/* mallctl tree. */
225
Jason Evansc0cc5db2017-01-19 21:41:41 -0800226#define NAME(n) {true}, n
227#define CHILD(t, c) \
Jason Evans65f343a2012-04-23 19:31:45 -0700228 sizeof(c##_node) / sizeof(ctl_##t##_node_t), \
229 (ctl_node_t *)c##_node, \
230 NULL
Jason Evansc0cc5db2017-01-19 21:41:41 -0800231#define CTL(c) 0, NULL, c##_ctl
Jason Evans3c234352010-01-27 13:10:55 -0800232
233/*
234 * Only handles internal indexed nodes, since there are currently no external
235 * ones.
236 */
Jason Evansc0cc5db2017-01-19 21:41:41 -0800237#define INDEX(i) {false}, i##_index
Jason Evans3c234352010-01-27 13:10:55 -0800238
Jason Evans602c8e02014-08-18 16:22:13 -0700239static const ctl_named_node_t thread_tcache_node[] = {
Jason Evansd4be8b72012-03-26 18:54:44 -0700240 {NAME("enabled"), CTL(thread_tcache_enabled)},
Jason Evanse7b8fa12012-03-16 17:09:32 -0700241 {NAME("flush"), CTL(thread_tcache_flush)}
Jason Evans3c234352010-01-27 13:10:55 -0800242};
Jason Evans3c234352010-01-27 13:10:55 -0800243
Jason Evans602c8e02014-08-18 16:22:13 -0700244static const ctl_named_node_t thread_prof_node[] = {
245 {NAME("name"), CTL(thread_prof_name)},
246 {NAME("active"), CTL(thread_prof_active)}
247};
248
Mike Hommey461ad5c2012-04-20 08:38:42 +0200249static const ctl_named_node_t thread_node[] = {
Jason Evans7372b152012-02-10 20:22:09 -0800250 {NAME("arena"), CTL(thread_arena)},
Jason Evans93443682010-10-20 17:39:18 -0700251 {NAME("allocated"), CTL(thread_allocated)},
Jason Evansecf229a2010-12-03 15:55:47 -0800252 {NAME("allocatedp"), CTL(thread_allocatedp)},
253 {NAME("deallocated"), CTL(thread_deallocated)},
Jason Evanse7b8fa12012-03-16 17:09:32 -0700254 {NAME("deallocatedp"), CTL(thread_deallocatedp)},
Jason Evans602c8e02014-08-18 16:22:13 -0700255 {NAME("tcache"), CHILD(named, thread_tcache)},
256 {NAME("prof"), CHILD(named, thread_prof)}
Jason Evansb267d0f2010-08-13 15:42:29 -0700257};
Jason Evansb267d0f2010-08-13 15:42:29 -0700258
Mike Hommey461ad5c2012-04-20 08:38:42 +0200259static const ctl_named_node_t config_node[] = {
Jason Evansf2bc8522015-07-17 16:38:25 -0700260 {NAME("cache_oblivious"), CTL(config_cache_oblivious)},
Jason Evans3c4d92e2014-10-12 22:53:59 -0700261 {NAME("debug"), CTL(config_debug)},
262 {NAME("fill"), CTL(config_fill)},
263 {NAME("lazy_lock"), CTL(config_lazy_lock)},
Jason Evansf8290092016-02-07 14:23:22 -0800264 {NAME("malloc_conf"), CTL(config_malloc_conf)},
Jason Evans3c4d92e2014-10-12 22:53:59 -0700265 {NAME("prof"), CTL(config_prof)},
266 {NAME("prof_libgcc"), CTL(config_prof_libgcc)},
267 {NAME("prof_libunwind"), CTL(config_prof_libunwind)},
268 {NAME("stats"), CTL(config_stats)},
Jason Evansc606a872017-05-30 09:54:49 -0700269 {NAME("thp"), CTL(config_thp)},
Jason Evans3c4d92e2014-10-12 22:53:59 -0700270 {NAME("utrace"), CTL(config_utrace)},
Jason Evans3c4d92e2014-10-12 22:53:59 -0700271 {NAME("xmalloc"), CTL(config_xmalloc)}
Jason Evans3c234352010-01-27 13:10:55 -0800272};
273
Mike Hommey461ad5c2012-04-20 08:38:42 +0200274static const ctl_named_node_t opt_node[] = {
Jason Evans3c4d92e2014-10-12 22:53:59 -0700275 {NAME("abort"), CTL(opt_abort)},
Qi Wangb86d2712017-05-25 15:30:11 -0700276 {NAME("abort_conf"), CTL(opt_abort_conf)},
Jason Evansb9ab04a2017-04-26 16:26:12 -0700277 {NAME("retain"), CTL(opt_retain)},
Jason Evans3c4d92e2014-10-12 22:53:59 -0700278 {NAME("dss"), CTL(opt_dss)},
Jason Evans3c4d92e2014-10-12 22:53:59 -0700279 {NAME("narenas"), CTL(opt_narenas)},
Qi Wangec532e22017-02-02 17:02:05 -0800280 {NAME("percpu_arena"), CTL(opt_percpu_arena)},
Qi Wangb693c782017-03-17 12:42:33 -0700281 {NAME("background_thread"), CTL(opt_background_thread)},
Jason Evans6e62c622017-05-17 10:47:00 -0700282 {NAME("dirty_decay_ms"), CTL(opt_dirty_decay_ms)},
283 {NAME("muzzy_decay_ms"), CTL(opt_muzzy_decay_ms)},
Jason Evans3c4d92e2014-10-12 22:53:59 -0700284 {NAME("stats_print"), CTL(opt_stats_print)},
Qi Wangd5ef5ae2017-05-27 15:35:36 -0700285 {NAME("stats_print_opts"), CTL(opt_stats_print_opts)},
Jason Evans3c4d92e2014-10-12 22:53:59 -0700286 {NAME("junk"), CTL(opt_junk)},
287 {NAME("zero"), CTL(opt_zero)},
Jason Evans3c4d92e2014-10-12 22:53:59 -0700288 {NAME("utrace"), CTL(opt_utrace)},
289 {NAME("xmalloc"), CTL(opt_xmalloc)},
290 {NAME("tcache"), CTL(opt_tcache)},
291 {NAME("lg_tcache_max"), CTL(opt_lg_tcache_max)},
292 {NAME("prof"), CTL(opt_prof)},
293 {NAME("prof_prefix"), CTL(opt_prof_prefix)},
294 {NAME("prof_active"), CTL(opt_prof_active)},
Jason Evansfc12c0b2014-10-03 23:25:30 -0700295 {NAME("prof_thread_active_init"), CTL(opt_prof_thread_active_init)},
Jason Evans3c4d92e2014-10-12 22:53:59 -0700296 {NAME("lg_prof_sample"), CTL(opt_lg_prof_sample)},
297 {NAME("lg_prof_interval"), CTL(opt_lg_prof_interval)},
298 {NAME("prof_gdump"), CTL(opt_prof_gdump)},
299 {NAME("prof_final"), CTL(opt_prof_final)},
300 {NAME("prof_leak"), CTL(opt_prof_leak)},
301 {NAME("prof_accum"), CTL(opt_prof_accum)}
Jason Evans3c234352010-01-27 13:10:55 -0800302};
303
Jason Evans1cb181e2015-01-29 15:30:47 -0800304static const ctl_named_node_t tcache_node[] = {
305 {NAME("create"), CTL(tcache_create)},
306 {NAME("flush"), CTL(tcache_flush)},
307 {NAME("destroy"), CTL(tcache_destroy)}
308};
309
Jason Evans609ae592012-10-11 13:53:15 -0700310static const ctl_named_node_t arena_i_node[] = {
Jason Evansdc2125c2017-01-04 10:21:53 -0800311 {NAME("initialized"), CTL(arena_i_initialized)},
Jason Evans243f7a02016-02-19 20:09:31 -0800312 {NAME("decay"), CTL(arena_i_decay)},
Jason Evans64e458f2017-03-08 22:42:57 -0800313 {NAME("purge"), CTL(arena_i_purge)},
Jason Evans19ff2ce2016-04-22 14:37:17 -0700314 {NAME("reset"), CTL(arena_i_reset)},
Jason Evansedf1baf2017-01-03 17:21:59 -0800315 {NAME("destroy"), CTL(arena_i_destroy)},
Jason Evans3c4d92e2014-10-12 22:53:59 -0700316 {NAME("dss"), CTL(arena_i_dss)},
Jason Evans6e62c622017-05-17 10:47:00 -0700317 {NAME("dirty_decay_ms"), CTL(arena_i_dirty_decay_ms)},
318 {NAME("muzzy_decay_ms"), CTL(arena_i_muzzy_decay_ms)},
Jason Evans9c305c92016-05-31 15:03:51 -0700319 {NAME("extent_hooks"), CTL(arena_i_extent_hooks)}
Jason Evans609ae592012-10-11 13:53:15 -0700320};
321static const ctl_named_node_t super_arena_i_node[] = {
Jason Evans3c4d92e2014-10-12 22:53:59 -0700322 {NAME(""), CHILD(named, arena_i)}
Jason Evans609ae592012-10-11 13:53:15 -0700323};
324
325static const ctl_indexed_node_t arena_node[] = {
326 {INDEX(arena_i)}
327};
328
Mike Hommey461ad5c2012-04-20 08:38:42 +0200329static const ctl_named_node_t arenas_bin_i_node[] = {
Jason Evans3c4d92e2014-10-12 22:53:59 -0700330 {NAME("size"), CTL(arenas_bin_i_size)},
331 {NAME("nregs"), CTL(arenas_bin_i_nregs)},
Jason Evans498856f2016-05-29 18:34:50 -0700332 {NAME("slab_size"), CTL(arenas_bin_i_slab_size)}
Jason Evans3c234352010-01-27 13:10:55 -0800333};
Mike Hommey461ad5c2012-04-20 08:38:42 +0200334static const ctl_named_node_t super_arenas_bin_i_node[] = {
Jason Evans3c4d92e2014-10-12 22:53:59 -0700335 {NAME(""), CHILD(named, arenas_bin_i)}
Jason Evans3c234352010-01-27 13:10:55 -0800336};
337
Mike Hommey461ad5c2012-04-20 08:38:42 +0200338static const ctl_indexed_node_t arenas_bin_node[] = {
Jason Evans3c234352010-01-27 13:10:55 -0800339 {INDEX(arenas_bin_i)}
340};
341
Jason Evans7d63fed2016-05-31 14:50:21 -0700342static const ctl_named_node_t arenas_lextent_i_node[] = {
343 {NAME("size"), CTL(arenas_lextent_i_size)}
Jason Evans3c4d92e2014-10-12 22:53:59 -0700344};
Jason Evans7d63fed2016-05-31 14:50:21 -0700345static const ctl_named_node_t super_arenas_lextent_i_node[] = {
346 {NAME(""), CHILD(named, arenas_lextent_i)}
Jason Evans3c4d92e2014-10-12 22:53:59 -0700347};
348
Jason Evans7d63fed2016-05-31 14:50:21 -0700349static const ctl_indexed_node_t arenas_lextent_node[] = {
350 {INDEX(arenas_lextent_i)}
Jason Evans3c4d92e2014-10-12 22:53:59 -0700351};
352
Mike Hommey461ad5c2012-04-20 08:38:42 +0200353static const ctl_named_node_t arenas_node[] = {
Jason Evans3c4d92e2014-10-12 22:53:59 -0700354 {NAME("narenas"), CTL(arenas_narenas)},
Jason Evans6e62c622017-05-17 10:47:00 -0700355 {NAME("dirty_decay_ms"), CTL(arenas_dirty_decay_ms)},
356 {NAME("muzzy_decay_ms"), CTL(arenas_muzzy_decay_ms)},
Jason Evans3c4d92e2014-10-12 22:53:59 -0700357 {NAME("quantum"), CTL(arenas_quantum)},
358 {NAME("page"), CTL(arenas_page)},
359 {NAME("tcache_max"), CTL(arenas_tcache_max)},
360 {NAME("nbins"), CTL(arenas_nbins)},
361 {NAME("nhbins"), CTL(arenas_nhbins)},
362 {NAME("bin"), CHILD(indexed, arenas_bin)},
Jason Evans7d63fed2016-05-31 14:50:21 -0700363 {NAME("nlextents"), CTL(arenas_nlextents)},
364 {NAME("lextent"), CHILD(indexed, arenas_lextent)},
Jason Evans0f04bb12017-01-03 08:21:29 -0800365 {NAME("create"), CTL(arenas_create)}
Jason Evans3c234352010-01-27 13:10:55 -0800366};
367
Mike Hommey461ad5c2012-04-20 08:38:42 +0200368static const ctl_named_node_t prof_node[] = {
Jason Evansfc12c0b2014-10-03 23:25:30 -0700369 {NAME("thread_active_init"), CTL(prof_thread_active_init)},
Jason Evansf18c9822010-03-31 18:43:24 -0700370 {NAME("active"), CTL(prof_active)},
Jason Evansd34f9e72010-02-11 13:19:21 -0800371 {NAME("dump"), CTL(prof_dump)},
Jason Evans5b8ed5b2015-01-25 21:16:57 -0800372 {NAME("gdump"), CTL(prof_gdump)},
Jason Evans602c8e02014-08-18 16:22:13 -0700373 {NAME("reset"), CTL(prof_reset)},
374 {NAME("interval"), CTL(prof_interval)},
375 {NAME("lg_sample"), CTL(lg_prof_sample)}
Jason Evansd34f9e72010-02-11 13:19:21 -0800376};
Jason Evansd34f9e72010-02-11 13:19:21 -0800377
Mike Hommey461ad5c2012-04-20 08:38:42 +0200378static const ctl_named_node_t stats_arenas_i_small_node[] = {
Jason Evans3c4d92e2014-10-12 22:53:59 -0700379 {NAME("allocated"), CTL(stats_arenas_i_small_allocated)},
380 {NAME("nmalloc"), CTL(stats_arenas_i_small_nmalloc)},
381 {NAME("ndalloc"), CTL(stats_arenas_i_small_ndalloc)},
382 {NAME("nrequests"), CTL(stats_arenas_i_small_nrequests)}
Jason Evans3c234352010-01-27 13:10:55 -0800383};
384
Jason Evans7d63fed2016-05-31 14:50:21 -0700385static const ctl_named_node_t stats_arenas_i_large_node[] = {
386 {NAME("allocated"), CTL(stats_arenas_i_large_allocated)},
387 {NAME("nmalloc"), CTL(stats_arenas_i_large_nmalloc)},
388 {NAME("ndalloc"), CTL(stats_arenas_i_large_ndalloc)},
389 {NAME("nrequests"), CTL(stats_arenas_i_large_nrequests)}
Jason Evanse2deab72014-05-15 22:22:27 -0700390};
391
Qi Wang64c5f5c2017-03-13 17:29:03 -0700392#define MUTEX_PROF_DATA_NODE(prefix) \
Qi Wangca9074d2017-03-11 20:28:31 -0800393static const ctl_named_node_t stats_##prefix##_node[] = { \
Qi Wang0fb5c0e2017-03-10 12:14:05 -0800394 {NAME("num_ops"), \
Qi Wangca9074d2017-03-11 20:28:31 -0800395 CTL(stats_##prefix##_num_ops)}, \
Qi Wang0fb5c0e2017-03-10 12:14:05 -0800396 {NAME("num_wait"), \
Qi Wangca9074d2017-03-11 20:28:31 -0800397 CTL(stats_##prefix##_num_wait)}, \
Qi Wang0fb5c0e2017-03-10 12:14:05 -0800398 {NAME("num_spin_acq"), \
Qi Wangca9074d2017-03-11 20:28:31 -0800399 CTL(stats_##prefix##_num_spin_acq)}, \
Qi Wang0fb5c0e2017-03-10 12:14:05 -0800400 {NAME("num_owner_switch"), \
Qi Wangca9074d2017-03-11 20:28:31 -0800401 CTL(stats_##prefix##_num_owner_switch)}, \
Qi Wang0fb5c0e2017-03-10 12:14:05 -0800402 {NAME("total_wait_time"), \
Qi Wangca9074d2017-03-11 20:28:31 -0800403 CTL(stats_##prefix##_total_wait_time)}, \
Qi Wang0fb5c0e2017-03-10 12:14:05 -0800404 {NAME("max_wait_time"), \
Qi Wangca9074d2017-03-11 20:28:31 -0800405 CTL(stats_##prefix##_max_wait_time)}, \
Qi Wang0fb5c0e2017-03-10 12:14:05 -0800406 {NAME("max_num_thds"), \
Qi Wangca9074d2017-03-11 20:28:31 -0800407 CTL(stats_##prefix##_max_num_thds)} \
Qi Wang0fb5c0e2017-03-10 12:14:05 -0800408 /* Note that # of current waiting thread not provided. */ \
409};
410
Qi Wang64c5f5c2017-03-13 17:29:03 -0700411MUTEX_PROF_DATA_NODE(arenas_i_bins_j_mutex)
Qi Wangca9074d2017-03-11 20:28:31 -0800412
Mike Hommey461ad5c2012-04-20 08:38:42 +0200413static const ctl_named_node_t stats_arenas_i_bins_j_node[] = {
Jason Evans3c4d92e2014-10-12 22:53:59 -0700414 {NAME("nmalloc"), CTL(stats_arenas_i_bins_j_nmalloc)},
415 {NAME("ndalloc"), CTL(stats_arenas_i_bins_j_ndalloc)},
416 {NAME("nrequests"), CTL(stats_arenas_i_bins_j_nrequests)},
417 {NAME("curregs"), CTL(stats_arenas_i_bins_j_curregs)},
418 {NAME("nfills"), CTL(stats_arenas_i_bins_j_nfills)},
419 {NAME("nflushes"), CTL(stats_arenas_i_bins_j_nflushes)},
Jason Evans498856f2016-05-29 18:34:50 -0700420 {NAME("nslabs"), CTL(stats_arenas_i_bins_j_nslabs)},
421 {NAME("nreslabs"), CTL(stats_arenas_i_bins_j_nreslabs)},
Qi Wanga4f176a2017-03-03 19:58:43 -0800422 {NAME("curslabs"), CTL(stats_arenas_i_bins_j_curslabs)},
Qi Wang64c5f5c2017-03-13 17:29:03 -0700423 {NAME("mutex"), CHILD(named, stats_arenas_i_bins_j_mutex)}
Jason Evans3c234352010-01-27 13:10:55 -0800424};
Qi Wang0fb5c0e2017-03-10 12:14:05 -0800425
Mike Hommey461ad5c2012-04-20 08:38:42 +0200426static const ctl_named_node_t super_stats_arenas_i_bins_j_node[] = {
Jason Evans3c4d92e2014-10-12 22:53:59 -0700427 {NAME(""), CHILD(named, stats_arenas_i_bins_j)}
Jason Evans3c234352010-01-27 13:10:55 -0800428};
429
Mike Hommey461ad5c2012-04-20 08:38:42 +0200430static const ctl_indexed_node_t stats_arenas_i_bins_node[] = {
Jason Evans3c234352010-01-27 13:10:55 -0800431 {INDEX(stats_arenas_i_bins_j)}
432};
433
Jason Evans7d63fed2016-05-31 14:50:21 -0700434static const ctl_named_node_t stats_arenas_i_lextents_j_node[] = {
435 {NAME("nmalloc"), CTL(stats_arenas_i_lextents_j_nmalloc)},
436 {NAME("ndalloc"), CTL(stats_arenas_i_lextents_j_ndalloc)},
437 {NAME("nrequests"), CTL(stats_arenas_i_lextents_j_nrequests)},
438 {NAME("curlextents"), CTL(stats_arenas_i_lextents_j_curlextents)}
Jason Evans3c4d92e2014-10-12 22:53:59 -0700439};
Jason Evans7d63fed2016-05-31 14:50:21 -0700440static const ctl_named_node_t super_stats_arenas_i_lextents_j_node[] = {
441 {NAME(""), CHILD(named, stats_arenas_i_lextents_j)}
Jason Evans3c4d92e2014-10-12 22:53:59 -0700442};
443
Jason Evans7d63fed2016-05-31 14:50:21 -0700444static const ctl_indexed_node_t stats_arenas_i_lextents_node[] = {
445 {INDEX(stats_arenas_i_lextents_j)}
Jason Evans3c4d92e2014-10-12 22:53:59 -0700446};
447
Qi Wangd3fde1c2017-03-21 11:56:38 -0700448#define OP(mtx) MUTEX_PROF_DATA_NODE(arenas_i_mutexes_##mtx)
David Goldblatt89e2d3c2017-04-24 17:09:56 -0700449MUTEX_PROF_ARENA_MUTEXES
Qi Wangd3fde1c2017-03-21 11:56:38 -0700450#undef OP
Qi Wang0fb5c0e2017-03-10 12:14:05 -0800451
Qi Wang64c5f5c2017-03-13 17:29:03 -0700452static const ctl_named_node_t stats_arenas_i_mutexes_node[] = {
Qi Wangd3fde1c2017-03-21 11:56:38 -0700453#define OP(mtx) {NAME(#mtx), CHILD(named, stats_arenas_i_mutexes_##mtx)},
David Goldblatt89e2d3c2017-04-24 17:09:56 -0700454MUTEX_PROF_ARENA_MUTEXES
Qi Wangd3fde1c2017-03-21 11:56:38 -0700455#undef OP
Qi Wang0fb5c0e2017-03-10 12:14:05 -0800456};
Qi Wang0fb5c0e2017-03-10 12:14:05 -0800457
Mike Hommey461ad5c2012-04-20 08:38:42 +0200458static const ctl_named_node_t stats_arenas_i_node[] = {
Jason Evans3c4d92e2014-10-12 22:53:59 -0700459 {NAME("nthreads"), CTL(stats_arenas_i_nthreads)},
Qi Wangbaf3e292017-05-16 13:56:00 -0700460 {NAME("uptime"), CTL(stats_arenas_i_uptime)},
Jason Evans3c4d92e2014-10-12 22:53:59 -0700461 {NAME("dss"), CTL(stats_arenas_i_dss)},
Jason Evans6e62c622017-05-17 10:47:00 -0700462 {NAME("dirty_decay_ms"), CTL(stats_arenas_i_dirty_decay_ms)},
463 {NAME("muzzy_decay_ms"), CTL(stats_arenas_i_muzzy_decay_ms)},
Jason Evans3c4d92e2014-10-12 22:53:59 -0700464 {NAME("pactive"), CTL(stats_arenas_i_pactive)},
465 {NAME("pdirty"), CTL(stats_arenas_i_pdirty)},
Jason Evans64e458f2017-03-08 22:42:57 -0800466 {NAME("pmuzzy"), CTL(stats_arenas_i_pmuzzy)},
Jason Evans3c4d92e2014-10-12 22:53:59 -0700467 {NAME("mapped"), CTL(stats_arenas_i_mapped)},
Jason Evans04c3c0f2016-05-03 22:11:35 -0700468 {NAME("retained"), CTL(stats_arenas_i_retained)},
Jason Evans64e458f2017-03-08 22:42:57 -0800469 {NAME("dirty_npurge"), CTL(stats_arenas_i_dirty_npurge)},
470 {NAME("dirty_nmadvise"), CTL(stats_arenas_i_dirty_nmadvise)},
471 {NAME("dirty_purged"), CTL(stats_arenas_i_dirty_purged)},
472 {NAME("muzzy_npurge"), CTL(stats_arenas_i_muzzy_npurge)},
473 {NAME("muzzy_nmadvise"), CTL(stats_arenas_i_muzzy_nmadvise)},
474 {NAME("muzzy_purged"), CTL(stats_arenas_i_muzzy_purged)},
Jason Evansa0dd3a42016-12-22 16:39:10 -0600475 {NAME("base"), CTL(stats_arenas_i_base)},
476 {NAME("internal"), CTL(stats_arenas_i_internal)},
Qi Wang58424e62016-04-22 18:37:44 -0700477 {NAME("tcache_bytes"), CTL(stats_arenas_i_tcache_bytes)},
Jason Evansa0dd3a42016-12-22 16:39:10 -0600478 {NAME("resident"), CTL(stats_arenas_i_resident)},
Jason Evans3c4d92e2014-10-12 22:53:59 -0700479 {NAME("small"), CHILD(named, stats_arenas_i_small)},
Jason Evans7d63fed2016-05-31 14:50:21 -0700480 {NAME("large"), CHILD(named, stats_arenas_i_large)},
Jason Evans3c4d92e2014-10-12 22:53:59 -0700481 {NAME("bins"), CHILD(indexed, stats_arenas_i_bins)},
Qi Wang0fb5c0e2017-03-10 12:14:05 -0800482 {NAME("lextents"), CHILD(indexed, stats_arenas_i_lextents)},
Qi Wang64c5f5c2017-03-13 17:29:03 -0700483 {NAME("mutexes"), CHILD(named, stats_arenas_i_mutexes)}
Jason Evans3c234352010-01-27 13:10:55 -0800484};
Mike Hommey461ad5c2012-04-20 08:38:42 +0200485static const ctl_named_node_t super_stats_arenas_i_node[] = {
Jason Evans3c4d92e2014-10-12 22:53:59 -0700486 {NAME(""), CHILD(named, stats_arenas_i)}
Jason Evans3c234352010-01-27 13:10:55 -0800487};
488
Mike Hommey461ad5c2012-04-20 08:38:42 +0200489static const ctl_indexed_node_t stats_arenas_node[] = {
Jason Evans3c234352010-01-27 13:10:55 -0800490 {INDEX(stats_arenas_i)}
491};
492
Qi Wang2bee0c62017-05-12 12:30:33 -0700493static const ctl_named_node_t stats_background_thread_node[] = {
494 {NAME("num_threads"), CTL(stats_background_thread_num_threads)},
495 {NAME("num_runs"), CTL(stats_background_thread_num_runs)},
496 {NAME("run_interval"), CTL(stats_background_thread_run_interval)}
497};
498
Qi Wangd3fde1c2017-03-21 11:56:38 -0700499#define OP(mtx) MUTEX_PROF_DATA_NODE(mutexes_##mtx)
David Goldblatt89e2d3c2017-04-24 17:09:56 -0700500MUTEX_PROF_GLOBAL_MUTEXES
Qi Wangd3fde1c2017-03-21 11:56:38 -0700501#undef OP
502
Qi Wang64c5f5c2017-03-13 17:29:03 -0700503static const ctl_named_node_t stats_mutexes_node[] = {
Qi Wangd3fde1c2017-03-21 11:56:38 -0700504#define OP(mtx) {NAME(#mtx), CHILD(named, stats_mutexes_##mtx)},
David Goldblatt89e2d3c2017-04-24 17:09:56 -0700505MUTEX_PROF_GLOBAL_MUTEXES
Qi Wangd3fde1c2017-03-21 11:56:38 -0700506#undef OP
Qi Wang64c5f5c2017-03-13 17:29:03 -0700507 {NAME("reset"), CTL(stats_mutexes_reset)}
Qi Wangca9074d2017-03-11 20:28:31 -0800508};
Qi Wangd3fde1c2017-03-21 11:56:38 -0700509#undef MUTEX_PROF_DATA_NODE
Qi Wangca9074d2017-03-11 20:28:31 -0800510
Mike Hommey461ad5c2012-04-20 08:38:42 +0200511static const ctl_named_node_t stats_node[] = {
Jason Evans3c4d92e2014-10-12 22:53:59 -0700512 {NAME("allocated"), CTL(stats_allocated)},
513 {NAME("active"), CTL(stats_active)},
Jason Evans4581b972014-11-27 17:22:36 -0200514 {NAME("metadata"), CTL(stats_metadata)},
Jason Evans4acd75a2015-03-23 17:25:57 -0700515 {NAME("resident"), CTL(stats_resident)},
Jason Evans3c4d92e2014-10-12 22:53:59 -0700516 {NAME("mapped"), CTL(stats_mapped)},
Jason Evans04c3c0f2016-05-03 22:11:35 -0700517 {NAME("retained"), CTL(stats_retained)},
Qi Wang2bee0c62017-05-12 12:30:33 -0700518 {NAME("background_thread"),
519 CHILD(named, stats_background_thread)},
Qi Wang64c5f5c2017-03-13 17:29:03 -0700520 {NAME("mutexes"), CHILD(named, stats_mutexes)},
Jason Evans3c4d92e2014-10-12 22:53:59 -0700521 {NAME("arenas"), CHILD(indexed, stats_arenas)}
Jason Evans3c234352010-01-27 13:10:55 -0800522};
523
Mike Hommey461ad5c2012-04-20 08:38:42 +0200524static const ctl_named_node_t root_node[] = {
Jason Evansa40bc7a2010-03-02 13:01:16 -0800525 {NAME("version"), CTL(version)},
Jason Evans3c234352010-01-27 13:10:55 -0800526 {NAME("epoch"), CTL(epoch)},
Qi Wangb693c782017-03-17 12:42:33 -0700527 {NAME("background_thread"), CTL(background_thread)},
Jason Evans65f343a2012-04-23 19:31:45 -0700528 {NAME("thread"), CHILD(named, thread)},
529 {NAME("config"), CHILD(named, config)},
530 {NAME("opt"), CHILD(named, opt)},
Jason Evans1cb181e2015-01-29 15:30:47 -0800531 {NAME("tcache"), CHILD(named, tcache)},
Jason Evans609ae592012-10-11 13:53:15 -0700532 {NAME("arena"), CHILD(indexed, arena)},
Jason Evans65f343a2012-04-23 19:31:45 -0700533 {NAME("arenas"), CHILD(named, arenas)},
534 {NAME("prof"), CHILD(named, prof)},
535 {NAME("stats"), CHILD(named, stats)}
Jason Evans3c234352010-01-27 13:10:55 -0800536};
Mike Hommey461ad5c2012-04-20 08:38:42 +0200537static const ctl_named_node_t super_root_node[] = {
Jason Evans65f343a2012-04-23 19:31:45 -0700538 {NAME(""), CHILD(named, root)}
Jason Evans3c234352010-01-27 13:10:55 -0800539};
540
541#undef NAME
542#undef CHILD
543#undef CTL
544#undef INDEX
545
546/******************************************************************************/
547
David Goldblatt4fc2acf2017-03-08 15:56:31 -0800548/*
549 * Sets *dst + *src non-atomically. This is safe, since everything is
550 * synchronized by the ctl mutex.
551 */
552static void
553accum_arena_stats_u64(arena_stats_u64_t *dst, arena_stats_u64_t *src) {
554#ifdef JEMALLOC_ATOMIC_U64
555 uint64_t cur_dst = atomic_load_u64(dst, ATOMIC_RELAXED);
556 uint64_t cur_src = atomic_load_u64(src, ATOMIC_RELAXED);
557 atomic_store_u64(dst, cur_dst + cur_src, ATOMIC_RELAXED);
558#else
559 *dst += *src;
560#endif
561}
562
563/* Likewise: with ctl mutex synchronization, reading is simple. */
564static uint64_t
565arena_stats_read_u64(arena_stats_u64_t *p) {
566#ifdef JEMALLOC_ATOMIC_U64
567 return atomic_load_u64(p, ATOMIC_RELAXED);
568#else
569 return *p;
570#endif
571}
572
David Goldblattee202ef2017-03-13 16:18:40 -0700573static void accum_atomic_zu(atomic_zu_t *dst, atomic_zu_t *src) {
574 size_t cur_dst = atomic_load_zu(dst, ATOMIC_RELAXED);
575 size_t cur_src = atomic_load_zu(src, ATOMIC_RELAXED);
576 atomic_store_zu(dst, cur_dst + cur_src, ATOMIC_RELAXED);
577}
578
David Goldblatt4fc2acf2017-03-08 15:56:31 -0800579/******************************************************************************/
580
Jason Evans3dc4e832017-01-03 07:27:42 -0800581static unsigned
Jason Evansc4c25922017-01-15 16:56:30 -0800582arenas_i2a_impl(size_t i, bool compat, bool validate) {
Jason Evans3dc4e832017-01-03 07:27:42 -0800583 unsigned a;
584
Jason Evans3dc4e832017-01-03 07:27:42 -0800585 switch (i) {
586 case MALLCTL_ARENAS_ALL:
587 a = 0;
588 break;
Jason Evansedf1baf2017-01-03 17:21:59 -0800589 case MALLCTL_ARENAS_DESTROYED:
590 a = 1;
591 break;
Jason Evans3dc4e832017-01-03 07:27:42 -0800592 default:
Jason Evans9eb1b1c2017-01-18 23:03:37 -0800593 if (compat && i == ctl_arenas->narenas) {
Jason Evans3dc4e832017-01-03 07:27:42 -0800594 /*
595 * Provide deprecated backward compatibility for
596 * accessing the merged stats at index narenas rather
597 * than via MALLCTL_ARENAS_ALL. This is scheduled for
598 * removal in 6.0.0.
599 */
600 a = 0;
Jason Evansc4c25922017-01-15 16:56:30 -0800601 } else if (validate && i >= ctl_arenas->narenas) {
Jason Evans3dc4e832017-01-03 07:27:42 -0800602 a = UINT_MAX;
Jason Evansc4c25922017-01-15 16:56:30 -0800603 } else {
Jason Evans3dc4e832017-01-03 07:27:42 -0800604 /*
605 * This function should never be called for an index
606 * more than one past the range of indices that have
Jason Evans9eb1b1c2017-01-18 23:03:37 -0800607 * initialized ctl data.
Jason Evans3dc4e832017-01-03 07:27:42 -0800608 */
Jason Evans9eb1b1c2017-01-18 23:03:37 -0800609 assert(i < ctl_arenas->narenas || (!validate && i ==
610 ctl_arenas->narenas));
Jason Evansedf1baf2017-01-03 17:21:59 -0800611 a = (unsigned)i + 2;
Jason Evans3dc4e832017-01-03 07:27:42 -0800612 }
613 break;
614 }
615
Jason Evansf4086432017-01-19 18:15:45 -0800616 return a;
Jason Evans3dc4e832017-01-03 07:27:42 -0800617}
618
Jason Evansedf1baf2017-01-03 17:21:59 -0800619static unsigned
Jason Evansc4c25922017-01-15 16:56:30 -0800620arenas_i2a(size_t i) {
Jason Evansf4086432017-01-19 18:15:45 -0800621 return arenas_i2a_impl(i, true, false);
Jason Evansedf1baf2017-01-03 17:21:59 -0800622}
623
Jason Evans9eb1b1c2017-01-18 23:03:37 -0800624static ctl_arena_t *
Jason Evansc4c25922017-01-15 16:56:30 -0800625arenas_i_impl(tsdn_t *tsdn, size_t i, bool compat, bool init) {
Jason Evans9eb1b1c2017-01-18 23:03:37 -0800626 ctl_arena_t *ret;
Jason Evansd778dd22017-01-03 12:40:54 -0800627
628 assert(!compat || !init);
629
Jason Evans9eb1b1c2017-01-18 23:03:37 -0800630 ret = ctl_arenas->arenas[arenas_i2a_impl(i, compat, false)];
Jason Evansd778dd22017-01-03 12:40:54 -0800631 if (init && ret == NULL) {
Jason Evans9eb1b1c2017-01-18 23:03:37 -0800632 if (config_stats) {
633 struct container_s {
634 ctl_arena_t ctl_arena;
635 ctl_arena_stats_t astats;
636 };
637 struct container_s *cont =
638 (struct container_s *)base_alloc(tsdn, b0get(),
639 sizeof(struct container_s), QUANTUM);
640 if (cont == NULL) {
641 return NULL;
642 }
643 ret = &cont->ctl_arena;
644 ret->astats = &cont->astats;
645 } else {
646 ret = (ctl_arena_t *)base_alloc(tsdn, b0get(),
647 sizeof(ctl_arena_t), QUANTUM);
648 if (ret == NULL) {
649 return NULL;
650 }
651 }
Jason Evansedf1baf2017-01-03 17:21:59 -0800652 ret->arena_ind = (unsigned)i;
Jason Evans9eb1b1c2017-01-18 23:03:37 -0800653 ctl_arenas->arenas[arenas_i2a_impl(i, compat, false)] = ret;
Jason Evansd778dd22017-01-03 12:40:54 -0800654 }
655
Jason Evans9eb1b1c2017-01-18 23:03:37 -0800656 assert(ret == NULL || arenas_i2a(ret->arena_ind) == arenas_i2a(i));
Jason Evansf4086432017-01-19 18:15:45 -0800657 return ret;
Jason Evansd778dd22017-01-03 12:40:54 -0800658}
659
Jason Evans9eb1b1c2017-01-18 23:03:37 -0800660static ctl_arena_t *
Jason Evansc4c25922017-01-15 16:56:30 -0800661arenas_i(size_t i) {
Jason Evans9eb1b1c2017-01-18 23:03:37 -0800662 ctl_arena_t *ret = arenas_i_impl(TSDN_NULL, i, true, false);
Jason Evansd778dd22017-01-03 12:40:54 -0800663 assert(ret != NULL);
Jason Evansf4086432017-01-19 18:15:45 -0800664 return ret;
Jason Evans3dc4e832017-01-03 07:27:42 -0800665}
666
Jason Evans3c234352010-01-27 13:10:55 -0800667static void
Jason Evansc4c25922017-01-15 16:56:30 -0800668ctl_arena_clear(ctl_arena_t *ctl_arena) {
Jason Evans9eb1b1c2017-01-18 23:03:37 -0800669 ctl_arena->nthreads = 0;
670 ctl_arena->dss = dss_prec_names[dss_prec_limit];
Jason Evans6e62c622017-05-17 10:47:00 -0700671 ctl_arena->dirty_decay_ms = -1;
672 ctl_arena->muzzy_decay_ms = -1;
Jason Evans9eb1b1c2017-01-18 23:03:37 -0800673 ctl_arena->pactive = 0;
674 ctl_arena->pdirty = 0;
Jason Evans64e458f2017-03-08 22:42:57 -0800675 ctl_arena->pmuzzy = 0;
Jason Evans7372b152012-02-10 20:22:09 -0800676 if (config_stats) {
Jason Evans9eb1b1c2017-01-18 23:03:37 -0800677 memset(&ctl_arena->astats->astats, 0, sizeof(arena_stats_t));
678 ctl_arena->astats->allocated_small = 0;
679 ctl_arena->astats->nmalloc_small = 0;
680 ctl_arena->astats->ndalloc_small = 0;
681 ctl_arena->astats->nrequests_small = 0;
682 memset(ctl_arena->astats->bstats, 0, NBINS *
683 sizeof(malloc_bin_stats_t));
684 memset(ctl_arena->astats->lstats, 0, (NSIZES - NBINS) *
Jason Evans7d63fed2016-05-31 14:50:21 -0700685 sizeof(malloc_large_stats_t));
Jason Evans7372b152012-02-10 20:22:09 -0800686 }
Jason Evans3c234352010-01-27 13:10:55 -0800687}
688
Jason Evans86815df2010-03-13 20:32:56 -0800689static void
Jason Evansc4c25922017-01-15 16:56:30 -0800690ctl_arena_stats_amerge(tsdn_t *tsdn, ctl_arena_t *ctl_arena, arena_t *arena) {
Jason Evans86815df2010-03-13 20:32:56 -0800691 unsigned i;
692
Jason Evans3c07f802016-02-27 20:40:13 -0800693 if (config_stats) {
Jason Evans9eb1b1c2017-01-18 23:03:37 -0800694 arena_stats_merge(tsdn, arena, &ctl_arena->nthreads,
Jason Evans6e62c622017-05-17 10:47:00 -0700695 &ctl_arena->dss, &ctl_arena->dirty_decay_ms,
696 &ctl_arena->muzzy_decay_ms, &ctl_arena->pactive,
Jason Evans64e458f2017-03-08 22:42:57 -0800697 &ctl_arena->pdirty, &ctl_arena->pmuzzy,
Jason Evans9eb1b1c2017-01-18 23:03:37 -0800698 &ctl_arena->astats->astats, ctl_arena->astats->bstats,
699 ctl_arena->astats->lstats);
Jason Evans86815df2010-03-13 20:32:56 -0800700
Jason Evans3c07f802016-02-27 20:40:13 -0800701 for (i = 0; i < NBINS; i++) {
Jason Evans9eb1b1c2017-01-18 23:03:37 -0800702 ctl_arena->astats->allocated_small +=
703 ctl_arena->astats->bstats[i].curregs *
David Goldblatt8261e582017-05-30 10:45:37 -0700704 sz_index2size(i);
Jason Evans9eb1b1c2017-01-18 23:03:37 -0800705 ctl_arena->astats->nmalloc_small +=
706 ctl_arena->astats->bstats[i].nmalloc;
707 ctl_arena->astats->ndalloc_small +=
708 ctl_arena->astats->bstats[i].ndalloc;
709 ctl_arena->astats->nrequests_small +=
710 ctl_arena->astats->bstats[i].nrequests;
Jason Evans3c07f802016-02-27 20:40:13 -0800711 }
712 } else {
Jason Evans9eb1b1c2017-01-18 23:03:37 -0800713 arena_basic_stats_merge(tsdn, arena, &ctl_arena->nthreads,
Jason Evans6e62c622017-05-17 10:47:00 -0700714 &ctl_arena->dss, &ctl_arena->dirty_decay_ms,
715 &ctl_arena->muzzy_decay_ms, &ctl_arena->pactive,
Jason Evans64e458f2017-03-08 22:42:57 -0800716 &ctl_arena->pdirty, &ctl_arena->pmuzzy);
Jason Evans86815df2010-03-13 20:32:56 -0800717 }
Jason Evans86815df2010-03-13 20:32:56 -0800718}
719
720static void
Jason Evans9eb1b1c2017-01-18 23:03:37 -0800721ctl_arena_stats_sdmerge(ctl_arena_t *ctl_sdarena, ctl_arena_t *ctl_arena,
Jason Evansc4c25922017-01-15 16:56:30 -0800722 bool destroyed) {
Jason Evans86815df2010-03-13 20:32:56 -0800723 unsigned i;
724
Jason Evansedf1baf2017-01-03 17:21:59 -0800725 if (!destroyed) {
Jason Evans9eb1b1c2017-01-18 23:03:37 -0800726 ctl_sdarena->nthreads += ctl_arena->nthreads;
727 ctl_sdarena->pactive += ctl_arena->pactive;
728 ctl_sdarena->pdirty += ctl_arena->pdirty;
Jason Evans64e458f2017-03-08 22:42:57 -0800729 ctl_sdarena->pmuzzy += ctl_arena->pmuzzy;
Jason Evansedf1baf2017-01-03 17:21:59 -0800730 } else {
Jason Evans9eb1b1c2017-01-18 23:03:37 -0800731 assert(ctl_arena->nthreads == 0);
732 assert(ctl_arena->pactive == 0);
733 assert(ctl_arena->pdirty == 0);
Jason Evans64e458f2017-03-08 22:42:57 -0800734 assert(ctl_arena->pmuzzy == 0);
Jason Evansedf1baf2017-01-03 17:21:59 -0800735 }
Jason Evans86815df2010-03-13 20:32:56 -0800736
Jason Evans3c07f802016-02-27 20:40:13 -0800737 if (config_stats) {
Jason Evans9eb1b1c2017-01-18 23:03:37 -0800738 ctl_arena_stats_t *sdstats = ctl_sdarena->astats;
739 ctl_arena_stats_t *astats = ctl_arena->astats;
740
Jason Evansedf1baf2017-01-03 17:21:59 -0800741 if (!destroyed) {
David Goldblattee202ef2017-03-13 16:18:40 -0700742 accum_atomic_zu(&sdstats->astats.mapped,
743 &astats->astats.mapped);
744 accum_atomic_zu(&sdstats->astats.retained,
745 &astats->astats.retained);
Jason Evansedf1baf2017-01-03 17:21:59 -0800746 }
Jason Evans64e458f2017-03-08 22:42:57 -0800747
748 accum_arena_stats_u64(&sdstats->astats.decay_dirty.npurge,
749 &astats->astats.decay_dirty.npurge);
750 accum_arena_stats_u64(&sdstats->astats.decay_dirty.nmadvise,
751 &astats->astats.decay_dirty.nmadvise);
752 accum_arena_stats_u64(&sdstats->astats.decay_dirty.purged,
753 &astats->astats.decay_dirty.purged);
754
755 accum_arena_stats_u64(&sdstats->astats.decay_muzzy.npurge,
756 &astats->astats.decay_muzzy.npurge);
757 accum_arena_stats_u64(&sdstats->astats.decay_muzzy.nmadvise,
758 &astats->astats.decay_muzzy.nmadvise);
759 accum_arena_stats_u64(&sdstats->astats.decay_muzzy.purged,
760 &astats->astats.decay_muzzy.purged);
Jason Evans86815df2010-03-13 20:32:56 -0800761
Qi Wangd3fde1c2017-03-21 11:56:38 -0700762#define OP(mtx) malloc_mutex_prof_merge( \
763 &(sdstats->astats.mutex_prof_data[ \
764 arena_prof_mutex_##mtx]), \
765 &(astats->astats.mutex_prof_data[ \
766 arena_prof_mutex_##mtx]));
David Goldblatt89e2d3c2017-04-24 17:09:56 -0700767MUTEX_PROF_ARENA_MUTEXES
Qi Wangd3fde1c2017-03-21 11:56:38 -0700768#undef OP
Jason Evansedf1baf2017-01-03 17:21:59 -0800769 if (!destroyed) {
David Goldblattee202ef2017-03-13 16:18:40 -0700770 accum_atomic_zu(&sdstats->astats.base,
771 &astats->astats.base);
772 accum_atomic_zu(&sdstats->astats.internal,
773 &astats->astats.internal);
774 accum_atomic_zu(&sdstats->astats.resident,
775 &astats->astats.resident);
Jason Evansc4c25922017-01-15 16:56:30 -0800776 } else {
David Goldblattee202ef2017-03-13 16:18:40 -0700777 assert(atomic_load_zu(
778 &astats->astats.internal, ATOMIC_RELAXED) == 0);
Jason Evansc4c25922017-01-15 16:56:30 -0800779 }
Jason Evans4581b972014-11-27 17:22:36 -0200780
Jason Evansc4c25922017-01-15 16:56:30 -0800781 if (!destroyed) {
Jason Evansedf1baf2017-01-03 17:21:59 -0800782 sdstats->allocated_small += astats->allocated_small;
Jason Evansc4c25922017-01-15 16:56:30 -0800783 } else {
Jason Evansedf1baf2017-01-03 17:21:59 -0800784 assert(astats->allocated_small == 0);
Jason Evansc4c25922017-01-15 16:56:30 -0800785 }
Jason Evansedf1baf2017-01-03 17:21:59 -0800786 sdstats->nmalloc_small += astats->nmalloc_small;
787 sdstats->ndalloc_small += astats->ndalloc_small;
788 sdstats->nrequests_small += astats->nrequests_small;
Jason Evans86815df2010-03-13 20:32:56 -0800789
Jason Evansedf1baf2017-01-03 17:21:59 -0800790 if (!destroyed) {
David Goldblattee202ef2017-03-13 16:18:40 -0700791 accum_atomic_zu(&sdstats->astats.allocated_large,
792 &astats->astats.allocated_large);
Jason Evansc4c25922017-01-15 16:56:30 -0800793 } else {
David Goldblattee202ef2017-03-13 16:18:40 -0700794 assert(atomic_load_zu(&astats->astats.allocated_large,
795 ATOMIC_RELAXED) == 0);
Jason Evansc4c25922017-01-15 16:56:30 -0800796 }
David Goldblatt4fc2acf2017-03-08 15:56:31 -0800797 accum_arena_stats_u64(&sdstats->astats.nmalloc_large,
798 &astats->astats.nmalloc_large);
799 accum_arena_stats_u64(&sdstats->astats.ndalloc_large,
800 &astats->astats.ndalloc_large);
801 accum_arena_stats_u64(&sdstats->astats.nrequests_large,
802 &astats->astats.nrequests_large);
Jason Evans86815df2010-03-13 20:32:56 -0800803
Jason Evans4403c9a2017-04-20 17:21:37 -0700804 accum_atomic_zu(&sdstats->astats.tcache_bytes,
805 &astats->astats.tcache_bytes);
Qi Wang58424e62016-04-22 18:37:44 -0700806
Qi Wangbaf3e292017-05-16 13:56:00 -0700807 if (ctl_arena->arena_ind == 0) {
808 sdstats->astats.uptime = astats->astats.uptime;
809 }
810
Jason Evans3c07f802016-02-27 20:40:13 -0800811 for (i = 0; i < NBINS; i++) {
Jason Evansedf1baf2017-01-03 17:21:59 -0800812 sdstats->bstats[i].nmalloc += astats->bstats[i].nmalloc;
813 sdstats->bstats[i].ndalloc += astats->bstats[i].ndalloc;
814 sdstats->bstats[i].nrequests +=
Jason Evans3c07f802016-02-27 20:40:13 -0800815 astats->bstats[i].nrequests;
Jason Evansedf1baf2017-01-03 17:21:59 -0800816 if (!destroyed) {
817 sdstats->bstats[i].curregs +=
818 astats->bstats[i].curregs;
Jason Evansc4c25922017-01-15 16:56:30 -0800819 } else {
Jason Evansedf1baf2017-01-03 17:21:59 -0800820 assert(astats->bstats[i].curregs == 0);
Jason Evansc4c25922017-01-15 16:56:30 -0800821 }
Jason Evans4403c9a2017-04-20 17:21:37 -0700822 sdstats->bstats[i].nfills += astats->bstats[i].nfills;
823 sdstats->bstats[i].nflushes +=
824 astats->bstats[i].nflushes;
Jason Evansedf1baf2017-01-03 17:21:59 -0800825 sdstats->bstats[i].nslabs += astats->bstats[i].nslabs;
826 sdstats->bstats[i].reslabs += astats->bstats[i].reslabs;
827 if (!destroyed) {
828 sdstats->bstats[i].curslabs +=
829 astats->bstats[i].curslabs;
Jason Evansc4c25922017-01-15 16:56:30 -0800830 } else {
Jason Evansedf1baf2017-01-03 17:21:59 -0800831 assert(astats->bstats[i].curslabs == 0);
Jason Evansc4c25922017-01-15 16:56:30 -0800832 }
Qi Wang64c5f5c2017-03-13 17:29:03 -0700833 malloc_mutex_prof_merge(&sdstats->bstats[i].mutex_data,
834 &astats->bstats[i].mutex_data);
Jason Evans7372b152012-02-10 20:22:09 -0800835 }
Jason Evans3c4d92e2014-10-12 22:53:59 -0700836
Jason Evansed2c2422016-05-28 00:17:28 -0700837 for (i = 0; i < NSIZES - NBINS; i++) {
David Goldblatt4fc2acf2017-03-08 15:56:31 -0800838 accum_arena_stats_u64(&sdstats->lstats[i].nmalloc,
839 &astats->lstats[i].nmalloc);
840 accum_arena_stats_u64(&sdstats->lstats[i].ndalloc,
841 &astats->lstats[i].ndalloc);
842 accum_arena_stats_u64(&sdstats->lstats[i].nrequests,
843 &astats->lstats[i].nrequests);
Jason Evansedf1baf2017-01-03 17:21:59 -0800844 if (!destroyed) {
845 sdstats->lstats[i].curlextents +=
846 astats->lstats[i].curlextents;
Jason Evansc4c25922017-01-15 16:56:30 -0800847 } else {
Jason Evansedf1baf2017-01-03 17:21:59 -0800848 assert(astats->lstats[i].curlextents == 0);
Jason Evansc4c25922017-01-15 16:56:30 -0800849 }
Jason Evans3c07f802016-02-27 20:40:13 -0800850 }
Jason Evans3c4d92e2014-10-12 22:53:59 -0700851 }
Jason Evans86815df2010-03-13 20:32:56 -0800852}
Jason Evans86815df2010-03-13 20:32:56 -0800853
Jason Evans3c234352010-01-27 13:10:55 -0800854static void
Jason Evans9eb1b1c2017-01-18 23:03:37 -0800855ctl_arena_refresh(tsdn_t *tsdn, arena_t *arena, ctl_arena_t *ctl_sdarena,
Jason Evansc4c25922017-01-15 16:56:30 -0800856 unsigned i, bool destroyed) {
Jason Evans9eb1b1c2017-01-18 23:03:37 -0800857 ctl_arena_t *ctl_arena = arenas_i(i);
Jason Evans3c234352010-01-27 13:10:55 -0800858
Jason Evans9eb1b1c2017-01-18 23:03:37 -0800859 ctl_arena_clear(ctl_arena);
860 ctl_arena_stats_amerge(tsdn, ctl_arena, arena);
Jason Evans3c07f802016-02-27 20:40:13 -0800861 /* Merge into sum stats as well. */
Jason Evans9eb1b1c2017-01-18 23:03:37 -0800862 ctl_arena_stats_sdmerge(ctl_sdarena, ctl_arena, destroyed);
Jason Evans3c234352010-01-27 13:10:55 -0800863}
864
Jason Evansedf1baf2017-01-03 17:21:59 -0800865static unsigned
Jason Evansc4c25922017-01-15 16:56:30 -0800866ctl_arena_init(tsdn_t *tsdn, extent_hooks_t *extent_hooks) {
Jason Evansedf1baf2017-01-03 17:21:59 -0800867 unsigned arena_ind;
Jason Evans9eb1b1c2017-01-18 23:03:37 -0800868 ctl_arena_t *ctl_arena;
Jason Evansedf1baf2017-01-03 17:21:59 -0800869
Jason Evans9eb1b1c2017-01-18 23:03:37 -0800870 if ((ctl_arena = ql_last(&ctl_arenas->destroyed, destroyed_link)) !=
871 NULL) {
872 ql_remove(&ctl_arenas->destroyed, ctl_arena, destroyed_link);
873 arena_ind = ctl_arena->arena_ind;
Jason Evansc4c25922017-01-15 16:56:30 -0800874 } else {
Jason Evans9eb1b1c2017-01-18 23:03:37 -0800875 arena_ind = ctl_arenas->narenas;
Jason Evansc4c25922017-01-15 16:56:30 -0800876 }
Jason Evansd778dd22017-01-03 12:40:54 -0800877
878 /* Trigger stats allocation. */
Jason Evansc4c25922017-01-15 16:56:30 -0800879 if (arenas_i_impl(tsdn, arena_ind, false, true) == NULL) {
Jason Evansf4086432017-01-19 18:15:45 -0800880 return UINT_MAX;
Jason Evansc4c25922017-01-15 16:56:30 -0800881 }
Jason Evans609ae592012-10-11 13:53:15 -0700882
Jason Evans8bb31982014-10-07 23:14:57 -0700883 /* Initialize new arena. */
Jason Evansc4c25922017-01-15 16:56:30 -0800884 if (arena_init(tsdn, arena_ind, extent_hooks) == NULL) {
Jason Evansf4086432017-01-19 18:15:45 -0800885 return UINT_MAX;
Jason Evansc4c25922017-01-15 16:56:30 -0800886 }
Jason Evans609ae592012-10-11 13:53:15 -0700887
Jason Evansc4c25922017-01-15 16:56:30 -0800888 if (arena_ind == ctl_arenas->narenas) {
Jason Evans9eb1b1c2017-01-18 23:03:37 -0800889 ctl_arenas->narenas++;
Jason Evansc4c25922017-01-15 16:56:30 -0800890 }
Jason Evansedf1baf2017-01-03 17:21:59 -0800891
Jason Evansf4086432017-01-19 18:15:45 -0800892 return arena_ind;
Jason Evans609ae592012-10-11 13:53:15 -0700893}
894
Jason Evans3c234352010-01-27 13:10:55 -0800895static void
Qi Wang2bee0c62017-05-12 12:30:33 -0700896ctl_background_thread_stats_read(tsdn_t *tsdn) {
897 background_thread_stats_t *stats = &ctl_stats->background_thread;
898 if (!have_background_thread ||
899 background_thread_stats_read(tsdn, stats)) {
900 memset(stats, 0, sizeof(background_thread_stats_t));
901 nstime_init(&stats->run_interval, 0);
902 }
903}
904
905static void
Jason Evansc4c25922017-01-15 16:56:30 -0800906ctl_refresh(tsdn_t *tsdn) {
Jason Evans3c234352010-01-27 13:10:55 -0800907 unsigned i;
Jason Evans9eb1b1c2017-01-18 23:03:37 -0800908 ctl_arena_t *ctl_sarena = arenas_i(MALLCTL_ARENAS_ALL);
909 VARIABLE_ARRAY(arena_t *, tarenas, ctl_arenas->narenas);
Jason Evans3c234352010-01-27 13:10:55 -0800910
Jason Evans3c234352010-01-27 13:10:55 -0800911 /*
Jason Evans13668262010-01-31 03:57:29 -0800912 * Clear sum stats, since they will be merged into by
Jason Evans3c234352010-01-27 13:10:55 -0800913 * ctl_arena_refresh().
914 */
Jason Evans9eb1b1c2017-01-18 23:03:37 -0800915 ctl_arena_clear(ctl_sarena);
Jason Evans3c234352010-01-27 13:10:55 -0800916
Jason Evans9eb1b1c2017-01-18 23:03:37 -0800917 for (i = 0; i < ctl_arenas->narenas; i++) {
Jason Evansc1e00ef2016-05-10 22:21:10 -0700918 tarenas[i] = arena_get(tsdn, i, false);
Jason Evans9eb1b1c2017-01-18 23:03:37 -0800919 }
Jason Evans8bb31982014-10-07 23:14:57 -0700920
Jason Evans9eb1b1c2017-01-18 23:03:37 -0800921 for (i = 0; i < ctl_arenas->narenas; i++) {
922 ctl_arena_t *ctl_arena = arenas_i(i);
Jason Evans3c234352010-01-27 13:10:55 -0800923 bool initialized = (tarenas[i] != NULL);
924
Jason Evans9eb1b1c2017-01-18 23:03:37 -0800925 ctl_arena->initialized = initialized;
926 if (initialized) {
927 ctl_arena_refresh(tsdn, tarenas[i], ctl_sarena, i,
928 false);
929 }
Jason Evans3c234352010-01-27 13:10:55 -0800930 }
931
Jason Evans7372b152012-02-10 20:22:09 -0800932 if (config_stats) {
Jason Evans9eb1b1c2017-01-18 23:03:37 -0800933 ctl_stats->allocated = ctl_sarena->astats->allocated_small +
David Goldblattee202ef2017-03-13 16:18:40 -0700934 atomic_load_zu(&ctl_sarena->astats->astats.allocated_large,
935 ATOMIC_RELAXED);
Jason Evans9eb1b1c2017-01-18 23:03:37 -0800936 ctl_stats->active = (ctl_sarena->pactive << LG_PAGE);
David Goldblattee202ef2017-03-13 16:18:40 -0700937 ctl_stats->metadata = atomic_load_zu(
938 &ctl_sarena->astats->astats.base, ATOMIC_RELAXED) +
939 atomic_load_zu(&ctl_sarena->astats->astats.internal,
940 ATOMIC_RELAXED);
941 ctl_stats->resident = atomic_load_zu(
942 &ctl_sarena->astats->astats.resident, ATOMIC_RELAXED);
943 ctl_stats->mapped = atomic_load_zu(
944 &ctl_sarena->astats->astats.mapped, ATOMIC_RELAXED);
945 ctl_stats->retained = atomic_load_zu(
946 &ctl_sarena->astats->astats.retained, ATOMIC_RELAXED);
Qi Wangca9074d2017-03-11 20:28:31 -0800947
Qi Wang2bee0c62017-05-12 12:30:33 -0700948 ctl_background_thread_stats_read(tsdn);
949
Qi Wangd3fde1c2017-03-21 11:56:38 -0700950#define READ_GLOBAL_MUTEX_PROF_DATA(i, mtx) \
Qi Wangca9074d2017-03-11 20:28:31 -0800951 malloc_mutex_lock(tsdn, &mtx); \
Qi Wangd3fde1c2017-03-21 11:56:38 -0700952 malloc_mutex_prof_read(tsdn, &ctl_stats->mutex_prof_data[i], &mtx); \
Qi Wangca9074d2017-03-11 20:28:31 -0800953 malloc_mutex_unlock(tsdn, &mtx);
954
Qi Wangbd2006a2017-03-12 01:28:52 -0800955 if (config_prof && opt_prof) {
Qi Wangd3fde1c2017-03-21 11:56:38 -0700956 READ_GLOBAL_MUTEX_PROF_DATA(global_prof_mutex_prof,
957 bt2gctx_mtx);
Qi Wangbd2006a2017-03-12 01:28:52 -0800958 }
Qi Wang5f5ed212017-05-12 16:26:59 -0700959 if (have_background_thread) {
960 READ_GLOBAL_MUTEX_PROF_DATA(
961 global_prof_mutex_background_thread,
962 background_thread_lock);
963 } else {
964 memset(&ctl_stats->mutex_prof_data[
965 global_prof_mutex_background_thread], 0,
966 sizeof(mutex_prof_data_t));
967 }
Qi Wangca9074d2017-03-11 20:28:31 -0800968 /* We own ctl mutex already. */
Qi Wangd3fde1c2017-03-21 11:56:38 -0700969 malloc_mutex_prof_read(tsdn,
970 &ctl_stats->mutex_prof_data[global_prof_mutex_ctl],
971 &ctl_mtx);
Qi Wangca9074d2017-03-11 20:28:31 -0800972#undef READ_GLOBAL_MUTEX_PROF_DATA
Jason Evans7372b152012-02-10 20:22:09 -0800973 }
Jason Evans9eb1b1c2017-01-18 23:03:37 -0800974 ctl_arenas->epoch++;
Jason Evans3c234352010-01-27 13:10:55 -0800975}
976
977static bool
Jason Evansc4c25922017-01-15 16:56:30 -0800978ctl_init(tsdn_t *tsdn) {
Jason Evansfc4dcfa2010-11-24 15:44:21 -0800979 bool ret;
Jason Evans3c234352010-01-27 13:10:55 -0800980
Jason Evansc1e00ef2016-05-10 22:21:10 -0700981 malloc_mutex_lock(tsdn, &ctl_mtx);
Jason Evans551ebc42014-10-03 10:16:09 -0700982 if (!ctl_initialized) {
Jason Evans9eb1b1c2017-01-18 23:03:37 -0800983 ctl_arena_t *ctl_sarena, *ctl_darena;
Jason Evansd778dd22017-01-03 12:40:54 -0800984 unsigned i;
985
Jason Evans3c234352010-01-27 13:10:55 -0800986 /*
Jason Evans9eb1b1c2017-01-18 23:03:37 -0800987 * Allocate demand-zeroed space for pointers to the full
988 * range of supported arena indices.
Jason Evans3c234352010-01-27 13:10:55 -0800989 */
Jason Evans9eb1b1c2017-01-18 23:03:37 -0800990 if (ctl_arenas == NULL) {
991 ctl_arenas = (ctl_arenas_t *)base_alloc(tsdn,
992 b0get(), sizeof(ctl_arenas_t), QUANTUM);
993 if (ctl_arenas == NULL) {
994 ret = true;
995 goto label_return;
996 }
997 }
998
999 if (config_stats && ctl_stats == NULL) {
Jason Evansd778dd22017-01-03 12:40:54 -08001000 ctl_stats = (ctl_stats_t *)base_alloc(tsdn, b0get(),
1001 sizeof(ctl_stats_t), QUANTUM);
1002 if (ctl_stats == NULL) {
1003 ret = true;
1004 goto label_return;
1005 }
1006 }
1007
1008 /*
Jason Evans9eb1b1c2017-01-18 23:03:37 -08001009 * Allocate space for the current full range of arenas
1010 * here rather than doing it lazily elsewhere, in order
1011 * to limit when OOM-caused errors can occur.
Jason Evansd778dd22017-01-03 12:40:54 -08001012 */
Jason Evans9eb1b1c2017-01-18 23:03:37 -08001013 if ((ctl_sarena = arenas_i_impl(tsdn, MALLCTL_ARENAS_ALL, false,
1014 true)) == NULL) {
1015 ret = true;
1016 goto label_return;
1017 }
1018 ctl_sarena->initialized = true;
1019
1020 if ((ctl_darena = arenas_i_impl(tsdn, MALLCTL_ARENAS_DESTROYED,
Jason Evansd778dd22017-01-03 12:40:54 -08001021 false, true)) == NULL) {
Jason Evansfc4dcfa2010-11-24 15:44:21 -08001022 ret = true;
Jason Evansa1ee7832012-04-10 15:07:44 -07001023 goto label_return;
Jason Evansfc4dcfa2010-11-24 15:44:21 -08001024 }
Jason Evans9eb1b1c2017-01-18 23:03:37 -08001025 ctl_arena_clear(ctl_darena);
Jason Evansedf1baf2017-01-03 17:21:59 -08001026 /*
Jason Evans9eb1b1c2017-01-18 23:03:37 -08001027 * Don't toggle ctl_darena to initialized until an arena is
1028 * actually destroyed, so that arena.<i>.initialized can be used
1029 * to query whether the stats are relevant.
Jason Evansedf1baf2017-01-03 17:21:59 -08001030 */
1031
Jason Evans9eb1b1c2017-01-18 23:03:37 -08001032 ctl_arenas->narenas = narenas_total_get();
1033 for (i = 0; i < ctl_arenas->narenas; i++) {
1034 if (arenas_i_impl(tsdn, i, false, true) == NULL) {
Jason Evansd778dd22017-01-03 12:40:54 -08001035 ret = true;
1036 goto label_return;
1037 }
1038 }
Jason Evans3c234352010-01-27 13:10:55 -08001039
Jason Evans9eb1b1c2017-01-18 23:03:37 -08001040 ql_new(&ctl_arenas->destroyed);
Jason Evansc1e00ef2016-05-10 22:21:10 -07001041 ctl_refresh(tsdn);
Jason Evans9eb1b1c2017-01-18 23:03:37 -08001042
Jason Evans3c234352010-01-27 13:10:55 -08001043 ctl_initialized = true;
1044 }
1045
Jason Evansfc4dcfa2010-11-24 15:44:21 -08001046 ret = false;
Jason Evansa1ee7832012-04-10 15:07:44 -07001047label_return:
Jason Evansc1e00ef2016-05-10 22:21:10 -07001048 malloc_mutex_unlock(tsdn, &ctl_mtx);
Jason Evansf4086432017-01-19 18:15:45 -08001049 return ret;
Jason Evans3c234352010-01-27 13:10:55 -08001050}
1051
1052static int
Jason Evansc1e00ef2016-05-10 22:21:10 -07001053ctl_lookup(tsdn_t *tsdn, const char *name, ctl_node_t const **nodesp,
Jason Evansc4c25922017-01-15 16:56:30 -08001054 size_t *mibp, size_t *depthp) {
Jason Evans3c234352010-01-27 13:10:55 -08001055 int ret;
1056 const char *elm, *tdot, *dot;
1057 size_t elen, i, j;
Mike Hommey461ad5c2012-04-20 08:38:42 +02001058 const ctl_named_node_t *node;
Jason Evans3c234352010-01-27 13:10:55 -08001059
1060 elm = name;
1061 /* Equivalent to strchrnul(). */
1062 dot = ((tdot = strchr(elm, '.')) != NULL) ? tdot : strchr(elm, '\0');
1063 elen = (size_t)((uintptr_t)dot - (uintptr_t)elm);
1064 if (elen == 0) {
1065 ret = ENOENT;
Jason Evansa1ee7832012-04-10 15:07:44 -07001066 goto label_return;
Jason Evans3c234352010-01-27 13:10:55 -08001067 }
1068 node = super_root_node;
1069 for (i = 0; i < *depthp; i++) {
Mike Hommey461ad5c2012-04-20 08:38:42 +02001070 assert(node);
1071 assert(node->nchildren > 0);
1072 if (ctl_named_node(node->children) != NULL) {
1073 const ctl_named_node_t *pnode = node;
Jason Evans3c234352010-01-27 13:10:55 -08001074
1075 /* Children are named. */
Mike Hommey461ad5c2012-04-20 08:38:42 +02001076 for (j = 0; j < node->nchildren; j++) {
1077 const ctl_named_node_t *child =
1078 ctl_named_children(node, j);
1079 if (strlen(child->name) == elen &&
1080 strncmp(elm, child->name, elen) == 0) {
Jason Evans3c234352010-01-27 13:10:55 -08001081 node = child;
Jason Evansc4c25922017-01-15 16:56:30 -08001082 if (nodesp != NULL) {
Mike Hommey461ad5c2012-04-20 08:38:42 +02001083 nodesp[i] =
1084 (const ctl_node_t *)node;
Jason Evansc4c25922017-01-15 16:56:30 -08001085 }
Jason Evans3c234352010-01-27 13:10:55 -08001086 mibp[i] = j;
1087 break;
1088 }
1089 }
1090 if (node == pnode) {
1091 ret = ENOENT;
Jason Evansa1ee7832012-04-10 15:07:44 -07001092 goto label_return;
Jason Evans3c234352010-01-27 13:10:55 -08001093 }
1094 } else {
Jason Evans41b6afb2012-02-02 22:04:57 -08001095 uintmax_t index;
Mike Hommey461ad5c2012-04-20 08:38:42 +02001096 const ctl_indexed_node_t *inode;
Jason Evans3c234352010-01-27 13:10:55 -08001097
1098 /* Children are indexed. */
Jason Evans41b6afb2012-02-02 22:04:57 -08001099 index = malloc_strtoumax(elm, NULL, 10);
1100 if (index == UINTMAX_MAX || index > SIZE_T_MAX) {
Jason Evans3c234352010-01-27 13:10:55 -08001101 ret = ENOENT;
Jason Evansa1ee7832012-04-10 15:07:44 -07001102 goto label_return;
Jason Evans3c234352010-01-27 13:10:55 -08001103 }
1104
Mike Hommey461ad5c2012-04-20 08:38:42 +02001105 inode = ctl_indexed_node(node->children);
Jason Evansc1e00ef2016-05-10 22:21:10 -07001106 node = inode->index(tsdn, mibp, *depthp, (size_t)index);
Jason Evans3c234352010-01-27 13:10:55 -08001107 if (node == NULL) {
1108 ret = ENOENT;
Jason Evansa1ee7832012-04-10 15:07:44 -07001109 goto label_return;
Jason Evans3c234352010-01-27 13:10:55 -08001110 }
1111
Jason Evansc4c25922017-01-15 16:56:30 -08001112 if (nodesp != NULL) {
Mike Hommey461ad5c2012-04-20 08:38:42 +02001113 nodesp[i] = (const ctl_node_t *)node;
Jason Evansc4c25922017-01-15 16:56:30 -08001114 }
Jason Evans3c234352010-01-27 13:10:55 -08001115 mibp[i] = (size_t)index;
1116 }
1117
1118 if (node->ctl != NULL) {
1119 /* Terminal node. */
1120 if (*dot != '\0') {
1121 /*
1122 * The name contains more elements than are
1123 * in this path through the tree.
1124 */
1125 ret = ENOENT;
Jason Evansa1ee7832012-04-10 15:07:44 -07001126 goto label_return;
Jason Evans3c234352010-01-27 13:10:55 -08001127 }
1128 /* Complete lookup successful. */
1129 *depthp = i + 1;
1130 break;
1131 }
1132
1133 /* Update elm. */
1134 if (*dot == '\0') {
1135 /* No more elements. */
1136 ret = ENOENT;
Jason Evansa1ee7832012-04-10 15:07:44 -07001137 goto label_return;
Jason Evans3c234352010-01-27 13:10:55 -08001138 }
1139 elm = &dot[1];
1140 dot = ((tdot = strchr(elm, '.')) != NULL) ? tdot :
1141 strchr(elm, '\0');
1142 elen = (size_t)((uintptr_t)dot - (uintptr_t)elm);
1143 }
1144
1145 ret = 0;
Jason Evansa1ee7832012-04-10 15:07:44 -07001146label_return:
Jason Evansf4086432017-01-19 18:15:45 -08001147 return ret;
Jason Evans3c234352010-01-27 13:10:55 -08001148}
1149
1150int
Jason Evansb2c0d632016-04-13 23:36:15 -07001151ctl_byname(tsd_t *tsd, const char *name, void *oldp, size_t *oldlenp,
Jason Evansc4c25922017-01-15 16:56:30 -08001152 void *newp, size_t newlen) {
Jason Evans3c234352010-01-27 13:10:55 -08001153 int ret;
1154 size_t depth;
1155 ctl_node_t const *nodes[CTL_MAX_DEPTH];
1156 size_t mib[CTL_MAX_DEPTH];
Mike Hommey461ad5c2012-04-20 08:38:42 +02001157 const ctl_named_node_t *node;
Jason Evans3c234352010-01-27 13:10:55 -08001158
Jason Evansc1e00ef2016-05-10 22:21:10 -07001159 if (!ctl_initialized && ctl_init(tsd_tsdn(tsd))) {
Jason Evans3c234352010-01-27 13:10:55 -08001160 ret = EAGAIN;
Jason Evansa1ee7832012-04-10 15:07:44 -07001161 goto label_return;
Jason Evans3c234352010-01-27 13:10:55 -08001162 }
1163
1164 depth = CTL_MAX_DEPTH;
Jason Evansc1e00ef2016-05-10 22:21:10 -07001165 ret = ctl_lookup(tsd_tsdn(tsd), name, nodes, mib, &depth);
Jason Evansc4c25922017-01-15 16:56:30 -08001166 if (ret != 0) {
Jason Evansa1ee7832012-04-10 15:07:44 -07001167 goto label_return;
Jason Evansc4c25922017-01-15 16:56:30 -08001168 }
Jason Evans3c234352010-01-27 13:10:55 -08001169
Mike Hommey461ad5c2012-04-20 08:38:42 +02001170 node = ctl_named_node(nodes[depth-1]);
Jason Evansc4c25922017-01-15 16:56:30 -08001171 if (node != NULL && node->ctl) {
Jason Evansb2c0d632016-04-13 23:36:15 -07001172 ret = node->ctl(tsd, mib, depth, oldp, oldlenp, newp, newlen);
Qi Wangaa1de062017-03-01 14:43:35 -08001173 } else {
Jason Evans3c234352010-01-27 13:10:55 -08001174 /* The name refers to a partial path through the ctl tree. */
1175 ret = ENOENT;
Jason Evans3c234352010-01-27 13:10:55 -08001176 }
Jason Evans3c234352010-01-27 13:10:55 -08001177
Jason Evansa1ee7832012-04-10 15:07:44 -07001178label_return:
Jason Evans3c234352010-01-27 13:10:55 -08001179 return(ret);
1180}
1181
1182int
Jason Evansc4c25922017-01-15 16:56:30 -08001183ctl_nametomib(tsdn_t *tsdn, const char *name, size_t *mibp, size_t *miblenp) {
Jason Evans3c234352010-01-27 13:10:55 -08001184 int ret;
1185
Jason Evansc1e00ef2016-05-10 22:21:10 -07001186 if (!ctl_initialized && ctl_init(tsdn)) {
Jason Evans3c234352010-01-27 13:10:55 -08001187 ret = EAGAIN;
Jason Evansa1ee7832012-04-10 15:07:44 -07001188 goto label_return;
Jason Evans3c234352010-01-27 13:10:55 -08001189 }
1190
Jason Evansc1e00ef2016-05-10 22:21:10 -07001191 ret = ctl_lookup(tsdn, name, NULL, mibp, miblenp);
Jason Evansa1ee7832012-04-10 15:07:44 -07001192label_return:
Jason Evans3c234352010-01-27 13:10:55 -08001193 return(ret);
1194}
1195
1196int
Jason Evansb2c0d632016-04-13 23:36:15 -07001197ctl_bymib(tsd_t *tsd, const size_t *mib, size_t miblen, void *oldp,
Jason Evansc4c25922017-01-15 16:56:30 -08001198 size_t *oldlenp, void *newp, size_t newlen) {
Jason Evans3c234352010-01-27 13:10:55 -08001199 int ret;
Mike Hommey461ad5c2012-04-20 08:38:42 +02001200 const ctl_named_node_t *node;
Jason Evans3c234352010-01-27 13:10:55 -08001201 size_t i;
1202
Jason Evansc1e00ef2016-05-10 22:21:10 -07001203 if (!ctl_initialized && ctl_init(tsd_tsdn(tsd))) {
Jason Evans3c234352010-01-27 13:10:55 -08001204 ret = EAGAIN;
Jason Evansa1ee7832012-04-10 15:07:44 -07001205 goto label_return;
Jason Evans3c234352010-01-27 13:10:55 -08001206 }
1207
1208 /* Iterate down the tree. */
1209 node = super_root_node;
1210 for (i = 0; i < miblen; i++) {
Mike Hommey461ad5c2012-04-20 08:38:42 +02001211 assert(node);
1212 assert(node->nchildren > 0);
1213 if (ctl_named_node(node->children) != NULL) {
Jason Evans3c234352010-01-27 13:10:55 -08001214 /* Children are named. */
Jason Evans6edbedd2017-01-04 07:51:49 -08001215 if (node->nchildren <= mib[i]) {
Jason Evans3c234352010-01-27 13:10:55 -08001216 ret = ENOENT;
Jason Evansa1ee7832012-04-10 15:07:44 -07001217 goto label_return;
Jason Evans3c234352010-01-27 13:10:55 -08001218 }
Mike Hommey461ad5c2012-04-20 08:38:42 +02001219 node = ctl_named_children(node, mib[i]);
Jason Evans3c234352010-01-27 13:10:55 -08001220 } else {
Mike Hommey461ad5c2012-04-20 08:38:42 +02001221 const ctl_indexed_node_t *inode;
Jason Evans3c234352010-01-27 13:10:55 -08001222
1223 /* Indexed element. */
Mike Hommey461ad5c2012-04-20 08:38:42 +02001224 inode = ctl_indexed_node(node->children);
Jason Evansc1e00ef2016-05-10 22:21:10 -07001225 node = inode->index(tsd_tsdn(tsd), mib, miblen, mib[i]);
Jason Evans3c234352010-01-27 13:10:55 -08001226 if (node == NULL) {
1227 ret = ENOENT;
Jason Evansa1ee7832012-04-10 15:07:44 -07001228 goto label_return;
Jason Evans3c234352010-01-27 13:10:55 -08001229 }
1230 }
1231 }
1232
1233 /* Call the ctl function. */
Jason Evansc4c25922017-01-15 16:56:30 -08001234 if (node && node->ctl) {
Jason Evansb2c0d632016-04-13 23:36:15 -07001235 ret = node->ctl(tsd, mib, miblen, oldp, oldlenp, newp, newlen);
Jason Evansc4c25922017-01-15 16:56:30 -08001236 } else {
Jason Evans3c234352010-01-27 13:10:55 -08001237 /* Partial MIB. */
1238 ret = ENOENT;
Jason Evans3c234352010-01-27 13:10:55 -08001239 }
Jason Evans3c234352010-01-27 13:10:55 -08001240
Jason Evansa1ee7832012-04-10 15:07:44 -07001241label_return:
Jason Evans3c234352010-01-27 13:10:55 -08001242 return(ret);
1243}
1244
1245bool
Jason Evansc4c25922017-01-15 16:56:30 -08001246ctl_boot(void) {
David Goldblatt26c792e2017-05-15 15:38:15 -07001247 if (malloc_mutex_init(&ctl_mtx, "ctl", WITNESS_RANK_CTL,
1248 malloc_mutex_rank_exclusive)) {
Jason Evansf4086432017-01-19 18:15:45 -08001249 return true;
Jason Evansc4c25922017-01-15 16:56:30 -08001250 }
Jason Evans3c234352010-01-27 13:10:55 -08001251
1252 ctl_initialized = false;
1253
Jason Evansf4086432017-01-19 18:15:45 -08001254 return false;
Jason Evans3c234352010-01-27 13:10:55 -08001255}
1256
Jason Evans20f1fc92012-10-09 14:46:22 -07001257void
Jason Evansc4c25922017-01-15 16:56:30 -08001258ctl_prefork(tsdn_t *tsdn) {
Jason Evansc1e00ef2016-05-10 22:21:10 -07001259 malloc_mutex_prefork(tsdn, &ctl_mtx);
Jason Evans20f1fc92012-10-09 14:46:22 -07001260}
1261
1262void
Jason Evansc4c25922017-01-15 16:56:30 -08001263ctl_postfork_parent(tsdn_t *tsdn) {
Jason Evansc1e00ef2016-05-10 22:21:10 -07001264 malloc_mutex_postfork_parent(tsdn, &ctl_mtx);
Jason Evans20f1fc92012-10-09 14:46:22 -07001265}
1266
1267void
Jason Evansc4c25922017-01-15 16:56:30 -08001268ctl_postfork_child(tsdn_t *tsdn) {
Jason Evansc1e00ef2016-05-10 22:21:10 -07001269 malloc_mutex_postfork_child(tsdn, &ctl_mtx);
Jason Evans20f1fc92012-10-09 14:46:22 -07001270}
1271
Jason Evans3c234352010-01-27 13:10:55 -08001272/******************************************************************************/
1273/* *_ctl() functions. */
1274
Jason Evansc0cc5db2017-01-19 21:41:41 -08001275#define READONLY() do { \
Jason Evans3c234352010-01-27 13:10:55 -08001276 if (newp != NULL || newlen != 0) { \
1277 ret = EPERM; \
Jason Evans6b9ed672012-04-25 13:12:46 -07001278 goto label_return; \
Jason Evans3c234352010-01-27 13:10:55 -08001279 } \
1280} while (0)
1281
Jason Evansc0cc5db2017-01-19 21:41:41 -08001282#define WRITEONLY() do { \
Jason Evans3c234352010-01-27 13:10:55 -08001283 if (oldp != NULL || oldlenp != NULL) { \
1284 ret = EPERM; \
Jason Evans6b9ed672012-04-25 13:12:46 -07001285 goto label_return; \
Jason Evans3c234352010-01-27 13:10:55 -08001286 } \
1287} while (0)
1288
Jason Evansc0cc5db2017-01-19 21:41:41 -08001289#define READ_XOR_WRITE() do { \
Jason Evansfc12c0b2014-10-03 23:25:30 -07001290 if ((oldp != NULL && oldlenp != NULL) && (newp != NULL || \
1291 newlen != 0)) { \
1292 ret = EPERM; \
1293 goto label_return; \
1294 } \
1295} while (0)
1296
Jason Evansc0cc5db2017-01-19 21:41:41 -08001297#define READ(v, t) do { \
Jason Evans3c234352010-01-27 13:10:55 -08001298 if (oldp != NULL && oldlenp != NULL) { \
1299 if (*oldlenp != sizeof(t)) { \
1300 size_t copylen = (sizeof(t) <= *oldlenp) \
1301 ? sizeof(t) : *oldlenp; \
Jason Evans6eb84fb2012-11-29 22:13:04 -08001302 memcpy(oldp, (void *)&(v), copylen); \
Jason Evans3c234352010-01-27 13:10:55 -08001303 ret = EINVAL; \
Jason Evans6b9ed672012-04-25 13:12:46 -07001304 goto label_return; \
Jason Evansb49a3342015-07-28 11:28:19 -04001305 } \
1306 *(t *)oldp = (v); \
Jason Evans3c234352010-01-27 13:10:55 -08001307 } \
1308} while (0)
1309
Jason Evansc0cc5db2017-01-19 21:41:41 -08001310#define WRITE(v, t) do { \
Jason Evans3c234352010-01-27 13:10:55 -08001311 if (newp != NULL) { \
1312 if (newlen != sizeof(t)) { \
1313 ret = EINVAL; \
Jason Evans6b9ed672012-04-25 13:12:46 -07001314 goto label_return; \
Jason Evans3c234352010-01-27 13:10:55 -08001315 } \
Jason Evans6eb84fb2012-11-29 22:13:04 -08001316 (v) = *(t *)newp; \
Jason Evans3c234352010-01-27 13:10:55 -08001317 } \
1318} while (0)
1319
Jason Evansc0cc5db2017-01-19 21:41:41 -08001320#define MIB_UNSIGNED(v, i) do { \
Jason Evans6edbedd2017-01-04 07:51:49 -08001321 if (mib[i] > UINT_MAX) { \
1322 ret = EFAULT; \
1323 goto label_return; \
1324 } \
1325 v = (unsigned)mib[i]; \
1326} while (0)
1327
Jason Evans7372b152012-02-10 20:22:09 -08001328/*
1329 * There's a lot of code duplication in the following macros due to limitations
1330 * in how nested cpp macros are expanded.
1331 */
Jason Evansc0cc5db2017-01-19 21:41:41 -08001332#define CTL_RO_CLGEN(c, l, n, v, t) \
Jason Evans7372b152012-02-10 20:22:09 -08001333static int \
Jason Evansb2c0d632016-04-13 23:36:15 -07001334n##_ctl(tsd_t *tsd, const size_t *mib, size_t miblen, void *oldp, \
Jason Evansc4c25922017-01-15 16:56:30 -08001335 size_t *oldlenp, void *newp, size_t newlen) { \
Jason Evans7372b152012-02-10 20:22:09 -08001336 int ret; \
1337 t oldval; \
1338 \
Jason Evansc4c25922017-01-15 16:56:30 -08001339 if (!(c)) { \
Jason Evansf4086432017-01-19 18:15:45 -08001340 return ENOENT; \
Jason Evansc4c25922017-01-15 16:56:30 -08001341 } \
1342 if (l) { \
Jason Evansc1e00ef2016-05-10 22:21:10 -07001343 malloc_mutex_lock(tsd_tsdn(tsd), &ctl_mtx); \
Jason Evansc4c25922017-01-15 16:56:30 -08001344 } \
Jason Evans7372b152012-02-10 20:22:09 -08001345 READONLY(); \
Jason Evans6eb84fb2012-11-29 22:13:04 -08001346 oldval = (v); \
Jason Evans7372b152012-02-10 20:22:09 -08001347 READ(oldval, t); \
1348 \
1349 ret = 0; \
Jason Evans6b9ed672012-04-25 13:12:46 -07001350label_return: \
Jason Evansc4c25922017-01-15 16:56:30 -08001351 if (l) { \
Jason Evansc1e00ef2016-05-10 22:21:10 -07001352 malloc_mutex_unlock(tsd_tsdn(tsd), &ctl_mtx); \
Jason Evansc4c25922017-01-15 16:56:30 -08001353 } \
Jason Evansf4086432017-01-19 18:15:45 -08001354 return ret; \
Jason Evans7372b152012-02-10 20:22:09 -08001355}
1356
Jason Evansc0cc5db2017-01-19 21:41:41 -08001357#define CTL_RO_CGEN(c, n, v, t) \
Jason Evans7372b152012-02-10 20:22:09 -08001358static int \
Jason Evansb2c0d632016-04-13 23:36:15 -07001359n##_ctl(tsd_t *tsd, const size_t *mib, size_t miblen, void *oldp, \
Jason Evansc4c25922017-01-15 16:56:30 -08001360 size_t *oldlenp, void *newp, size_t newlen) { \
Jason Evans7372b152012-02-10 20:22:09 -08001361 int ret; \
1362 t oldval; \
1363 \
Jason Evansc4c25922017-01-15 16:56:30 -08001364 if (!(c)) { \
Jason Evansf4086432017-01-19 18:15:45 -08001365 return ENOENT; \
Jason Evansc4c25922017-01-15 16:56:30 -08001366 } \
Jason Evansc1e00ef2016-05-10 22:21:10 -07001367 malloc_mutex_lock(tsd_tsdn(tsd), &ctl_mtx); \
Jason Evans7372b152012-02-10 20:22:09 -08001368 READONLY(); \
Jason Evans6eb84fb2012-11-29 22:13:04 -08001369 oldval = (v); \
Jason Evans7372b152012-02-10 20:22:09 -08001370 READ(oldval, t); \
1371 \
1372 ret = 0; \
Jason Evans6b9ed672012-04-25 13:12:46 -07001373label_return: \
Jason Evansc1e00ef2016-05-10 22:21:10 -07001374 malloc_mutex_unlock(tsd_tsdn(tsd), &ctl_mtx); \
Jason Evansf4086432017-01-19 18:15:45 -08001375 return ret; \
Jason Evans7372b152012-02-10 20:22:09 -08001376}
1377
Jason Evansc0cc5db2017-01-19 21:41:41 -08001378#define CTL_RO_GEN(n, v, t) \
Jason Evans3c234352010-01-27 13:10:55 -08001379static int \
Jason Evansb2c0d632016-04-13 23:36:15 -07001380n##_ctl(tsd_t *tsd, const size_t *mib, size_t miblen, void *oldp, \
Jason Evansc4c25922017-01-15 16:56:30 -08001381 size_t *oldlenp, void *newp, size_t newlen) { \
Jason Evans3c234352010-01-27 13:10:55 -08001382 int ret; \
1383 t oldval; \
1384 \
Jason Evansc1e00ef2016-05-10 22:21:10 -07001385 malloc_mutex_lock(tsd_tsdn(tsd), &ctl_mtx); \
Jason Evansfc4dcfa2010-11-24 15:44:21 -08001386 READONLY(); \
Jason Evans6eb84fb2012-11-29 22:13:04 -08001387 oldval = (v); \
Jason Evansfc4dcfa2010-11-24 15:44:21 -08001388 READ(oldval, t); \
1389 \
1390 ret = 0; \
Jason Evans6b9ed672012-04-25 13:12:46 -07001391label_return: \
Jason Evansc1e00ef2016-05-10 22:21:10 -07001392 malloc_mutex_unlock(tsd_tsdn(tsd), &ctl_mtx); \
Jason Evansf4086432017-01-19 18:15:45 -08001393 return ret; \
Jason Evansfc4dcfa2010-11-24 15:44:21 -08001394}
1395
1396/*
1397 * ctl_mtx is not acquired, under the assumption that no pertinent data will
1398 * mutate during the call.
1399 */
Jason Evansc0cc5db2017-01-19 21:41:41 -08001400#define CTL_RO_NL_CGEN(c, n, v, t) \
Jason Evans7372b152012-02-10 20:22:09 -08001401static int \
Jason Evansb2c0d632016-04-13 23:36:15 -07001402n##_ctl(tsd_t *tsd, const size_t *mib, size_t miblen, void *oldp, \
Jason Evansc4c25922017-01-15 16:56:30 -08001403 size_t *oldlenp, void *newp, size_t newlen) { \
Jason Evans7372b152012-02-10 20:22:09 -08001404 int ret; \
1405 t oldval; \
1406 \
Jason Evansc4c25922017-01-15 16:56:30 -08001407 if (!(c)) { \
Jason Evansf4086432017-01-19 18:15:45 -08001408 return ENOENT; \
Jason Evansc4c25922017-01-15 16:56:30 -08001409 } \
Jason Evans7372b152012-02-10 20:22:09 -08001410 READONLY(); \
Jason Evans6eb84fb2012-11-29 22:13:04 -08001411 oldval = (v); \
Jason Evans7372b152012-02-10 20:22:09 -08001412 READ(oldval, t); \
1413 \
1414 ret = 0; \
Jason Evans6b9ed672012-04-25 13:12:46 -07001415label_return: \
Jason Evansf4086432017-01-19 18:15:45 -08001416 return ret; \
Jason Evans7372b152012-02-10 20:22:09 -08001417}
1418
Jason Evansc0cc5db2017-01-19 21:41:41 -08001419#define CTL_RO_NL_GEN(n, v, t) \
Jason Evansfc4dcfa2010-11-24 15:44:21 -08001420static int \
Jason Evansb2c0d632016-04-13 23:36:15 -07001421n##_ctl(tsd_t *tsd, const size_t *mib, size_t miblen, void *oldp, \
Jason Evansc4c25922017-01-15 16:56:30 -08001422 size_t *oldlenp, void *newp, size_t newlen) { \
Jason Evansfc4dcfa2010-11-24 15:44:21 -08001423 int ret; \
1424 t oldval; \
1425 \
Jason Evans3c234352010-01-27 13:10:55 -08001426 READONLY(); \
Jason Evans6eb84fb2012-11-29 22:13:04 -08001427 oldval = (v); \
Jason Evans3c234352010-01-27 13:10:55 -08001428 READ(oldval, t); \
1429 \
1430 ret = 0; \
Jason Evans6b9ed672012-04-25 13:12:46 -07001431label_return: \
Jason Evansf4086432017-01-19 18:15:45 -08001432 return ret; \
Jason Evans3c234352010-01-27 13:10:55 -08001433}
1434
Jason Evansc0cc5db2017-01-19 21:41:41 -08001435#define CTL_TSD_RO_NL_CGEN(c, n, m, t) \
Jason Evans5460aa62014-09-22 21:09:23 -07001436static int \
Jason Evansb2c0d632016-04-13 23:36:15 -07001437n##_ctl(tsd_t *tsd, const size_t *mib, size_t miblen, void *oldp, \
Jason Evansc4c25922017-01-15 16:56:30 -08001438 size_t *oldlenp, void *newp, size_t newlen) { \
Jason Evans5460aa62014-09-22 21:09:23 -07001439 int ret; \
1440 t oldval; \
Jason Evans5460aa62014-09-22 21:09:23 -07001441 \
Jason Evansc4c25922017-01-15 16:56:30 -08001442 if (!(c)) { \
Jason Evansf4086432017-01-19 18:15:45 -08001443 return ENOENT; \
Jason Evansc4c25922017-01-15 16:56:30 -08001444 } \
Jason Evans5460aa62014-09-22 21:09:23 -07001445 READONLY(); \
Jason Evans5460aa62014-09-22 21:09:23 -07001446 oldval = (m(tsd)); \
1447 READ(oldval, t); \
1448 \
1449 ret = 0; \
1450label_return: \
Jason Evansf4086432017-01-19 18:15:45 -08001451 return ret; \
Jason Evans5460aa62014-09-22 21:09:23 -07001452}
1453
Jason Evansc0cc5db2017-01-19 21:41:41 -08001454#define CTL_RO_CONFIG_GEN(n, t) \
Jason Evans3c234352010-01-27 13:10:55 -08001455static int \
Jason Evansb2c0d632016-04-13 23:36:15 -07001456n##_ctl(tsd_t *tsd, const size_t *mib, size_t miblen, void *oldp, \
Jason Evansc4c25922017-01-15 16:56:30 -08001457 size_t *oldlenp, void *newp, size_t newlen) { \
Jason Evans3c234352010-01-27 13:10:55 -08001458 int ret; \
Jason Evansf8290092016-02-07 14:23:22 -08001459 t oldval; \
Jason Evans3c234352010-01-27 13:10:55 -08001460 \
1461 READONLY(); \
Jason Evans7372b152012-02-10 20:22:09 -08001462 oldval = n; \
Jason Evansf8290092016-02-07 14:23:22 -08001463 READ(oldval, t); \
Jason Evans3c234352010-01-27 13:10:55 -08001464 \
1465 ret = 0; \
Jason Evans6b9ed672012-04-25 13:12:46 -07001466label_return: \
Jason Evansf4086432017-01-19 18:15:45 -08001467 return ret; \
Jason Evans3c234352010-01-27 13:10:55 -08001468}
1469
Jason Evansd8a39002013-12-19 21:40:41 -08001470/******************************************************************************/
1471
Jason Evansfc4dcfa2010-11-24 15:44:21 -08001472CTL_RO_NL_GEN(version, JEMALLOC_VERSION, const char *)
Jason Evansa40bc7a2010-03-02 13:01:16 -08001473
Jason Evans3c234352010-01-27 13:10:55 -08001474static int
Jason Evansb2c0d632016-04-13 23:36:15 -07001475epoch_ctl(tsd_t *tsd, const size_t *mib, size_t miblen, void *oldp,
Jason Evansc4c25922017-01-15 16:56:30 -08001476 size_t *oldlenp, void *newp, size_t newlen) {
Jason Evans3c234352010-01-27 13:10:55 -08001477 int ret;
Jason Evans3ab682d2013-10-19 17:19:49 -07001478 UNUSED uint64_t newval;
Jason Evans3c234352010-01-27 13:10:55 -08001479
Jason Evansc1e00ef2016-05-10 22:21:10 -07001480 malloc_mutex_lock(tsd_tsdn(tsd), &ctl_mtx);
Jason Evans3c234352010-01-27 13:10:55 -08001481 WRITE(newval, uint64_t);
Jason Evansc4c25922017-01-15 16:56:30 -08001482 if (newp != NULL) {
Jason Evansc1e00ef2016-05-10 22:21:10 -07001483 ctl_refresh(tsd_tsdn(tsd));
Jason Evansc4c25922017-01-15 16:56:30 -08001484 }
Jason Evans9eb1b1c2017-01-18 23:03:37 -08001485 READ(ctl_arenas->epoch, uint64_t);
Jason Evans3c234352010-01-27 13:10:55 -08001486
1487 ret = 0;
Jason Evansa1ee7832012-04-10 15:07:44 -07001488label_return:
Jason Evansc1e00ef2016-05-10 22:21:10 -07001489 malloc_mutex_unlock(tsd_tsdn(tsd), &ctl_mtx);
Jason Evansf4086432017-01-19 18:15:45 -08001490 return ret;
Jason Evans3c234352010-01-27 13:10:55 -08001491}
1492
Qi Wangb693c782017-03-17 12:42:33 -07001493static int
1494background_thread_ctl(tsd_t *tsd, const size_t *mib, size_t miblen,
1495 void *oldp, size_t *oldlenp, void *newp, size_t newlen) {
1496 int ret;
1497 bool oldval;
1498
1499 if (!have_background_thread) {
1500 return ENOENT;
1501 }
1502
1503 malloc_mutex_lock(tsd_tsdn(tsd), &background_thread_lock);
1504 if (newp == NULL) {
1505 oldval = background_thread_enabled();
1506 READ(oldval, bool);
1507 } else {
1508 if (newlen != sizeof(bool)) {
1509 ret = EINVAL;
1510 goto label_return;
1511 }
1512 oldval = background_thread_enabled();
1513 READ(oldval, bool);
1514
1515 bool newval = *(bool *)newp;
1516 if (newval == oldval) {
1517 ret = 0;
1518 goto label_return;
1519 }
1520
1521 background_thread_enabled_set(tsd_tsdn(tsd), newval);
1522 if (newval) {
1523 if (background_threads_enable(tsd)) {
1524 ret = EFAULT;
1525 goto label_return;
1526 }
1527 } else {
1528 if (background_threads_disable(tsd)) {
1529 ret = EFAULT;
1530 goto label_return;
1531 }
1532 }
1533 }
1534 ret = 0;
1535label_return:
1536 malloc_mutex_unlock(tsd_tsdn(tsd), &background_thread_lock);
1537 return ret;
1538}
1539
Jason Evansd8a39002013-12-19 21:40:41 -08001540/******************************************************************************/
Jason Evansd4be8b72012-03-26 18:54:44 -07001541
Jason Evansf8290092016-02-07 14:23:22 -08001542CTL_RO_CONFIG_GEN(config_cache_oblivious, bool)
1543CTL_RO_CONFIG_GEN(config_debug, bool)
1544CTL_RO_CONFIG_GEN(config_fill, bool)
1545CTL_RO_CONFIG_GEN(config_lazy_lock, bool)
1546CTL_RO_CONFIG_GEN(config_malloc_conf, const char *)
Jason Evansf8290092016-02-07 14:23:22 -08001547CTL_RO_CONFIG_GEN(config_prof, bool)
1548CTL_RO_CONFIG_GEN(config_prof_libgcc, bool)
1549CTL_RO_CONFIG_GEN(config_prof_libunwind, bool)
1550CTL_RO_CONFIG_GEN(config_stats, bool)
Jason Evansc606a872017-05-30 09:54:49 -07001551CTL_RO_CONFIG_GEN(config_thp, bool)
Jason Evansf8290092016-02-07 14:23:22 -08001552CTL_RO_CONFIG_GEN(config_utrace, bool)
Jason Evansf8290092016-02-07 14:23:22 -08001553CTL_RO_CONFIG_GEN(config_xmalloc, bool)
Jason Evansd4be8b72012-03-26 18:54:44 -07001554
Jason Evansd8a39002013-12-19 21:40:41 -08001555/******************************************************************************/
Jason Evansd4be8b72012-03-26 18:54:44 -07001556
Jason Evansd8a39002013-12-19 21:40:41 -08001557CTL_RO_NL_GEN(opt_abort, opt_abort, bool)
Qi Wangb86d2712017-05-25 15:30:11 -07001558CTL_RO_NL_GEN(opt_abort_conf, opt_abort_conf, bool)
Jason Evansb9ab04a2017-04-26 16:26:12 -07001559CTL_RO_NL_GEN(opt_retain, opt_retain, bool)
Jason Evansd8a39002013-12-19 21:40:41 -08001560CTL_RO_NL_GEN(opt_dss, opt_dss, const char *)
Jason Evans8f683b92016-02-24 11:03:40 -08001561CTL_RO_NL_GEN(opt_narenas, opt_narenas, unsigned)
Qi Wangec532e22017-02-02 17:02:05 -08001562CTL_RO_NL_GEN(opt_percpu_arena, opt_percpu_arena, const char *)
Qi Wangb693c782017-03-17 12:42:33 -07001563CTL_RO_NL_GEN(opt_background_thread, opt_background_thread, bool)
Jason Evans6e62c622017-05-17 10:47:00 -07001564CTL_RO_NL_GEN(opt_dirty_decay_ms, opt_dirty_decay_ms, ssize_t)
1565CTL_RO_NL_GEN(opt_muzzy_decay_ms, opt_muzzy_decay_ms, ssize_t)
Jason Evansd8a39002013-12-19 21:40:41 -08001566CTL_RO_NL_GEN(opt_stats_print, opt_stats_print, bool)
Qi Wangd5ef5ae2017-05-27 15:35:36 -07001567CTL_RO_NL_GEN(opt_stats_print_opts, opt_stats_print_opts, const char *)
Guilherme Goncalves2c5cb612014-12-08 19:12:41 -02001568CTL_RO_NL_CGEN(config_fill, opt_junk, opt_junk, const char *)
Jason Evansd8a39002013-12-19 21:40:41 -08001569CTL_RO_NL_CGEN(config_fill, opt_zero, opt_zero, bool)
1570CTL_RO_NL_CGEN(config_utrace, opt_utrace, opt_utrace, bool)
Jason Evansd8a39002013-12-19 21:40:41 -08001571CTL_RO_NL_CGEN(config_xmalloc, opt_xmalloc, opt_xmalloc, bool)
Jason Evans4403c9a2017-04-20 17:21:37 -07001572CTL_RO_NL_GEN(opt_tcache, opt_tcache, bool)
1573CTL_RO_NL_GEN(opt_lg_tcache_max, opt_lg_tcache_max, ssize_t)
Jason Evansd8a39002013-12-19 21:40:41 -08001574CTL_RO_NL_CGEN(config_prof, opt_prof, opt_prof, bool)
1575CTL_RO_NL_CGEN(config_prof, opt_prof_prefix, opt_prof_prefix, const char *)
Jason Evansfc12c0b2014-10-03 23:25:30 -07001576CTL_RO_NL_CGEN(config_prof, opt_prof_active, opt_prof_active, bool)
1577CTL_RO_NL_CGEN(config_prof, opt_prof_thread_active_init,
1578 opt_prof_thread_active_init, bool)
Jason Evansd8a39002013-12-19 21:40:41 -08001579CTL_RO_NL_CGEN(config_prof, opt_lg_prof_sample, opt_lg_prof_sample, size_t)
1580CTL_RO_NL_CGEN(config_prof, opt_prof_accum, opt_prof_accum, bool)
1581CTL_RO_NL_CGEN(config_prof, opt_lg_prof_interval, opt_lg_prof_interval, ssize_t)
1582CTL_RO_NL_CGEN(config_prof, opt_prof_gdump, opt_prof_gdump, bool)
1583CTL_RO_NL_CGEN(config_prof, opt_prof_final, opt_prof_final, bool)
1584CTL_RO_NL_CGEN(config_prof, opt_prof_leak, opt_prof_leak, bool)
Jason Evansd4be8b72012-03-26 18:54:44 -07001585
Jason Evansd8a39002013-12-19 21:40:41 -08001586/******************************************************************************/
Jason Evans3c234352010-01-27 13:10:55 -08001587
Jason Evansb267d0f2010-08-13 15:42:29 -07001588static int
Jason Evansb2c0d632016-04-13 23:36:15 -07001589thread_arena_ctl(tsd_t *tsd, const size_t *mib, size_t miblen, void *oldp,
Jason Evansc4c25922017-01-15 16:56:30 -08001590 size_t *oldlenp, void *newp, size_t newlen) {
Jason Evansb267d0f2010-08-13 15:42:29 -07001591 int ret;
Jason Evans1cb181e2015-01-29 15:30:47 -08001592 arena_t *oldarena;
Jason Evansb267d0f2010-08-13 15:42:29 -07001593 unsigned newind, oldind;
1594
Jason Evans90827a32016-05-03 15:00:42 -07001595 oldarena = arena_choose(tsd, NULL);
Jason Evansc4c25922017-01-15 16:56:30 -08001596 if (oldarena == NULL) {
Jason Evansf4086432017-01-19 18:15:45 -08001597 return EAGAIN;
Jason Evansc4c25922017-01-15 16:56:30 -08001598 }
Jason Evansa0dd3a42016-12-22 16:39:10 -06001599 newind = oldind = arena_ind_get(oldarena);
Jason Evansa7153a02011-03-14 11:39:49 -07001600 WRITE(newind, unsigned);
1601 READ(oldind, unsigned);
Qi Wangec532e22017-02-02 17:02:05 -08001602
Jason Evansb267d0f2010-08-13 15:42:29 -07001603 if (newind != oldind) {
Jason Evans1cb181e2015-01-29 15:30:47 -08001604 arena_t *newarena;
1605
Jason Evansb6c08672016-10-03 10:37:12 -07001606 if (newind >= narenas_total_get()) {
Jason Evansb267d0f2010-08-13 15:42:29 -07001607 /* New arena index is out of range. */
1608 ret = EFAULT;
Jason Evansa1ee7832012-04-10 15:07:44 -07001609 goto label_return;
Jason Evansb267d0f2010-08-13 15:42:29 -07001610 }
1611
Qi Wangec532e22017-02-02 17:02:05 -08001612 if (have_percpu_arena &&
1613 (percpu_arena_mode != percpu_arena_disabled)) {
1614 if (newind < percpu_arena_ind_limit()) {
1615 /*
1616 * If perCPU arena is enabled, thread_arena
1617 * control is not allowed for the auto arena
1618 * range.
1619 */
1620 ret = EPERM;
1621 goto label_return;
1622 }
1623 }
1624
Jason Evansb267d0f2010-08-13 15:42:29 -07001625 /* Initialize arena if necessary. */
Jason Evansc1e00ef2016-05-10 22:21:10 -07001626 newarena = arena_get(tsd_tsdn(tsd), newind, true);
Jason Evans1cb181e2015-01-29 15:30:47 -08001627 if (newarena == NULL) {
Jason Evansb267d0f2010-08-13 15:42:29 -07001628 ret = EAGAIN;
Jason Evansa1ee7832012-04-10 15:07:44 -07001629 goto label_return;
Jason Evansb267d0f2010-08-13 15:42:29 -07001630 }
Jason Evans8bb31982014-10-07 23:14:57 -07001631 /* Set new arena/tcache associations. */
1632 arena_migrate(tsd, oldind, newind);
Jason Evans4403c9a2017-04-20 17:21:37 -07001633 if (tcache_available(tsd)) {
1634 tcache_arena_reassociate(tsd_tsdn(tsd),
1635 tsd_tcachep_get(tsd), newarena);
Jason Evans624f2f32010-12-29 12:21:05 -08001636 }
Jason Evansb267d0f2010-08-13 15:42:29 -07001637 }
1638
1639 ret = 0;
Jason Evansa1ee7832012-04-10 15:07:44 -07001640label_return:
Jason Evansf4086432017-01-19 18:15:45 -08001641 return ret;
Jason Evansb267d0f2010-08-13 15:42:29 -07001642}
Jason Evansb267d0f2010-08-13 15:42:29 -07001643
Jason Evans5460aa62014-09-22 21:09:23 -07001644CTL_TSD_RO_NL_CGEN(config_stats, thread_allocated, tsd_thread_allocated_get,
1645 uint64_t)
1646CTL_TSD_RO_NL_CGEN(config_stats, thread_allocatedp, tsd_thread_allocatedp_get,
1647 uint64_t *)
1648CTL_TSD_RO_NL_CGEN(config_stats, thread_deallocated, tsd_thread_deallocated_get,
1649 uint64_t)
1650CTL_TSD_RO_NL_CGEN(config_stats, thread_deallocatedp,
1651 tsd_thread_deallocatedp_get, uint64_t *)
Jason Evans93443682010-10-20 17:39:18 -07001652
Jason Evansd8a39002013-12-19 21:40:41 -08001653static int
Jason Evansb2c0d632016-04-13 23:36:15 -07001654thread_tcache_enabled_ctl(tsd_t *tsd, const size_t *mib, size_t miblen,
Jason Evansc4c25922017-01-15 16:56:30 -08001655 void *oldp, size_t *oldlenp, void *newp, size_t newlen) {
Jason Evansd8a39002013-12-19 21:40:41 -08001656 int ret;
1657 bool oldval;
Jason Evans3c234352010-01-27 13:10:55 -08001658
Qi Wangfde3e202017-03-27 21:50:38 -07001659 oldval = tcache_enabled_get(tsd);
Jason Evansd8a39002013-12-19 21:40:41 -08001660 if (newp != NULL) {
1661 if (newlen != sizeof(bool)) {
1662 ret = EINVAL;
1663 goto label_return;
1664 }
Qi Wangfde3e202017-03-27 21:50:38 -07001665 tcache_enabled_set(tsd, *(bool *)newp);
Jason Evansd8a39002013-12-19 21:40:41 -08001666 }
1667 READ(oldval, bool);
Jason Evans3c234352010-01-27 13:10:55 -08001668
Jason Evansd8a39002013-12-19 21:40:41 -08001669 ret = 0;
1670label_return:
Jason Evansf4086432017-01-19 18:15:45 -08001671 return ret;
Jason Evansd8a39002013-12-19 21:40:41 -08001672}
1673
1674static int
Jason Evansb2c0d632016-04-13 23:36:15 -07001675thread_tcache_flush_ctl(tsd_t *tsd, const size_t *mib, size_t miblen,
Jason Evansc4c25922017-01-15 16:56:30 -08001676 void *oldp, size_t *oldlenp, void *newp, size_t newlen) {
Jason Evansd8a39002013-12-19 21:40:41 -08001677 int ret;
1678
Jason Evans4403c9a2017-04-20 17:21:37 -07001679 if (!tcache_available(tsd)) {
1680 ret = EFAULT;
1681 goto label_return;
Jason Evansc4c25922017-01-15 16:56:30 -08001682 }
Jason Evansd8a39002013-12-19 21:40:41 -08001683
1684 READONLY();
1685 WRITEONLY();
1686
1687 tcache_flush();
1688
1689 ret = 0;
1690label_return:
Jason Evansf4086432017-01-19 18:15:45 -08001691 return ret;
Jason Evansd8a39002013-12-19 21:40:41 -08001692}
Jason Evans3c234352010-01-27 13:10:55 -08001693
Jason Evans602c8e02014-08-18 16:22:13 -07001694static int
Jason Evansb2c0d632016-04-13 23:36:15 -07001695thread_prof_name_ctl(tsd_t *tsd, const size_t *mib, size_t miblen, void *oldp,
Jason Evansc4c25922017-01-15 16:56:30 -08001696 size_t *oldlenp, void *newp, size_t newlen) {
Jason Evans602c8e02014-08-18 16:22:13 -07001697 int ret;
Jason Evans602c8e02014-08-18 16:22:13 -07001698
Jason Evansc4c25922017-01-15 16:56:30 -08001699 if (!config_prof) {
Jason Evansf4086432017-01-19 18:15:45 -08001700 return ENOENT;
Jason Evansc4c25922017-01-15 16:56:30 -08001701 }
Jason Evans602c8e02014-08-18 16:22:13 -07001702
Jason Evansfc12c0b2014-10-03 23:25:30 -07001703 READ_XOR_WRITE();
1704
Jason Evans602c8e02014-08-18 16:22:13 -07001705 if (newp != NULL) {
1706 if (newlen != sizeof(const char *)) {
1707 ret = EINVAL;
1708 goto label_return;
1709 }
Jason Evans5460aa62014-09-22 21:09:23 -07001710
Jason Evansfc12c0b2014-10-03 23:25:30 -07001711 if ((ret = prof_thread_name_set(tsd, *(const char **)newp)) !=
Jason Evansc4c25922017-01-15 16:56:30 -08001712 0) {
Jason Evans602c8e02014-08-18 16:22:13 -07001713 goto label_return;
Jason Evansc4c25922017-01-15 16:56:30 -08001714 }
Jason Evansfc12c0b2014-10-03 23:25:30 -07001715 } else {
Jason Evansb2c0d632016-04-13 23:36:15 -07001716 const char *oldname = prof_thread_name_get(tsd);
Jason Evansfc12c0b2014-10-03 23:25:30 -07001717 READ(oldname, const char *);
Jason Evans602c8e02014-08-18 16:22:13 -07001718 }
Jason Evans602c8e02014-08-18 16:22:13 -07001719
1720 ret = 0;
1721label_return:
Jason Evansf4086432017-01-19 18:15:45 -08001722 return ret;
Jason Evans602c8e02014-08-18 16:22:13 -07001723}
1724
1725static int
Jason Evansb2c0d632016-04-13 23:36:15 -07001726thread_prof_active_ctl(tsd_t *tsd, const size_t *mib, size_t miblen, void *oldp,
Jason Evansc4c25922017-01-15 16:56:30 -08001727 size_t *oldlenp, void *newp, size_t newlen) {
Jason Evans602c8e02014-08-18 16:22:13 -07001728 int ret;
1729 bool oldval;
1730
Jason Evansc4c25922017-01-15 16:56:30 -08001731 if (!config_prof) {
Jason Evansf4086432017-01-19 18:15:45 -08001732 return ENOENT;
Jason Evansc4c25922017-01-15 16:56:30 -08001733 }
Jason Evans602c8e02014-08-18 16:22:13 -07001734
Jason Evansb2c0d632016-04-13 23:36:15 -07001735 oldval = prof_thread_active_get(tsd);
Jason Evans602c8e02014-08-18 16:22:13 -07001736 if (newp != NULL) {
1737 if (newlen != sizeof(bool)) {
1738 ret = EINVAL;
1739 goto label_return;
1740 }
Jason Evansb2c0d632016-04-13 23:36:15 -07001741 if (prof_thread_active_set(tsd, *(bool *)newp)) {
Jason Evans602c8e02014-08-18 16:22:13 -07001742 ret = EAGAIN;
1743 goto label_return;
1744 }
1745 }
1746 READ(oldval, bool);
1747
1748 ret = 0;
1749label_return:
Jason Evansf4086432017-01-19 18:15:45 -08001750 return ret;
Jason Evans602c8e02014-08-18 16:22:13 -07001751}
1752
Jason Evans3c234352010-01-27 13:10:55 -08001753/******************************************************************************/
1754
Jason Evans1cb181e2015-01-29 15:30:47 -08001755static int
Jason Evansb2c0d632016-04-13 23:36:15 -07001756tcache_create_ctl(tsd_t *tsd, const size_t *mib, size_t miblen, void *oldp,
Jason Evansc4c25922017-01-15 16:56:30 -08001757 size_t *oldlenp, void *newp, size_t newlen) {
Jason Evans1cb181e2015-01-29 15:30:47 -08001758 int ret;
Jason Evans1cb181e2015-01-29 15:30:47 -08001759 unsigned tcache_ind;
1760
Jason Evans1cb181e2015-01-29 15:30:47 -08001761 READONLY();
Jason Evansb54d1602016-10-20 23:59:12 -07001762 if (tcaches_create(tsd, &tcache_ind)) {
Jason Evans1cb181e2015-01-29 15:30:47 -08001763 ret = EFAULT;
1764 goto label_return;
1765 }
1766 READ(tcache_ind, unsigned);
1767
1768 ret = 0;
1769label_return:
Jason Evansf4086432017-01-19 18:15:45 -08001770 return ret;
Jason Evans1cb181e2015-01-29 15:30:47 -08001771}
1772
1773static int
Jason Evansb2c0d632016-04-13 23:36:15 -07001774tcache_flush_ctl(tsd_t *tsd, const size_t *mib, size_t miblen, void *oldp,
Jason Evansc4c25922017-01-15 16:56:30 -08001775 size_t *oldlenp, void *newp, size_t newlen) {
Jason Evans1cb181e2015-01-29 15:30:47 -08001776 int ret;
Jason Evans1cb181e2015-01-29 15:30:47 -08001777 unsigned tcache_ind;
1778
Jason Evans1cb181e2015-01-29 15:30:47 -08001779 WRITEONLY();
1780 tcache_ind = UINT_MAX;
1781 WRITE(tcache_ind, unsigned);
1782 if (tcache_ind == UINT_MAX) {
1783 ret = EFAULT;
1784 goto label_return;
1785 }
1786 tcaches_flush(tsd, tcache_ind);
1787
1788 ret = 0;
1789label_return:
Jason Evansf4086432017-01-19 18:15:45 -08001790 return ret;
Jason Evans1cb181e2015-01-29 15:30:47 -08001791}
1792
1793static int
Jason Evansb2c0d632016-04-13 23:36:15 -07001794tcache_destroy_ctl(tsd_t *tsd, const size_t *mib, size_t miblen, void *oldp,
Jason Evansc4c25922017-01-15 16:56:30 -08001795 size_t *oldlenp, void *newp, size_t newlen) {
Jason Evans1cb181e2015-01-29 15:30:47 -08001796 int ret;
Jason Evans1cb181e2015-01-29 15:30:47 -08001797 unsigned tcache_ind;
1798
Jason Evans1cb181e2015-01-29 15:30:47 -08001799 WRITEONLY();
1800 tcache_ind = UINT_MAX;
1801 WRITE(tcache_ind, unsigned);
1802 if (tcache_ind == UINT_MAX) {
1803 ret = EFAULT;
1804 goto label_return;
1805 }
1806 tcaches_destroy(tsd, tcache_ind);
1807
1808 ret = 0;
1809label_return:
Jason Evansf4086432017-01-19 18:15:45 -08001810 return ret;
Jason Evans1cb181e2015-01-29 15:30:47 -08001811}
1812
1813/******************************************************************************/
1814
Jason Evansdc2125c2017-01-04 10:21:53 -08001815static int
1816arena_i_initialized_ctl(tsd_t *tsd, const size_t *mib, size_t miblen,
Jason Evansc4c25922017-01-15 16:56:30 -08001817 void *oldp, size_t *oldlenp, void *newp, size_t newlen) {
Jason Evansdc2125c2017-01-04 10:21:53 -08001818 int ret;
1819 tsdn_t *tsdn = tsd_tsdn(tsd);
1820 unsigned arena_ind;
1821 bool initialized;
1822
1823 READONLY();
1824 MIB_UNSIGNED(arena_ind, 1);
1825
1826 malloc_mutex_lock(tsdn, &ctl_mtx);
Jason Evans9eb1b1c2017-01-18 23:03:37 -08001827 initialized = arenas_i(arena_ind)->initialized;
Jason Evansdc2125c2017-01-04 10:21:53 -08001828 malloc_mutex_unlock(tsdn, &ctl_mtx);
1829
1830 READ(initialized, bool);
1831
1832 ret = 0;
1833label_return:
Jason Evansf4086432017-01-19 18:15:45 -08001834 return ret;
Jason Evansdc2125c2017-01-04 10:21:53 -08001835}
1836
Jason Evans34457f52012-11-03 21:18:28 -07001837static void
Jason Evans64e458f2017-03-08 22:42:57 -08001838arena_i_decay(tsdn_t *tsdn, unsigned arena_ind, bool all) {
Jason Evansc1e00ef2016-05-10 22:21:10 -07001839 malloc_mutex_lock(tsdn, &ctl_mtx);
Jason Evans243f7a02016-02-19 20:09:31 -08001840 {
Jason Evans9eb1b1c2017-01-18 23:03:37 -08001841 unsigned narenas = ctl_arenas->narenas;
Jason Evans609ae592012-10-11 13:53:15 -07001842
Jason Evans3dc4e832017-01-03 07:27:42 -08001843 /*
1844 * Access via index narenas is deprecated, and scheduled for
1845 * removal in 6.0.0.
1846 */
1847 if (arena_ind == MALLCTL_ARENAS_ALL || arena_ind == narenas) {
Jason Evans243f7a02016-02-19 20:09:31 -08001848 unsigned i;
Jason Evans243f7a02016-02-19 20:09:31 -08001849 VARIABLE_ARRAY(arena_t *, tarenas, narenas);
1850
Jason Evansc4c25922017-01-15 16:56:30 -08001851 for (i = 0; i < narenas; i++) {
Jason Evansc1e00ef2016-05-10 22:21:10 -07001852 tarenas[i] = arena_get(tsdn, i, false);
Jason Evansc4c25922017-01-15 16:56:30 -08001853 }
Jason Evans243f7a02016-02-19 20:09:31 -08001854
1855 /*
1856 * No further need to hold ctl_mtx, since narenas and
1857 * tarenas contain everything needed below.
1858 */
Jason Evansc1e00ef2016-05-10 22:21:10 -07001859 malloc_mutex_unlock(tsdn, &ctl_mtx);
Jason Evans243f7a02016-02-19 20:09:31 -08001860
1861 for (i = 0; i < narenas; i++) {
Jason Evansc4c25922017-01-15 16:56:30 -08001862 if (tarenas[i] != NULL) {
Qi Wangb693c782017-03-17 12:42:33 -07001863 arena_decay(tsdn, tarenas[i], false,
1864 all);
Jason Evansc4c25922017-01-15 16:56:30 -08001865 }
Jason Evans243f7a02016-02-19 20:09:31 -08001866 }
1867 } else {
1868 arena_t *tarena;
1869
1870 assert(arena_ind < narenas);
1871
Jason Evansc1e00ef2016-05-10 22:21:10 -07001872 tarena = arena_get(tsdn, arena_ind, false);
Jason Evans243f7a02016-02-19 20:09:31 -08001873
1874 /* No further need to hold ctl_mtx. */
Jason Evansc1e00ef2016-05-10 22:21:10 -07001875 malloc_mutex_unlock(tsdn, &ctl_mtx);
Jason Evans243f7a02016-02-19 20:09:31 -08001876
Jason Evansc4c25922017-01-15 16:56:30 -08001877 if (tarena != NULL) {
Qi Wangb693c782017-03-17 12:42:33 -07001878 arena_decay(tsdn, tarena, false, all);
Jason Evansc4c25922017-01-15 16:56:30 -08001879 }
Jason Evans609ae592012-10-11 13:53:15 -07001880 }
1881 }
Jason Evans609ae592012-10-11 13:53:15 -07001882}
1883
1884static int
Jason Evansb2c0d632016-04-13 23:36:15 -07001885arena_i_decay_ctl(tsd_t *tsd, const size_t *mib, size_t miblen, void *oldp,
Jason Evansc4c25922017-01-15 16:56:30 -08001886 size_t *oldlenp, void *newp, size_t newlen) {
Jason Evans243f7a02016-02-19 20:09:31 -08001887 int ret;
Jason Evans6edbedd2017-01-04 07:51:49 -08001888 unsigned arena_ind;
Jason Evans243f7a02016-02-19 20:09:31 -08001889
1890 READONLY();
1891 WRITEONLY();
Jason Evans6edbedd2017-01-04 07:51:49 -08001892 MIB_UNSIGNED(arena_ind, 1);
Jason Evans64e458f2017-03-08 22:42:57 -08001893 arena_i_decay(tsd_tsdn(tsd), arena_ind, false);
1894
1895 ret = 0;
1896label_return:
1897 return ret;
1898}
1899
1900static int
1901arena_i_purge_ctl(tsd_t *tsd, const size_t *mib, size_t miblen, void *oldp,
1902 size_t *oldlenp, void *newp, size_t newlen) {
1903 int ret;
1904 unsigned arena_ind;
1905
1906 READONLY();
1907 WRITEONLY();
1908 MIB_UNSIGNED(arena_ind, 1);
1909 arena_i_decay(tsd_tsdn(tsd), arena_ind, true);
Jason Evans609ae592012-10-11 13:53:15 -07001910
Jason Evans34457f52012-11-03 21:18:28 -07001911 ret = 0;
Jason Evans609ae592012-10-11 13:53:15 -07001912label_return:
Jason Evansf4086432017-01-19 18:15:45 -08001913 return ret;
Jason Evans609ae592012-10-11 13:53:15 -07001914}
1915
1916static int
Jason Evansedf1baf2017-01-03 17:21:59 -08001917arena_i_reset_destroy_helper(tsd_t *tsd, const size_t *mib, size_t miblen,
1918 void *oldp, size_t *oldlenp, void *newp, size_t newlen, unsigned *arena_ind,
Jason Evansc4c25922017-01-15 16:56:30 -08001919 arena_t **arena) {
Jason Evansedf1baf2017-01-03 17:21:59 -08001920 int ret;
1921
1922 READONLY();
1923 WRITEONLY();
1924 MIB_UNSIGNED(*arena_ind, 1);
1925
Jason Evansedf1baf2017-01-03 17:21:59 -08001926 *arena = arena_get(tsd_tsdn(tsd), *arena_ind, false);
Qi Wang5aa46f02017-04-20 15:19:02 -07001927 if (*arena == NULL || arena_is_auto(*arena)) {
Jason Evansedf1baf2017-01-03 17:21:59 -08001928 ret = EFAULT;
1929 goto label_return;
1930 }
1931
1932 ret = 0;
1933label_return:
Jason Evansf4086432017-01-19 18:15:45 -08001934 return ret;
Jason Evansedf1baf2017-01-03 17:21:59 -08001935}
1936
Qi Wangb693c782017-03-17 12:42:33 -07001937static void
1938arena_reset_prepare_background_thread(tsd_t *tsd, unsigned arena_ind) {
1939 /* Temporarily disable the background thread during arena reset. */
1940 if (have_background_thread) {
1941 malloc_mutex_lock(tsd_tsdn(tsd), &background_thread_lock);
1942 if (background_thread_enabled()) {
1943 unsigned ind = arena_ind % ncpus;
1944 background_thread_info_t *info =
1945 &background_thread_info[ind];
1946 assert(info->started);
1947 background_threads_disable_single(tsd, info);
1948 }
1949 }
1950}
1951
1952static void
1953arena_reset_finish_background_thread(tsd_t *tsd, unsigned arena_ind) {
1954 if (have_background_thread) {
1955 if (background_thread_enabled()) {
1956 unsigned ind = arena_ind % ncpus;
1957 background_thread_info_t *info =
1958 &background_thread_info[ind];
1959 assert(!info->started);
1960 background_thread_create(tsd, ind);
1961 }
1962 malloc_mutex_unlock(tsd_tsdn(tsd), &background_thread_lock);
1963 }
1964}
1965
Jason Evansedf1baf2017-01-03 17:21:59 -08001966static int
Jason Evans19ff2ce2016-04-22 14:37:17 -07001967arena_i_reset_ctl(tsd_t *tsd, const size_t *mib, size_t miblen, void *oldp,
Jason Evansc4c25922017-01-15 16:56:30 -08001968 size_t *oldlenp, void *newp, size_t newlen) {
Jason Evans19ff2ce2016-04-22 14:37:17 -07001969 int ret;
1970 unsigned arena_ind;
1971 arena_t *arena;
1972
Jason Evansedf1baf2017-01-03 17:21:59 -08001973 ret = arena_i_reset_destroy_helper(tsd, mib, miblen, oldp, oldlenp,
1974 newp, newlen, &arena_ind, &arena);
Jason Evansc4c25922017-01-15 16:56:30 -08001975 if (ret != 0) {
Jason Evansf4086432017-01-19 18:15:45 -08001976 return ret;
Jason Evansc4c25922017-01-15 16:56:30 -08001977 }
Jason Evans19ff2ce2016-04-22 14:37:17 -07001978
Qi Wangb693c782017-03-17 12:42:33 -07001979 arena_reset_prepare_background_thread(tsd, arena_ind);
Jason Evansedf1baf2017-01-03 17:21:59 -08001980 arena_reset(tsd, arena);
Qi Wangb693c782017-03-17 12:42:33 -07001981 arena_reset_finish_background_thread(tsd, arena_ind);
Jason Evans19ff2ce2016-04-22 14:37:17 -07001982
Jason Evansf4086432017-01-19 18:15:45 -08001983 return ret;
Jason Evansedf1baf2017-01-03 17:21:59 -08001984}
1985
1986static int
1987arena_i_destroy_ctl(tsd_t *tsd, const size_t *mib, size_t miblen, void *oldp,
Jason Evansc4c25922017-01-15 16:56:30 -08001988 size_t *oldlenp, void *newp, size_t newlen) {
Jason Evansedf1baf2017-01-03 17:21:59 -08001989 int ret;
1990 unsigned arena_ind;
1991 arena_t *arena;
Jason Evans9eb1b1c2017-01-18 23:03:37 -08001992 ctl_arena_t *ctl_darena, *ctl_arena;
Jason Evansedf1baf2017-01-03 17:21:59 -08001993
1994 ret = arena_i_reset_destroy_helper(tsd, mib, miblen, oldp, oldlenp,
1995 newp, newlen, &arena_ind, &arena);
Jason Evansc4c25922017-01-15 16:56:30 -08001996 if (ret != 0) {
Jason Evansedf1baf2017-01-03 17:21:59 -08001997 goto label_return;
Jason Evansc4c25922017-01-15 16:56:30 -08001998 }
Jason Evansedf1baf2017-01-03 17:21:59 -08001999
2000 if (arena_nthreads_get(arena, false) != 0 || arena_nthreads_get(arena,
2001 true) != 0) {
Jason Evans3dc4e832017-01-03 07:27:42 -08002002 ret = EFAULT;
2003 goto label_return;
2004 }
Jason Evans19ff2ce2016-04-22 14:37:17 -07002005
Qi Wangb693c782017-03-17 12:42:33 -07002006 arena_reset_prepare_background_thread(tsd, arena_ind);
Jason Evansedf1baf2017-01-03 17:21:59 -08002007 /* Merge stats after resetting and purging arena. */
Jason Evans19ff2ce2016-04-22 14:37:17 -07002008 arena_reset(tsd, arena);
Qi Wangb693c782017-03-17 12:42:33 -07002009 arena_decay(tsd_tsdn(tsd), arena, false, true);
Jason Evans9eb1b1c2017-01-18 23:03:37 -08002010 ctl_darena = arenas_i(MALLCTL_ARENAS_DESTROYED);
2011 ctl_darena->initialized = true;
2012 ctl_arena_refresh(tsd_tsdn(tsd), arena, ctl_darena, arena_ind, true);
Jason Evansedf1baf2017-01-03 17:21:59 -08002013 /* Destroy arena. */
2014 arena_destroy(tsd, arena);
Jason Evans9eb1b1c2017-01-18 23:03:37 -08002015 ctl_arena = arenas_i(arena_ind);
2016 ctl_arena->initialized = false;
Jason Evansedf1baf2017-01-03 17:21:59 -08002017 /* Record arena index for later recycling via arenas.create. */
Jason Evans9eb1b1c2017-01-18 23:03:37 -08002018 ql_elm_new(ctl_arena, destroyed_link);
2019 ql_tail_insert(&ctl_arenas->destroyed, ctl_arena, destroyed_link);
Qi Wangb693c782017-03-17 12:42:33 -07002020 arena_reset_finish_background_thread(tsd, arena_ind);
Jason Evans19ff2ce2016-04-22 14:37:17 -07002021
Jason Evansedf1baf2017-01-03 17:21:59 -08002022 assert(ret == 0);
Jason Evans19ff2ce2016-04-22 14:37:17 -07002023label_return:
Jason Evansf4086432017-01-19 18:15:45 -08002024 return ret;
Jason Evans19ff2ce2016-04-22 14:37:17 -07002025}
2026
2027static int
Jason Evansb2c0d632016-04-13 23:36:15 -07002028arena_i_dss_ctl(tsd_t *tsd, const size_t *mib, size_t miblen, void *oldp,
Jason Evansc4c25922017-01-15 16:56:30 -08002029 size_t *oldlenp, void *newp, size_t newlen) {
Jason Evans586c8ed2014-08-15 12:20:20 -07002030 int ret;
2031 const char *dss = NULL;
Jason Evans6edbedd2017-01-04 07:51:49 -08002032 unsigned arena_ind;
Jason Evans609ae592012-10-11 13:53:15 -07002033 dss_prec_t dss_prec_old = dss_prec_limit;
2034 dss_prec_t dss_prec = dss_prec_limit;
2035
Jason Evansc1e00ef2016-05-10 22:21:10 -07002036 malloc_mutex_lock(tsd_tsdn(tsd), &ctl_mtx);
Jason Evans609ae592012-10-11 13:53:15 -07002037 WRITE(dss, const char *);
Jason Evans6edbedd2017-01-04 07:51:49 -08002038 MIB_UNSIGNED(arena_ind, 1);
Jason Evans586c8ed2014-08-15 12:20:20 -07002039 if (dss != NULL) {
2040 int i;
2041 bool match = false;
2042
2043 for (i = 0; i < dss_prec_limit; i++) {
2044 if (strcmp(dss_prec_names[i], dss) == 0) {
2045 dss_prec = i;
2046 match = true;
2047 break;
2048 }
Jason Evans609ae592012-10-11 13:53:15 -07002049 }
Jason Evans586c8ed2014-08-15 12:20:20 -07002050
Jason Evans551ebc42014-10-03 10:16:09 -07002051 if (!match) {
Jason Evans586c8ed2014-08-15 12:20:20 -07002052 ret = EINVAL;
2053 goto label_return;
2054 }
Jason Evans609ae592012-10-11 13:53:15 -07002055 }
2056
Jason Evans3dc4e832017-01-03 07:27:42 -08002057 /*
2058 * Access via index narenas is deprecated, and scheduled for removal in
2059 * 6.0.0.
2060 */
Jason Evansd778dd22017-01-03 12:40:54 -08002061 if (arena_ind == MALLCTL_ARENAS_ALL || arena_ind ==
Jason Evans9eb1b1c2017-01-18 23:03:37 -08002062 ctl_arenas->narenas) {
Jason Evans3dc4e832017-01-03 07:27:42 -08002063 if (dss_prec != dss_prec_limit &&
2064 extent_dss_prec_set(dss_prec)) {
2065 ret = EFAULT;
2066 goto label_return;
2067 }
2068 dss_prec_old = extent_dss_prec_get();
2069 } else {
Jason Evansc1e00ef2016-05-10 22:21:10 -07002070 arena_t *arena = arena_get(tsd_tsdn(tsd), arena_ind, false);
Jason Evans586c8ed2014-08-15 12:20:20 -07002071 if (arena == NULL || (dss_prec != dss_prec_limit &&
Jason Evansb7795222017-02-12 16:34:36 -08002072 arena_dss_prec_set(arena, dss_prec))) {
Jason Evans586c8ed2014-08-15 12:20:20 -07002073 ret = EFAULT;
2074 goto label_return;
2075 }
Jason Evansb7795222017-02-12 16:34:36 -08002076 dss_prec_old = arena_dss_prec_get(arena);
Jason Evans609ae592012-10-11 13:53:15 -07002077 }
Jason Evans586c8ed2014-08-15 12:20:20 -07002078
Jason Evans609ae592012-10-11 13:53:15 -07002079 dss = dss_prec_names[dss_prec_old];
2080 READ(dss, const char *);
Jason Evans609ae592012-10-11 13:53:15 -07002081
2082 ret = 0;
2083label_return:
Jason Evansc1e00ef2016-05-10 22:21:10 -07002084 malloc_mutex_unlock(tsd_tsdn(tsd), &ctl_mtx);
Jason Evansf4086432017-01-19 18:15:45 -08002085 return ret;
Jason Evans609ae592012-10-11 13:53:15 -07002086}
2087
aravindfb7fe502014-05-05 15:16:56 -07002088static int
Jason Evans6e62c622017-05-17 10:47:00 -07002089arena_i_decay_ms_ctl_impl(tsd_t *tsd, const size_t *mib, size_t miblen,
Jason Evans64e458f2017-03-08 22:42:57 -08002090 void *oldp, size_t *oldlenp, void *newp, size_t newlen, bool dirty) {
Jason Evans243f7a02016-02-19 20:09:31 -08002091 int ret;
Jason Evans6edbedd2017-01-04 07:51:49 -08002092 unsigned arena_ind;
Jason Evans243f7a02016-02-19 20:09:31 -08002093 arena_t *arena;
2094
Jason Evans6edbedd2017-01-04 07:51:49 -08002095 MIB_UNSIGNED(arena_ind, 1);
Jason Evansc1e00ef2016-05-10 22:21:10 -07002096 arena = arena_get(tsd_tsdn(tsd), arena_ind, false);
Jason Evans243f7a02016-02-19 20:09:31 -08002097 if (arena == NULL) {
2098 ret = EFAULT;
2099 goto label_return;
2100 }
2101
2102 if (oldp != NULL && oldlenp != NULL) {
Jason Evans6e62c622017-05-17 10:47:00 -07002103 size_t oldval = dirty ? arena_dirty_decay_ms_get(arena) :
2104 arena_muzzy_decay_ms_get(arena);
Jason Evans243f7a02016-02-19 20:09:31 -08002105 READ(oldval, ssize_t);
2106 }
2107 if (newp != NULL) {
2108 if (newlen != sizeof(ssize_t)) {
2109 ret = EINVAL;
2110 goto label_return;
2111 }
Jason Evans6e62c622017-05-17 10:47:00 -07002112 if (dirty ? arena_dirty_decay_ms_set(tsd_tsdn(tsd), arena,
2113 *(ssize_t *)newp) : arena_muzzy_decay_ms_set(tsd_tsdn(tsd),
2114 arena, *(ssize_t *)newp)) {
Jason Evans243f7a02016-02-19 20:09:31 -08002115 ret = EFAULT;
2116 goto label_return;
2117 }
2118 }
2119
2120 ret = 0;
2121label_return:
Jason Evansf4086432017-01-19 18:15:45 -08002122 return ret;
Jason Evans243f7a02016-02-19 20:09:31 -08002123}
2124
2125static int
Jason Evans6e62c622017-05-17 10:47:00 -07002126arena_i_dirty_decay_ms_ctl(tsd_t *tsd, const size_t *mib, size_t miblen,
Jason Evans64e458f2017-03-08 22:42:57 -08002127 void *oldp, size_t *oldlenp, void *newp, size_t newlen) {
Jason Evans6e62c622017-05-17 10:47:00 -07002128 return arena_i_decay_ms_ctl_impl(tsd, mib, miblen, oldp, oldlenp, newp,
2129 newlen, true);
Jason Evans64e458f2017-03-08 22:42:57 -08002130}
2131
2132static int
Jason Evans6e62c622017-05-17 10:47:00 -07002133arena_i_muzzy_decay_ms_ctl(tsd_t *tsd, const size_t *mib, size_t miblen,
Jason Evans64e458f2017-03-08 22:42:57 -08002134 void *oldp, size_t *oldlenp, void *newp, size_t newlen) {
Jason Evans6e62c622017-05-17 10:47:00 -07002135 return arena_i_decay_ms_ctl_impl(tsd, mib, miblen, oldp, oldlenp, newp,
2136 newlen, false);
Jason Evans64e458f2017-03-08 22:42:57 -08002137}
2138
2139static int
Jason Evans9c305c92016-05-31 15:03:51 -07002140arena_i_extent_hooks_ctl(tsd_t *tsd, const size_t *mib, size_t miblen,
Jason Evansc4c25922017-01-15 16:56:30 -08002141 void *oldp, size_t *oldlenp, void *newp, size_t newlen) {
Jason Evansb49a3342015-07-28 11:28:19 -04002142 int ret;
Jason Evans6edbedd2017-01-04 07:51:49 -08002143 unsigned arena_ind;
Jason Evansb49a3342015-07-28 11:28:19 -04002144 arena_t *arena;
2145
Jason Evansc1e00ef2016-05-10 22:21:10 -07002146 malloc_mutex_lock(tsd_tsdn(tsd), &ctl_mtx);
Jason Evans6edbedd2017-01-04 07:51:49 -08002147 MIB_UNSIGNED(arena_ind, 1);
Jason Evansb49a3342015-07-28 11:28:19 -04002148 if (arena_ind < narenas_total_get() && (arena =
Jason Evansc1e00ef2016-05-10 22:21:10 -07002149 arena_get(tsd_tsdn(tsd), arena_ind, false)) != NULL) {
Jason Evansb49a3342015-07-28 11:28:19 -04002150 if (newp != NULL) {
Jason Evansf02fec82016-06-03 19:39:14 -07002151 extent_hooks_t *old_extent_hooks;
2152 extent_hooks_t *new_extent_hooks
2153 JEMALLOC_CC_SILENCE_INIT(NULL);
Jason Evansf8f05422016-06-03 12:05:53 -07002154 WRITE(new_extent_hooks, extent_hooks_t *);
2155 old_extent_hooks = extent_hooks_set(arena,
2156 new_extent_hooks);
2157 READ(old_extent_hooks, extent_hooks_t *);
Jason Evansb49a3342015-07-28 11:28:19 -04002158 } else {
Jason Evansf8f05422016-06-03 12:05:53 -07002159 extent_hooks_t *old_extent_hooks =
2160 extent_hooks_get(arena);
2161 READ(old_extent_hooks, extent_hooks_t *);
Jason Evansb49a3342015-07-28 11:28:19 -04002162 }
2163 } else {
2164 ret = EFAULT;
2165 goto label_return;
2166 }
2167 ret = 0;
2168label_return:
Jason Evansc1e00ef2016-05-10 22:21:10 -07002169 malloc_mutex_unlock(tsd_tsdn(tsd), &ctl_mtx);
Jason Evansf4086432017-01-19 18:15:45 -08002170 return ret;
aravindfb7fe502014-05-05 15:16:56 -07002171}
2172
Jason Evans609ae592012-10-11 13:53:15 -07002173static const ctl_named_node_t *
Jason Evansc4c25922017-01-15 16:56:30 -08002174arena_i_index(tsdn_t *tsdn, const size_t *mib, size_t miblen, size_t i) {
Jason Evansb2c0d632016-04-13 23:36:15 -07002175 const ctl_named_node_t *ret;
Jason Evans609ae592012-10-11 13:53:15 -07002176
Jason Evansc1e00ef2016-05-10 22:21:10 -07002177 malloc_mutex_lock(tsdn, &ctl_mtx);
Jason Evansedf1baf2017-01-03 17:21:59 -08002178 switch (i) {
2179 case MALLCTL_ARENAS_ALL:
2180 case MALLCTL_ARENAS_DESTROYED:
2181 break;
2182 default:
Jason Evans9eb1b1c2017-01-18 23:03:37 -08002183 if (i > ctl_arenas->narenas) {
Jason Evansedf1baf2017-01-03 17:21:59 -08002184 ret = NULL;
2185 goto label_return;
2186 }
2187 break;
Jason Evans609ae592012-10-11 13:53:15 -07002188 }
2189
2190 ret = super_arena_i_node;
2191label_return:
Jason Evansc1e00ef2016-05-10 22:21:10 -07002192 malloc_mutex_unlock(tsdn, &ctl_mtx);
Jason Evansf4086432017-01-19 18:15:45 -08002193 return ret;
Jason Evans609ae592012-10-11 13:53:15 -07002194}
2195
Jason Evans609ae592012-10-11 13:53:15 -07002196/******************************************************************************/
2197
Jason Evans609ae592012-10-11 13:53:15 -07002198static int
Jason Evansb2c0d632016-04-13 23:36:15 -07002199arenas_narenas_ctl(tsd_t *tsd, const size_t *mib, size_t miblen, void *oldp,
Jason Evansc4c25922017-01-15 16:56:30 -08002200 size_t *oldlenp, void *newp, size_t newlen) {
Jason Evans609ae592012-10-11 13:53:15 -07002201 int ret;
2202 unsigned narenas;
2203
Jason Evansc1e00ef2016-05-10 22:21:10 -07002204 malloc_mutex_lock(tsd_tsdn(tsd), &ctl_mtx);
Jason Evans609ae592012-10-11 13:53:15 -07002205 READONLY();
2206 if (*oldlenp != sizeof(unsigned)) {
2207 ret = EINVAL;
2208 goto label_return;
2209 }
Jason Evans9eb1b1c2017-01-18 23:03:37 -08002210 narenas = ctl_arenas->narenas;
Jason Evans609ae592012-10-11 13:53:15 -07002211 READ(narenas, unsigned);
2212
2213 ret = 0;
2214label_return:
Jason Evansc1e00ef2016-05-10 22:21:10 -07002215 malloc_mutex_unlock(tsd_tsdn(tsd), &ctl_mtx);
Jason Evansf4086432017-01-19 18:15:45 -08002216 return ret;
Jason Evans609ae592012-10-11 13:53:15 -07002217}
Jason Evans3c234352010-01-27 13:10:55 -08002218
2219static int
Jason Evans6e62c622017-05-17 10:47:00 -07002220arenas_decay_ms_ctl_impl(tsd_t *tsd, const size_t *mib, size_t miblen,
Jason Evans64e458f2017-03-08 22:42:57 -08002221 void *oldp, size_t *oldlenp, void *newp, size_t newlen, bool dirty) {
Jason Evans243f7a02016-02-19 20:09:31 -08002222 int ret;
2223
2224 if (oldp != NULL && oldlenp != NULL) {
Jason Evans6e62c622017-05-17 10:47:00 -07002225 size_t oldval = (dirty ? arena_dirty_decay_ms_default_get() :
2226 arena_muzzy_decay_ms_default_get());
Jason Evans243f7a02016-02-19 20:09:31 -08002227 READ(oldval, ssize_t);
2228 }
2229 if (newp != NULL) {
2230 if (newlen != sizeof(ssize_t)) {
2231 ret = EINVAL;
2232 goto label_return;
2233 }
Jason Evans6e62c622017-05-17 10:47:00 -07002234 if (dirty ? arena_dirty_decay_ms_default_set(*(ssize_t *)newp)
2235 : arena_muzzy_decay_ms_default_set(*(ssize_t *)newp)) {
Jason Evans243f7a02016-02-19 20:09:31 -08002236 ret = EFAULT;
2237 goto label_return;
2238 }
2239 }
2240
2241 ret = 0;
2242label_return:
Jason Evansf4086432017-01-19 18:15:45 -08002243 return ret;
Jason Evans243f7a02016-02-19 20:09:31 -08002244}
2245
Jason Evans64e458f2017-03-08 22:42:57 -08002246static int
Jason Evans6e62c622017-05-17 10:47:00 -07002247arenas_dirty_decay_ms_ctl(tsd_t *tsd, const size_t *mib, size_t miblen,
Jason Evans64e458f2017-03-08 22:42:57 -08002248 void *oldp, size_t *oldlenp, void *newp, size_t newlen) {
Jason Evans6e62c622017-05-17 10:47:00 -07002249 return arenas_decay_ms_ctl_impl(tsd, mib, miblen, oldp, oldlenp, newp,
Jason Evans64e458f2017-03-08 22:42:57 -08002250 newlen, true);
2251}
2252
2253static int
Jason Evans6e62c622017-05-17 10:47:00 -07002254arenas_muzzy_decay_ms_ctl(tsd_t *tsd, const size_t *mib, size_t miblen,
Jason Evans64e458f2017-03-08 22:42:57 -08002255 void *oldp, size_t *oldlenp, void *newp, size_t newlen) {
Jason Evans6e62c622017-05-17 10:47:00 -07002256 return arenas_decay_ms_ctl_impl(tsd, mib, miblen, oldp, oldlenp, newp,
Jason Evans64e458f2017-03-08 22:42:57 -08002257 newlen, false);
2258}
2259
Jason Evansfc4dcfa2010-11-24 15:44:21 -08002260CTL_RO_NL_GEN(arenas_quantum, QUANTUM, size_t)
Jason Evansae4c7b42012-04-02 07:04:34 -07002261CTL_RO_NL_GEN(arenas_page, PAGE, size_t)
Jason Evans4403c9a2017-04-20 17:21:37 -07002262CTL_RO_NL_GEN(arenas_tcache_max, tcache_maxclass, size_t)
Jason Evansb1726102012-02-28 16:50:47 -08002263CTL_RO_NL_GEN(arenas_nbins, NBINS, unsigned)
Jason Evans4403c9a2017-04-20 17:21:37 -07002264CTL_RO_NL_GEN(arenas_nhbins, nhbins, unsigned)
Jason Evansd8a39002013-12-19 21:40:41 -08002265CTL_RO_NL_GEN(arenas_bin_i_size, arena_bin_info[mib[2]].reg_size, size_t)
2266CTL_RO_NL_GEN(arenas_bin_i_nregs, arena_bin_info[mib[2]].nregs, uint32_t)
Jason Evans498856f2016-05-29 18:34:50 -07002267CTL_RO_NL_GEN(arenas_bin_i_slab_size, arena_bin_info[mib[2]].slab_size, size_t)
Jason Evansd8a39002013-12-19 21:40:41 -08002268static const ctl_named_node_t *
Jason Evansc4c25922017-01-15 16:56:30 -08002269arenas_bin_i_index(tsdn_t *tsdn, const size_t *mib, size_t miblen, size_t i) {
2270 if (i > NBINS) {
Jason Evansf4086432017-01-19 18:15:45 -08002271 return NULL;
Jason Evansc4c25922017-01-15 16:56:30 -08002272 }
Jason Evansf4086432017-01-19 18:15:45 -08002273 return super_arenas_bin_i_node;
Jason Evansd8a39002013-12-19 21:40:41 -08002274}
2275
Jason Evans7d63fed2016-05-31 14:50:21 -07002276CTL_RO_NL_GEN(arenas_nlextents, NSIZES - NBINS, unsigned)
David Goldblatt8261e582017-05-30 10:45:37 -07002277CTL_RO_NL_GEN(arenas_lextent_i_size, sz_index2size(NBINS+(szind_t)mib[2]),
2278 size_t)
Jason Evans3c4d92e2014-10-12 22:53:59 -07002279static const ctl_named_node_t *
Jason Evansc4c25922017-01-15 16:56:30 -08002280arenas_lextent_i_index(tsdn_t *tsdn, const size_t *mib, size_t miblen,
2281 size_t i) {
2282 if (i > NSIZES - NBINS) {
Jason Evansf4086432017-01-19 18:15:45 -08002283 return NULL;
Jason Evansc4c25922017-01-15 16:56:30 -08002284 }
Jason Evansf4086432017-01-19 18:15:45 -08002285 return super_arenas_lextent_i_node;
Jason Evans3c4d92e2014-10-12 22:53:59 -07002286}
2287
Jason Evans6005f072010-09-30 16:55:08 -07002288static int
Jason Evans0f04bb12017-01-03 08:21:29 -08002289arenas_create_ctl(tsd_t *tsd, const size_t *mib, size_t miblen, void *oldp,
Jason Evansc4c25922017-01-15 16:56:30 -08002290 size_t *oldlenp, void *newp, size_t newlen) {
Jason Evans609ae592012-10-11 13:53:15 -07002291 int ret;
Jason Evansa0dd3a42016-12-22 16:39:10 -06002292 extent_hooks_t *extent_hooks;
Jason Evansedf1baf2017-01-03 17:21:59 -08002293 unsigned arena_ind;
Jason Evans609ae592012-10-11 13:53:15 -07002294
Jason Evansc1e00ef2016-05-10 22:21:10 -07002295 malloc_mutex_lock(tsd_tsdn(tsd), &ctl_mtx);
Jason Evansa0dd3a42016-12-22 16:39:10 -06002296
2297 extent_hooks = (extent_hooks_t *)&extent_hooks_default;
2298 WRITE(extent_hooks, extent_hooks_t *);
Jason Evansedf1baf2017-01-03 17:21:59 -08002299 if ((arena_ind = ctl_arena_init(tsd_tsdn(tsd), extent_hooks)) ==
2300 UINT_MAX) {
Jason Evans609ae592012-10-11 13:53:15 -07002301 ret = EAGAIN;
2302 goto label_return;
2303 }
Jason Evansedf1baf2017-01-03 17:21:59 -08002304 READ(arena_ind, unsigned);
Jason Evans609ae592012-10-11 13:53:15 -07002305
Jason Evans6005f072010-09-30 16:55:08 -07002306 ret = 0;
Jason Evansa1ee7832012-04-10 15:07:44 -07002307label_return:
Jason Evansc1e00ef2016-05-10 22:21:10 -07002308 malloc_mutex_unlock(tsd_tsdn(tsd), &ctl_mtx);
Jason Evansf4086432017-01-19 18:15:45 -08002309 return ret;
Jason Evans6005f072010-09-30 16:55:08 -07002310}
2311
Jason Evans3c234352010-01-27 13:10:55 -08002312/******************************************************************************/
2313
Jason Evansd34f9e72010-02-11 13:19:21 -08002314static int
Jason Evansb2c0d632016-04-13 23:36:15 -07002315prof_thread_active_init_ctl(tsd_t *tsd, const size_t *mib, size_t miblen,
Jason Evansc4c25922017-01-15 16:56:30 -08002316 void *oldp, size_t *oldlenp, void *newp, size_t newlen) {
Jason Evansb2c0d632016-04-13 23:36:15 -07002317 int ret;
2318 bool oldval;
2319
Jason Evansc4c25922017-01-15 16:56:30 -08002320 if (!config_prof) {
Jason Evansf4086432017-01-19 18:15:45 -08002321 return ENOENT;
Jason Evansc4c25922017-01-15 16:56:30 -08002322 }
Jason Evansb2c0d632016-04-13 23:36:15 -07002323
2324 if (newp != NULL) {
2325 if (newlen != sizeof(bool)) {
2326 ret = EINVAL;
2327 goto label_return;
2328 }
Jason Evansc1e00ef2016-05-10 22:21:10 -07002329 oldval = prof_thread_active_init_set(tsd_tsdn(tsd),
2330 *(bool *)newp);
Jason Evansc4c25922017-01-15 16:56:30 -08002331 } else {
Jason Evansc1e00ef2016-05-10 22:21:10 -07002332 oldval = prof_thread_active_init_get(tsd_tsdn(tsd));
Jason Evansc4c25922017-01-15 16:56:30 -08002333 }
Jason Evansb2c0d632016-04-13 23:36:15 -07002334 READ(oldval, bool);
2335
2336 ret = 0;
2337label_return:
Jason Evansf4086432017-01-19 18:15:45 -08002338 return ret;
Jason Evansb2c0d632016-04-13 23:36:15 -07002339}
2340
2341static int
2342prof_active_ctl(tsd_t *tsd, const size_t *mib, size_t miblen, void *oldp,
Jason Evansc4c25922017-01-15 16:56:30 -08002343 size_t *oldlenp, void *newp, size_t newlen) {
Jason Evansfc12c0b2014-10-03 23:25:30 -07002344 int ret;
2345 bool oldval;
2346
Jason Evansc4c25922017-01-15 16:56:30 -08002347 if (!config_prof) {
Jason Evansf4086432017-01-19 18:15:45 -08002348 return ENOENT;
Jason Evansc4c25922017-01-15 16:56:30 -08002349 }
Jason Evansfc12c0b2014-10-03 23:25:30 -07002350
2351 if (newp != NULL) {
2352 if (newlen != sizeof(bool)) {
2353 ret = EINVAL;
2354 goto label_return;
2355 }
Jason Evansc1e00ef2016-05-10 22:21:10 -07002356 oldval = prof_active_set(tsd_tsdn(tsd), *(bool *)newp);
Jason Evansc4c25922017-01-15 16:56:30 -08002357 } else {
Jason Evansc1e00ef2016-05-10 22:21:10 -07002358 oldval = prof_active_get(tsd_tsdn(tsd));
Jason Evansc4c25922017-01-15 16:56:30 -08002359 }
Jason Evansfc12c0b2014-10-03 23:25:30 -07002360 READ(oldval, bool);
2361
2362 ret = 0;
2363label_return:
Jason Evansf4086432017-01-19 18:15:45 -08002364 return ret;
Jason Evansfc12c0b2014-10-03 23:25:30 -07002365}
2366
2367static int
Jason Evansb2c0d632016-04-13 23:36:15 -07002368prof_dump_ctl(tsd_t *tsd, const size_t *mib, size_t miblen, void *oldp,
Jason Evansc4c25922017-01-15 16:56:30 -08002369 size_t *oldlenp, void *newp, size_t newlen) {
Jason Evansd34f9e72010-02-11 13:19:21 -08002370 int ret;
Jason Evans22ca8552010-03-02 11:57:30 -08002371 const char *filename = NULL;
Jason Evansd34f9e72010-02-11 13:19:21 -08002372
Jason Evansc4c25922017-01-15 16:56:30 -08002373 if (!config_prof) {
Jason Evansf4086432017-01-19 18:15:45 -08002374 return ENOENT;
Jason Evansc4c25922017-01-15 16:56:30 -08002375 }
Jason Evans7372b152012-02-10 20:22:09 -08002376
Jason Evans22ca8552010-03-02 11:57:30 -08002377 WRITEONLY();
2378 WRITE(filename, const char *);
Jason Evansd34f9e72010-02-11 13:19:21 -08002379
Jason Evansb2c0d632016-04-13 23:36:15 -07002380 if (prof_mdump(tsd, filename)) {
Jason Evans22ca8552010-03-02 11:57:30 -08002381 ret = EFAULT;
Jason Evansa1ee7832012-04-10 15:07:44 -07002382 goto label_return;
Jason Evans22ca8552010-03-02 11:57:30 -08002383 }
Jason Evansd34f9e72010-02-11 13:19:21 -08002384
2385 ret = 0;
Jason Evansa1ee7832012-04-10 15:07:44 -07002386label_return:
Jason Evansf4086432017-01-19 18:15:45 -08002387 return ret;
Jason Evansd34f9e72010-02-11 13:19:21 -08002388}
2389
Jason Evans602c8e02014-08-18 16:22:13 -07002390static int
Jason Evansb2c0d632016-04-13 23:36:15 -07002391prof_gdump_ctl(tsd_t *tsd, const size_t *mib, size_t miblen, void *oldp,
Jason Evansc4c25922017-01-15 16:56:30 -08002392 size_t *oldlenp, void *newp, size_t newlen) {
Jason Evans5b8ed5b2015-01-25 21:16:57 -08002393 int ret;
2394 bool oldval;
2395
Jason Evansc4c25922017-01-15 16:56:30 -08002396 if (!config_prof) {
Jason Evansf4086432017-01-19 18:15:45 -08002397 return ENOENT;
Jason Evansc4c25922017-01-15 16:56:30 -08002398 }
Jason Evans5b8ed5b2015-01-25 21:16:57 -08002399
2400 if (newp != NULL) {
2401 if (newlen != sizeof(bool)) {
2402 ret = EINVAL;
2403 goto label_return;
2404 }
Jason Evansc1e00ef2016-05-10 22:21:10 -07002405 oldval = prof_gdump_set(tsd_tsdn(tsd), *(bool *)newp);
Jason Evansc4c25922017-01-15 16:56:30 -08002406 } else {
Jason Evansc1e00ef2016-05-10 22:21:10 -07002407 oldval = prof_gdump_get(tsd_tsdn(tsd));
Jason Evansc4c25922017-01-15 16:56:30 -08002408 }
Jason Evans5b8ed5b2015-01-25 21:16:57 -08002409 READ(oldval, bool);
2410
2411 ret = 0;
2412label_return:
Jason Evansf4086432017-01-19 18:15:45 -08002413 return ret;
Jason Evans5b8ed5b2015-01-25 21:16:57 -08002414}
2415
2416static int
Jason Evansb2c0d632016-04-13 23:36:15 -07002417prof_reset_ctl(tsd_t *tsd, const size_t *mib, size_t miblen, void *oldp,
Jason Evansc4c25922017-01-15 16:56:30 -08002418 size_t *oldlenp, void *newp, size_t newlen) {
Jason Evans602c8e02014-08-18 16:22:13 -07002419 int ret;
2420 size_t lg_sample = lg_prof_sample;
2421
Jason Evansc4c25922017-01-15 16:56:30 -08002422 if (!config_prof) {
Jason Evansf4086432017-01-19 18:15:45 -08002423 return ENOENT;
Jason Evansc4c25922017-01-15 16:56:30 -08002424 }
Jason Evans602c8e02014-08-18 16:22:13 -07002425
2426 WRITEONLY();
2427 WRITE(lg_sample, size_t);
Jason Evansc4c25922017-01-15 16:56:30 -08002428 if (lg_sample >= (sizeof(uint64_t) << 3)) {
Jason Evans602c8e02014-08-18 16:22:13 -07002429 lg_sample = (sizeof(uint64_t) << 3) - 1;
Jason Evansc4c25922017-01-15 16:56:30 -08002430 }
Jason Evans602c8e02014-08-18 16:22:13 -07002431
Jason Evansb54d1602016-10-20 23:59:12 -07002432 prof_reset(tsd, lg_sample);
Jason Evans602c8e02014-08-18 16:22:13 -07002433
2434 ret = 0;
2435label_return:
Jason Evansf4086432017-01-19 18:15:45 -08002436 return ret;
Jason Evans602c8e02014-08-18 16:22:13 -07002437}
2438
Jason Evans7372b152012-02-10 20:22:09 -08002439CTL_RO_NL_CGEN(config_prof, prof_interval, prof_interval, uint64_t)
Jason Evans602c8e02014-08-18 16:22:13 -07002440CTL_RO_NL_CGEN(config_prof, lg_prof_sample, lg_prof_sample, size_t)
Jason Evansd34f9e72010-02-11 13:19:21 -08002441
2442/******************************************************************************/
2443
Jason Evansd778dd22017-01-03 12:40:54 -08002444CTL_RO_CGEN(config_stats, stats_allocated, ctl_stats->allocated, size_t)
2445CTL_RO_CGEN(config_stats, stats_active, ctl_stats->active, size_t)
2446CTL_RO_CGEN(config_stats, stats_metadata, ctl_stats->metadata, size_t)
2447CTL_RO_CGEN(config_stats, stats_resident, ctl_stats->resident, size_t)
2448CTL_RO_CGEN(config_stats, stats_mapped, ctl_stats->mapped, size_t)
2449CTL_RO_CGEN(config_stats, stats_retained, ctl_stats->retained, size_t)
Jason Evansd8a39002013-12-19 21:40:41 -08002450
Qi Wang2bee0c62017-05-12 12:30:33 -07002451CTL_RO_CGEN(config_stats, stats_background_thread_num_threads,
2452 ctl_stats->background_thread.num_threads, size_t)
2453CTL_RO_CGEN(config_stats, stats_background_thread_num_runs,
2454 ctl_stats->background_thread.num_runs, uint64_t)
2455CTL_RO_CGEN(config_stats, stats_background_thread_run_interval,
2456 nstime_ns(&ctl_stats->background_thread.run_interval), uint64_t)
2457
Jason Evans9eb1b1c2017-01-18 23:03:37 -08002458CTL_RO_GEN(stats_arenas_i_dss, arenas_i(mib[2])->dss, const char *)
Jason Evans6e62c622017-05-17 10:47:00 -07002459CTL_RO_GEN(stats_arenas_i_dirty_decay_ms, arenas_i(mib[2])->dirty_decay_ms,
Jason Evans64e458f2017-03-08 22:42:57 -08002460 ssize_t)
Jason Evans6e62c622017-05-17 10:47:00 -07002461CTL_RO_GEN(stats_arenas_i_muzzy_decay_ms, arenas_i(mib[2])->muzzy_decay_ms,
Jason Evans243f7a02016-02-19 20:09:31 -08002462 ssize_t)
Jason Evans9eb1b1c2017-01-18 23:03:37 -08002463CTL_RO_GEN(stats_arenas_i_nthreads, arenas_i(mib[2])->nthreads, unsigned)
Qi Wangbaf3e292017-05-16 13:56:00 -07002464CTL_RO_GEN(stats_arenas_i_uptime,
2465 nstime_ns(&arenas_i(mib[2])->astats->astats.uptime), uint64_t)
Jason Evans9eb1b1c2017-01-18 23:03:37 -08002466CTL_RO_GEN(stats_arenas_i_pactive, arenas_i(mib[2])->pactive, size_t)
2467CTL_RO_GEN(stats_arenas_i_pdirty, arenas_i(mib[2])->pdirty, size_t)
Jason Evans64e458f2017-03-08 22:42:57 -08002468CTL_RO_GEN(stats_arenas_i_pmuzzy, arenas_i(mib[2])->pmuzzy, size_t)
Jason Evansd8a39002013-12-19 21:40:41 -08002469CTL_RO_CGEN(config_stats, stats_arenas_i_mapped,
David Goldblattee202ef2017-03-13 16:18:40 -07002470 atomic_load_zu(&arenas_i(mib[2])->astats->astats.mapped, ATOMIC_RELAXED),
2471 size_t)
Jason Evans04c3c0f2016-05-03 22:11:35 -07002472CTL_RO_CGEN(config_stats, stats_arenas_i_retained,
David Goldblattee202ef2017-03-13 16:18:40 -07002473 atomic_load_zu(&arenas_i(mib[2])->astats->astats.retained, ATOMIC_RELAXED),
2474 size_t)
Jason Evans64e458f2017-03-08 22:42:57 -08002475
2476CTL_RO_CGEN(config_stats, stats_arenas_i_dirty_npurge,
2477 arena_stats_read_u64(&arenas_i(mib[2])->astats->astats.decay_dirty.npurge),
2478 uint64_t)
2479CTL_RO_CGEN(config_stats, stats_arenas_i_dirty_nmadvise,
2480 arena_stats_read_u64(
2481 &arenas_i(mib[2])->astats->astats.decay_dirty.nmadvise), uint64_t)
2482CTL_RO_CGEN(config_stats, stats_arenas_i_dirty_purged,
2483 arena_stats_read_u64(&arenas_i(mib[2])->astats->astats.decay_dirty.purged),
2484 uint64_t)
2485
2486CTL_RO_CGEN(config_stats, stats_arenas_i_muzzy_npurge,
2487 arena_stats_read_u64(&arenas_i(mib[2])->astats->astats.decay_muzzy.npurge),
2488 uint64_t)
2489CTL_RO_CGEN(config_stats, stats_arenas_i_muzzy_nmadvise,
2490 arena_stats_read_u64(
2491 &arenas_i(mib[2])->astats->astats.decay_muzzy.nmadvise), uint64_t)
2492CTL_RO_CGEN(config_stats, stats_arenas_i_muzzy_purged,
2493 arena_stats_read_u64(&arenas_i(mib[2])->astats->astats.decay_muzzy.purged),
2494 uint64_t)
2495
Jason Evansa0dd3a42016-12-22 16:39:10 -06002496CTL_RO_CGEN(config_stats, stats_arenas_i_base,
David Goldblattee202ef2017-03-13 16:18:40 -07002497 atomic_load_zu(&arenas_i(mib[2])->astats->astats.base, ATOMIC_RELAXED),
2498 size_t)
Jason Evansa0dd3a42016-12-22 16:39:10 -06002499CTL_RO_CGEN(config_stats, stats_arenas_i_internal,
David Goldblattee202ef2017-03-13 16:18:40 -07002500 atomic_load_zu(&arenas_i(mib[2])->astats->astats.internal, ATOMIC_RELAXED),
2501 size_t)
Jason Evans4403c9a2017-04-20 17:21:37 -07002502CTL_RO_CGEN(config_stats, stats_arenas_i_tcache_bytes,
David Goldblattee202ef2017-03-13 16:18:40 -07002503 atomic_load_zu(&arenas_i(mib[2])->astats->astats.tcache_bytes,
2504 ATOMIC_RELAXED), size_t)
Jason Evansa0dd3a42016-12-22 16:39:10 -06002505CTL_RO_CGEN(config_stats, stats_arenas_i_resident,
David Goldblattee202ef2017-03-13 16:18:40 -07002506 atomic_load_zu(&arenas_i(mib[2])->astats->astats.resident, ATOMIC_RELAXED),
2507 size_t)
Jason Evansd8a39002013-12-19 21:40:41 -08002508
Jason Evans7372b152012-02-10 20:22:09 -08002509CTL_RO_CGEN(config_stats, stats_arenas_i_small_allocated,
Jason Evans9eb1b1c2017-01-18 23:03:37 -08002510 arenas_i(mib[2])->astats->allocated_small, size_t)
Jason Evans7372b152012-02-10 20:22:09 -08002511CTL_RO_CGEN(config_stats, stats_arenas_i_small_nmalloc,
Jason Evans9eb1b1c2017-01-18 23:03:37 -08002512 arenas_i(mib[2])->astats->nmalloc_small, uint64_t)
Jason Evans7372b152012-02-10 20:22:09 -08002513CTL_RO_CGEN(config_stats, stats_arenas_i_small_ndalloc,
Jason Evans9eb1b1c2017-01-18 23:03:37 -08002514 arenas_i(mib[2])->astats->ndalloc_small, uint64_t)
Jason Evans7372b152012-02-10 20:22:09 -08002515CTL_RO_CGEN(config_stats, stats_arenas_i_small_nrequests,
Jason Evans9eb1b1c2017-01-18 23:03:37 -08002516 arenas_i(mib[2])->astats->nrequests_small, uint64_t)
Jason Evans7d63fed2016-05-31 14:50:21 -07002517CTL_RO_CGEN(config_stats, stats_arenas_i_large_allocated,
David Goldblattee202ef2017-03-13 16:18:40 -07002518 atomic_load_zu(&arenas_i(mib[2])->astats->astats.allocated_large,
2519 ATOMIC_RELAXED), size_t)
Jason Evans7d63fed2016-05-31 14:50:21 -07002520CTL_RO_CGEN(config_stats, stats_arenas_i_large_nmalloc,
David Goldblatt4fc2acf2017-03-08 15:56:31 -08002521 arena_stats_read_u64(&arenas_i(mib[2])->astats->astats.nmalloc_large),
2522 uint64_t)
Jason Evans7d63fed2016-05-31 14:50:21 -07002523CTL_RO_CGEN(config_stats, stats_arenas_i_large_ndalloc,
David Goldblatt4fc2acf2017-03-08 15:56:31 -08002524 arena_stats_read_u64(&arenas_i(mib[2])->astats->astats.ndalloc_large),
2525 uint64_t)
Jason Evans7d63fed2016-05-31 14:50:21 -07002526CTL_RO_CGEN(config_stats, stats_arenas_i_large_nrequests,
David Goldblatt4fc2acf2017-03-08 15:56:31 -08002527 arena_stats_read_u64(&arenas_i(mib[2])->astats->astats.nmalloc_large),
2528 uint64_t) /* Intentional. */
Jason Evans3c234352010-01-27 13:10:55 -08002529
Qi Wang0fb5c0e2017-03-10 12:14:05 -08002530/* Lock profiling related APIs below. */
Qi Wang64c5f5c2017-03-13 17:29:03 -07002531#define RO_MUTEX_CTL_GEN(n, l) \
Qi Wangca9074d2017-03-11 20:28:31 -08002532CTL_RO_CGEN(config_stats, stats_##n##_num_ops, \
2533 l.n_lock_ops, uint64_t) \
2534CTL_RO_CGEN(config_stats, stats_##n##_num_wait, \
2535 l.n_wait_times, uint64_t) \
2536CTL_RO_CGEN(config_stats, stats_##n##_num_spin_acq, \
2537 l.n_spin_acquired, uint64_t) \
2538CTL_RO_CGEN(config_stats, stats_##n##_num_owner_switch, \
2539 l.n_owner_switches, uint64_t) \
2540CTL_RO_CGEN(config_stats, stats_##n##_total_wait_time, \
Qi Wangf6698ec2017-03-17 17:42:10 -07002541 nstime_ns(&l.tot_wait_time), uint64_t) \
Qi Wangca9074d2017-03-11 20:28:31 -08002542CTL_RO_CGEN(config_stats, stats_##n##_max_wait_time, \
Qi Wangf6698ec2017-03-17 17:42:10 -07002543 nstime_ns(&l.max_wait_time), uint64_t) \
Qi Wangca9074d2017-03-11 20:28:31 -08002544CTL_RO_CGEN(config_stats, stats_##n##_max_num_thds, \
Qi Wangd3fde1c2017-03-21 11:56:38 -07002545 l.max_n_thds, uint32_t)
Qi Wang0fb5c0e2017-03-10 12:14:05 -08002546
Qi Wang64c5f5c2017-03-13 17:29:03 -07002547/* Global mutexes. */
Qi Wangd3fde1c2017-03-21 11:56:38 -07002548#define OP(mtx) \
2549 RO_MUTEX_CTL_GEN(mutexes_##mtx, \
2550 ctl_stats->mutex_prof_data[global_prof_mutex_##mtx])
David Goldblatt89e2d3c2017-04-24 17:09:56 -07002551MUTEX_PROF_GLOBAL_MUTEXES
Qi Wangd3fde1c2017-03-21 11:56:38 -07002552#undef OP
2553
2554/* Per arena mutexes */
2555#define OP(mtx) RO_MUTEX_CTL_GEN(arenas_i_mutexes_##mtx, \
2556 arenas_i(mib[2])->astats->astats.mutex_prof_data[arena_prof_mutex_##mtx])
David Goldblatt89e2d3c2017-04-24 17:09:56 -07002557MUTEX_PROF_ARENA_MUTEXES
Qi Wangd3fde1c2017-03-21 11:56:38 -07002558#undef OP
Qi Wangca9074d2017-03-11 20:28:31 -08002559
Qi Wang20b8c702017-03-15 14:00:57 -07002560/* tcache bin mutex */
Qi Wang64c5f5c2017-03-13 17:29:03 -07002561RO_MUTEX_CTL_GEN(arenas_i_bins_j_mutex,
2562 arenas_i(mib[2])->astats->bstats[mib[4]].mutex_data)
Qi Wang64c5f5c2017-03-13 17:29:03 -07002563#undef RO_MUTEX_CTL_GEN
2564
2565/* Resets all mutex stats, including global, arena and bin mutexes. */
2566static int
2567stats_mutexes_reset_ctl(tsd_t *tsd, const size_t *mib, size_t miblen,
2568 void *oldp, size_t *oldlenp, void *newp, size_t newlen) {
2569 if (!config_stats) {
2570 return ENOENT;
2571 }
2572
2573 tsdn_t *tsdn = tsd_tsdn(tsd);
2574
2575#define MUTEX_PROF_RESET(mtx) \
2576 malloc_mutex_lock(tsdn, &mtx); \
2577 malloc_mutex_prof_data_reset(tsdn, &mtx); \
2578 malloc_mutex_unlock(tsdn, &mtx);
2579
Qi Wang362e3562017-03-22 01:49:56 -07002580 /* Global mutexes: ctl and prof. */
2581 MUTEX_PROF_RESET(ctl_mtx);
Qi Wang5f5ed212017-05-12 16:26:59 -07002582 if (have_background_thread) {
2583 MUTEX_PROF_RESET(background_thread_lock);
2584 }
Qi Wang64c5f5c2017-03-13 17:29:03 -07002585 if (config_prof && opt_prof) {
2586 MUTEX_PROF_RESET(bt2gctx_mtx);
2587 }
Qi Wang362e3562017-03-22 01:49:56 -07002588
Qi Wang64c5f5c2017-03-13 17:29:03 -07002589
2590 /* Per arena mutexes. */
2591 unsigned n = narenas_total_get();
2592
2593 for (unsigned i = 0; i < n; i++) {
2594 arena_t *arena = arena_get(tsdn, i, false);
2595 if (!arena) {
2596 continue;
2597 }
2598 MUTEX_PROF_RESET(arena->large_mtx);
Jason Evans881fbf72017-04-16 22:31:16 -07002599 MUTEX_PROF_RESET(arena->extent_avail_mtx);
Qi Wang20b8c702017-03-15 14:00:57 -07002600 MUTEX_PROF_RESET(arena->extents_dirty.mtx);
2601 MUTEX_PROF_RESET(arena->extents_muzzy.mtx);
Qi Wang64c5f5c2017-03-13 17:29:03 -07002602 MUTEX_PROF_RESET(arena->extents_retained.mtx);
Qi Wang20b8c702017-03-15 14:00:57 -07002603 MUTEX_PROF_RESET(arena->decay_dirty.mtx);
2604 MUTEX_PROF_RESET(arena->decay_muzzy.mtx);
Jason Evans4403c9a2017-04-20 17:21:37 -07002605 MUTEX_PROF_RESET(arena->tcache_ql_mtx);
Qi Wang362e3562017-03-22 01:49:56 -07002606 MUTEX_PROF_RESET(arena->base->mtx);
Qi Wang64c5f5c2017-03-13 17:29:03 -07002607
2608 for (szind_t i = 0; i < NBINS; i++) {
2609 arena_bin_t *bin = &arena->bins[i];
2610 MUTEX_PROF_RESET(bin->lock);
2611 }
2612 }
2613#undef MUTEX_PROF_RESET
2614 return 0;
2615}
Qi Wang0fb5c0e2017-03-10 12:14:05 -08002616
Jason Evans7372b152012-02-10 20:22:09 -08002617CTL_RO_CGEN(config_stats, stats_arenas_i_bins_j_nmalloc,
Jason Evans9eb1b1c2017-01-18 23:03:37 -08002618 arenas_i(mib[2])->astats->bstats[mib[4]].nmalloc, uint64_t)
Jason Evans7372b152012-02-10 20:22:09 -08002619CTL_RO_CGEN(config_stats, stats_arenas_i_bins_j_ndalloc,
Jason Evans9eb1b1c2017-01-18 23:03:37 -08002620 arenas_i(mib[2])->astats->bstats[mib[4]].ndalloc, uint64_t)
Jason Evans7372b152012-02-10 20:22:09 -08002621CTL_RO_CGEN(config_stats, stats_arenas_i_bins_j_nrequests,
Jason Evans9eb1b1c2017-01-18 23:03:37 -08002622 arenas_i(mib[2])->astats->bstats[mib[4]].nrequests, uint64_t)
Jason Evans3c4d92e2014-10-12 22:53:59 -07002623CTL_RO_CGEN(config_stats, stats_arenas_i_bins_j_curregs,
Jason Evans9eb1b1c2017-01-18 23:03:37 -08002624 arenas_i(mib[2])->astats->bstats[mib[4]].curregs, size_t)
Jason Evans4403c9a2017-04-20 17:21:37 -07002625CTL_RO_CGEN(config_stats, stats_arenas_i_bins_j_nfills,
Jason Evans9eb1b1c2017-01-18 23:03:37 -08002626 arenas_i(mib[2])->astats->bstats[mib[4]].nfills, uint64_t)
Jason Evans4403c9a2017-04-20 17:21:37 -07002627CTL_RO_CGEN(config_stats, stats_arenas_i_bins_j_nflushes,
Jason Evans9eb1b1c2017-01-18 23:03:37 -08002628 arenas_i(mib[2])->astats->bstats[mib[4]].nflushes, uint64_t)
Jason Evans498856f2016-05-29 18:34:50 -07002629CTL_RO_CGEN(config_stats, stats_arenas_i_bins_j_nslabs,
Jason Evans9eb1b1c2017-01-18 23:03:37 -08002630 arenas_i(mib[2])->astats->bstats[mib[4]].nslabs, uint64_t)
Jason Evans498856f2016-05-29 18:34:50 -07002631CTL_RO_CGEN(config_stats, stats_arenas_i_bins_j_nreslabs,
Jason Evans9eb1b1c2017-01-18 23:03:37 -08002632 arenas_i(mib[2])->astats->bstats[mib[4]].reslabs, uint64_t)
Jason Evans498856f2016-05-29 18:34:50 -07002633CTL_RO_CGEN(config_stats, stats_arenas_i_bins_j_curslabs,
Jason Evans9eb1b1c2017-01-18 23:03:37 -08002634 arenas_i(mib[2])->astats->bstats[mib[4]].curslabs, size_t)
Jason Evans3c234352010-01-27 13:10:55 -08002635
Jason Evans609ae592012-10-11 13:53:15 -07002636static const ctl_named_node_t *
Jason Evansc1e00ef2016-05-10 22:21:10 -07002637stats_arenas_i_bins_j_index(tsdn_t *tsdn, const size_t *mib, size_t miblen,
Jason Evansc4c25922017-01-15 16:56:30 -08002638 size_t j) {
2639 if (j > NBINS) {
Jason Evansf4086432017-01-19 18:15:45 -08002640 return NULL;
Jason Evansc4c25922017-01-15 16:56:30 -08002641 }
Jason Evansf4086432017-01-19 18:15:45 -08002642 return super_stats_arenas_i_bins_j_node;
Jason Evans3c234352010-01-27 13:10:55 -08002643}
2644
Jason Evans7d63fed2016-05-31 14:50:21 -07002645CTL_RO_CGEN(config_stats, stats_arenas_i_lextents_j_nmalloc,
David Goldblatt4fc2acf2017-03-08 15:56:31 -08002646 arena_stats_read_u64(&arenas_i(mib[2])->astats->lstats[mib[4]].nmalloc),
2647 uint64_t)
Jason Evans7d63fed2016-05-31 14:50:21 -07002648CTL_RO_CGEN(config_stats, stats_arenas_i_lextents_j_ndalloc,
David Goldblatt4fc2acf2017-03-08 15:56:31 -08002649 arena_stats_read_u64(&arenas_i(mib[2])->astats->lstats[mib[4]].ndalloc),
2650 uint64_t)
Jason Evans7d63fed2016-05-31 14:50:21 -07002651CTL_RO_CGEN(config_stats, stats_arenas_i_lextents_j_nrequests,
Jason Evans64e458f2017-03-08 22:42:57 -08002652 arena_stats_read_u64(&arenas_i(mib[2])->astats->lstats[mib[4]].nrequests),
2653 uint64_t)
Jason Evans7d63fed2016-05-31 14:50:21 -07002654CTL_RO_CGEN(config_stats, stats_arenas_i_lextents_j_curlextents,
Jason Evans9eb1b1c2017-01-18 23:03:37 -08002655 arenas_i(mib[2])->astats->lstats[mib[4]].curlextents, size_t)
Jason Evans3c4d92e2014-10-12 22:53:59 -07002656
2657static const ctl_named_node_t *
Jason Evans7d63fed2016-05-31 14:50:21 -07002658stats_arenas_i_lextents_j_index(tsdn_t *tsdn, const size_t *mib, size_t miblen,
Jason Evansc4c25922017-01-15 16:56:30 -08002659 size_t j) {
2660 if (j > NSIZES - NBINS) {
Jason Evansf4086432017-01-19 18:15:45 -08002661 return NULL;
Jason Evansc4c25922017-01-15 16:56:30 -08002662 }
Jason Evansf4086432017-01-19 18:15:45 -08002663 return super_stats_arenas_i_lextents_j_node;
Jason Evans3c4d92e2014-10-12 22:53:59 -07002664}
2665
Jason Evans609ae592012-10-11 13:53:15 -07002666static const ctl_named_node_t *
Jason Evansc4c25922017-01-15 16:56:30 -08002667stats_arenas_i_index(tsdn_t *tsdn, const size_t *mib, size_t miblen, size_t i) {
Jason Evans3dc4e832017-01-03 07:27:42 -08002668 const ctl_named_node_t *ret;
2669 size_t a;
Jason Evans3c234352010-01-27 13:10:55 -08002670
Jason Evansc1e00ef2016-05-10 22:21:10 -07002671 malloc_mutex_lock(tsdn, &ctl_mtx);
Jason Evans9eb1b1c2017-01-18 23:03:37 -08002672 a = arenas_i2a_impl(i, true, true);
2673 if (a == UINT_MAX || !ctl_arenas->arenas[a]->initialized) {
Jason Evansfc4dcfa2010-11-24 15:44:21 -08002674 ret = NULL;
Jason Evansa1ee7832012-04-10 15:07:44 -07002675 goto label_return;
Jason Evansfc4dcfa2010-11-24 15:44:21 -08002676 }
2677
2678 ret = super_stats_arenas_i_node;
Jason Evansa1ee7832012-04-10 15:07:44 -07002679label_return:
Jason Evansc1e00ef2016-05-10 22:21:10 -07002680 malloc_mutex_unlock(tsdn, &ctl_mtx);
Jason Evansf4086432017-01-19 18:15:45 -08002681 return ret;
Jason Evans3c234352010-01-27 13:10:55 -08002682}