blob: 28f4939880081e14e1281b2397a66e4953783947 [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 Goldblatt18ecbfa2017-05-23 12:28:19 -07007#include "jemalloc/internal/mutex.h"
David Goldblatt418d96a2017-04-17 16:17:02 -07008#include "jemalloc/internal/nstime.h"
David Goldblatt31b43212017-04-19 15:09:01 -07009#include "jemalloc/internal/size_classes.h"
David Goldblattf692e6c2017-04-11 13:31:16 -070010#include "jemalloc/internal/util.h"
11
Jason Evans3c234352010-01-27 13:10:55 -080012/******************************************************************************/
13/* Data. */
14
Jason Evansfc4dcfa2010-11-24 15:44:21 -080015/*
16 * ctl_mtx protects the following:
Jason Evansd778dd22017-01-03 12:40:54 -080017 * - ctl_stats->*
Jason Evansfc4dcfa2010-11-24 15:44:21 -080018 */
Jason Evans3c234352010-01-27 13:10:55 -080019static malloc_mutex_t ctl_mtx;
20static bool ctl_initialized;
Jason Evansd778dd22017-01-03 12:40:54 -080021static ctl_stats_t *ctl_stats;
Jason Evans9eb1b1c2017-01-18 23:03:37 -080022static ctl_arenas_t *ctl_arenas;
Jason Evans3c234352010-01-27 13:10:55 -080023
24/******************************************************************************/
Mike Hommey461ad5c2012-04-20 08:38:42 +020025/* Helpers for named and indexed nodes. */
26
David Goldblatt4d2e4bf2017-04-21 09:37:34 -070027static const ctl_named_node_t *
Jason Evansc4c25922017-01-15 16:56:30 -080028ctl_named_node(const ctl_node_t *node) {
Mike Hommey461ad5c2012-04-20 08:38:42 +020029 return ((node->named) ? (const ctl_named_node_t *)node : NULL);
30}
31
David Goldblatt4d2e4bf2017-04-21 09:37:34 -070032static const ctl_named_node_t *
Jason Evansc4c25922017-01-15 16:56:30 -080033ctl_named_children(const ctl_named_node_t *node, size_t index) {
Mike Hommey461ad5c2012-04-20 08:38:42 +020034 const ctl_named_node_t *children = ctl_named_node(node->children);
35
36 return (children ? &children[index] : NULL);
37}
38
David Goldblatt4d2e4bf2017-04-21 09:37:34 -070039static const ctl_indexed_node_t *
Jason Evansc4c25922017-01-15 16:56:30 -080040ctl_indexed_node(const ctl_node_t *node) {
Jason Evans551ebc42014-10-03 10:16:09 -070041 return (!node->named ? (const ctl_indexed_node_t *)node : NULL);
Mike Hommey461ad5c2012-04-20 08:38:42 +020042}
43
44/******************************************************************************/
Jason Evans3c234352010-01-27 13:10:55 -080045/* Function prototypes for non-inline static functions. */
46
Jason Evansc0cc5db2017-01-19 21:41:41 -080047#define CTL_PROTO(n) \
Jason Evansb2c0d632016-04-13 23:36:15 -070048static int n##_ctl(tsd_t *tsd, const size_t *mib, size_t miblen, \
49 void *oldp, size_t *oldlenp, void *newp, size_t newlen);
Jason Evans3c234352010-01-27 13:10:55 -080050
Jason Evansc0cc5db2017-01-19 21:41:41 -080051#define INDEX_PROTO(n) \
Jason Evansc1e00ef2016-05-10 22:21:10 -070052static const ctl_named_node_t *n##_index(tsdn_t *tsdn, \
Jason Evansb2c0d632016-04-13 23:36:15 -070053 const size_t *mib, size_t miblen, size_t i);
Jason Evans3c234352010-01-27 13:10:55 -080054
Jason Evansa40bc7a2010-03-02 13:01:16 -080055CTL_PROTO(version)
Jason Evans3c234352010-01-27 13:10:55 -080056CTL_PROTO(epoch)
Qi Wangb693c782017-03-17 12:42:33 -070057CTL_PROTO(background_thread)
Jason Evansd4be8b72012-03-26 18:54:44 -070058CTL_PROTO(thread_tcache_enabled)
Jason Evanse7b8fa12012-03-16 17:09:32 -070059CTL_PROTO(thread_tcache_flush)
Jason Evans602c8e02014-08-18 16:22:13 -070060CTL_PROTO(thread_prof_name)
61CTL_PROTO(thread_prof_active)
Jason Evansb267d0f2010-08-13 15:42:29 -070062CTL_PROTO(thread_arena)
Jason Evans93443682010-10-20 17:39:18 -070063CTL_PROTO(thread_allocated)
Jason Evansecf229a2010-12-03 15:55:47 -080064CTL_PROTO(thread_allocatedp)
Jason Evans93443682010-10-20 17:39:18 -070065CTL_PROTO(thread_deallocated)
Jason Evansecf229a2010-12-03 15:55:47 -080066CTL_PROTO(thread_deallocatedp)
Jason Evansf2bc8522015-07-17 16:38:25 -070067CTL_PROTO(config_cache_oblivious)
Jason Evans3c234352010-01-27 13:10:55 -080068CTL_PROTO(config_debug)
Jason Evans3c234352010-01-27 13:10:55 -080069CTL_PROTO(config_fill)
70CTL_PROTO(config_lazy_lock)
Jason Evansf8290092016-02-07 14:23:22 -080071CTL_PROTO(config_malloc_conf)
Jason Evansd34f9e72010-02-11 13:19:21 -080072CTL_PROTO(config_prof)
73CTL_PROTO(config_prof_libgcc)
74CTL_PROTO(config_prof_libunwind)
Jason Evans3c234352010-01-27 13:10:55 -080075CTL_PROTO(config_stats)
Jason Evansb1476112012-04-05 13:36:17 -070076CTL_PROTO(config_utrace)
Jason Evans3c234352010-01-27 13:10:55 -080077CTL_PROTO(config_xmalloc)
78CTL_PROTO(opt_abort)
Qi Wangb86d2712017-05-25 15:30:11 -070079CTL_PROTO(opt_abort_conf)
Jason Evansb9ab04a2017-04-26 16:26:12 -070080CTL_PROTO(opt_retain)
Jason Evans609ae592012-10-11 13:53:15 -070081CTL_PROTO(opt_dss)
Jason Evanse7339702010-10-23 18:37:06 -070082CTL_PROTO(opt_narenas)
Qi Wangec532e22017-02-02 17:02:05 -080083CTL_PROTO(opt_percpu_arena)
Qi Wangb693c782017-03-17 12:42:33 -070084CTL_PROTO(opt_background_thread)
Jason Evans6e62c622017-05-17 10:47:00 -070085CTL_PROTO(opt_dirty_decay_ms)
86CTL_PROTO(opt_muzzy_decay_ms)
Jason Evanse7339702010-10-23 18:37:06 -070087CTL_PROTO(opt_stats_print)
Jason Evans3c234352010-01-27 13:10:55 -080088CTL_PROTO(opt_junk)
Jason Evanse7339702010-10-23 18:37:06 -070089CTL_PROTO(opt_zero)
Jason Evansb1476112012-04-05 13:36:17 -070090CTL_PROTO(opt_utrace)
Jason Evans3c234352010-01-27 13:10:55 -080091CTL_PROTO(opt_xmalloc)
Jason Evans3fa9a2f2010-03-07 15:34:14 -080092CTL_PROTO(opt_tcache)
Jason Evansf3ca7c82012-04-04 16:16:09 -070093CTL_PROTO(opt_lg_tcache_max)
Jason Evansd34f9e72010-02-11 13:19:21 -080094CTL_PROTO(opt_prof)
Jason Evanse7339702010-10-23 18:37:06 -070095CTL_PROTO(opt_prof_prefix)
Jason Evansf18c9822010-03-31 18:43:24 -070096CTL_PROTO(opt_prof_active)
Jason Evansfc12c0b2014-10-03 23:25:30 -070097CTL_PROTO(opt_prof_thread_active_init)
Jason Evansb9477e72010-03-01 20:15:26 -080098CTL_PROTO(opt_lg_prof_sample)
Jason Evansd34f9e72010-02-11 13:19:21 -080099CTL_PROTO(opt_lg_prof_interval)
Jason Evanse7339702010-10-23 18:37:06 -0700100CTL_PROTO(opt_prof_gdump)
Jason Evans0b25fe72012-04-17 16:39:33 -0700101CTL_PROTO(opt_prof_final)
Jason Evansd34f9e72010-02-11 13:19:21 -0800102CTL_PROTO(opt_prof_leak)
Jason Evansa881cd22010-10-02 15:18:50 -0700103CTL_PROTO(opt_prof_accum)
Jason Evans1cb181e2015-01-29 15:30:47 -0800104CTL_PROTO(tcache_create)
105CTL_PROTO(tcache_flush)
106CTL_PROTO(tcache_destroy)
Jason Evansdc2125c2017-01-04 10:21:53 -0800107CTL_PROTO(arena_i_initialized)
Jason Evans243f7a02016-02-19 20:09:31 -0800108CTL_PROTO(arena_i_decay)
Jason Evans64e458f2017-03-08 22:42:57 -0800109CTL_PROTO(arena_i_purge)
Jason Evans19ff2ce2016-04-22 14:37:17 -0700110CTL_PROTO(arena_i_reset)
Jason Evansedf1baf2017-01-03 17:21:59 -0800111CTL_PROTO(arena_i_destroy)
Jason Evans609ae592012-10-11 13:53:15 -0700112CTL_PROTO(arena_i_dss)
Jason Evans6e62c622017-05-17 10:47:00 -0700113CTL_PROTO(arena_i_dirty_decay_ms)
114CTL_PROTO(arena_i_muzzy_decay_ms)
Jason Evans9c305c92016-05-31 15:03:51 -0700115CTL_PROTO(arena_i_extent_hooks)
Jason Evans609ae592012-10-11 13:53:15 -0700116INDEX_PROTO(arena_i)
Jason Evans3c234352010-01-27 13:10:55 -0800117CTL_PROTO(arenas_bin_i_size)
118CTL_PROTO(arenas_bin_i_nregs)
Jason Evans498856f2016-05-29 18:34:50 -0700119CTL_PROTO(arenas_bin_i_slab_size)
Jason Evans3c234352010-01-27 13:10:55 -0800120INDEX_PROTO(arenas_bin_i)
Jason Evans7d63fed2016-05-31 14:50:21 -0700121CTL_PROTO(arenas_lextent_i_size)
122INDEX_PROTO(arenas_lextent_i)
Jason Evans3c234352010-01-27 13:10:55 -0800123CTL_PROTO(arenas_narenas)
Jason Evans6e62c622017-05-17 10:47:00 -0700124CTL_PROTO(arenas_dirty_decay_ms)
125CTL_PROTO(arenas_muzzy_decay_ms)
Jason Evans3c234352010-01-27 13:10:55 -0800126CTL_PROTO(arenas_quantum)
Jason Evansae4c7b42012-04-02 07:04:34 -0700127CTL_PROTO(arenas_page)
Jason Evansdafde142010-03-17 16:27:39 -0700128CTL_PROTO(arenas_tcache_max)
Jason Evans3c234352010-01-27 13:10:55 -0800129CTL_PROTO(arenas_nbins)
Jason Evansdafde142010-03-17 16:27:39 -0700130CTL_PROTO(arenas_nhbins)
Jason Evans7d63fed2016-05-31 14:50:21 -0700131CTL_PROTO(arenas_nlextents)
Jason Evans0f04bb12017-01-03 08:21:29 -0800132CTL_PROTO(arenas_create)
Jason Evansfc12c0b2014-10-03 23:25:30 -0700133CTL_PROTO(prof_thread_active_init)
Jason Evansf18c9822010-03-31 18:43:24 -0700134CTL_PROTO(prof_active)
Jason Evansd34f9e72010-02-11 13:19:21 -0800135CTL_PROTO(prof_dump)
Jason Evans5b8ed5b2015-01-25 21:16:57 -0800136CTL_PROTO(prof_gdump)
Jason Evans602c8e02014-08-18 16:22:13 -0700137CTL_PROTO(prof_reset)
Jason Evansd34f9e72010-02-11 13:19:21 -0800138CTL_PROTO(prof_interval)
Jason Evans602c8e02014-08-18 16:22:13 -0700139CTL_PROTO(lg_prof_sample)
Jason Evans3c234352010-01-27 13:10:55 -0800140CTL_PROTO(stats_arenas_i_small_allocated)
141CTL_PROTO(stats_arenas_i_small_nmalloc)
142CTL_PROTO(stats_arenas_i_small_ndalloc)
Jason Evans86815df2010-03-13 20:32:56 -0800143CTL_PROTO(stats_arenas_i_small_nrequests)
Jason Evans7d63fed2016-05-31 14:50:21 -0700144CTL_PROTO(stats_arenas_i_large_allocated)
145CTL_PROTO(stats_arenas_i_large_nmalloc)
146CTL_PROTO(stats_arenas_i_large_ndalloc)
147CTL_PROTO(stats_arenas_i_large_nrequests)
Jason Evans86815df2010-03-13 20:32:56 -0800148CTL_PROTO(stats_arenas_i_bins_j_nmalloc)
149CTL_PROTO(stats_arenas_i_bins_j_ndalloc)
Jason Evans3c234352010-01-27 13:10:55 -0800150CTL_PROTO(stats_arenas_i_bins_j_nrequests)
Jason Evans3c4d92e2014-10-12 22:53:59 -0700151CTL_PROTO(stats_arenas_i_bins_j_curregs)
Jason Evans3c234352010-01-27 13:10:55 -0800152CTL_PROTO(stats_arenas_i_bins_j_nfills)
153CTL_PROTO(stats_arenas_i_bins_j_nflushes)
Jason Evans498856f2016-05-29 18:34:50 -0700154CTL_PROTO(stats_arenas_i_bins_j_nslabs)
155CTL_PROTO(stats_arenas_i_bins_j_nreslabs)
156CTL_PROTO(stats_arenas_i_bins_j_curslabs)
Jason Evans3c234352010-01-27 13:10:55 -0800157INDEX_PROTO(stats_arenas_i_bins_j)
Jason Evans7d63fed2016-05-31 14:50:21 -0700158CTL_PROTO(stats_arenas_i_lextents_j_nmalloc)
159CTL_PROTO(stats_arenas_i_lextents_j_ndalloc)
160CTL_PROTO(stats_arenas_i_lextents_j_nrequests)
161CTL_PROTO(stats_arenas_i_lextents_j_curlextents)
162INDEX_PROTO(stats_arenas_i_lextents_j)
Jason Evans597632b2011-03-18 13:41:33 -0700163CTL_PROTO(stats_arenas_i_nthreads)
Qi Wangbaf3e292017-05-16 13:56:00 -0700164CTL_PROTO(stats_arenas_i_uptime)
Jason Evans609ae592012-10-11 13:53:15 -0700165CTL_PROTO(stats_arenas_i_dss)
Jason Evans6e62c622017-05-17 10:47:00 -0700166CTL_PROTO(stats_arenas_i_dirty_decay_ms)
167CTL_PROTO(stats_arenas_i_muzzy_decay_ms)
Jason Evans3c234352010-01-27 13:10:55 -0800168CTL_PROTO(stats_arenas_i_pactive)
169CTL_PROTO(stats_arenas_i_pdirty)
Jason Evans64e458f2017-03-08 22:42:57 -0800170CTL_PROTO(stats_arenas_i_pmuzzy)
Jason Evans3c234352010-01-27 13:10:55 -0800171CTL_PROTO(stats_arenas_i_mapped)
Jason Evans04c3c0f2016-05-03 22:11:35 -0700172CTL_PROTO(stats_arenas_i_retained)
Jason Evans64e458f2017-03-08 22:42:57 -0800173CTL_PROTO(stats_arenas_i_dirty_npurge)
174CTL_PROTO(stats_arenas_i_dirty_nmadvise)
175CTL_PROTO(stats_arenas_i_dirty_purged)
176CTL_PROTO(stats_arenas_i_muzzy_npurge)
177CTL_PROTO(stats_arenas_i_muzzy_nmadvise)
178CTL_PROTO(stats_arenas_i_muzzy_purged)
Jason Evansa0dd3a42016-12-22 16:39:10 -0600179CTL_PROTO(stats_arenas_i_base)
180CTL_PROTO(stats_arenas_i_internal)
Qi Wang58424e62016-04-22 18:37:44 -0700181CTL_PROTO(stats_arenas_i_tcache_bytes)
Jason Evansa0dd3a42016-12-22 16:39:10 -0600182CTL_PROTO(stats_arenas_i_resident)
Jason Evans3c234352010-01-27 13:10:55 -0800183INDEX_PROTO(stats_arenas_i)
Jason Evans3c234352010-01-27 13:10:55 -0800184CTL_PROTO(stats_allocated)
185CTL_PROTO(stats_active)
Qi Wang2bee0c62017-05-12 12:30:33 -0700186CTL_PROTO(stats_background_thread_num_threads)
187CTL_PROTO(stats_background_thread_num_runs)
188CTL_PROTO(stats_background_thread_run_interval)
Jason Evans4581b972014-11-27 17:22:36 -0200189CTL_PROTO(stats_metadata)
Jason Evans4acd75a2015-03-23 17:25:57 -0700190CTL_PROTO(stats_resident)
Jason Evans3c234352010-01-27 13:10:55 -0800191CTL_PROTO(stats_mapped)
Jason Evans04c3c0f2016-05-03 22:11:35 -0700192CTL_PROTO(stats_retained)
Jason Evans3c234352010-01-27 13:10:55 -0800193
Qi Wang64c5f5c2017-03-13 17:29:03 -0700194#define MUTEX_STATS_CTL_PROTO_GEN(n) \
Qi Wangca9074d2017-03-11 20:28:31 -0800195CTL_PROTO(stats_##n##_num_ops) \
196CTL_PROTO(stats_##n##_num_wait) \
197CTL_PROTO(stats_##n##_num_spin_acq) \
198CTL_PROTO(stats_##n##_num_owner_switch) \
199CTL_PROTO(stats_##n##_total_wait_time) \
200CTL_PROTO(stats_##n##_max_wait_time) \
201CTL_PROTO(stats_##n##_max_num_thds)
Qi Wang0fb5c0e2017-03-10 12:14:05 -0800202
Qi Wang64c5f5c2017-03-13 17:29:03 -0700203/* Global mutexes. */
Qi Wangd3fde1c2017-03-21 11:56:38 -0700204#define OP(mtx) MUTEX_STATS_CTL_PROTO_GEN(mutexes_##mtx)
David Goldblatt89e2d3c2017-04-24 17:09:56 -0700205MUTEX_PROF_GLOBAL_MUTEXES
Qi Wangd3fde1c2017-03-21 11:56:38 -0700206#undef OP
207
208/* Per arena mutexes. */
209#define OP(mtx) MUTEX_STATS_CTL_PROTO_GEN(arenas_i_mutexes_##mtx)
David Goldblatt89e2d3c2017-04-24 17:09:56 -0700210MUTEX_PROF_ARENA_MUTEXES
Qi Wangd3fde1c2017-03-21 11:56:38 -0700211#undef OP
Qi Wangca9074d2017-03-11 20:28:31 -0800212
Qi Wang64c5f5c2017-03-13 17:29:03 -0700213/* Arena bin mutexes. */
214MUTEX_STATS_CTL_PROTO_GEN(arenas_i_bins_j_mutex)
Qi Wang64c5f5c2017-03-13 17:29:03 -0700215#undef MUTEX_STATS_CTL_PROTO_GEN
216
217CTL_PROTO(stats_mutexes_reset)
Qi Wang0fb5c0e2017-03-10 12:14:05 -0800218
Jason Evans3c234352010-01-27 13:10:55 -0800219/******************************************************************************/
220/* mallctl tree. */
221
Jason Evansc0cc5db2017-01-19 21:41:41 -0800222#define NAME(n) {true}, n
223#define CHILD(t, c) \
Jason Evans65f343a2012-04-23 19:31:45 -0700224 sizeof(c##_node) / sizeof(ctl_##t##_node_t), \
225 (ctl_node_t *)c##_node, \
226 NULL
Jason Evansc0cc5db2017-01-19 21:41:41 -0800227#define CTL(c) 0, NULL, c##_ctl
Jason Evans3c234352010-01-27 13:10:55 -0800228
229/*
230 * Only handles internal indexed nodes, since there are currently no external
231 * ones.
232 */
Jason Evansc0cc5db2017-01-19 21:41:41 -0800233#define INDEX(i) {false}, i##_index
Jason Evans3c234352010-01-27 13:10:55 -0800234
Jason Evans602c8e02014-08-18 16:22:13 -0700235static const ctl_named_node_t thread_tcache_node[] = {
Jason Evansd4be8b72012-03-26 18:54:44 -0700236 {NAME("enabled"), CTL(thread_tcache_enabled)},
Jason Evanse7b8fa12012-03-16 17:09:32 -0700237 {NAME("flush"), CTL(thread_tcache_flush)}
Jason Evans3c234352010-01-27 13:10:55 -0800238};
Jason Evans3c234352010-01-27 13:10:55 -0800239
Jason Evans602c8e02014-08-18 16:22:13 -0700240static const ctl_named_node_t thread_prof_node[] = {
241 {NAME("name"), CTL(thread_prof_name)},
242 {NAME("active"), CTL(thread_prof_active)}
243};
244
Mike Hommey461ad5c2012-04-20 08:38:42 +0200245static const ctl_named_node_t thread_node[] = {
Jason Evans7372b152012-02-10 20:22:09 -0800246 {NAME("arena"), CTL(thread_arena)},
Jason Evans93443682010-10-20 17:39:18 -0700247 {NAME("allocated"), CTL(thread_allocated)},
Jason Evansecf229a2010-12-03 15:55:47 -0800248 {NAME("allocatedp"), CTL(thread_allocatedp)},
249 {NAME("deallocated"), CTL(thread_deallocated)},
Jason Evanse7b8fa12012-03-16 17:09:32 -0700250 {NAME("deallocatedp"), CTL(thread_deallocatedp)},
Jason Evans602c8e02014-08-18 16:22:13 -0700251 {NAME("tcache"), CHILD(named, thread_tcache)},
252 {NAME("prof"), CHILD(named, thread_prof)}
Jason Evansb267d0f2010-08-13 15:42:29 -0700253};
Jason Evansb267d0f2010-08-13 15:42:29 -0700254
Mike Hommey461ad5c2012-04-20 08:38:42 +0200255static const ctl_named_node_t config_node[] = {
Jason Evansf2bc8522015-07-17 16:38:25 -0700256 {NAME("cache_oblivious"), CTL(config_cache_oblivious)},
Jason Evans3c4d92e2014-10-12 22:53:59 -0700257 {NAME("debug"), CTL(config_debug)},
258 {NAME("fill"), CTL(config_fill)},
259 {NAME("lazy_lock"), CTL(config_lazy_lock)},
Jason Evansf8290092016-02-07 14:23:22 -0800260 {NAME("malloc_conf"), CTL(config_malloc_conf)},
Jason Evans3c4d92e2014-10-12 22:53:59 -0700261 {NAME("prof"), CTL(config_prof)},
262 {NAME("prof_libgcc"), CTL(config_prof_libgcc)},
263 {NAME("prof_libunwind"), CTL(config_prof_libunwind)},
264 {NAME("stats"), CTL(config_stats)},
Jason Evans3c4d92e2014-10-12 22:53:59 -0700265 {NAME("utrace"), CTL(config_utrace)},
Jason Evans3c4d92e2014-10-12 22:53:59 -0700266 {NAME("xmalloc"), CTL(config_xmalloc)}
Jason Evans3c234352010-01-27 13:10:55 -0800267};
268
Mike Hommey461ad5c2012-04-20 08:38:42 +0200269static const ctl_named_node_t opt_node[] = {
Jason Evans3c4d92e2014-10-12 22:53:59 -0700270 {NAME("abort"), CTL(opt_abort)},
Qi Wangb86d2712017-05-25 15:30:11 -0700271 {NAME("abort_conf"), CTL(opt_abort_conf)},
Jason Evansb9ab04a2017-04-26 16:26:12 -0700272 {NAME("retain"), CTL(opt_retain)},
Jason Evans3c4d92e2014-10-12 22:53:59 -0700273 {NAME("dss"), CTL(opt_dss)},
Jason Evans3c4d92e2014-10-12 22:53:59 -0700274 {NAME("narenas"), CTL(opt_narenas)},
Qi Wangec532e22017-02-02 17:02:05 -0800275 {NAME("percpu_arena"), CTL(opt_percpu_arena)},
Qi Wangb693c782017-03-17 12:42:33 -0700276 {NAME("background_thread"), CTL(opt_background_thread)},
Jason Evans6e62c622017-05-17 10:47:00 -0700277 {NAME("dirty_decay_ms"), CTL(opt_dirty_decay_ms)},
278 {NAME("muzzy_decay_ms"), CTL(opt_muzzy_decay_ms)},
Jason Evans3c4d92e2014-10-12 22:53:59 -0700279 {NAME("stats_print"), CTL(opt_stats_print)},
280 {NAME("junk"), CTL(opt_junk)},
281 {NAME("zero"), CTL(opt_zero)},
Jason Evans3c4d92e2014-10-12 22:53:59 -0700282 {NAME("utrace"), CTL(opt_utrace)},
283 {NAME("xmalloc"), CTL(opt_xmalloc)},
284 {NAME("tcache"), CTL(opt_tcache)},
285 {NAME("lg_tcache_max"), CTL(opt_lg_tcache_max)},
286 {NAME("prof"), CTL(opt_prof)},
287 {NAME("prof_prefix"), CTL(opt_prof_prefix)},
288 {NAME("prof_active"), CTL(opt_prof_active)},
Jason Evansfc12c0b2014-10-03 23:25:30 -0700289 {NAME("prof_thread_active_init"), CTL(opt_prof_thread_active_init)},
Jason Evans3c4d92e2014-10-12 22:53:59 -0700290 {NAME("lg_prof_sample"), CTL(opt_lg_prof_sample)},
291 {NAME("lg_prof_interval"), CTL(opt_lg_prof_interval)},
292 {NAME("prof_gdump"), CTL(opt_prof_gdump)},
293 {NAME("prof_final"), CTL(opt_prof_final)},
294 {NAME("prof_leak"), CTL(opt_prof_leak)},
295 {NAME("prof_accum"), CTL(opt_prof_accum)}
Jason Evans3c234352010-01-27 13:10:55 -0800296};
297
Jason Evans1cb181e2015-01-29 15:30:47 -0800298static const ctl_named_node_t tcache_node[] = {
299 {NAME("create"), CTL(tcache_create)},
300 {NAME("flush"), CTL(tcache_flush)},
301 {NAME("destroy"), CTL(tcache_destroy)}
302};
303
Jason Evans609ae592012-10-11 13:53:15 -0700304static const ctl_named_node_t arena_i_node[] = {
Jason Evansdc2125c2017-01-04 10:21:53 -0800305 {NAME("initialized"), CTL(arena_i_initialized)},
Jason Evans243f7a02016-02-19 20:09:31 -0800306 {NAME("decay"), CTL(arena_i_decay)},
Jason Evans64e458f2017-03-08 22:42:57 -0800307 {NAME("purge"), CTL(arena_i_purge)},
Jason Evans19ff2ce2016-04-22 14:37:17 -0700308 {NAME("reset"), CTL(arena_i_reset)},
Jason Evansedf1baf2017-01-03 17:21:59 -0800309 {NAME("destroy"), CTL(arena_i_destroy)},
Jason Evans3c4d92e2014-10-12 22:53:59 -0700310 {NAME("dss"), CTL(arena_i_dss)},
Jason Evans6e62c622017-05-17 10:47:00 -0700311 {NAME("dirty_decay_ms"), CTL(arena_i_dirty_decay_ms)},
312 {NAME("muzzy_decay_ms"), CTL(arena_i_muzzy_decay_ms)},
Jason Evans9c305c92016-05-31 15:03:51 -0700313 {NAME("extent_hooks"), CTL(arena_i_extent_hooks)}
Jason Evans609ae592012-10-11 13:53:15 -0700314};
315static const ctl_named_node_t super_arena_i_node[] = {
Jason Evans3c4d92e2014-10-12 22:53:59 -0700316 {NAME(""), CHILD(named, arena_i)}
Jason Evans609ae592012-10-11 13:53:15 -0700317};
318
319static const ctl_indexed_node_t arena_node[] = {
320 {INDEX(arena_i)}
321};
322
Mike Hommey461ad5c2012-04-20 08:38:42 +0200323static const ctl_named_node_t arenas_bin_i_node[] = {
Jason Evans3c4d92e2014-10-12 22:53:59 -0700324 {NAME("size"), CTL(arenas_bin_i_size)},
325 {NAME("nregs"), CTL(arenas_bin_i_nregs)},
Jason Evans498856f2016-05-29 18:34:50 -0700326 {NAME("slab_size"), CTL(arenas_bin_i_slab_size)}
Jason Evans3c234352010-01-27 13:10:55 -0800327};
Mike Hommey461ad5c2012-04-20 08:38:42 +0200328static const ctl_named_node_t super_arenas_bin_i_node[] = {
Jason Evans3c4d92e2014-10-12 22:53:59 -0700329 {NAME(""), CHILD(named, arenas_bin_i)}
Jason Evans3c234352010-01-27 13:10:55 -0800330};
331
Mike Hommey461ad5c2012-04-20 08:38:42 +0200332static const ctl_indexed_node_t arenas_bin_node[] = {
Jason Evans3c234352010-01-27 13:10:55 -0800333 {INDEX(arenas_bin_i)}
334};
335
Jason Evans7d63fed2016-05-31 14:50:21 -0700336static const ctl_named_node_t arenas_lextent_i_node[] = {
337 {NAME("size"), CTL(arenas_lextent_i_size)}
Jason Evans3c4d92e2014-10-12 22:53:59 -0700338};
Jason Evans7d63fed2016-05-31 14:50:21 -0700339static const ctl_named_node_t super_arenas_lextent_i_node[] = {
340 {NAME(""), CHILD(named, arenas_lextent_i)}
Jason Evans3c4d92e2014-10-12 22:53:59 -0700341};
342
Jason Evans7d63fed2016-05-31 14:50:21 -0700343static const ctl_indexed_node_t arenas_lextent_node[] = {
344 {INDEX(arenas_lextent_i)}
Jason Evans3c4d92e2014-10-12 22:53:59 -0700345};
346
Mike Hommey461ad5c2012-04-20 08:38:42 +0200347static const ctl_named_node_t arenas_node[] = {
Jason Evans3c4d92e2014-10-12 22:53:59 -0700348 {NAME("narenas"), CTL(arenas_narenas)},
Jason Evans6e62c622017-05-17 10:47:00 -0700349 {NAME("dirty_decay_ms"), CTL(arenas_dirty_decay_ms)},
350 {NAME("muzzy_decay_ms"), CTL(arenas_muzzy_decay_ms)},
Jason Evans3c4d92e2014-10-12 22:53:59 -0700351 {NAME("quantum"), CTL(arenas_quantum)},
352 {NAME("page"), CTL(arenas_page)},
353 {NAME("tcache_max"), CTL(arenas_tcache_max)},
354 {NAME("nbins"), CTL(arenas_nbins)},
355 {NAME("nhbins"), CTL(arenas_nhbins)},
356 {NAME("bin"), CHILD(indexed, arenas_bin)},
Jason Evans7d63fed2016-05-31 14:50:21 -0700357 {NAME("nlextents"), CTL(arenas_nlextents)},
358 {NAME("lextent"), CHILD(indexed, arenas_lextent)},
Jason Evans0f04bb12017-01-03 08:21:29 -0800359 {NAME("create"), CTL(arenas_create)}
Jason Evans3c234352010-01-27 13:10:55 -0800360};
361
Mike Hommey461ad5c2012-04-20 08:38:42 +0200362static const ctl_named_node_t prof_node[] = {
Jason Evansfc12c0b2014-10-03 23:25:30 -0700363 {NAME("thread_active_init"), CTL(prof_thread_active_init)},
Jason Evansf18c9822010-03-31 18:43:24 -0700364 {NAME("active"), CTL(prof_active)},
Jason Evansd34f9e72010-02-11 13:19:21 -0800365 {NAME("dump"), CTL(prof_dump)},
Jason Evans5b8ed5b2015-01-25 21:16:57 -0800366 {NAME("gdump"), CTL(prof_gdump)},
Jason Evans602c8e02014-08-18 16:22:13 -0700367 {NAME("reset"), CTL(prof_reset)},
368 {NAME("interval"), CTL(prof_interval)},
369 {NAME("lg_sample"), CTL(lg_prof_sample)}
Jason Evansd34f9e72010-02-11 13:19:21 -0800370};
Jason Evansd34f9e72010-02-11 13:19:21 -0800371
Mike Hommey461ad5c2012-04-20 08:38:42 +0200372static const ctl_named_node_t stats_arenas_i_small_node[] = {
Jason Evans3c4d92e2014-10-12 22:53:59 -0700373 {NAME("allocated"), CTL(stats_arenas_i_small_allocated)},
374 {NAME("nmalloc"), CTL(stats_arenas_i_small_nmalloc)},
375 {NAME("ndalloc"), CTL(stats_arenas_i_small_ndalloc)},
376 {NAME("nrequests"), CTL(stats_arenas_i_small_nrequests)}
Jason Evans3c234352010-01-27 13:10:55 -0800377};
378
Jason Evans7d63fed2016-05-31 14:50:21 -0700379static const ctl_named_node_t stats_arenas_i_large_node[] = {
380 {NAME("allocated"), CTL(stats_arenas_i_large_allocated)},
381 {NAME("nmalloc"), CTL(stats_arenas_i_large_nmalloc)},
382 {NAME("ndalloc"), CTL(stats_arenas_i_large_ndalloc)},
383 {NAME("nrequests"), CTL(stats_arenas_i_large_nrequests)}
Jason Evanse2deab72014-05-15 22:22:27 -0700384};
385
Qi Wang64c5f5c2017-03-13 17:29:03 -0700386#define MUTEX_PROF_DATA_NODE(prefix) \
Qi Wangca9074d2017-03-11 20:28:31 -0800387static const ctl_named_node_t stats_##prefix##_node[] = { \
Qi Wang0fb5c0e2017-03-10 12:14:05 -0800388 {NAME("num_ops"), \
Qi Wangca9074d2017-03-11 20:28:31 -0800389 CTL(stats_##prefix##_num_ops)}, \
Qi Wang0fb5c0e2017-03-10 12:14:05 -0800390 {NAME("num_wait"), \
Qi Wangca9074d2017-03-11 20:28:31 -0800391 CTL(stats_##prefix##_num_wait)}, \
Qi Wang0fb5c0e2017-03-10 12:14:05 -0800392 {NAME("num_spin_acq"), \
Qi Wangca9074d2017-03-11 20:28:31 -0800393 CTL(stats_##prefix##_num_spin_acq)}, \
Qi Wang0fb5c0e2017-03-10 12:14:05 -0800394 {NAME("num_owner_switch"), \
Qi Wangca9074d2017-03-11 20:28:31 -0800395 CTL(stats_##prefix##_num_owner_switch)}, \
Qi Wang0fb5c0e2017-03-10 12:14:05 -0800396 {NAME("total_wait_time"), \
Qi Wangca9074d2017-03-11 20:28:31 -0800397 CTL(stats_##prefix##_total_wait_time)}, \
Qi Wang0fb5c0e2017-03-10 12:14:05 -0800398 {NAME("max_wait_time"), \
Qi Wangca9074d2017-03-11 20:28:31 -0800399 CTL(stats_##prefix##_max_wait_time)}, \
Qi Wang0fb5c0e2017-03-10 12:14:05 -0800400 {NAME("max_num_thds"), \
Qi Wangca9074d2017-03-11 20:28:31 -0800401 CTL(stats_##prefix##_max_num_thds)} \
Qi Wang0fb5c0e2017-03-10 12:14:05 -0800402 /* Note that # of current waiting thread not provided. */ \
403};
404
Qi Wang64c5f5c2017-03-13 17:29:03 -0700405MUTEX_PROF_DATA_NODE(arenas_i_bins_j_mutex)
Qi Wangca9074d2017-03-11 20:28:31 -0800406
Mike Hommey461ad5c2012-04-20 08:38:42 +0200407static const ctl_named_node_t stats_arenas_i_bins_j_node[] = {
Jason Evans3c4d92e2014-10-12 22:53:59 -0700408 {NAME("nmalloc"), CTL(stats_arenas_i_bins_j_nmalloc)},
409 {NAME("ndalloc"), CTL(stats_arenas_i_bins_j_ndalloc)},
410 {NAME("nrequests"), CTL(stats_arenas_i_bins_j_nrequests)},
411 {NAME("curregs"), CTL(stats_arenas_i_bins_j_curregs)},
412 {NAME("nfills"), CTL(stats_arenas_i_bins_j_nfills)},
413 {NAME("nflushes"), CTL(stats_arenas_i_bins_j_nflushes)},
Jason Evans498856f2016-05-29 18:34:50 -0700414 {NAME("nslabs"), CTL(stats_arenas_i_bins_j_nslabs)},
415 {NAME("nreslabs"), CTL(stats_arenas_i_bins_j_nreslabs)},
Qi Wanga4f176a2017-03-03 19:58:43 -0800416 {NAME("curslabs"), CTL(stats_arenas_i_bins_j_curslabs)},
Qi Wang64c5f5c2017-03-13 17:29:03 -0700417 {NAME("mutex"), CHILD(named, stats_arenas_i_bins_j_mutex)}
Jason Evans3c234352010-01-27 13:10:55 -0800418};
Qi Wang0fb5c0e2017-03-10 12:14:05 -0800419
Mike Hommey461ad5c2012-04-20 08:38:42 +0200420static const ctl_named_node_t super_stats_arenas_i_bins_j_node[] = {
Jason Evans3c4d92e2014-10-12 22:53:59 -0700421 {NAME(""), CHILD(named, stats_arenas_i_bins_j)}
Jason Evans3c234352010-01-27 13:10:55 -0800422};
423
Mike Hommey461ad5c2012-04-20 08:38:42 +0200424static const ctl_indexed_node_t stats_arenas_i_bins_node[] = {
Jason Evans3c234352010-01-27 13:10:55 -0800425 {INDEX(stats_arenas_i_bins_j)}
426};
427
Jason Evans7d63fed2016-05-31 14:50:21 -0700428static const ctl_named_node_t stats_arenas_i_lextents_j_node[] = {
429 {NAME("nmalloc"), CTL(stats_arenas_i_lextents_j_nmalloc)},
430 {NAME("ndalloc"), CTL(stats_arenas_i_lextents_j_ndalloc)},
431 {NAME("nrequests"), CTL(stats_arenas_i_lextents_j_nrequests)},
432 {NAME("curlextents"), CTL(stats_arenas_i_lextents_j_curlextents)}
Jason Evans3c4d92e2014-10-12 22:53:59 -0700433};
Jason Evans7d63fed2016-05-31 14:50:21 -0700434static const ctl_named_node_t super_stats_arenas_i_lextents_j_node[] = {
435 {NAME(""), CHILD(named, stats_arenas_i_lextents_j)}
Jason Evans3c4d92e2014-10-12 22:53:59 -0700436};
437
Jason Evans7d63fed2016-05-31 14:50:21 -0700438static const ctl_indexed_node_t stats_arenas_i_lextents_node[] = {
439 {INDEX(stats_arenas_i_lextents_j)}
Jason Evans3c4d92e2014-10-12 22:53:59 -0700440};
441
Qi Wangd3fde1c2017-03-21 11:56:38 -0700442#define OP(mtx) MUTEX_PROF_DATA_NODE(arenas_i_mutexes_##mtx)
David Goldblatt89e2d3c2017-04-24 17:09:56 -0700443MUTEX_PROF_ARENA_MUTEXES
Qi Wangd3fde1c2017-03-21 11:56:38 -0700444#undef OP
Qi Wang0fb5c0e2017-03-10 12:14:05 -0800445
Qi Wang64c5f5c2017-03-13 17:29:03 -0700446static const ctl_named_node_t stats_arenas_i_mutexes_node[] = {
Qi Wangd3fde1c2017-03-21 11:56:38 -0700447#define OP(mtx) {NAME(#mtx), CHILD(named, stats_arenas_i_mutexes_##mtx)},
David Goldblatt89e2d3c2017-04-24 17:09:56 -0700448MUTEX_PROF_ARENA_MUTEXES
Qi Wangd3fde1c2017-03-21 11:56:38 -0700449#undef OP
Qi Wang0fb5c0e2017-03-10 12:14:05 -0800450};
Qi Wang0fb5c0e2017-03-10 12:14:05 -0800451
Mike Hommey461ad5c2012-04-20 08:38:42 +0200452static const ctl_named_node_t stats_arenas_i_node[] = {
Jason Evans3c4d92e2014-10-12 22:53:59 -0700453 {NAME("nthreads"), CTL(stats_arenas_i_nthreads)},
Qi Wangbaf3e292017-05-16 13:56:00 -0700454 {NAME("uptime"), CTL(stats_arenas_i_uptime)},
Jason Evans3c4d92e2014-10-12 22:53:59 -0700455 {NAME("dss"), CTL(stats_arenas_i_dss)},
Jason Evans6e62c622017-05-17 10:47:00 -0700456 {NAME("dirty_decay_ms"), CTL(stats_arenas_i_dirty_decay_ms)},
457 {NAME("muzzy_decay_ms"), CTL(stats_arenas_i_muzzy_decay_ms)},
Jason Evans3c4d92e2014-10-12 22:53:59 -0700458 {NAME("pactive"), CTL(stats_arenas_i_pactive)},
459 {NAME("pdirty"), CTL(stats_arenas_i_pdirty)},
Jason Evans64e458f2017-03-08 22:42:57 -0800460 {NAME("pmuzzy"), CTL(stats_arenas_i_pmuzzy)},
Jason Evans3c4d92e2014-10-12 22:53:59 -0700461 {NAME("mapped"), CTL(stats_arenas_i_mapped)},
Jason Evans04c3c0f2016-05-03 22:11:35 -0700462 {NAME("retained"), CTL(stats_arenas_i_retained)},
Jason Evans64e458f2017-03-08 22:42:57 -0800463 {NAME("dirty_npurge"), CTL(stats_arenas_i_dirty_npurge)},
464 {NAME("dirty_nmadvise"), CTL(stats_arenas_i_dirty_nmadvise)},
465 {NAME("dirty_purged"), CTL(stats_arenas_i_dirty_purged)},
466 {NAME("muzzy_npurge"), CTL(stats_arenas_i_muzzy_npurge)},
467 {NAME("muzzy_nmadvise"), CTL(stats_arenas_i_muzzy_nmadvise)},
468 {NAME("muzzy_purged"), CTL(stats_arenas_i_muzzy_purged)},
Jason Evansa0dd3a42016-12-22 16:39:10 -0600469 {NAME("base"), CTL(stats_arenas_i_base)},
470 {NAME("internal"), CTL(stats_arenas_i_internal)},
Qi Wang58424e62016-04-22 18:37:44 -0700471 {NAME("tcache_bytes"), CTL(stats_arenas_i_tcache_bytes)},
Jason Evansa0dd3a42016-12-22 16:39:10 -0600472 {NAME("resident"), CTL(stats_arenas_i_resident)},
Jason Evans3c4d92e2014-10-12 22:53:59 -0700473 {NAME("small"), CHILD(named, stats_arenas_i_small)},
Jason Evans7d63fed2016-05-31 14:50:21 -0700474 {NAME("large"), CHILD(named, stats_arenas_i_large)},
Jason Evans3c4d92e2014-10-12 22:53:59 -0700475 {NAME("bins"), CHILD(indexed, stats_arenas_i_bins)},
Qi Wang0fb5c0e2017-03-10 12:14:05 -0800476 {NAME("lextents"), CHILD(indexed, stats_arenas_i_lextents)},
Qi Wang64c5f5c2017-03-13 17:29:03 -0700477 {NAME("mutexes"), CHILD(named, stats_arenas_i_mutexes)}
Jason Evans3c234352010-01-27 13:10:55 -0800478};
Mike Hommey461ad5c2012-04-20 08:38:42 +0200479static const ctl_named_node_t super_stats_arenas_i_node[] = {
Jason Evans3c4d92e2014-10-12 22:53:59 -0700480 {NAME(""), CHILD(named, stats_arenas_i)}
Jason Evans3c234352010-01-27 13:10:55 -0800481};
482
Mike Hommey461ad5c2012-04-20 08:38:42 +0200483static const ctl_indexed_node_t stats_arenas_node[] = {
Jason Evans3c234352010-01-27 13:10:55 -0800484 {INDEX(stats_arenas_i)}
485};
486
Qi Wang2bee0c62017-05-12 12:30:33 -0700487static const ctl_named_node_t stats_background_thread_node[] = {
488 {NAME("num_threads"), CTL(stats_background_thread_num_threads)},
489 {NAME("num_runs"), CTL(stats_background_thread_num_runs)},
490 {NAME("run_interval"), CTL(stats_background_thread_run_interval)}
491};
492
Qi Wangd3fde1c2017-03-21 11:56:38 -0700493#define OP(mtx) MUTEX_PROF_DATA_NODE(mutexes_##mtx)
David Goldblatt89e2d3c2017-04-24 17:09:56 -0700494MUTEX_PROF_GLOBAL_MUTEXES
Qi Wangd3fde1c2017-03-21 11:56:38 -0700495#undef OP
496
Qi Wang64c5f5c2017-03-13 17:29:03 -0700497static const ctl_named_node_t stats_mutexes_node[] = {
Qi Wangd3fde1c2017-03-21 11:56:38 -0700498#define OP(mtx) {NAME(#mtx), CHILD(named, stats_mutexes_##mtx)},
David Goldblatt89e2d3c2017-04-24 17:09:56 -0700499MUTEX_PROF_GLOBAL_MUTEXES
Qi Wangd3fde1c2017-03-21 11:56:38 -0700500#undef OP
Qi Wang64c5f5c2017-03-13 17:29:03 -0700501 {NAME("reset"), CTL(stats_mutexes_reset)}
Qi Wangca9074d2017-03-11 20:28:31 -0800502};
Qi Wangd3fde1c2017-03-21 11:56:38 -0700503#undef MUTEX_PROF_DATA_NODE
Qi Wangca9074d2017-03-11 20:28:31 -0800504
Mike Hommey461ad5c2012-04-20 08:38:42 +0200505static const ctl_named_node_t stats_node[] = {
Jason Evans3c4d92e2014-10-12 22:53:59 -0700506 {NAME("allocated"), CTL(stats_allocated)},
507 {NAME("active"), CTL(stats_active)},
Jason Evans4581b972014-11-27 17:22:36 -0200508 {NAME("metadata"), CTL(stats_metadata)},
Jason Evans4acd75a2015-03-23 17:25:57 -0700509 {NAME("resident"), CTL(stats_resident)},
Jason Evans3c4d92e2014-10-12 22:53:59 -0700510 {NAME("mapped"), CTL(stats_mapped)},
Jason Evans04c3c0f2016-05-03 22:11:35 -0700511 {NAME("retained"), CTL(stats_retained)},
Qi Wang2bee0c62017-05-12 12:30:33 -0700512 {NAME("background_thread"),
513 CHILD(named, stats_background_thread)},
Qi Wang64c5f5c2017-03-13 17:29:03 -0700514 {NAME("mutexes"), CHILD(named, stats_mutexes)},
Jason Evans3c4d92e2014-10-12 22:53:59 -0700515 {NAME("arenas"), CHILD(indexed, stats_arenas)}
Jason Evans3c234352010-01-27 13:10:55 -0800516};
517
Mike Hommey461ad5c2012-04-20 08:38:42 +0200518static const ctl_named_node_t root_node[] = {
Jason Evansa40bc7a2010-03-02 13:01:16 -0800519 {NAME("version"), CTL(version)},
Jason Evans3c234352010-01-27 13:10:55 -0800520 {NAME("epoch"), CTL(epoch)},
Qi Wangb693c782017-03-17 12:42:33 -0700521 {NAME("background_thread"), CTL(background_thread)},
Jason Evans65f343a2012-04-23 19:31:45 -0700522 {NAME("thread"), CHILD(named, thread)},
523 {NAME("config"), CHILD(named, config)},
524 {NAME("opt"), CHILD(named, opt)},
Jason Evans1cb181e2015-01-29 15:30:47 -0800525 {NAME("tcache"), CHILD(named, tcache)},
Jason Evans609ae592012-10-11 13:53:15 -0700526 {NAME("arena"), CHILD(indexed, arena)},
Jason Evans65f343a2012-04-23 19:31:45 -0700527 {NAME("arenas"), CHILD(named, arenas)},
528 {NAME("prof"), CHILD(named, prof)},
529 {NAME("stats"), CHILD(named, stats)}
Jason Evans3c234352010-01-27 13:10:55 -0800530};
Mike Hommey461ad5c2012-04-20 08:38:42 +0200531static const ctl_named_node_t super_root_node[] = {
Jason Evans65f343a2012-04-23 19:31:45 -0700532 {NAME(""), CHILD(named, root)}
Jason Evans3c234352010-01-27 13:10:55 -0800533};
534
535#undef NAME
536#undef CHILD
537#undef CTL
538#undef INDEX
539
540/******************************************************************************/
541
David Goldblatt4fc2acf2017-03-08 15:56:31 -0800542/*
543 * Sets *dst + *src non-atomically. This is safe, since everything is
544 * synchronized by the ctl mutex.
545 */
546static void
547accum_arena_stats_u64(arena_stats_u64_t *dst, arena_stats_u64_t *src) {
548#ifdef JEMALLOC_ATOMIC_U64
549 uint64_t cur_dst = atomic_load_u64(dst, ATOMIC_RELAXED);
550 uint64_t cur_src = atomic_load_u64(src, ATOMIC_RELAXED);
551 atomic_store_u64(dst, cur_dst + cur_src, ATOMIC_RELAXED);
552#else
553 *dst += *src;
554#endif
555}
556
557/* Likewise: with ctl mutex synchronization, reading is simple. */
558static uint64_t
559arena_stats_read_u64(arena_stats_u64_t *p) {
560#ifdef JEMALLOC_ATOMIC_U64
561 return atomic_load_u64(p, ATOMIC_RELAXED);
562#else
563 return *p;
564#endif
565}
566
David Goldblattee202ef2017-03-13 16:18:40 -0700567static void accum_atomic_zu(atomic_zu_t *dst, atomic_zu_t *src) {
568 size_t cur_dst = atomic_load_zu(dst, ATOMIC_RELAXED);
569 size_t cur_src = atomic_load_zu(src, ATOMIC_RELAXED);
570 atomic_store_zu(dst, cur_dst + cur_src, ATOMIC_RELAXED);
571}
572
David Goldblatt4fc2acf2017-03-08 15:56:31 -0800573/******************************************************************************/
574
Jason Evans3dc4e832017-01-03 07:27:42 -0800575static unsigned
Jason Evansc4c25922017-01-15 16:56:30 -0800576arenas_i2a_impl(size_t i, bool compat, bool validate) {
Jason Evans3dc4e832017-01-03 07:27:42 -0800577 unsigned a;
578
Jason Evans3dc4e832017-01-03 07:27:42 -0800579 switch (i) {
580 case MALLCTL_ARENAS_ALL:
581 a = 0;
582 break;
Jason Evansedf1baf2017-01-03 17:21:59 -0800583 case MALLCTL_ARENAS_DESTROYED:
584 a = 1;
585 break;
Jason Evans3dc4e832017-01-03 07:27:42 -0800586 default:
Jason Evans9eb1b1c2017-01-18 23:03:37 -0800587 if (compat && i == ctl_arenas->narenas) {
Jason Evans3dc4e832017-01-03 07:27:42 -0800588 /*
589 * Provide deprecated backward compatibility for
590 * accessing the merged stats at index narenas rather
591 * than via MALLCTL_ARENAS_ALL. This is scheduled for
592 * removal in 6.0.0.
593 */
594 a = 0;
Jason Evansc4c25922017-01-15 16:56:30 -0800595 } else if (validate && i >= ctl_arenas->narenas) {
Jason Evans3dc4e832017-01-03 07:27:42 -0800596 a = UINT_MAX;
Jason Evansc4c25922017-01-15 16:56:30 -0800597 } else {
Jason Evans3dc4e832017-01-03 07:27:42 -0800598 /*
599 * This function should never be called for an index
600 * more than one past the range of indices that have
Jason Evans9eb1b1c2017-01-18 23:03:37 -0800601 * initialized ctl data.
Jason Evans3dc4e832017-01-03 07:27:42 -0800602 */
Jason Evans9eb1b1c2017-01-18 23:03:37 -0800603 assert(i < ctl_arenas->narenas || (!validate && i ==
604 ctl_arenas->narenas));
Jason Evansedf1baf2017-01-03 17:21:59 -0800605 a = (unsigned)i + 2;
Jason Evans3dc4e832017-01-03 07:27:42 -0800606 }
607 break;
608 }
609
Jason Evansf4086432017-01-19 18:15:45 -0800610 return a;
Jason Evans3dc4e832017-01-03 07:27:42 -0800611}
612
Jason Evansedf1baf2017-01-03 17:21:59 -0800613static unsigned
Jason Evansc4c25922017-01-15 16:56:30 -0800614arenas_i2a(size_t i) {
Jason Evansf4086432017-01-19 18:15:45 -0800615 return arenas_i2a_impl(i, true, false);
Jason Evansedf1baf2017-01-03 17:21:59 -0800616}
617
Jason Evans9eb1b1c2017-01-18 23:03:37 -0800618static ctl_arena_t *
Jason Evansc4c25922017-01-15 16:56:30 -0800619arenas_i_impl(tsdn_t *tsdn, size_t i, bool compat, bool init) {
Jason Evans9eb1b1c2017-01-18 23:03:37 -0800620 ctl_arena_t *ret;
Jason Evansd778dd22017-01-03 12:40:54 -0800621
622 assert(!compat || !init);
623
Jason Evans9eb1b1c2017-01-18 23:03:37 -0800624 ret = ctl_arenas->arenas[arenas_i2a_impl(i, compat, false)];
Jason Evansd778dd22017-01-03 12:40:54 -0800625 if (init && ret == NULL) {
Jason Evans9eb1b1c2017-01-18 23:03:37 -0800626 if (config_stats) {
627 struct container_s {
628 ctl_arena_t ctl_arena;
629 ctl_arena_stats_t astats;
630 };
631 struct container_s *cont =
632 (struct container_s *)base_alloc(tsdn, b0get(),
633 sizeof(struct container_s), QUANTUM);
634 if (cont == NULL) {
635 return NULL;
636 }
637 ret = &cont->ctl_arena;
638 ret->astats = &cont->astats;
639 } else {
640 ret = (ctl_arena_t *)base_alloc(tsdn, b0get(),
641 sizeof(ctl_arena_t), QUANTUM);
642 if (ret == NULL) {
643 return NULL;
644 }
645 }
Jason Evansedf1baf2017-01-03 17:21:59 -0800646 ret->arena_ind = (unsigned)i;
Jason Evans9eb1b1c2017-01-18 23:03:37 -0800647 ctl_arenas->arenas[arenas_i2a_impl(i, compat, false)] = ret;
Jason Evansd778dd22017-01-03 12:40:54 -0800648 }
649
Jason Evans9eb1b1c2017-01-18 23:03:37 -0800650 assert(ret == NULL || arenas_i2a(ret->arena_ind) == arenas_i2a(i));
Jason Evansf4086432017-01-19 18:15:45 -0800651 return ret;
Jason Evansd778dd22017-01-03 12:40:54 -0800652}
653
Jason Evans9eb1b1c2017-01-18 23:03:37 -0800654static ctl_arena_t *
Jason Evansc4c25922017-01-15 16:56:30 -0800655arenas_i(size_t i) {
Jason Evans9eb1b1c2017-01-18 23:03:37 -0800656 ctl_arena_t *ret = arenas_i_impl(TSDN_NULL, i, true, false);
Jason Evansd778dd22017-01-03 12:40:54 -0800657 assert(ret != NULL);
Jason Evansf4086432017-01-19 18:15:45 -0800658 return ret;
Jason Evans3dc4e832017-01-03 07:27:42 -0800659}
660
Jason Evans3c234352010-01-27 13:10:55 -0800661static void
Jason Evansc4c25922017-01-15 16:56:30 -0800662ctl_arena_clear(ctl_arena_t *ctl_arena) {
Jason Evans9eb1b1c2017-01-18 23:03:37 -0800663 ctl_arena->nthreads = 0;
664 ctl_arena->dss = dss_prec_names[dss_prec_limit];
Jason Evans6e62c622017-05-17 10:47:00 -0700665 ctl_arena->dirty_decay_ms = -1;
666 ctl_arena->muzzy_decay_ms = -1;
Jason Evans9eb1b1c2017-01-18 23:03:37 -0800667 ctl_arena->pactive = 0;
668 ctl_arena->pdirty = 0;
Jason Evans64e458f2017-03-08 22:42:57 -0800669 ctl_arena->pmuzzy = 0;
Jason Evans7372b152012-02-10 20:22:09 -0800670 if (config_stats) {
Jason Evans9eb1b1c2017-01-18 23:03:37 -0800671 memset(&ctl_arena->astats->astats, 0, sizeof(arena_stats_t));
672 ctl_arena->astats->allocated_small = 0;
673 ctl_arena->astats->nmalloc_small = 0;
674 ctl_arena->astats->ndalloc_small = 0;
675 ctl_arena->astats->nrequests_small = 0;
676 memset(ctl_arena->astats->bstats, 0, NBINS *
677 sizeof(malloc_bin_stats_t));
678 memset(ctl_arena->astats->lstats, 0, (NSIZES - NBINS) *
Jason Evans7d63fed2016-05-31 14:50:21 -0700679 sizeof(malloc_large_stats_t));
Jason Evans7372b152012-02-10 20:22:09 -0800680 }
Jason Evans3c234352010-01-27 13:10:55 -0800681}
682
Jason Evans86815df2010-03-13 20:32:56 -0800683static void
Jason Evansc4c25922017-01-15 16:56:30 -0800684ctl_arena_stats_amerge(tsdn_t *tsdn, ctl_arena_t *ctl_arena, arena_t *arena) {
Jason Evans86815df2010-03-13 20:32:56 -0800685 unsigned i;
686
Jason Evans3c07f802016-02-27 20:40:13 -0800687 if (config_stats) {
Jason Evans9eb1b1c2017-01-18 23:03:37 -0800688 arena_stats_merge(tsdn, arena, &ctl_arena->nthreads,
Jason Evans6e62c622017-05-17 10:47:00 -0700689 &ctl_arena->dss, &ctl_arena->dirty_decay_ms,
690 &ctl_arena->muzzy_decay_ms, &ctl_arena->pactive,
Jason Evans64e458f2017-03-08 22:42:57 -0800691 &ctl_arena->pdirty, &ctl_arena->pmuzzy,
Jason Evans9eb1b1c2017-01-18 23:03:37 -0800692 &ctl_arena->astats->astats, ctl_arena->astats->bstats,
693 ctl_arena->astats->lstats);
Jason Evans86815df2010-03-13 20:32:56 -0800694
Jason Evans3c07f802016-02-27 20:40:13 -0800695 for (i = 0; i < NBINS; i++) {
Jason Evans9eb1b1c2017-01-18 23:03:37 -0800696 ctl_arena->astats->allocated_small +=
697 ctl_arena->astats->bstats[i].curregs *
Jason Evans3c07f802016-02-27 20:40:13 -0800698 index2size(i);
Jason Evans9eb1b1c2017-01-18 23:03:37 -0800699 ctl_arena->astats->nmalloc_small +=
700 ctl_arena->astats->bstats[i].nmalloc;
701 ctl_arena->astats->ndalloc_small +=
702 ctl_arena->astats->bstats[i].ndalloc;
703 ctl_arena->astats->nrequests_small +=
704 ctl_arena->astats->bstats[i].nrequests;
Jason Evans3c07f802016-02-27 20:40:13 -0800705 }
706 } else {
Jason Evans9eb1b1c2017-01-18 23:03:37 -0800707 arena_basic_stats_merge(tsdn, arena, &ctl_arena->nthreads,
Jason Evans6e62c622017-05-17 10:47:00 -0700708 &ctl_arena->dss, &ctl_arena->dirty_decay_ms,
709 &ctl_arena->muzzy_decay_ms, &ctl_arena->pactive,
Jason Evans64e458f2017-03-08 22:42:57 -0800710 &ctl_arena->pdirty, &ctl_arena->pmuzzy);
Jason Evans86815df2010-03-13 20:32:56 -0800711 }
Jason Evans86815df2010-03-13 20:32:56 -0800712}
713
714static void
Jason Evans9eb1b1c2017-01-18 23:03:37 -0800715ctl_arena_stats_sdmerge(ctl_arena_t *ctl_sdarena, ctl_arena_t *ctl_arena,
Jason Evansc4c25922017-01-15 16:56:30 -0800716 bool destroyed) {
Jason Evans86815df2010-03-13 20:32:56 -0800717 unsigned i;
718
Jason Evansedf1baf2017-01-03 17:21:59 -0800719 if (!destroyed) {
Jason Evans9eb1b1c2017-01-18 23:03:37 -0800720 ctl_sdarena->nthreads += ctl_arena->nthreads;
721 ctl_sdarena->pactive += ctl_arena->pactive;
722 ctl_sdarena->pdirty += ctl_arena->pdirty;
Jason Evans64e458f2017-03-08 22:42:57 -0800723 ctl_sdarena->pmuzzy += ctl_arena->pmuzzy;
Jason Evansedf1baf2017-01-03 17:21:59 -0800724 } else {
Jason Evans9eb1b1c2017-01-18 23:03:37 -0800725 assert(ctl_arena->nthreads == 0);
726 assert(ctl_arena->pactive == 0);
727 assert(ctl_arena->pdirty == 0);
Jason Evans64e458f2017-03-08 22:42:57 -0800728 assert(ctl_arena->pmuzzy == 0);
Jason Evansedf1baf2017-01-03 17:21:59 -0800729 }
Jason Evans86815df2010-03-13 20:32:56 -0800730
Jason Evans3c07f802016-02-27 20:40:13 -0800731 if (config_stats) {
Jason Evans9eb1b1c2017-01-18 23:03:37 -0800732 ctl_arena_stats_t *sdstats = ctl_sdarena->astats;
733 ctl_arena_stats_t *astats = ctl_arena->astats;
734
Jason Evansedf1baf2017-01-03 17:21:59 -0800735 if (!destroyed) {
David Goldblattee202ef2017-03-13 16:18:40 -0700736 accum_atomic_zu(&sdstats->astats.mapped,
737 &astats->astats.mapped);
738 accum_atomic_zu(&sdstats->astats.retained,
739 &astats->astats.retained);
Jason Evansedf1baf2017-01-03 17:21:59 -0800740 }
Jason Evans64e458f2017-03-08 22:42:57 -0800741
742 accum_arena_stats_u64(&sdstats->astats.decay_dirty.npurge,
743 &astats->astats.decay_dirty.npurge);
744 accum_arena_stats_u64(&sdstats->astats.decay_dirty.nmadvise,
745 &astats->astats.decay_dirty.nmadvise);
746 accum_arena_stats_u64(&sdstats->astats.decay_dirty.purged,
747 &astats->astats.decay_dirty.purged);
748
749 accum_arena_stats_u64(&sdstats->astats.decay_muzzy.npurge,
750 &astats->astats.decay_muzzy.npurge);
751 accum_arena_stats_u64(&sdstats->astats.decay_muzzy.nmadvise,
752 &astats->astats.decay_muzzy.nmadvise);
753 accum_arena_stats_u64(&sdstats->astats.decay_muzzy.purged,
754 &astats->astats.decay_muzzy.purged);
Jason Evans86815df2010-03-13 20:32:56 -0800755
Qi Wangd3fde1c2017-03-21 11:56:38 -0700756#define OP(mtx) malloc_mutex_prof_merge( \
757 &(sdstats->astats.mutex_prof_data[ \
758 arena_prof_mutex_##mtx]), \
759 &(astats->astats.mutex_prof_data[ \
760 arena_prof_mutex_##mtx]));
David Goldblatt89e2d3c2017-04-24 17:09:56 -0700761MUTEX_PROF_ARENA_MUTEXES
Qi Wangd3fde1c2017-03-21 11:56:38 -0700762#undef OP
Jason Evansedf1baf2017-01-03 17:21:59 -0800763 if (!destroyed) {
David Goldblattee202ef2017-03-13 16:18:40 -0700764 accum_atomic_zu(&sdstats->astats.base,
765 &astats->astats.base);
766 accum_atomic_zu(&sdstats->astats.internal,
767 &astats->astats.internal);
768 accum_atomic_zu(&sdstats->astats.resident,
769 &astats->astats.resident);
Jason Evansc4c25922017-01-15 16:56:30 -0800770 } else {
David Goldblattee202ef2017-03-13 16:18:40 -0700771 assert(atomic_load_zu(
772 &astats->astats.internal, ATOMIC_RELAXED) == 0);
Jason Evansc4c25922017-01-15 16:56:30 -0800773 }
Jason Evans4581b972014-11-27 17:22:36 -0200774
Jason Evansc4c25922017-01-15 16:56:30 -0800775 if (!destroyed) {
Jason Evansedf1baf2017-01-03 17:21:59 -0800776 sdstats->allocated_small += astats->allocated_small;
Jason Evansc4c25922017-01-15 16:56:30 -0800777 } else {
Jason Evansedf1baf2017-01-03 17:21:59 -0800778 assert(astats->allocated_small == 0);
Jason Evansc4c25922017-01-15 16:56:30 -0800779 }
Jason Evansedf1baf2017-01-03 17:21:59 -0800780 sdstats->nmalloc_small += astats->nmalloc_small;
781 sdstats->ndalloc_small += astats->ndalloc_small;
782 sdstats->nrequests_small += astats->nrequests_small;
Jason Evans86815df2010-03-13 20:32:56 -0800783
Jason Evansedf1baf2017-01-03 17:21:59 -0800784 if (!destroyed) {
David Goldblattee202ef2017-03-13 16:18:40 -0700785 accum_atomic_zu(&sdstats->astats.allocated_large,
786 &astats->astats.allocated_large);
Jason Evansc4c25922017-01-15 16:56:30 -0800787 } else {
David Goldblattee202ef2017-03-13 16:18:40 -0700788 assert(atomic_load_zu(&astats->astats.allocated_large,
789 ATOMIC_RELAXED) == 0);
Jason Evansc4c25922017-01-15 16:56:30 -0800790 }
David Goldblatt4fc2acf2017-03-08 15:56:31 -0800791 accum_arena_stats_u64(&sdstats->astats.nmalloc_large,
792 &astats->astats.nmalloc_large);
793 accum_arena_stats_u64(&sdstats->astats.ndalloc_large,
794 &astats->astats.ndalloc_large);
795 accum_arena_stats_u64(&sdstats->astats.nrequests_large,
796 &astats->astats.nrequests_large);
Jason Evans86815df2010-03-13 20:32:56 -0800797
Jason Evans4403c9a2017-04-20 17:21:37 -0700798 accum_atomic_zu(&sdstats->astats.tcache_bytes,
799 &astats->astats.tcache_bytes);
Qi Wang58424e62016-04-22 18:37:44 -0700800
Qi Wangbaf3e292017-05-16 13:56:00 -0700801 if (ctl_arena->arena_ind == 0) {
802 sdstats->astats.uptime = astats->astats.uptime;
803 }
804
Jason Evans3c07f802016-02-27 20:40:13 -0800805 for (i = 0; i < NBINS; i++) {
Jason Evansedf1baf2017-01-03 17:21:59 -0800806 sdstats->bstats[i].nmalloc += astats->bstats[i].nmalloc;
807 sdstats->bstats[i].ndalloc += astats->bstats[i].ndalloc;
808 sdstats->bstats[i].nrequests +=
Jason Evans3c07f802016-02-27 20:40:13 -0800809 astats->bstats[i].nrequests;
Jason Evansedf1baf2017-01-03 17:21:59 -0800810 if (!destroyed) {
811 sdstats->bstats[i].curregs +=
812 astats->bstats[i].curregs;
Jason Evansc4c25922017-01-15 16:56:30 -0800813 } else {
Jason Evansedf1baf2017-01-03 17:21:59 -0800814 assert(astats->bstats[i].curregs == 0);
Jason Evansc4c25922017-01-15 16:56:30 -0800815 }
Jason Evans4403c9a2017-04-20 17:21:37 -0700816 sdstats->bstats[i].nfills += astats->bstats[i].nfills;
817 sdstats->bstats[i].nflushes +=
818 astats->bstats[i].nflushes;
Jason Evansedf1baf2017-01-03 17:21:59 -0800819 sdstats->bstats[i].nslabs += astats->bstats[i].nslabs;
820 sdstats->bstats[i].reslabs += astats->bstats[i].reslabs;
821 if (!destroyed) {
822 sdstats->bstats[i].curslabs +=
823 astats->bstats[i].curslabs;
Jason Evansc4c25922017-01-15 16:56:30 -0800824 } else {
Jason Evansedf1baf2017-01-03 17:21:59 -0800825 assert(astats->bstats[i].curslabs == 0);
Jason Evansc4c25922017-01-15 16:56:30 -0800826 }
Qi Wang64c5f5c2017-03-13 17:29:03 -0700827 malloc_mutex_prof_merge(&sdstats->bstats[i].mutex_data,
828 &astats->bstats[i].mutex_data);
Jason Evans7372b152012-02-10 20:22:09 -0800829 }
Jason Evans3c4d92e2014-10-12 22:53:59 -0700830
Jason Evansed2c2422016-05-28 00:17:28 -0700831 for (i = 0; i < NSIZES - NBINS; i++) {
David Goldblatt4fc2acf2017-03-08 15:56:31 -0800832 accum_arena_stats_u64(&sdstats->lstats[i].nmalloc,
833 &astats->lstats[i].nmalloc);
834 accum_arena_stats_u64(&sdstats->lstats[i].ndalloc,
835 &astats->lstats[i].ndalloc);
836 accum_arena_stats_u64(&sdstats->lstats[i].nrequests,
837 &astats->lstats[i].nrequests);
Jason Evansedf1baf2017-01-03 17:21:59 -0800838 if (!destroyed) {
839 sdstats->lstats[i].curlextents +=
840 astats->lstats[i].curlextents;
Jason Evansc4c25922017-01-15 16:56:30 -0800841 } else {
Jason Evansedf1baf2017-01-03 17:21:59 -0800842 assert(astats->lstats[i].curlextents == 0);
Jason Evansc4c25922017-01-15 16:56:30 -0800843 }
Jason Evans3c07f802016-02-27 20:40:13 -0800844 }
Jason Evans3c4d92e2014-10-12 22:53:59 -0700845 }
Jason Evans86815df2010-03-13 20:32:56 -0800846}
Jason Evans86815df2010-03-13 20:32:56 -0800847
Jason Evans3c234352010-01-27 13:10:55 -0800848static void
Jason Evans9eb1b1c2017-01-18 23:03:37 -0800849ctl_arena_refresh(tsdn_t *tsdn, arena_t *arena, ctl_arena_t *ctl_sdarena,
Jason Evansc4c25922017-01-15 16:56:30 -0800850 unsigned i, bool destroyed) {
Jason Evans9eb1b1c2017-01-18 23:03:37 -0800851 ctl_arena_t *ctl_arena = arenas_i(i);
Jason Evans3c234352010-01-27 13:10:55 -0800852
Jason Evans9eb1b1c2017-01-18 23:03:37 -0800853 ctl_arena_clear(ctl_arena);
854 ctl_arena_stats_amerge(tsdn, ctl_arena, arena);
Jason Evans3c07f802016-02-27 20:40:13 -0800855 /* Merge into sum stats as well. */
Jason Evans9eb1b1c2017-01-18 23:03:37 -0800856 ctl_arena_stats_sdmerge(ctl_sdarena, ctl_arena, destroyed);
Jason Evans3c234352010-01-27 13:10:55 -0800857}
858
Jason Evansedf1baf2017-01-03 17:21:59 -0800859static unsigned
Jason Evansc4c25922017-01-15 16:56:30 -0800860ctl_arena_init(tsdn_t *tsdn, extent_hooks_t *extent_hooks) {
Jason Evansedf1baf2017-01-03 17:21:59 -0800861 unsigned arena_ind;
Jason Evans9eb1b1c2017-01-18 23:03:37 -0800862 ctl_arena_t *ctl_arena;
Jason Evansedf1baf2017-01-03 17:21:59 -0800863
Jason Evans9eb1b1c2017-01-18 23:03:37 -0800864 if ((ctl_arena = ql_last(&ctl_arenas->destroyed, destroyed_link)) !=
865 NULL) {
866 ql_remove(&ctl_arenas->destroyed, ctl_arena, destroyed_link);
867 arena_ind = ctl_arena->arena_ind;
Jason Evansc4c25922017-01-15 16:56:30 -0800868 } else {
Jason Evans9eb1b1c2017-01-18 23:03:37 -0800869 arena_ind = ctl_arenas->narenas;
Jason Evansc4c25922017-01-15 16:56:30 -0800870 }
Jason Evansd778dd22017-01-03 12:40:54 -0800871
872 /* Trigger stats allocation. */
Jason Evansc4c25922017-01-15 16:56:30 -0800873 if (arenas_i_impl(tsdn, arena_ind, false, true) == NULL) {
Jason Evansf4086432017-01-19 18:15:45 -0800874 return UINT_MAX;
Jason Evansc4c25922017-01-15 16:56:30 -0800875 }
Jason Evans609ae592012-10-11 13:53:15 -0700876
Jason Evans8bb31982014-10-07 23:14:57 -0700877 /* Initialize new arena. */
Jason Evansc4c25922017-01-15 16:56:30 -0800878 if (arena_init(tsdn, arena_ind, extent_hooks) == NULL) {
Jason Evansf4086432017-01-19 18:15:45 -0800879 return UINT_MAX;
Jason Evansc4c25922017-01-15 16:56:30 -0800880 }
Jason Evans609ae592012-10-11 13:53:15 -0700881
Jason Evansc4c25922017-01-15 16:56:30 -0800882 if (arena_ind == ctl_arenas->narenas) {
Jason Evans9eb1b1c2017-01-18 23:03:37 -0800883 ctl_arenas->narenas++;
Jason Evansc4c25922017-01-15 16:56:30 -0800884 }
Jason Evansedf1baf2017-01-03 17:21:59 -0800885
Jason Evansf4086432017-01-19 18:15:45 -0800886 return arena_ind;
Jason Evans609ae592012-10-11 13:53:15 -0700887}
888
Jason Evans3c234352010-01-27 13:10:55 -0800889static void
Qi Wang2bee0c62017-05-12 12:30:33 -0700890ctl_background_thread_stats_read(tsdn_t *tsdn) {
891 background_thread_stats_t *stats = &ctl_stats->background_thread;
892 if (!have_background_thread ||
893 background_thread_stats_read(tsdn, stats)) {
894 memset(stats, 0, sizeof(background_thread_stats_t));
895 nstime_init(&stats->run_interval, 0);
896 }
897}
898
899static void
Jason Evansc4c25922017-01-15 16:56:30 -0800900ctl_refresh(tsdn_t *tsdn) {
Jason Evans3c234352010-01-27 13:10:55 -0800901 unsigned i;
Jason Evans9eb1b1c2017-01-18 23:03:37 -0800902 ctl_arena_t *ctl_sarena = arenas_i(MALLCTL_ARENAS_ALL);
903 VARIABLE_ARRAY(arena_t *, tarenas, ctl_arenas->narenas);
Jason Evans3c234352010-01-27 13:10:55 -0800904
Jason Evans3c234352010-01-27 13:10:55 -0800905 /*
Jason Evans13668262010-01-31 03:57:29 -0800906 * Clear sum stats, since they will be merged into by
Jason Evans3c234352010-01-27 13:10:55 -0800907 * ctl_arena_refresh().
908 */
Jason Evans9eb1b1c2017-01-18 23:03:37 -0800909 ctl_arena_clear(ctl_sarena);
Jason Evans3c234352010-01-27 13:10:55 -0800910
Jason Evans9eb1b1c2017-01-18 23:03:37 -0800911 for (i = 0; i < ctl_arenas->narenas; i++) {
Jason Evansc1e00ef2016-05-10 22:21:10 -0700912 tarenas[i] = arena_get(tsdn, i, false);
Jason Evans9eb1b1c2017-01-18 23:03:37 -0800913 }
Jason Evans8bb31982014-10-07 23:14:57 -0700914
Jason Evans9eb1b1c2017-01-18 23:03:37 -0800915 for (i = 0; i < ctl_arenas->narenas; i++) {
916 ctl_arena_t *ctl_arena = arenas_i(i);
Jason Evans3c234352010-01-27 13:10:55 -0800917 bool initialized = (tarenas[i] != NULL);
918
Jason Evans9eb1b1c2017-01-18 23:03:37 -0800919 ctl_arena->initialized = initialized;
920 if (initialized) {
921 ctl_arena_refresh(tsdn, tarenas[i], ctl_sarena, i,
922 false);
923 }
Jason Evans3c234352010-01-27 13:10:55 -0800924 }
925
Jason Evans7372b152012-02-10 20:22:09 -0800926 if (config_stats) {
Jason Evans9eb1b1c2017-01-18 23:03:37 -0800927 ctl_stats->allocated = ctl_sarena->astats->allocated_small +
David Goldblattee202ef2017-03-13 16:18:40 -0700928 atomic_load_zu(&ctl_sarena->astats->astats.allocated_large,
929 ATOMIC_RELAXED);
Jason Evans9eb1b1c2017-01-18 23:03:37 -0800930 ctl_stats->active = (ctl_sarena->pactive << LG_PAGE);
David Goldblattee202ef2017-03-13 16:18:40 -0700931 ctl_stats->metadata = atomic_load_zu(
932 &ctl_sarena->astats->astats.base, ATOMIC_RELAXED) +
933 atomic_load_zu(&ctl_sarena->astats->astats.internal,
934 ATOMIC_RELAXED);
935 ctl_stats->resident = atomic_load_zu(
936 &ctl_sarena->astats->astats.resident, ATOMIC_RELAXED);
937 ctl_stats->mapped = atomic_load_zu(
938 &ctl_sarena->astats->astats.mapped, ATOMIC_RELAXED);
939 ctl_stats->retained = atomic_load_zu(
940 &ctl_sarena->astats->astats.retained, ATOMIC_RELAXED);
Qi Wangca9074d2017-03-11 20:28:31 -0800941
Qi Wang2bee0c62017-05-12 12:30:33 -0700942 ctl_background_thread_stats_read(tsdn);
943
Qi Wangd3fde1c2017-03-21 11:56:38 -0700944#define READ_GLOBAL_MUTEX_PROF_DATA(i, mtx) \
Qi Wangca9074d2017-03-11 20:28:31 -0800945 malloc_mutex_lock(tsdn, &mtx); \
Qi Wangd3fde1c2017-03-21 11:56:38 -0700946 malloc_mutex_prof_read(tsdn, &ctl_stats->mutex_prof_data[i], &mtx); \
Qi Wangca9074d2017-03-11 20:28:31 -0800947 malloc_mutex_unlock(tsdn, &mtx);
948
Qi Wangbd2006a2017-03-12 01:28:52 -0800949 if (config_prof && opt_prof) {
Qi Wangd3fde1c2017-03-21 11:56:38 -0700950 READ_GLOBAL_MUTEX_PROF_DATA(global_prof_mutex_prof,
951 bt2gctx_mtx);
Qi Wangbd2006a2017-03-12 01:28:52 -0800952 }
Qi Wang5f5ed212017-05-12 16:26:59 -0700953 if (have_background_thread) {
954 READ_GLOBAL_MUTEX_PROF_DATA(
955 global_prof_mutex_background_thread,
956 background_thread_lock);
957 } else {
958 memset(&ctl_stats->mutex_prof_data[
959 global_prof_mutex_background_thread], 0,
960 sizeof(mutex_prof_data_t));
961 }
Qi Wangca9074d2017-03-11 20:28:31 -0800962 /* We own ctl mutex already. */
Qi Wangd3fde1c2017-03-21 11:56:38 -0700963 malloc_mutex_prof_read(tsdn,
964 &ctl_stats->mutex_prof_data[global_prof_mutex_ctl],
965 &ctl_mtx);
Qi Wangca9074d2017-03-11 20:28:31 -0800966#undef READ_GLOBAL_MUTEX_PROF_DATA
Jason Evans7372b152012-02-10 20:22:09 -0800967 }
Jason Evans9eb1b1c2017-01-18 23:03:37 -0800968 ctl_arenas->epoch++;
Jason Evans3c234352010-01-27 13:10:55 -0800969}
970
971static bool
Jason Evansc4c25922017-01-15 16:56:30 -0800972ctl_init(tsdn_t *tsdn) {
Jason Evansfc4dcfa2010-11-24 15:44:21 -0800973 bool ret;
Jason Evans3c234352010-01-27 13:10:55 -0800974
Jason Evansc1e00ef2016-05-10 22:21:10 -0700975 malloc_mutex_lock(tsdn, &ctl_mtx);
Jason Evans551ebc42014-10-03 10:16:09 -0700976 if (!ctl_initialized) {
Jason Evans9eb1b1c2017-01-18 23:03:37 -0800977 ctl_arena_t *ctl_sarena, *ctl_darena;
Jason Evansd778dd22017-01-03 12:40:54 -0800978 unsigned i;
979
Jason Evans3c234352010-01-27 13:10:55 -0800980 /*
Jason Evans9eb1b1c2017-01-18 23:03:37 -0800981 * Allocate demand-zeroed space for pointers to the full
982 * range of supported arena indices.
Jason Evans3c234352010-01-27 13:10:55 -0800983 */
Jason Evans9eb1b1c2017-01-18 23:03:37 -0800984 if (ctl_arenas == NULL) {
985 ctl_arenas = (ctl_arenas_t *)base_alloc(tsdn,
986 b0get(), sizeof(ctl_arenas_t), QUANTUM);
987 if (ctl_arenas == NULL) {
988 ret = true;
989 goto label_return;
990 }
991 }
992
993 if (config_stats && ctl_stats == NULL) {
Jason Evansd778dd22017-01-03 12:40:54 -0800994 ctl_stats = (ctl_stats_t *)base_alloc(tsdn, b0get(),
995 sizeof(ctl_stats_t), QUANTUM);
996 if (ctl_stats == NULL) {
997 ret = true;
998 goto label_return;
999 }
1000 }
1001
1002 /*
Jason Evans9eb1b1c2017-01-18 23:03:37 -08001003 * Allocate space for the current full range of arenas
1004 * here rather than doing it lazily elsewhere, in order
1005 * to limit when OOM-caused errors can occur.
Jason Evansd778dd22017-01-03 12:40:54 -08001006 */
Jason Evans9eb1b1c2017-01-18 23:03:37 -08001007 if ((ctl_sarena = arenas_i_impl(tsdn, MALLCTL_ARENAS_ALL, false,
1008 true)) == NULL) {
1009 ret = true;
1010 goto label_return;
1011 }
1012 ctl_sarena->initialized = true;
1013
1014 if ((ctl_darena = arenas_i_impl(tsdn, MALLCTL_ARENAS_DESTROYED,
Jason Evansd778dd22017-01-03 12:40:54 -08001015 false, true)) == NULL) {
Jason Evansfc4dcfa2010-11-24 15:44:21 -08001016 ret = true;
Jason Evansa1ee7832012-04-10 15:07:44 -07001017 goto label_return;
Jason Evansfc4dcfa2010-11-24 15:44:21 -08001018 }
Jason Evans9eb1b1c2017-01-18 23:03:37 -08001019 ctl_arena_clear(ctl_darena);
Jason Evansedf1baf2017-01-03 17:21:59 -08001020 /*
Jason Evans9eb1b1c2017-01-18 23:03:37 -08001021 * Don't toggle ctl_darena to initialized until an arena is
1022 * actually destroyed, so that arena.<i>.initialized can be used
1023 * to query whether the stats are relevant.
Jason Evansedf1baf2017-01-03 17:21:59 -08001024 */
1025
Jason Evans9eb1b1c2017-01-18 23:03:37 -08001026 ctl_arenas->narenas = narenas_total_get();
1027 for (i = 0; i < ctl_arenas->narenas; i++) {
1028 if (arenas_i_impl(tsdn, i, false, true) == NULL) {
Jason Evansd778dd22017-01-03 12:40:54 -08001029 ret = true;
1030 goto label_return;
1031 }
1032 }
Jason Evans3c234352010-01-27 13:10:55 -08001033
Jason Evans9eb1b1c2017-01-18 23:03:37 -08001034 ql_new(&ctl_arenas->destroyed);
Jason Evansc1e00ef2016-05-10 22:21:10 -07001035 ctl_refresh(tsdn);
Jason Evans9eb1b1c2017-01-18 23:03:37 -08001036
Jason Evans3c234352010-01-27 13:10:55 -08001037 ctl_initialized = true;
1038 }
1039
Jason Evansfc4dcfa2010-11-24 15:44:21 -08001040 ret = false;
Jason Evansa1ee7832012-04-10 15:07:44 -07001041label_return:
Jason Evansc1e00ef2016-05-10 22:21:10 -07001042 malloc_mutex_unlock(tsdn, &ctl_mtx);
Jason Evansf4086432017-01-19 18:15:45 -08001043 return ret;
Jason Evans3c234352010-01-27 13:10:55 -08001044}
1045
1046static int
Jason Evansc1e00ef2016-05-10 22:21:10 -07001047ctl_lookup(tsdn_t *tsdn, const char *name, ctl_node_t const **nodesp,
Jason Evansc4c25922017-01-15 16:56:30 -08001048 size_t *mibp, size_t *depthp) {
Jason Evans3c234352010-01-27 13:10:55 -08001049 int ret;
1050 const char *elm, *tdot, *dot;
1051 size_t elen, i, j;
Mike Hommey461ad5c2012-04-20 08:38:42 +02001052 const ctl_named_node_t *node;
Jason Evans3c234352010-01-27 13:10:55 -08001053
1054 elm = name;
1055 /* Equivalent to strchrnul(). */
1056 dot = ((tdot = strchr(elm, '.')) != NULL) ? tdot : strchr(elm, '\0');
1057 elen = (size_t)((uintptr_t)dot - (uintptr_t)elm);
1058 if (elen == 0) {
1059 ret = ENOENT;
Jason Evansa1ee7832012-04-10 15:07:44 -07001060 goto label_return;
Jason Evans3c234352010-01-27 13:10:55 -08001061 }
1062 node = super_root_node;
1063 for (i = 0; i < *depthp; i++) {
Mike Hommey461ad5c2012-04-20 08:38:42 +02001064 assert(node);
1065 assert(node->nchildren > 0);
1066 if (ctl_named_node(node->children) != NULL) {
1067 const ctl_named_node_t *pnode = node;
Jason Evans3c234352010-01-27 13:10:55 -08001068
1069 /* Children are named. */
Mike Hommey461ad5c2012-04-20 08:38:42 +02001070 for (j = 0; j < node->nchildren; j++) {
1071 const ctl_named_node_t *child =
1072 ctl_named_children(node, j);
1073 if (strlen(child->name) == elen &&
1074 strncmp(elm, child->name, elen) == 0) {
Jason Evans3c234352010-01-27 13:10:55 -08001075 node = child;
Jason Evansc4c25922017-01-15 16:56:30 -08001076 if (nodesp != NULL) {
Mike Hommey461ad5c2012-04-20 08:38:42 +02001077 nodesp[i] =
1078 (const ctl_node_t *)node;
Jason Evansc4c25922017-01-15 16:56:30 -08001079 }
Jason Evans3c234352010-01-27 13:10:55 -08001080 mibp[i] = j;
1081 break;
1082 }
1083 }
1084 if (node == pnode) {
1085 ret = ENOENT;
Jason Evansa1ee7832012-04-10 15:07:44 -07001086 goto label_return;
Jason Evans3c234352010-01-27 13:10:55 -08001087 }
1088 } else {
Jason Evans41b6afb2012-02-02 22:04:57 -08001089 uintmax_t index;
Mike Hommey461ad5c2012-04-20 08:38:42 +02001090 const ctl_indexed_node_t *inode;
Jason Evans3c234352010-01-27 13:10:55 -08001091
1092 /* Children are indexed. */
Jason Evans41b6afb2012-02-02 22:04:57 -08001093 index = malloc_strtoumax(elm, NULL, 10);
1094 if (index == UINTMAX_MAX || index > SIZE_T_MAX) {
Jason Evans3c234352010-01-27 13:10:55 -08001095 ret = ENOENT;
Jason Evansa1ee7832012-04-10 15:07:44 -07001096 goto label_return;
Jason Evans3c234352010-01-27 13:10:55 -08001097 }
1098
Mike Hommey461ad5c2012-04-20 08:38:42 +02001099 inode = ctl_indexed_node(node->children);
Jason Evansc1e00ef2016-05-10 22:21:10 -07001100 node = inode->index(tsdn, mibp, *depthp, (size_t)index);
Jason Evans3c234352010-01-27 13:10:55 -08001101 if (node == NULL) {
1102 ret = ENOENT;
Jason Evansa1ee7832012-04-10 15:07:44 -07001103 goto label_return;
Jason Evans3c234352010-01-27 13:10:55 -08001104 }
1105
Jason Evansc4c25922017-01-15 16:56:30 -08001106 if (nodesp != NULL) {
Mike Hommey461ad5c2012-04-20 08:38:42 +02001107 nodesp[i] = (const ctl_node_t *)node;
Jason Evansc4c25922017-01-15 16:56:30 -08001108 }
Jason Evans3c234352010-01-27 13:10:55 -08001109 mibp[i] = (size_t)index;
1110 }
1111
1112 if (node->ctl != NULL) {
1113 /* Terminal node. */
1114 if (*dot != '\0') {
1115 /*
1116 * The name contains more elements than are
1117 * in this path through the tree.
1118 */
1119 ret = ENOENT;
Jason Evansa1ee7832012-04-10 15:07:44 -07001120 goto label_return;
Jason Evans3c234352010-01-27 13:10:55 -08001121 }
1122 /* Complete lookup successful. */
1123 *depthp = i + 1;
1124 break;
1125 }
1126
1127 /* Update elm. */
1128 if (*dot == '\0') {
1129 /* No more elements. */
1130 ret = ENOENT;
Jason Evansa1ee7832012-04-10 15:07:44 -07001131 goto label_return;
Jason Evans3c234352010-01-27 13:10:55 -08001132 }
1133 elm = &dot[1];
1134 dot = ((tdot = strchr(elm, '.')) != NULL) ? tdot :
1135 strchr(elm, '\0');
1136 elen = (size_t)((uintptr_t)dot - (uintptr_t)elm);
1137 }
1138
1139 ret = 0;
Jason Evansa1ee7832012-04-10 15:07:44 -07001140label_return:
Jason Evansf4086432017-01-19 18:15:45 -08001141 return ret;
Jason Evans3c234352010-01-27 13:10:55 -08001142}
1143
1144int
Jason Evansb2c0d632016-04-13 23:36:15 -07001145ctl_byname(tsd_t *tsd, const char *name, void *oldp, size_t *oldlenp,
Jason Evansc4c25922017-01-15 16:56:30 -08001146 void *newp, size_t newlen) {
Jason Evans3c234352010-01-27 13:10:55 -08001147 int ret;
1148 size_t depth;
1149 ctl_node_t const *nodes[CTL_MAX_DEPTH];
1150 size_t mib[CTL_MAX_DEPTH];
Mike Hommey461ad5c2012-04-20 08:38:42 +02001151 const ctl_named_node_t *node;
Jason Evans3c234352010-01-27 13:10:55 -08001152
Jason Evansc1e00ef2016-05-10 22:21:10 -07001153 if (!ctl_initialized && ctl_init(tsd_tsdn(tsd))) {
Jason Evans3c234352010-01-27 13:10:55 -08001154 ret = EAGAIN;
Jason Evansa1ee7832012-04-10 15:07:44 -07001155 goto label_return;
Jason Evans3c234352010-01-27 13:10:55 -08001156 }
1157
1158 depth = CTL_MAX_DEPTH;
Jason Evansc1e00ef2016-05-10 22:21:10 -07001159 ret = ctl_lookup(tsd_tsdn(tsd), name, nodes, mib, &depth);
Jason Evansc4c25922017-01-15 16:56:30 -08001160 if (ret != 0) {
Jason Evansa1ee7832012-04-10 15:07:44 -07001161 goto label_return;
Jason Evansc4c25922017-01-15 16:56:30 -08001162 }
Jason Evans3c234352010-01-27 13:10:55 -08001163
Mike Hommey461ad5c2012-04-20 08:38:42 +02001164 node = ctl_named_node(nodes[depth-1]);
Jason Evansc4c25922017-01-15 16:56:30 -08001165 if (node != NULL && node->ctl) {
Jason Evansb2c0d632016-04-13 23:36:15 -07001166 ret = node->ctl(tsd, mib, depth, oldp, oldlenp, newp, newlen);
Qi Wangaa1de062017-03-01 14:43:35 -08001167 } else {
Jason Evans3c234352010-01-27 13:10:55 -08001168 /* The name refers to a partial path through the ctl tree. */
1169 ret = ENOENT;
Jason Evans3c234352010-01-27 13:10:55 -08001170 }
Jason Evans3c234352010-01-27 13:10:55 -08001171
Jason Evansa1ee7832012-04-10 15:07:44 -07001172label_return:
Jason Evans3c234352010-01-27 13:10:55 -08001173 return(ret);
1174}
1175
1176int
Jason Evansc4c25922017-01-15 16:56:30 -08001177ctl_nametomib(tsdn_t *tsdn, const char *name, size_t *mibp, size_t *miblenp) {
Jason Evans3c234352010-01-27 13:10:55 -08001178 int ret;
1179
Jason Evansc1e00ef2016-05-10 22:21:10 -07001180 if (!ctl_initialized && ctl_init(tsdn)) {
Jason Evans3c234352010-01-27 13:10:55 -08001181 ret = EAGAIN;
Jason Evansa1ee7832012-04-10 15:07:44 -07001182 goto label_return;
Jason Evans3c234352010-01-27 13:10:55 -08001183 }
1184
Jason Evansc1e00ef2016-05-10 22:21:10 -07001185 ret = ctl_lookup(tsdn, name, NULL, mibp, miblenp);
Jason Evansa1ee7832012-04-10 15:07:44 -07001186label_return:
Jason Evans3c234352010-01-27 13:10:55 -08001187 return(ret);
1188}
1189
1190int
Jason Evansb2c0d632016-04-13 23:36:15 -07001191ctl_bymib(tsd_t *tsd, const size_t *mib, size_t miblen, void *oldp,
Jason Evansc4c25922017-01-15 16:56:30 -08001192 size_t *oldlenp, void *newp, size_t newlen) {
Jason Evans3c234352010-01-27 13:10:55 -08001193 int ret;
Mike Hommey461ad5c2012-04-20 08:38:42 +02001194 const ctl_named_node_t *node;
Jason Evans3c234352010-01-27 13:10:55 -08001195 size_t i;
1196
Jason Evansc1e00ef2016-05-10 22:21:10 -07001197 if (!ctl_initialized && ctl_init(tsd_tsdn(tsd))) {
Jason Evans3c234352010-01-27 13:10:55 -08001198 ret = EAGAIN;
Jason Evansa1ee7832012-04-10 15:07:44 -07001199 goto label_return;
Jason Evans3c234352010-01-27 13:10:55 -08001200 }
1201
1202 /* Iterate down the tree. */
1203 node = super_root_node;
1204 for (i = 0; i < miblen; i++) {
Mike Hommey461ad5c2012-04-20 08:38:42 +02001205 assert(node);
1206 assert(node->nchildren > 0);
1207 if (ctl_named_node(node->children) != NULL) {
Jason Evans3c234352010-01-27 13:10:55 -08001208 /* Children are named. */
Jason Evans6edbedd2017-01-04 07:51:49 -08001209 if (node->nchildren <= mib[i]) {
Jason Evans3c234352010-01-27 13:10:55 -08001210 ret = ENOENT;
Jason Evansa1ee7832012-04-10 15:07:44 -07001211 goto label_return;
Jason Evans3c234352010-01-27 13:10:55 -08001212 }
Mike Hommey461ad5c2012-04-20 08:38:42 +02001213 node = ctl_named_children(node, mib[i]);
Jason Evans3c234352010-01-27 13:10:55 -08001214 } else {
Mike Hommey461ad5c2012-04-20 08:38:42 +02001215 const ctl_indexed_node_t *inode;
Jason Evans3c234352010-01-27 13:10:55 -08001216
1217 /* Indexed element. */
Mike Hommey461ad5c2012-04-20 08:38:42 +02001218 inode = ctl_indexed_node(node->children);
Jason Evansc1e00ef2016-05-10 22:21:10 -07001219 node = inode->index(tsd_tsdn(tsd), mib, miblen, mib[i]);
Jason Evans3c234352010-01-27 13:10:55 -08001220 if (node == NULL) {
1221 ret = ENOENT;
Jason Evansa1ee7832012-04-10 15:07:44 -07001222 goto label_return;
Jason Evans3c234352010-01-27 13:10:55 -08001223 }
1224 }
1225 }
1226
1227 /* Call the ctl function. */
Jason Evansc4c25922017-01-15 16:56:30 -08001228 if (node && node->ctl) {
Jason Evansb2c0d632016-04-13 23:36:15 -07001229 ret = node->ctl(tsd, mib, miblen, oldp, oldlenp, newp, newlen);
Jason Evansc4c25922017-01-15 16:56:30 -08001230 } else {
Jason Evans3c234352010-01-27 13:10:55 -08001231 /* Partial MIB. */
1232 ret = ENOENT;
Jason Evans3c234352010-01-27 13:10:55 -08001233 }
Jason Evans3c234352010-01-27 13:10:55 -08001234
Jason Evansa1ee7832012-04-10 15:07:44 -07001235label_return:
Jason Evans3c234352010-01-27 13:10:55 -08001236 return(ret);
1237}
1238
1239bool
Jason Evansc4c25922017-01-15 16:56:30 -08001240ctl_boot(void) {
David Goldblatt26c792e2017-05-15 15:38:15 -07001241 if (malloc_mutex_init(&ctl_mtx, "ctl", WITNESS_RANK_CTL,
1242 malloc_mutex_rank_exclusive)) {
Jason Evansf4086432017-01-19 18:15:45 -08001243 return true;
Jason Evansc4c25922017-01-15 16:56:30 -08001244 }
Jason Evans3c234352010-01-27 13:10:55 -08001245
1246 ctl_initialized = false;
1247
Jason Evansf4086432017-01-19 18:15:45 -08001248 return false;
Jason Evans3c234352010-01-27 13:10:55 -08001249}
1250
Jason Evans20f1fc92012-10-09 14:46:22 -07001251void
Jason Evansc4c25922017-01-15 16:56:30 -08001252ctl_prefork(tsdn_t *tsdn) {
Jason Evansc1e00ef2016-05-10 22:21:10 -07001253 malloc_mutex_prefork(tsdn, &ctl_mtx);
Jason Evans20f1fc92012-10-09 14:46:22 -07001254}
1255
1256void
Jason Evansc4c25922017-01-15 16:56:30 -08001257ctl_postfork_parent(tsdn_t *tsdn) {
Jason Evansc1e00ef2016-05-10 22:21:10 -07001258 malloc_mutex_postfork_parent(tsdn, &ctl_mtx);
Jason Evans20f1fc92012-10-09 14:46:22 -07001259}
1260
1261void
Jason Evansc4c25922017-01-15 16:56:30 -08001262ctl_postfork_child(tsdn_t *tsdn) {
Jason Evansc1e00ef2016-05-10 22:21:10 -07001263 malloc_mutex_postfork_child(tsdn, &ctl_mtx);
Jason Evans20f1fc92012-10-09 14:46:22 -07001264}
1265
Jason Evans3c234352010-01-27 13:10:55 -08001266/******************************************************************************/
1267/* *_ctl() functions. */
1268
Jason Evansc0cc5db2017-01-19 21:41:41 -08001269#define READONLY() do { \
Jason Evans3c234352010-01-27 13:10:55 -08001270 if (newp != NULL || newlen != 0) { \
1271 ret = EPERM; \
Jason Evans6b9ed672012-04-25 13:12:46 -07001272 goto label_return; \
Jason Evans3c234352010-01-27 13:10:55 -08001273 } \
1274} while (0)
1275
Jason Evansc0cc5db2017-01-19 21:41:41 -08001276#define WRITEONLY() do { \
Jason Evans3c234352010-01-27 13:10:55 -08001277 if (oldp != NULL || oldlenp != NULL) { \
1278 ret = EPERM; \
Jason Evans6b9ed672012-04-25 13:12:46 -07001279 goto label_return; \
Jason Evans3c234352010-01-27 13:10:55 -08001280 } \
1281} while (0)
1282
Jason Evansc0cc5db2017-01-19 21:41:41 -08001283#define READ_XOR_WRITE() do { \
Jason Evansfc12c0b2014-10-03 23:25:30 -07001284 if ((oldp != NULL && oldlenp != NULL) && (newp != NULL || \
1285 newlen != 0)) { \
1286 ret = EPERM; \
1287 goto label_return; \
1288 } \
1289} while (0)
1290
Jason Evansc0cc5db2017-01-19 21:41:41 -08001291#define READ(v, t) do { \
Jason Evans3c234352010-01-27 13:10:55 -08001292 if (oldp != NULL && oldlenp != NULL) { \
1293 if (*oldlenp != sizeof(t)) { \
1294 size_t copylen = (sizeof(t) <= *oldlenp) \
1295 ? sizeof(t) : *oldlenp; \
Jason Evans6eb84fb2012-11-29 22:13:04 -08001296 memcpy(oldp, (void *)&(v), copylen); \
Jason Evans3c234352010-01-27 13:10:55 -08001297 ret = EINVAL; \
Jason Evans6b9ed672012-04-25 13:12:46 -07001298 goto label_return; \
Jason Evansb49a3342015-07-28 11:28:19 -04001299 } \
1300 *(t *)oldp = (v); \
Jason Evans3c234352010-01-27 13:10:55 -08001301 } \
1302} while (0)
1303
Jason Evansc0cc5db2017-01-19 21:41:41 -08001304#define WRITE(v, t) do { \
Jason Evans3c234352010-01-27 13:10:55 -08001305 if (newp != NULL) { \
1306 if (newlen != sizeof(t)) { \
1307 ret = EINVAL; \
Jason Evans6b9ed672012-04-25 13:12:46 -07001308 goto label_return; \
Jason Evans3c234352010-01-27 13:10:55 -08001309 } \
Jason Evans6eb84fb2012-11-29 22:13:04 -08001310 (v) = *(t *)newp; \
Jason Evans3c234352010-01-27 13:10:55 -08001311 } \
1312} while (0)
1313
Jason Evansc0cc5db2017-01-19 21:41:41 -08001314#define MIB_UNSIGNED(v, i) do { \
Jason Evans6edbedd2017-01-04 07:51:49 -08001315 if (mib[i] > UINT_MAX) { \
1316 ret = EFAULT; \
1317 goto label_return; \
1318 } \
1319 v = (unsigned)mib[i]; \
1320} while (0)
1321
Jason Evans7372b152012-02-10 20:22:09 -08001322/*
1323 * There's a lot of code duplication in the following macros due to limitations
1324 * in how nested cpp macros are expanded.
1325 */
Jason Evansc0cc5db2017-01-19 21:41:41 -08001326#define CTL_RO_CLGEN(c, l, n, v, t) \
Jason Evans7372b152012-02-10 20:22:09 -08001327static int \
Jason Evansb2c0d632016-04-13 23:36:15 -07001328n##_ctl(tsd_t *tsd, const size_t *mib, size_t miblen, void *oldp, \
Jason Evansc4c25922017-01-15 16:56:30 -08001329 size_t *oldlenp, void *newp, size_t newlen) { \
Jason Evans7372b152012-02-10 20:22:09 -08001330 int ret; \
1331 t oldval; \
1332 \
Jason Evansc4c25922017-01-15 16:56:30 -08001333 if (!(c)) { \
Jason Evansf4086432017-01-19 18:15:45 -08001334 return ENOENT; \
Jason Evansc4c25922017-01-15 16:56:30 -08001335 } \
1336 if (l) { \
Jason Evansc1e00ef2016-05-10 22:21:10 -07001337 malloc_mutex_lock(tsd_tsdn(tsd), &ctl_mtx); \
Jason Evansc4c25922017-01-15 16:56:30 -08001338 } \
Jason Evans7372b152012-02-10 20:22:09 -08001339 READONLY(); \
Jason Evans6eb84fb2012-11-29 22:13:04 -08001340 oldval = (v); \
Jason Evans7372b152012-02-10 20:22:09 -08001341 READ(oldval, t); \
1342 \
1343 ret = 0; \
Jason Evans6b9ed672012-04-25 13:12:46 -07001344label_return: \
Jason Evansc4c25922017-01-15 16:56:30 -08001345 if (l) { \
Jason Evansc1e00ef2016-05-10 22:21:10 -07001346 malloc_mutex_unlock(tsd_tsdn(tsd), &ctl_mtx); \
Jason Evansc4c25922017-01-15 16:56:30 -08001347 } \
Jason Evansf4086432017-01-19 18:15:45 -08001348 return ret; \
Jason Evans7372b152012-02-10 20:22:09 -08001349}
1350
Jason Evansc0cc5db2017-01-19 21:41:41 -08001351#define CTL_RO_CGEN(c, n, v, t) \
Jason Evans7372b152012-02-10 20:22:09 -08001352static int \
Jason Evansb2c0d632016-04-13 23:36:15 -07001353n##_ctl(tsd_t *tsd, const size_t *mib, size_t miblen, void *oldp, \
Jason Evansc4c25922017-01-15 16:56:30 -08001354 size_t *oldlenp, void *newp, size_t newlen) { \
Jason Evans7372b152012-02-10 20:22:09 -08001355 int ret; \
1356 t oldval; \
1357 \
Jason Evansc4c25922017-01-15 16:56:30 -08001358 if (!(c)) { \
Jason Evansf4086432017-01-19 18:15:45 -08001359 return ENOENT; \
Jason Evansc4c25922017-01-15 16:56:30 -08001360 } \
Jason Evansc1e00ef2016-05-10 22:21:10 -07001361 malloc_mutex_lock(tsd_tsdn(tsd), &ctl_mtx); \
Jason Evans7372b152012-02-10 20:22:09 -08001362 READONLY(); \
Jason Evans6eb84fb2012-11-29 22:13:04 -08001363 oldval = (v); \
Jason Evans7372b152012-02-10 20:22:09 -08001364 READ(oldval, t); \
1365 \
1366 ret = 0; \
Jason Evans6b9ed672012-04-25 13:12:46 -07001367label_return: \
Jason Evansc1e00ef2016-05-10 22:21:10 -07001368 malloc_mutex_unlock(tsd_tsdn(tsd), &ctl_mtx); \
Jason Evansf4086432017-01-19 18:15:45 -08001369 return ret; \
Jason Evans7372b152012-02-10 20:22:09 -08001370}
1371
Jason Evansc0cc5db2017-01-19 21:41:41 -08001372#define CTL_RO_GEN(n, v, t) \
Jason Evans3c234352010-01-27 13:10:55 -08001373static int \
Jason Evansb2c0d632016-04-13 23:36:15 -07001374n##_ctl(tsd_t *tsd, const size_t *mib, size_t miblen, void *oldp, \
Jason Evansc4c25922017-01-15 16:56:30 -08001375 size_t *oldlenp, void *newp, size_t newlen) { \
Jason Evans3c234352010-01-27 13:10:55 -08001376 int ret; \
1377 t oldval; \
1378 \
Jason Evansc1e00ef2016-05-10 22:21:10 -07001379 malloc_mutex_lock(tsd_tsdn(tsd), &ctl_mtx); \
Jason Evansfc4dcfa2010-11-24 15:44:21 -08001380 READONLY(); \
Jason Evans6eb84fb2012-11-29 22:13:04 -08001381 oldval = (v); \
Jason Evansfc4dcfa2010-11-24 15:44:21 -08001382 READ(oldval, t); \
1383 \
1384 ret = 0; \
Jason Evans6b9ed672012-04-25 13:12:46 -07001385label_return: \
Jason Evansc1e00ef2016-05-10 22:21:10 -07001386 malloc_mutex_unlock(tsd_tsdn(tsd), &ctl_mtx); \
Jason Evansf4086432017-01-19 18:15:45 -08001387 return ret; \
Jason Evansfc4dcfa2010-11-24 15:44:21 -08001388}
1389
1390/*
1391 * ctl_mtx is not acquired, under the assumption that no pertinent data will
1392 * mutate during the call.
1393 */
Jason Evansc0cc5db2017-01-19 21:41:41 -08001394#define CTL_RO_NL_CGEN(c, n, v, t) \
Jason Evans7372b152012-02-10 20:22:09 -08001395static int \
Jason Evansb2c0d632016-04-13 23:36:15 -07001396n##_ctl(tsd_t *tsd, const size_t *mib, size_t miblen, void *oldp, \
Jason Evansc4c25922017-01-15 16:56:30 -08001397 size_t *oldlenp, void *newp, size_t newlen) { \
Jason Evans7372b152012-02-10 20:22:09 -08001398 int ret; \
1399 t oldval; \
1400 \
Jason Evansc4c25922017-01-15 16:56:30 -08001401 if (!(c)) { \
Jason Evansf4086432017-01-19 18:15:45 -08001402 return ENOENT; \
Jason Evansc4c25922017-01-15 16:56:30 -08001403 } \
Jason Evans7372b152012-02-10 20:22:09 -08001404 READONLY(); \
Jason Evans6eb84fb2012-11-29 22:13:04 -08001405 oldval = (v); \
Jason Evans7372b152012-02-10 20:22:09 -08001406 READ(oldval, t); \
1407 \
1408 ret = 0; \
Jason Evans6b9ed672012-04-25 13:12:46 -07001409label_return: \
Jason Evansf4086432017-01-19 18:15:45 -08001410 return ret; \
Jason Evans7372b152012-02-10 20:22:09 -08001411}
1412
Jason Evansc0cc5db2017-01-19 21:41:41 -08001413#define CTL_RO_NL_GEN(n, v, t) \
Jason Evansfc4dcfa2010-11-24 15:44:21 -08001414static int \
Jason Evansb2c0d632016-04-13 23:36:15 -07001415n##_ctl(tsd_t *tsd, const size_t *mib, size_t miblen, void *oldp, \
Jason Evansc4c25922017-01-15 16:56:30 -08001416 size_t *oldlenp, void *newp, size_t newlen) { \
Jason Evansfc4dcfa2010-11-24 15:44:21 -08001417 int ret; \
1418 t oldval; \
1419 \
Jason Evans3c234352010-01-27 13:10:55 -08001420 READONLY(); \
Jason Evans6eb84fb2012-11-29 22:13:04 -08001421 oldval = (v); \
Jason Evans3c234352010-01-27 13:10:55 -08001422 READ(oldval, t); \
1423 \
1424 ret = 0; \
Jason Evans6b9ed672012-04-25 13:12:46 -07001425label_return: \
Jason Evansf4086432017-01-19 18:15:45 -08001426 return ret; \
Jason Evans3c234352010-01-27 13:10:55 -08001427}
1428
Jason Evansc0cc5db2017-01-19 21:41:41 -08001429#define CTL_TSD_RO_NL_CGEN(c, n, m, t) \
Jason Evans5460aa62014-09-22 21:09:23 -07001430static int \
Jason Evansb2c0d632016-04-13 23:36:15 -07001431n##_ctl(tsd_t *tsd, const size_t *mib, size_t miblen, void *oldp, \
Jason Evansc4c25922017-01-15 16:56:30 -08001432 size_t *oldlenp, void *newp, size_t newlen) { \
Jason Evans5460aa62014-09-22 21:09:23 -07001433 int ret; \
1434 t oldval; \
Jason Evans5460aa62014-09-22 21:09:23 -07001435 \
Jason Evansc4c25922017-01-15 16:56:30 -08001436 if (!(c)) { \
Jason Evansf4086432017-01-19 18:15:45 -08001437 return ENOENT; \
Jason Evansc4c25922017-01-15 16:56:30 -08001438 } \
Jason Evans5460aa62014-09-22 21:09:23 -07001439 READONLY(); \
Jason Evans5460aa62014-09-22 21:09:23 -07001440 oldval = (m(tsd)); \
1441 READ(oldval, t); \
1442 \
1443 ret = 0; \
1444label_return: \
Jason Evansf4086432017-01-19 18:15:45 -08001445 return ret; \
Jason Evans5460aa62014-09-22 21:09:23 -07001446}
1447
Jason Evansc0cc5db2017-01-19 21:41:41 -08001448#define CTL_RO_CONFIG_GEN(n, t) \
Jason Evans3c234352010-01-27 13:10:55 -08001449static int \
Jason Evansb2c0d632016-04-13 23:36:15 -07001450n##_ctl(tsd_t *tsd, const size_t *mib, size_t miblen, void *oldp, \
Jason Evansc4c25922017-01-15 16:56:30 -08001451 size_t *oldlenp, void *newp, size_t newlen) { \
Jason Evans3c234352010-01-27 13:10:55 -08001452 int ret; \
Jason Evansf8290092016-02-07 14:23:22 -08001453 t oldval; \
Jason Evans3c234352010-01-27 13:10:55 -08001454 \
1455 READONLY(); \
Jason Evans7372b152012-02-10 20:22:09 -08001456 oldval = n; \
Jason Evansf8290092016-02-07 14:23:22 -08001457 READ(oldval, t); \
Jason Evans3c234352010-01-27 13:10:55 -08001458 \
1459 ret = 0; \
Jason Evans6b9ed672012-04-25 13:12:46 -07001460label_return: \
Jason Evansf4086432017-01-19 18:15:45 -08001461 return ret; \
Jason Evans3c234352010-01-27 13:10:55 -08001462}
1463
Jason Evansd8a39002013-12-19 21:40:41 -08001464/******************************************************************************/
1465
Jason Evansfc4dcfa2010-11-24 15:44:21 -08001466CTL_RO_NL_GEN(version, JEMALLOC_VERSION, const char *)
Jason Evansa40bc7a2010-03-02 13:01:16 -08001467
Jason Evans3c234352010-01-27 13:10:55 -08001468static int
Jason Evansb2c0d632016-04-13 23:36:15 -07001469epoch_ctl(tsd_t *tsd, const size_t *mib, size_t miblen, void *oldp,
Jason Evansc4c25922017-01-15 16:56:30 -08001470 size_t *oldlenp, void *newp, size_t newlen) {
Jason Evans3c234352010-01-27 13:10:55 -08001471 int ret;
Jason Evans3ab682d2013-10-19 17:19:49 -07001472 UNUSED uint64_t newval;
Jason Evans3c234352010-01-27 13:10:55 -08001473
Jason Evansc1e00ef2016-05-10 22:21:10 -07001474 malloc_mutex_lock(tsd_tsdn(tsd), &ctl_mtx);
Jason Evans3c234352010-01-27 13:10:55 -08001475 WRITE(newval, uint64_t);
Jason Evansc4c25922017-01-15 16:56:30 -08001476 if (newp != NULL) {
Jason Evansc1e00ef2016-05-10 22:21:10 -07001477 ctl_refresh(tsd_tsdn(tsd));
Jason Evansc4c25922017-01-15 16:56:30 -08001478 }
Jason Evans9eb1b1c2017-01-18 23:03:37 -08001479 READ(ctl_arenas->epoch, uint64_t);
Jason Evans3c234352010-01-27 13:10:55 -08001480
1481 ret = 0;
Jason Evansa1ee7832012-04-10 15:07:44 -07001482label_return:
Jason Evansc1e00ef2016-05-10 22:21:10 -07001483 malloc_mutex_unlock(tsd_tsdn(tsd), &ctl_mtx);
Jason Evansf4086432017-01-19 18:15:45 -08001484 return ret;
Jason Evans3c234352010-01-27 13:10:55 -08001485}
1486
Qi Wangb693c782017-03-17 12:42:33 -07001487static int
1488background_thread_ctl(tsd_t *tsd, const size_t *mib, size_t miblen,
1489 void *oldp, size_t *oldlenp, void *newp, size_t newlen) {
1490 int ret;
1491 bool oldval;
1492
1493 if (!have_background_thread) {
1494 return ENOENT;
1495 }
1496
1497 malloc_mutex_lock(tsd_tsdn(tsd), &background_thread_lock);
1498 if (newp == NULL) {
1499 oldval = background_thread_enabled();
1500 READ(oldval, bool);
1501 } else {
1502 if (newlen != sizeof(bool)) {
1503 ret = EINVAL;
1504 goto label_return;
1505 }
1506 oldval = background_thread_enabled();
1507 READ(oldval, bool);
1508
1509 bool newval = *(bool *)newp;
1510 if (newval == oldval) {
1511 ret = 0;
1512 goto label_return;
1513 }
1514
1515 background_thread_enabled_set(tsd_tsdn(tsd), newval);
1516 if (newval) {
1517 if (background_threads_enable(tsd)) {
1518 ret = EFAULT;
1519 goto label_return;
1520 }
1521 } else {
1522 if (background_threads_disable(tsd)) {
1523 ret = EFAULT;
1524 goto label_return;
1525 }
1526 }
1527 }
1528 ret = 0;
1529label_return:
1530 malloc_mutex_unlock(tsd_tsdn(tsd), &background_thread_lock);
1531 return ret;
1532}
1533
Jason Evansd8a39002013-12-19 21:40:41 -08001534/******************************************************************************/
Jason Evansd4be8b72012-03-26 18:54:44 -07001535
Jason Evansf8290092016-02-07 14:23:22 -08001536CTL_RO_CONFIG_GEN(config_cache_oblivious, bool)
1537CTL_RO_CONFIG_GEN(config_debug, bool)
1538CTL_RO_CONFIG_GEN(config_fill, bool)
1539CTL_RO_CONFIG_GEN(config_lazy_lock, bool)
1540CTL_RO_CONFIG_GEN(config_malloc_conf, const char *)
Jason Evansf8290092016-02-07 14:23:22 -08001541CTL_RO_CONFIG_GEN(config_prof, bool)
1542CTL_RO_CONFIG_GEN(config_prof_libgcc, bool)
1543CTL_RO_CONFIG_GEN(config_prof_libunwind, bool)
1544CTL_RO_CONFIG_GEN(config_stats, bool)
Jason Evansf8290092016-02-07 14:23:22 -08001545CTL_RO_CONFIG_GEN(config_utrace, bool)
Jason Evansf8290092016-02-07 14:23:22 -08001546CTL_RO_CONFIG_GEN(config_xmalloc, bool)
Jason Evansd4be8b72012-03-26 18:54:44 -07001547
Jason Evansd8a39002013-12-19 21:40:41 -08001548/******************************************************************************/
Jason Evansd4be8b72012-03-26 18:54:44 -07001549
Jason Evansd8a39002013-12-19 21:40:41 -08001550CTL_RO_NL_GEN(opt_abort, opt_abort, bool)
Qi Wangb86d2712017-05-25 15:30:11 -07001551CTL_RO_NL_GEN(opt_abort_conf, opt_abort_conf, bool)
Jason Evansb9ab04a2017-04-26 16:26:12 -07001552CTL_RO_NL_GEN(opt_retain, opt_retain, bool)
Jason Evansd8a39002013-12-19 21:40:41 -08001553CTL_RO_NL_GEN(opt_dss, opt_dss, const char *)
Jason Evans8f683b92016-02-24 11:03:40 -08001554CTL_RO_NL_GEN(opt_narenas, opt_narenas, unsigned)
Qi Wangec532e22017-02-02 17:02:05 -08001555CTL_RO_NL_GEN(opt_percpu_arena, opt_percpu_arena, const char *)
Qi Wangb693c782017-03-17 12:42:33 -07001556CTL_RO_NL_GEN(opt_background_thread, opt_background_thread, bool)
Jason Evans6e62c622017-05-17 10:47:00 -07001557CTL_RO_NL_GEN(opt_dirty_decay_ms, opt_dirty_decay_ms, ssize_t)
1558CTL_RO_NL_GEN(opt_muzzy_decay_ms, opt_muzzy_decay_ms, ssize_t)
Jason Evansd8a39002013-12-19 21:40:41 -08001559CTL_RO_NL_GEN(opt_stats_print, opt_stats_print, bool)
Guilherme Goncalves2c5cb612014-12-08 19:12:41 -02001560CTL_RO_NL_CGEN(config_fill, opt_junk, opt_junk, const char *)
Jason Evansd8a39002013-12-19 21:40:41 -08001561CTL_RO_NL_CGEN(config_fill, opt_zero, opt_zero, bool)
1562CTL_RO_NL_CGEN(config_utrace, opt_utrace, opt_utrace, bool)
Jason Evansd8a39002013-12-19 21:40:41 -08001563CTL_RO_NL_CGEN(config_xmalloc, opt_xmalloc, opt_xmalloc, bool)
Jason Evans4403c9a2017-04-20 17:21:37 -07001564CTL_RO_NL_GEN(opt_tcache, opt_tcache, bool)
1565CTL_RO_NL_GEN(opt_lg_tcache_max, opt_lg_tcache_max, ssize_t)
Jason Evansd8a39002013-12-19 21:40:41 -08001566CTL_RO_NL_CGEN(config_prof, opt_prof, opt_prof, bool)
1567CTL_RO_NL_CGEN(config_prof, opt_prof_prefix, opt_prof_prefix, const char *)
Jason Evansfc12c0b2014-10-03 23:25:30 -07001568CTL_RO_NL_CGEN(config_prof, opt_prof_active, opt_prof_active, bool)
1569CTL_RO_NL_CGEN(config_prof, opt_prof_thread_active_init,
1570 opt_prof_thread_active_init, bool)
Jason Evansd8a39002013-12-19 21:40:41 -08001571CTL_RO_NL_CGEN(config_prof, opt_lg_prof_sample, opt_lg_prof_sample, size_t)
1572CTL_RO_NL_CGEN(config_prof, opt_prof_accum, opt_prof_accum, bool)
1573CTL_RO_NL_CGEN(config_prof, opt_lg_prof_interval, opt_lg_prof_interval, ssize_t)
1574CTL_RO_NL_CGEN(config_prof, opt_prof_gdump, opt_prof_gdump, bool)
1575CTL_RO_NL_CGEN(config_prof, opt_prof_final, opt_prof_final, bool)
1576CTL_RO_NL_CGEN(config_prof, opt_prof_leak, opt_prof_leak, bool)
Jason Evansd4be8b72012-03-26 18:54:44 -07001577
Jason Evansd8a39002013-12-19 21:40:41 -08001578/******************************************************************************/
Jason Evans3c234352010-01-27 13:10:55 -08001579
Jason Evansb267d0f2010-08-13 15:42:29 -07001580static int
Jason Evansb2c0d632016-04-13 23:36:15 -07001581thread_arena_ctl(tsd_t *tsd, const size_t *mib, size_t miblen, void *oldp,
Jason Evansc4c25922017-01-15 16:56:30 -08001582 size_t *oldlenp, void *newp, size_t newlen) {
Jason Evansb267d0f2010-08-13 15:42:29 -07001583 int ret;
Jason Evans1cb181e2015-01-29 15:30:47 -08001584 arena_t *oldarena;
Jason Evansb267d0f2010-08-13 15:42:29 -07001585 unsigned newind, oldind;
1586
Jason Evans90827a32016-05-03 15:00:42 -07001587 oldarena = arena_choose(tsd, NULL);
Jason Evansc4c25922017-01-15 16:56:30 -08001588 if (oldarena == NULL) {
Jason Evansf4086432017-01-19 18:15:45 -08001589 return EAGAIN;
Jason Evansc4c25922017-01-15 16:56:30 -08001590 }
Jason Evansa0dd3a42016-12-22 16:39:10 -06001591 newind = oldind = arena_ind_get(oldarena);
Jason Evansa7153a02011-03-14 11:39:49 -07001592 WRITE(newind, unsigned);
1593 READ(oldind, unsigned);
Qi Wangec532e22017-02-02 17:02:05 -08001594
Jason Evansb267d0f2010-08-13 15:42:29 -07001595 if (newind != oldind) {
Jason Evans1cb181e2015-01-29 15:30:47 -08001596 arena_t *newarena;
1597
Jason Evansb6c08672016-10-03 10:37:12 -07001598 if (newind >= narenas_total_get()) {
Jason Evansb267d0f2010-08-13 15:42:29 -07001599 /* New arena index is out of range. */
1600 ret = EFAULT;
Jason Evansa1ee7832012-04-10 15:07:44 -07001601 goto label_return;
Jason Evansb267d0f2010-08-13 15:42:29 -07001602 }
1603
Qi Wangec532e22017-02-02 17:02:05 -08001604 if (have_percpu_arena &&
1605 (percpu_arena_mode != percpu_arena_disabled)) {
1606 if (newind < percpu_arena_ind_limit()) {
1607 /*
1608 * If perCPU arena is enabled, thread_arena
1609 * control is not allowed for the auto arena
1610 * range.
1611 */
1612 ret = EPERM;
1613 goto label_return;
1614 }
1615 }
1616
Jason Evansb267d0f2010-08-13 15:42:29 -07001617 /* Initialize arena if necessary. */
Jason Evansc1e00ef2016-05-10 22:21:10 -07001618 newarena = arena_get(tsd_tsdn(tsd), newind, true);
Jason Evans1cb181e2015-01-29 15:30:47 -08001619 if (newarena == NULL) {
Jason Evansb267d0f2010-08-13 15:42:29 -07001620 ret = EAGAIN;
Jason Evansa1ee7832012-04-10 15:07:44 -07001621 goto label_return;
Jason Evansb267d0f2010-08-13 15:42:29 -07001622 }
Jason Evans8bb31982014-10-07 23:14:57 -07001623 /* Set new arena/tcache associations. */
1624 arena_migrate(tsd, oldind, newind);
Jason Evans4403c9a2017-04-20 17:21:37 -07001625 if (tcache_available(tsd)) {
1626 tcache_arena_reassociate(tsd_tsdn(tsd),
1627 tsd_tcachep_get(tsd), newarena);
Jason Evans624f2f32010-12-29 12:21:05 -08001628 }
Jason Evansb267d0f2010-08-13 15:42:29 -07001629 }
1630
1631 ret = 0;
Jason Evansa1ee7832012-04-10 15:07:44 -07001632label_return:
Jason Evansf4086432017-01-19 18:15:45 -08001633 return ret;
Jason Evansb267d0f2010-08-13 15:42:29 -07001634}
Jason Evansb267d0f2010-08-13 15:42:29 -07001635
Jason Evans5460aa62014-09-22 21:09:23 -07001636CTL_TSD_RO_NL_CGEN(config_stats, thread_allocated, tsd_thread_allocated_get,
1637 uint64_t)
1638CTL_TSD_RO_NL_CGEN(config_stats, thread_allocatedp, tsd_thread_allocatedp_get,
1639 uint64_t *)
1640CTL_TSD_RO_NL_CGEN(config_stats, thread_deallocated, tsd_thread_deallocated_get,
1641 uint64_t)
1642CTL_TSD_RO_NL_CGEN(config_stats, thread_deallocatedp,
1643 tsd_thread_deallocatedp_get, uint64_t *)
Jason Evans93443682010-10-20 17:39:18 -07001644
Jason Evansd8a39002013-12-19 21:40:41 -08001645static int
Jason Evansb2c0d632016-04-13 23:36:15 -07001646thread_tcache_enabled_ctl(tsd_t *tsd, const size_t *mib, size_t miblen,
Jason Evansc4c25922017-01-15 16:56:30 -08001647 void *oldp, size_t *oldlenp, void *newp, size_t newlen) {
Jason Evansd8a39002013-12-19 21:40:41 -08001648 int ret;
1649 bool oldval;
Jason Evans3c234352010-01-27 13:10:55 -08001650
Qi Wangfde3e202017-03-27 21:50:38 -07001651 oldval = tcache_enabled_get(tsd);
Jason Evansd8a39002013-12-19 21:40:41 -08001652 if (newp != NULL) {
1653 if (newlen != sizeof(bool)) {
1654 ret = EINVAL;
1655 goto label_return;
1656 }
Qi Wangfde3e202017-03-27 21:50:38 -07001657 tcache_enabled_set(tsd, *(bool *)newp);
Jason Evansd8a39002013-12-19 21:40:41 -08001658 }
1659 READ(oldval, bool);
Jason Evans3c234352010-01-27 13:10:55 -08001660
Jason Evansd8a39002013-12-19 21:40:41 -08001661 ret = 0;
1662label_return:
Jason Evansf4086432017-01-19 18:15:45 -08001663 return ret;
Jason Evansd8a39002013-12-19 21:40:41 -08001664}
1665
1666static int
Jason Evansb2c0d632016-04-13 23:36:15 -07001667thread_tcache_flush_ctl(tsd_t *tsd, const size_t *mib, size_t miblen,
Jason Evansc4c25922017-01-15 16:56:30 -08001668 void *oldp, size_t *oldlenp, void *newp, size_t newlen) {
Jason Evansd8a39002013-12-19 21:40:41 -08001669 int ret;
1670
Jason Evans4403c9a2017-04-20 17:21:37 -07001671 if (!tcache_available(tsd)) {
1672 ret = EFAULT;
1673 goto label_return;
Jason Evansc4c25922017-01-15 16:56:30 -08001674 }
Jason Evansd8a39002013-12-19 21:40:41 -08001675
1676 READONLY();
1677 WRITEONLY();
1678
1679 tcache_flush();
1680
1681 ret = 0;
1682label_return:
Jason Evansf4086432017-01-19 18:15:45 -08001683 return ret;
Jason Evansd8a39002013-12-19 21:40:41 -08001684}
Jason Evans3c234352010-01-27 13:10:55 -08001685
Jason Evans602c8e02014-08-18 16:22:13 -07001686static int
Jason Evansb2c0d632016-04-13 23:36:15 -07001687thread_prof_name_ctl(tsd_t *tsd, const size_t *mib, size_t miblen, void *oldp,
Jason Evansc4c25922017-01-15 16:56:30 -08001688 size_t *oldlenp, void *newp, size_t newlen) {
Jason Evans602c8e02014-08-18 16:22:13 -07001689 int ret;
Jason Evans602c8e02014-08-18 16:22:13 -07001690
Jason Evansc4c25922017-01-15 16:56:30 -08001691 if (!config_prof) {
Jason Evansf4086432017-01-19 18:15:45 -08001692 return ENOENT;
Jason Evansc4c25922017-01-15 16:56:30 -08001693 }
Jason Evans602c8e02014-08-18 16:22:13 -07001694
Jason Evansfc12c0b2014-10-03 23:25:30 -07001695 READ_XOR_WRITE();
1696
Jason Evans602c8e02014-08-18 16:22:13 -07001697 if (newp != NULL) {
1698 if (newlen != sizeof(const char *)) {
1699 ret = EINVAL;
1700 goto label_return;
1701 }
Jason Evans5460aa62014-09-22 21:09:23 -07001702
Jason Evansfc12c0b2014-10-03 23:25:30 -07001703 if ((ret = prof_thread_name_set(tsd, *(const char **)newp)) !=
Jason Evansc4c25922017-01-15 16:56:30 -08001704 0) {
Jason Evans602c8e02014-08-18 16:22:13 -07001705 goto label_return;
Jason Evansc4c25922017-01-15 16:56:30 -08001706 }
Jason Evansfc12c0b2014-10-03 23:25:30 -07001707 } else {
Jason Evansb2c0d632016-04-13 23:36:15 -07001708 const char *oldname = prof_thread_name_get(tsd);
Jason Evansfc12c0b2014-10-03 23:25:30 -07001709 READ(oldname, const char *);
Jason Evans602c8e02014-08-18 16:22:13 -07001710 }
Jason Evans602c8e02014-08-18 16:22:13 -07001711
1712 ret = 0;
1713label_return:
Jason Evansf4086432017-01-19 18:15:45 -08001714 return ret;
Jason Evans602c8e02014-08-18 16:22:13 -07001715}
1716
1717static int
Jason Evansb2c0d632016-04-13 23:36:15 -07001718thread_prof_active_ctl(tsd_t *tsd, const size_t *mib, size_t miblen, void *oldp,
Jason Evansc4c25922017-01-15 16:56:30 -08001719 size_t *oldlenp, void *newp, size_t newlen) {
Jason Evans602c8e02014-08-18 16:22:13 -07001720 int ret;
1721 bool oldval;
1722
Jason Evansc4c25922017-01-15 16:56:30 -08001723 if (!config_prof) {
Jason Evansf4086432017-01-19 18:15:45 -08001724 return ENOENT;
Jason Evansc4c25922017-01-15 16:56:30 -08001725 }
Jason Evans602c8e02014-08-18 16:22:13 -07001726
Jason Evansb2c0d632016-04-13 23:36:15 -07001727 oldval = prof_thread_active_get(tsd);
Jason Evans602c8e02014-08-18 16:22:13 -07001728 if (newp != NULL) {
1729 if (newlen != sizeof(bool)) {
1730 ret = EINVAL;
1731 goto label_return;
1732 }
Jason Evansb2c0d632016-04-13 23:36:15 -07001733 if (prof_thread_active_set(tsd, *(bool *)newp)) {
Jason Evans602c8e02014-08-18 16:22:13 -07001734 ret = EAGAIN;
1735 goto label_return;
1736 }
1737 }
1738 READ(oldval, bool);
1739
1740 ret = 0;
1741label_return:
Jason Evansf4086432017-01-19 18:15:45 -08001742 return ret;
Jason Evans602c8e02014-08-18 16:22:13 -07001743}
1744
Jason Evans3c234352010-01-27 13:10:55 -08001745/******************************************************************************/
1746
Jason Evans1cb181e2015-01-29 15:30:47 -08001747static int
Jason Evansb2c0d632016-04-13 23:36:15 -07001748tcache_create_ctl(tsd_t *tsd, const size_t *mib, size_t miblen, void *oldp,
Jason Evansc4c25922017-01-15 16:56:30 -08001749 size_t *oldlenp, void *newp, size_t newlen) {
Jason Evans1cb181e2015-01-29 15:30:47 -08001750 int ret;
Jason Evans1cb181e2015-01-29 15:30:47 -08001751 unsigned tcache_ind;
1752
Jason Evans1cb181e2015-01-29 15:30:47 -08001753 READONLY();
Jason Evansb54d1602016-10-20 23:59:12 -07001754 if (tcaches_create(tsd, &tcache_ind)) {
Jason Evans1cb181e2015-01-29 15:30:47 -08001755 ret = EFAULT;
1756 goto label_return;
1757 }
1758 READ(tcache_ind, unsigned);
1759
1760 ret = 0;
1761label_return:
Jason Evansf4086432017-01-19 18:15:45 -08001762 return ret;
Jason Evans1cb181e2015-01-29 15:30:47 -08001763}
1764
1765static int
Jason Evansb2c0d632016-04-13 23:36:15 -07001766tcache_flush_ctl(tsd_t *tsd, const size_t *mib, size_t miblen, void *oldp,
Jason Evansc4c25922017-01-15 16:56:30 -08001767 size_t *oldlenp, void *newp, size_t newlen) {
Jason Evans1cb181e2015-01-29 15:30:47 -08001768 int ret;
Jason Evans1cb181e2015-01-29 15:30:47 -08001769 unsigned tcache_ind;
1770
Jason Evans1cb181e2015-01-29 15:30:47 -08001771 WRITEONLY();
1772 tcache_ind = UINT_MAX;
1773 WRITE(tcache_ind, unsigned);
1774 if (tcache_ind == UINT_MAX) {
1775 ret = EFAULT;
1776 goto label_return;
1777 }
1778 tcaches_flush(tsd, tcache_ind);
1779
1780 ret = 0;
1781label_return:
Jason Evansf4086432017-01-19 18:15:45 -08001782 return ret;
Jason Evans1cb181e2015-01-29 15:30:47 -08001783}
1784
1785static int
Jason Evansb2c0d632016-04-13 23:36:15 -07001786tcache_destroy_ctl(tsd_t *tsd, const size_t *mib, size_t miblen, void *oldp,
Jason Evansc4c25922017-01-15 16:56:30 -08001787 size_t *oldlenp, void *newp, size_t newlen) {
Jason Evans1cb181e2015-01-29 15:30:47 -08001788 int ret;
Jason Evans1cb181e2015-01-29 15:30:47 -08001789 unsigned tcache_ind;
1790
Jason Evans1cb181e2015-01-29 15:30:47 -08001791 WRITEONLY();
1792 tcache_ind = UINT_MAX;
1793 WRITE(tcache_ind, unsigned);
1794 if (tcache_ind == UINT_MAX) {
1795 ret = EFAULT;
1796 goto label_return;
1797 }
1798 tcaches_destroy(tsd, tcache_ind);
1799
1800 ret = 0;
1801label_return:
Jason Evansf4086432017-01-19 18:15:45 -08001802 return ret;
Jason Evans1cb181e2015-01-29 15:30:47 -08001803}
1804
1805/******************************************************************************/
1806
Jason Evansdc2125c2017-01-04 10:21:53 -08001807static int
1808arena_i_initialized_ctl(tsd_t *tsd, const size_t *mib, size_t miblen,
Jason Evansc4c25922017-01-15 16:56:30 -08001809 void *oldp, size_t *oldlenp, void *newp, size_t newlen) {
Jason Evansdc2125c2017-01-04 10:21:53 -08001810 int ret;
1811 tsdn_t *tsdn = tsd_tsdn(tsd);
1812 unsigned arena_ind;
1813 bool initialized;
1814
1815 READONLY();
1816 MIB_UNSIGNED(arena_ind, 1);
1817
1818 malloc_mutex_lock(tsdn, &ctl_mtx);
Jason Evans9eb1b1c2017-01-18 23:03:37 -08001819 initialized = arenas_i(arena_ind)->initialized;
Jason Evansdc2125c2017-01-04 10:21:53 -08001820 malloc_mutex_unlock(tsdn, &ctl_mtx);
1821
1822 READ(initialized, bool);
1823
1824 ret = 0;
1825label_return:
Jason Evansf4086432017-01-19 18:15:45 -08001826 return ret;
Jason Evansdc2125c2017-01-04 10:21:53 -08001827}
1828
Jason Evans34457f52012-11-03 21:18:28 -07001829static void
Jason Evans64e458f2017-03-08 22:42:57 -08001830arena_i_decay(tsdn_t *tsdn, unsigned arena_ind, bool all) {
Jason Evansc1e00ef2016-05-10 22:21:10 -07001831 malloc_mutex_lock(tsdn, &ctl_mtx);
Jason Evans243f7a02016-02-19 20:09:31 -08001832 {
Jason Evans9eb1b1c2017-01-18 23:03:37 -08001833 unsigned narenas = ctl_arenas->narenas;
Jason Evans609ae592012-10-11 13:53:15 -07001834
Jason Evans3dc4e832017-01-03 07:27:42 -08001835 /*
1836 * Access via index narenas is deprecated, and scheduled for
1837 * removal in 6.0.0.
1838 */
1839 if (arena_ind == MALLCTL_ARENAS_ALL || arena_ind == narenas) {
Jason Evans243f7a02016-02-19 20:09:31 -08001840 unsigned i;
Jason Evans243f7a02016-02-19 20:09:31 -08001841 VARIABLE_ARRAY(arena_t *, tarenas, narenas);
1842
Jason Evansc4c25922017-01-15 16:56:30 -08001843 for (i = 0; i < narenas; i++) {
Jason Evansc1e00ef2016-05-10 22:21:10 -07001844 tarenas[i] = arena_get(tsdn, i, false);
Jason Evansc4c25922017-01-15 16:56:30 -08001845 }
Jason Evans243f7a02016-02-19 20:09:31 -08001846
1847 /*
1848 * No further need to hold ctl_mtx, since narenas and
1849 * tarenas contain everything needed below.
1850 */
Jason Evansc1e00ef2016-05-10 22:21:10 -07001851 malloc_mutex_unlock(tsdn, &ctl_mtx);
Jason Evans243f7a02016-02-19 20:09:31 -08001852
1853 for (i = 0; i < narenas; i++) {
Jason Evansc4c25922017-01-15 16:56:30 -08001854 if (tarenas[i] != NULL) {
Qi Wangb693c782017-03-17 12:42:33 -07001855 arena_decay(tsdn, tarenas[i], false,
1856 all);
Jason Evansc4c25922017-01-15 16:56:30 -08001857 }
Jason Evans243f7a02016-02-19 20:09:31 -08001858 }
1859 } else {
1860 arena_t *tarena;
1861
1862 assert(arena_ind < narenas);
1863
Jason Evansc1e00ef2016-05-10 22:21:10 -07001864 tarena = arena_get(tsdn, arena_ind, false);
Jason Evans243f7a02016-02-19 20:09:31 -08001865
1866 /* No further need to hold ctl_mtx. */
Jason Evansc1e00ef2016-05-10 22:21:10 -07001867 malloc_mutex_unlock(tsdn, &ctl_mtx);
Jason Evans243f7a02016-02-19 20:09:31 -08001868
Jason Evansc4c25922017-01-15 16:56:30 -08001869 if (tarena != NULL) {
Qi Wangb693c782017-03-17 12:42:33 -07001870 arena_decay(tsdn, tarena, false, all);
Jason Evansc4c25922017-01-15 16:56:30 -08001871 }
Jason Evans609ae592012-10-11 13:53:15 -07001872 }
1873 }
Jason Evans609ae592012-10-11 13:53:15 -07001874}
1875
1876static int
Jason Evansb2c0d632016-04-13 23:36:15 -07001877arena_i_decay_ctl(tsd_t *tsd, const size_t *mib, size_t miblen, void *oldp,
Jason Evansc4c25922017-01-15 16:56:30 -08001878 size_t *oldlenp, void *newp, size_t newlen) {
Jason Evans243f7a02016-02-19 20:09:31 -08001879 int ret;
Jason Evans6edbedd2017-01-04 07:51:49 -08001880 unsigned arena_ind;
Jason Evans243f7a02016-02-19 20:09:31 -08001881
1882 READONLY();
1883 WRITEONLY();
Jason Evans6edbedd2017-01-04 07:51:49 -08001884 MIB_UNSIGNED(arena_ind, 1);
Jason Evans64e458f2017-03-08 22:42:57 -08001885 arena_i_decay(tsd_tsdn(tsd), arena_ind, false);
1886
1887 ret = 0;
1888label_return:
1889 return ret;
1890}
1891
1892static int
1893arena_i_purge_ctl(tsd_t *tsd, const size_t *mib, size_t miblen, void *oldp,
1894 size_t *oldlenp, void *newp, size_t newlen) {
1895 int ret;
1896 unsigned arena_ind;
1897
1898 READONLY();
1899 WRITEONLY();
1900 MIB_UNSIGNED(arena_ind, 1);
1901 arena_i_decay(tsd_tsdn(tsd), arena_ind, true);
Jason Evans609ae592012-10-11 13:53:15 -07001902
Jason Evans34457f52012-11-03 21:18:28 -07001903 ret = 0;
Jason Evans609ae592012-10-11 13:53:15 -07001904label_return:
Jason Evansf4086432017-01-19 18:15:45 -08001905 return ret;
Jason Evans609ae592012-10-11 13:53:15 -07001906}
1907
1908static int
Jason Evansedf1baf2017-01-03 17:21:59 -08001909arena_i_reset_destroy_helper(tsd_t *tsd, const size_t *mib, size_t miblen,
1910 void *oldp, size_t *oldlenp, void *newp, size_t newlen, unsigned *arena_ind,
Jason Evansc4c25922017-01-15 16:56:30 -08001911 arena_t **arena) {
Jason Evansedf1baf2017-01-03 17:21:59 -08001912 int ret;
1913
1914 READONLY();
1915 WRITEONLY();
1916 MIB_UNSIGNED(*arena_ind, 1);
1917
Jason Evansedf1baf2017-01-03 17:21:59 -08001918 *arena = arena_get(tsd_tsdn(tsd), *arena_ind, false);
Qi Wang5aa46f02017-04-20 15:19:02 -07001919 if (*arena == NULL || arena_is_auto(*arena)) {
Jason Evansedf1baf2017-01-03 17:21:59 -08001920 ret = EFAULT;
1921 goto label_return;
1922 }
1923
1924 ret = 0;
1925label_return:
Jason Evansf4086432017-01-19 18:15:45 -08001926 return ret;
Jason Evansedf1baf2017-01-03 17:21:59 -08001927}
1928
Qi Wangb693c782017-03-17 12:42:33 -07001929static void
1930arena_reset_prepare_background_thread(tsd_t *tsd, unsigned arena_ind) {
1931 /* Temporarily disable the background thread during arena reset. */
1932 if (have_background_thread) {
1933 malloc_mutex_lock(tsd_tsdn(tsd), &background_thread_lock);
1934 if (background_thread_enabled()) {
1935 unsigned ind = arena_ind % ncpus;
1936 background_thread_info_t *info =
1937 &background_thread_info[ind];
1938 assert(info->started);
1939 background_threads_disable_single(tsd, info);
1940 }
1941 }
1942}
1943
1944static void
1945arena_reset_finish_background_thread(tsd_t *tsd, unsigned arena_ind) {
1946 if (have_background_thread) {
1947 if (background_thread_enabled()) {
1948 unsigned ind = arena_ind % ncpus;
1949 background_thread_info_t *info =
1950 &background_thread_info[ind];
1951 assert(!info->started);
1952 background_thread_create(tsd, ind);
1953 }
1954 malloc_mutex_unlock(tsd_tsdn(tsd), &background_thread_lock);
1955 }
1956}
1957
Jason Evansedf1baf2017-01-03 17:21:59 -08001958static int
Jason Evans19ff2ce2016-04-22 14:37:17 -07001959arena_i_reset_ctl(tsd_t *tsd, const size_t *mib, size_t miblen, void *oldp,
Jason Evansc4c25922017-01-15 16:56:30 -08001960 size_t *oldlenp, void *newp, size_t newlen) {
Jason Evans19ff2ce2016-04-22 14:37:17 -07001961 int ret;
1962 unsigned arena_ind;
1963 arena_t *arena;
1964
Jason Evansedf1baf2017-01-03 17:21:59 -08001965 ret = arena_i_reset_destroy_helper(tsd, mib, miblen, oldp, oldlenp,
1966 newp, newlen, &arena_ind, &arena);
Jason Evansc4c25922017-01-15 16:56:30 -08001967 if (ret != 0) {
Jason Evansf4086432017-01-19 18:15:45 -08001968 return ret;
Jason Evansc4c25922017-01-15 16:56:30 -08001969 }
Jason Evans19ff2ce2016-04-22 14:37:17 -07001970
Qi Wangb693c782017-03-17 12:42:33 -07001971 arena_reset_prepare_background_thread(tsd, arena_ind);
Jason Evansedf1baf2017-01-03 17:21:59 -08001972 arena_reset(tsd, arena);
Qi Wangb693c782017-03-17 12:42:33 -07001973 arena_reset_finish_background_thread(tsd, arena_ind);
Jason Evans19ff2ce2016-04-22 14:37:17 -07001974
Jason Evansf4086432017-01-19 18:15:45 -08001975 return ret;
Jason Evansedf1baf2017-01-03 17:21:59 -08001976}
1977
1978static int
1979arena_i_destroy_ctl(tsd_t *tsd, const size_t *mib, size_t miblen, void *oldp,
Jason Evansc4c25922017-01-15 16:56:30 -08001980 size_t *oldlenp, void *newp, size_t newlen) {
Jason Evansedf1baf2017-01-03 17:21:59 -08001981 int ret;
1982 unsigned arena_ind;
1983 arena_t *arena;
Jason Evans9eb1b1c2017-01-18 23:03:37 -08001984 ctl_arena_t *ctl_darena, *ctl_arena;
Jason Evansedf1baf2017-01-03 17:21:59 -08001985
1986 ret = arena_i_reset_destroy_helper(tsd, mib, miblen, oldp, oldlenp,
1987 newp, newlen, &arena_ind, &arena);
Jason Evansc4c25922017-01-15 16:56:30 -08001988 if (ret != 0) {
Jason Evansedf1baf2017-01-03 17:21:59 -08001989 goto label_return;
Jason Evansc4c25922017-01-15 16:56:30 -08001990 }
Jason Evansedf1baf2017-01-03 17:21:59 -08001991
1992 if (arena_nthreads_get(arena, false) != 0 || arena_nthreads_get(arena,
1993 true) != 0) {
Jason Evans3dc4e832017-01-03 07:27:42 -08001994 ret = EFAULT;
1995 goto label_return;
1996 }
Jason Evans19ff2ce2016-04-22 14:37:17 -07001997
Qi Wangb693c782017-03-17 12:42:33 -07001998 arena_reset_prepare_background_thread(tsd, arena_ind);
Jason Evansedf1baf2017-01-03 17:21:59 -08001999 /* Merge stats after resetting and purging arena. */
Jason Evans19ff2ce2016-04-22 14:37:17 -07002000 arena_reset(tsd, arena);
Qi Wangb693c782017-03-17 12:42:33 -07002001 arena_decay(tsd_tsdn(tsd), arena, false, true);
Jason Evans9eb1b1c2017-01-18 23:03:37 -08002002 ctl_darena = arenas_i(MALLCTL_ARENAS_DESTROYED);
2003 ctl_darena->initialized = true;
2004 ctl_arena_refresh(tsd_tsdn(tsd), arena, ctl_darena, arena_ind, true);
Jason Evansedf1baf2017-01-03 17:21:59 -08002005 /* Destroy arena. */
2006 arena_destroy(tsd, arena);
Jason Evans9eb1b1c2017-01-18 23:03:37 -08002007 ctl_arena = arenas_i(arena_ind);
2008 ctl_arena->initialized = false;
Jason Evansedf1baf2017-01-03 17:21:59 -08002009 /* Record arena index for later recycling via arenas.create. */
Jason Evans9eb1b1c2017-01-18 23:03:37 -08002010 ql_elm_new(ctl_arena, destroyed_link);
2011 ql_tail_insert(&ctl_arenas->destroyed, ctl_arena, destroyed_link);
Qi Wangb693c782017-03-17 12:42:33 -07002012 arena_reset_finish_background_thread(tsd, arena_ind);
Jason Evans19ff2ce2016-04-22 14:37:17 -07002013
Jason Evansedf1baf2017-01-03 17:21:59 -08002014 assert(ret == 0);
Jason Evans19ff2ce2016-04-22 14:37:17 -07002015label_return:
Jason Evansf4086432017-01-19 18:15:45 -08002016 return ret;
Jason Evans19ff2ce2016-04-22 14:37:17 -07002017}
2018
2019static int
Jason Evansb2c0d632016-04-13 23:36:15 -07002020arena_i_dss_ctl(tsd_t *tsd, const size_t *mib, size_t miblen, void *oldp,
Jason Evansc4c25922017-01-15 16:56:30 -08002021 size_t *oldlenp, void *newp, size_t newlen) {
Jason Evans586c8ed2014-08-15 12:20:20 -07002022 int ret;
2023 const char *dss = NULL;
Jason Evans6edbedd2017-01-04 07:51:49 -08002024 unsigned arena_ind;
Jason Evans609ae592012-10-11 13:53:15 -07002025 dss_prec_t dss_prec_old = dss_prec_limit;
2026 dss_prec_t dss_prec = dss_prec_limit;
2027
Jason Evansc1e00ef2016-05-10 22:21:10 -07002028 malloc_mutex_lock(tsd_tsdn(tsd), &ctl_mtx);
Jason Evans609ae592012-10-11 13:53:15 -07002029 WRITE(dss, const char *);
Jason Evans6edbedd2017-01-04 07:51:49 -08002030 MIB_UNSIGNED(arena_ind, 1);
Jason Evans586c8ed2014-08-15 12:20:20 -07002031 if (dss != NULL) {
2032 int i;
2033 bool match = false;
2034
2035 for (i = 0; i < dss_prec_limit; i++) {
2036 if (strcmp(dss_prec_names[i], dss) == 0) {
2037 dss_prec = i;
2038 match = true;
2039 break;
2040 }
Jason Evans609ae592012-10-11 13:53:15 -07002041 }
Jason Evans586c8ed2014-08-15 12:20:20 -07002042
Jason Evans551ebc42014-10-03 10:16:09 -07002043 if (!match) {
Jason Evans586c8ed2014-08-15 12:20:20 -07002044 ret = EINVAL;
2045 goto label_return;
2046 }
Jason Evans609ae592012-10-11 13:53:15 -07002047 }
2048
Jason Evans3dc4e832017-01-03 07:27:42 -08002049 /*
2050 * Access via index narenas is deprecated, and scheduled for removal in
2051 * 6.0.0.
2052 */
Jason Evansd778dd22017-01-03 12:40:54 -08002053 if (arena_ind == MALLCTL_ARENAS_ALL || arena_ind ==
Jason Evans9eb1b1c2017-01-18 23:03:37 -08002054 ctl_arenas->narenas) {
Jason Evans3dc4e832017-01-03 07:27:42 -08002055 if (dss_prec != dss_prec_limit &&
2056 extent_dss_prec_set(dss_prec)) {
2057 ret = EFAULT;
2058 goto label_return;
2059 }
2060 dss_prec_old = extent_dss_prec_get();
2061 } else {
Jason Evansc1e00ef2016-05-10 22:21:10 -07002062 arena_t *arena = arena_get(tsd_tsdn(tsd), arena_ind, false);
Jason Evans586c8ed2014-08-15 12:20:20 -07002063 if (arena == NULL || (dss_prec != dss_prec_limit &&
Jason Evansb7795222017-02-12 16:34:36 -08002064 arena_dss_prec_set(arena, dss_prec))) {
Jason Evans586c8ed2014-08-15 12:20:20 -07002065 ret = EFAULT;
2066 goto label_return;
2067 }
Jason Evansb7795222017-02-12 16:34:36 -08002068 dss_prec_old = arena_dss_prec_get(arena);
Jason Evans609ae592012-10-11 13:53:15 -07002069 }
Jason Evans586c8ed2014-08-15 12:20:20 -07002070
Jason Evans609ae592012-10-11 13:53:15 -07002071 dss = dss_prec_names[dss_prec_old];
2072 READ(dss, const char *);
Jason Evans609ae592012-10-11 13:53:15 -07002073
2074 ret = 0;
2075label_return:
Jason Evansc1e00ef2016-05-10 22:21:10 -07002076 malloc_mutex_unlock(tsd_tsdn(tsd), &ctl_mtx);
Jason Evansf4086432017-01-19 18:15:45 -08002077 return ret;
Jason Evans609ae592012-10-11 13:53:15 -07002078}
2079
aravindfb7fe502014-05-05 15:16:56 -07002080static int
Jason Evans6e62c622017-05-17 10:47:00 -07002081arena_i_decay_ms_ctl_impl(tsd_t *tsd, const size_t *mib, size_t miblen,
Jason Evans64e458f2017-03-08 22:42:57 -08002082 void *oldp, size_t *oldlenp, void *newp, size_t newlen, bool dirty) {
Jason Evans243f7a02016-02-19 20:09:31 -08002083 int ret;
Jason Evans6edbedd2017-01-04 07:51:49 -08002084 unsigned arena_ind;
Jason Evans243f7a02016-02-19 20:09:31 -08002085 arena_t *arena;
2086
Jason Evans6edbedd2017-01-04 07:51:49 -08002087 MIB_UNSIGNED(arena_ind, 1);
Jason Evansc1e00ef2016-05-10 22:21:10 -07002088 arena = arena_get(tsd_tsdn(tsd), arena_ind, false);
Jason Evans243f7a02016-02-19 20:09:31 -08002089 if (arena == NULL) {
2090 ret = EFAULT;
2091 goto label_return;
2092 }
2093
2094 if (oldp != NULL && oldlenp != NULL) {
Jason Evans6e62c622017-05-17 10:47:00 -07002095 size_t oldval = dirty ? arena_dirty_decay_ms_get(arena) :
2096 arena_muzzy_decay_ms_get(arena);
Jason Evans243f7a02016-02-19 20:09:31 -08002097 READ(oldval, ssize_t);
2098 }
2099 if (newp != NULL) {
2100 if (newlen != sizeof(ssize_t)) {
2101 ret = EINVAL;
2102 goto label_return;
2103 }
Jason Evans6e62c622017-05-17 10:47:00 -07002104 if (dirty ? arena_dirty_decay_ms_set(tsd_tsdn(tsd), arena,
2105 *(ssize_t *)newp) : arena_muzzy_decay_ms_set(tsd_tsdn(tsd),
2106 arena, *(ssize_t *)newp)) {
Jason Evans243f7a02016-02-19 20:09:31 -08002107 ret = EFAULT;
2108 goto label_return;
2109 }
2110 }
2111
2112 ret = 0;
2113label_return:
Jason Evansf4086432017-01-19 18:15:45 -08002114 return ret;
Jason Evans243f7a02016-02-19 20:09:31 -08002115}
2116
2117static int
Jason Evans6e62c622017-05-17 10:47:00 -07002118arena_i_dirty_decay_ms_ctl(tsd_t *tsd, const size_t *mib, size_t miblen,
Jason Evans64e458f2017-03-08 22:42:57 -08002119 void *oldp, size_t *oldlenp, void *newp, size_t newlen) {
Jason Evans6e62c622017-05-17 10:47:00 -07002120 return arena_i_decay_ms_ctl_impl(tsd, mib, miblen, oldp, oldlenp, newp,
2121 newlen, true);
Jason Evans64e458f2017-03-08 22:42:57 -08002122}
2123
2124static int
Jason Evans6e62c622017-05-17 10:47:00 -07002125arena_i_muzzy_decay_ms_ctl(tsd_t *tsd, const size_t *mib, size_t miblen,
Jason Evans64e458f2017-03-08 22:42:57 -08002126 void *oldp, size_t *oldlenp, void *newp, size_t newlen) {
Jason Evans6e62c622017-05-17 10:47:00 -07002127 return arena_i_decay_ms_ctl_impl(tsd, mib, miblen, oldp, oldlenp, newp,
2128 newlen, false);
Jason Evans64e458f2017-03-08 22:42:57 -08002129}
2130
2131static int
Jason Evans9c305c92016-05-31 15:03:51 -07002132arena_i_extent_hooks_ctl(tsd_t *tsd, const size_t *mib, size_t miblen,
Jason Evansc4c25922017-01-15 16:56:30 -08002133 void *oldp, size_t *oldlenp, void *newp, size_t newlen) {
Jason Evansb49a3342015-07-28 11:28:19 -04002134 int ret;
Jason Evans6edbedd2017-01-04 07:51:49 -08002135 unsigned arena_ind;
Jason Evansb49a3342015-07-28 11:28:19 -04002136 arena_t *arena;
2137
Jason Evansc1e00ef2016-05-10 22:21:10 -07002138 malloc_mutex_lock(tsd_tsdn(tsd), &ctl_mtx);
Jason Evans6edbedd2017-01-04 07:51:49 -08002139 MIB_UNSIGNED(arena_ind, 1);
Jason Evansb49a3342015-07-28 11:28:19 -04002140 if (arena_ind < narenas_total_get() && (arena =
Jason Evansc1e00ef2016-05-10 22:21:10 -07002141 arena_get(tsd_tsdn(tsd), arena_ind, false)) != NULL) {
Jason Evansb49a3342015-07-28 11:28:19 -04002142 if (newp != NULL) {
Jason Evansf02fec82016-06-03 19:39:14 -07002143 extent_hooks_t *old_extent_hooks;
2144 extent_hooks_t *new_extent_hooks
2145 JEMALLOC_CC_SILENCE_INIT(NULL);
Jason Evansf8f05422016-06-03 12:05:53 -07002146 WRITE(new_extent_hooks, extent_hooks_t *);
2147 old_extent_hooks = extent_hooks_set(arena,
2148 new_extent_hooks);
2149 READ(old_extent_hooks, extent_hooks_t *);
Jason Evansb49a3342015-07-28 11:28:19 -04002150 } else {
Jason Evansf8f05422016-06-03 12:05:53 -07002151 extent_hooks_t *old_extent_hooks =
2152 extent_hooks_get(arena);
2153 READ(old_extent_hooks, extent_hooks_t *);
Jason Evansb49a3342015-07-28 11:28:19 -04002154 }
2155 } else {
2156 ret = EFAULT;
2157 goto label_return;
2158 }
2159 ret = 0;
2160label_return:
Jason Evansc1e00ef2016-05-10 22:21:10 -07002161 malloc_mutex_unlock(tsd_tsdn(tsd), &ctl_mtx);
Jason Evansf4086432017-01-19 18:15:45 -08002162 return ret;
aravindfb7fe502014-05-05 15:16:56 -07002163}
2164
Jason Evans609ae592012-10-11 13:53:15 -07002165static const ctl_named_node_t *
Jason Evansc4c25922017-01-15 16:56:30 -08002166arena_i_index(tsdn_t *tsdn, const size_t *mib, size_t miblen, size_t i) {
Jason Evansb2c0d632016-04-13 23:36:15 -07002167 const ctl_named_node_t *ret;
Jason Evans609ae592012-10-11 13:53:15 -07002168
Jason Evansc1e00ef2016-05-10 22:21:10 -07002169 malloc_mutex_lock(tsdn, &ctl_mtx);
Jason Evansedf1baf2017-01-03 17:21:59 -08002170 switch (i) {
2171 case MALLCTL_ARENAS_ALL:
2172 case MALLCTL_ARENAS_DESTROYED:
2173 break;
2174 default:
Jason Evans9eb1b1c2017-01-18 23:03:37 -08002175 if (i > ctl_arenas->narenas) {
Jason Evansedf1baf2017-01-03 17:21:59 -08002176 ret = NULL;
2177 goto label_return;
2178 }
2179 break;
Jason Evans609ae592012-10-11 13:53:15 -07002180 }
2181
2182 ret = super_arena_i_node;
2183label_return:
Jason Evansc1e00ef2016-05-10 22:21:10 -07002184 malloc_mutex_unlock(tsdn, &ctl_mtx);
Jason Evansf4086432017-01-19 18:15:45 -08002185 return ret;
Jason Evans609ae592012-10-11 13:53:15 -07002186}
2187
Jason Evans609ae592012-10-11 13:53:15 -07002188/******************************************************************************/
2189
Jason Evans609ae592012-10-11 13:53:15 -07002190static int
Jason Evansb2c0d632016-04-13 23:36:15 -07002191arenas_narenas_ctl(tsd_t *tsd, const size_t *mib, size_t miblen, void *oldp,
Jason Evansc4c25922017-01-15 16:56:30 -08002192 size_t *oldlenp, void *newp, size_t newlen) {
Jason Evans609ae592012-10-11 13:53:15 -07002193 int ret;
2194 unsigned narenas;
2195
Jason Evansc1e00ef2016-05-10 22:21:10 -07002196 malloc_mutex_lock(tsd_tsdn(tsd), &ctl_mtx);
Jason Evans609ae592012-10-11 13:53:15 -07002197 READONLY();
2198 if (*oldlenp != sizeof(unsigned)) {
2199 ret = EINVAL;
2200 goto label_return;
2201 }
Jason Evans9eb1b1c2017-01-18 23:03:37 -08002202 narenas = ctl_arenas->narenas;
Jason Evans609ae592012-10-11 13:53:15 -07002203 READ(narenas, unsigned);
2204
2205 ret = 0;
2206label_return:
Jason Evansc1e00ef2016-05-10 22:21:10 -07002207 malloc_mutex_unlock(tsd_tsdn(tsd), &ctl_mtx);
Jason Evansf4086432017-01-19 18:15:45 -08002208 return ret;
Jason Evans609ae592012-10-11 13:53:15 -07002209}
Jason Evans3c234352010-01-27 13:10:55 -08002210
2211static int
Jason Evans6e62c622017-05-17 10:47:00 -07002212arenas_decay_ms_ctl_impl(tsd_t *tsd, const size_t *mib, size_t miblen,
Jason Evans64e458f2017-03-08 22:42:57 -08002213 void *oldp, size_t *oldlenp, void *newp, size_t newlen, bool dirty) {
Jason Evans243f7a02016-02-19 20:09:31 -08002214 int ret;
2215
2216 if (oldp != NULL && oldlenp != NULL) {
Jason Evans6e62c622017-05-17 10:47:00 -07002217 size_t oldval = (dirty ? arena_dirty_decay_ms_default_get() :
2218 arena_muzzy_decay_ms_default_get());
Jason Evans243f7a02016-02-19 20:09:31 -08002219 READ(oldval, ssize_t);
2220 }
2221 if (newp != NULL) {
2222 if (newlen != sizeof(ssize_t)) {
2223 ret = EINVAL;
2224 goto label_return;
2225 }
Jason Evans6e62c622017-05-17 10:47:00 -07002226 if (dirty ? arena_dirty_decay_ms_default_set(*(ssize_t *)newp)
2227 : arena_muzzy_decay_ms_default_set(*(ssize_t *)newp)) {
Jason Evans243f7a02016-02-19 20:09:31 -08002228 ret = EFAULT;
2229 goto label_return;
2230 }
2231 }
2232
2233 ret = 0;
2234label_return:
Jason Evansf4086432017-01-19 18:15:45 -08002235 return ret;
Jason Evans243f7a02016-02-19 20:09:31 -08002236}
2237
Jason Evans64e458f2017-03-08 22:42:57 -08002238static int
Jason Evans6e62c622017-05-17 10:47:00 -07002239arenas_dirty_decay_ms_ctl(tsd_t *tsd, const size_t *mib, size_t miblen,
Jason Evans64e458f2017-03-08 22:42:57 -08002240 void *oldp, size_t *oldlenp, void *newp, size_t newlen) {
Jason Evans6e62c622017-05-17 10:47:00 -07002241 return arenas_decay_ms_ctl_impl(tsd, mib, miblen, oldp, oldlenp, newp,
Jason Evans64e458f2017-03-08 22:42:57 -08002242 newlen, true);
2243}
2244
2245static int
Jason Evans6e62c622017-05-17 10:47:00 -07002246arenas_muzzy_decay_ms_ctl(tsd_t *tsd, const size_t *mib, size_t miblen,
Jason Evans64e458f2017-03-08 22:42:57 -08002247 void *oldp, size_t *oldlenp, void *newp, size_t newlen) {
Jason Evans6e62c622017-05-17 10:47:00 -07002248 return arenas_decay_ms_ctl_impl(tsd, mib, miblen, oldp, oldlenp, newp,
Jason Evans64e458f2017-03-08 22:42:57 -08002249 newlen, false);
2250}
2251
Jason Evansfc4dcfa2010-11-24 15:44:21 -08002252CTL_RO_NL_GEN(arenas_quantum, QUANTUM, size_t)
Jason Evansae4c7b42012-04-02 07:04:34 -07002253CTL_RO_NL_GEN(arenas_page, PAGE, size_t)
Jason Evans4403c9a2017-04-20 17:21:37 -07002254CTL_RO_NL_GEN(arenas_tcache_max, tcache_maxclass, size_t)
Jason Evansb1726102012-02-28 16:50:47 -08002255CTL_RO_NL_GEN(arenas_nbins, NBINS, unsigned)
Jason Evans4403c9a2017-04-20 17:21:37 -07002256CTL_RO_NL_GEN(arenas_nhbins, nhbins, unsigned)
Jason Evansd8a39002013-12-19 21:40:41 -08002257CTL_RO_NL_GEN(arenas_bin_i_size, arena_bin_info[mib[2]].reg_size, size_t)
2258CTL_RO_NL_GEN(arenas_bin_i_nregs, arena_bin_info[mib[2]].nregs, uint32_t)
Jason Evans498856f2016-05-29 18:34:50 -07002259CTL_RO_NL_GEN(arenas_bin_i_slab_size, arena_bin_info[mib[2]].slab_size, size_t)
Jason Evansd8a39002013-12-19 21:40:41 -08002260static const ctl_named_node_t *
Jason Evansc4c25922017-01-15 16:56:30 -08002261arenas_bin_i_index(tsdn_t *tsdn, const size_t *mib, size_t miblen, size_t i) {
2262 if (i > NBINS) {
Jason Evansf4086432017-01-19 18:15:45 -08002263 return NULL;
Jason Evansc4c25922017-01-15 16:56:30 -08002264 }
Jason Evansf4086432017-01-19 18:15:45 -08002265 return super_arenas_bin_i_node;
Jason Evansd8a39002013-12-19 21:40:41 -08002266}
2267
Jason Evans7d63fed2016-05-31 14:50:21 -07002268CTL_RO_NL_GEN(arenas_nlextents, NSIZES - NBINS, unsigned)
2269CTL_RO_NL_GEN(arenas_lextent_i_size, index2size(NBINS+(szind_t)mib[2]), size_t)
Jason Evans3c4d92e2014-10-12 22:53:59 -07002270static const ctl_named_node_t *
Jason Evansc4c25922017-01-15 16:56:30 -08002271arenas_lextent_i_index(tsdn_t *tsdn, const size_t *mib, size_t miblen,
2272 size_t i) {
2273 if (i > NSIZES - NBINS) {
Jason Evansf4086432017-01-19 18:15:45 -08002274 return NULL;
Jason Evansc4c25922017-01-15 16:56:30 -08002275 }
Jason Evansf4086432017-01-19 18:15:45 -08002276 return super_arenas_lextent_i_node;
Jason Evans3c4d92e2014-10-12 22:53:59 -07002277}
2278
Jason Evans6005f072010-09-30 16:55:08 -07002279static int
Jason Evans0f04bb12017-01-03 08:21:29 -08002280arenas_create_ctl(tsd_t *tsd, const size_t *mib, size_t miblen, void *oldp,
Jason Evansc4c25922017-01-15 16:56:30 -08002281 size_t *oldlenp, void *newp, size_t newlen) {
Jason Evans609ae592012-10-11 13:53:15 -07002282 int ret;
Jason Evansa0dd3a42016-12-22 16:39:10 -06002283 extent_hooks_t *extent_hooks;
Jason Evansedf1baf2017-01-03 17:21:59 -08002284 unsigned arena_ind;
Jason Evans609ae592012-10-11 13:53:15 -07002285
Jason Evansc1e00ef2016-05-10 22:21:10 -07002286 malloc_mutex_lock(tsd_tsdn(tsd), &ctl_mtx);
Jason Evansa0dd3a42016-12-22 16:39:10 -06002287
2288 extent_hooks = (extent_hooks_t *)&extent_hooks_default;
2289 WRITE(extent_hooks, extent_hooks_t *);
Jason Evansedf1baf2017-01-03 17:21:59 -08002290 if ((arena_ind = ctl_arena_init(tsd_tsdn(tsd), extent_hooks)) ==
2291 UINT_MAX) {
Jason Evans609ae592012-10-11 13:53:15 -07002292 ret = EAGAIN;
2293 goto label_return;
2294 }
Jason Evansedf1baf2017-01-03 17:21:59 -08002295 READ(arena_ind, unsigned);
Jason Evans609ae592012-10-11 13:53:15 -07002296
Jason Evans6005f072010-09-30 16:55:08 -07002297 ret = 0;
Jason Evansa1ee7832012-04-10 15:07:44 -07002298label_return:
Jason Evansc1e00ef2016-05-10 22:21:10 -07002299 malloc_mutex_unlock(tsd_tsdn(tsd), &ctl_mtx);
Jason Evansf4086432017-01-19 18:15:45 -08002300 return ret;
Jason Evans6005f072010-09-30 16:55:08 -07002301}
2302
Jason Evans3c234352010-01-27 13:10:55 -08002303/******************************************************************************/
2304
Jason Evansd34f9e72010-02-11 13:19:21 -08002305static int
Jason Evansb2c0d632016-04-13 23:36:15 -07002306prof_thread_active_init_ctl(tsd_t *tsd, const size_t *mib, size_t miblen,
Jason Evansc4c25922017-01-15 16:56:30 -08002307 void *oldp, size_t *oldlenp, void *newp, size_t newlen) {
Jason Evansb2c0d632016-04-13 23:36:15 -07002308 int ret;
2309 bool oldval;
2310
Jason Evansc4c25922017-01-15 16:56:30 -08002311 if (!config_prof) {
Jason Evansf4086432017-01-19 18:15:45 -08002312 return ENOENT;
Jason Evansc4c25922017-01-15 16:56:30 -08002313 }
Jason Evansb2c0d632016-04-13 23:36:15 -07002314
2315 if (newp != NULL) {
2316 if (newlen != sizeof(bool)) {
2317 ret = EINVAL;
2318 goto label_return;
2319 }
Jason Evansc1e00ef2016-05-10 22:21:10 -07002320 oldval = prof_thread_active_init_set(tsd_tsdn(tsd),
2321 *(bool *)newp);
Jason Evansc4c25922017-01-15 16:56:30 -08002322 } else {
Jason Evansc1e00ef2016-05-10 22:21:10 -07002323 oldval = prof_thread_active_init_get(tsd_tsdn(tsd));
Jason Evansc4c25922017-01-15 16:56:30 -08002324 }
Jason Evansb2c0d632016-04-13 23:36:15 -07002325 READ(oldval, bool);
2326
2327 ret = 0;
2328label_return:
Jason Evansf4086432017-01-19 18:15:45 -08002329 return ret;
Jason Evansb2c0d632016-04-13 23:36:15 -07002330}
2331
2332static int
2333prof_active_ctl(tsd_t *tsd, const size_t *mib, size_t miblen, void *oldp,
Jason Evansc4c25922017-01-15 16:56:30 -08002334 size_t *oldlenp, void *newp, size_t newlen) {
Jason Evansfc12c0b2014-10-03 23:25:30 -07002335 int ret;
2336 bool oldval;
2337
Jason Evansc4c25922017-01-15 16:56:30 -08002338 if (!config_prof) {
Jason Evansf4086432017-01-19 18:15:45 -08002339 return ENOENT;
Jason Evansc4c25922017-01-15 16:56:30 -08002340 }
Jason Evansfc12c0b2014-10-03 23:25:30 -07002341
2342 if (newp != NULL) {
2343 if (newlen != sizeof(bool)) {
2344 ret = EINVAL;
2345 goto label_return;
2346 }
Jason Evansc1e00ef2016-05-10 22:21:10 -07002347 oldval = prof_active_set(tsd_tsdn(tsd), *(bool *)newp);
Jason Evansc4c25922017-01-15 16:56:30 -08002348 } else {
Jason Evansc1e00ef2016-05-10 22:21:10 -07002349 oldval = prof_active_get(tsd_tsdn(tsd));
Jason Evansc4c25922017-01-15 16:56:30 -08002350 }
Jason Evansfc12c0b2014-10-03 23:25:30 -07002351 READ(oldval, bool);
2352
2353 ret = 0;
2354label_return:
Jason Evansf4086432017-01-19 18:15:45 -08002355 return ret;
Jason Evansfc12c0b2014-10-03 23:25:30 -07002356}
2357
2358static int
Jason Evansb2c0d632016-04-13 23:36:15 -07002359prof_dump_ctl(tsd_t *tsd, const size_t *mib, size_t miblen, void *oldp,
Jason Evansc4c25922017-01-15 16:56:30 -08002360 size_t *oldlenp, void *newp, size_t newlen) {
Jason Evansd34f9e72010-02-11 13:19:21 -08002361 int ret;
Jason Evans22ca8552010-03-02 11:57:30 -08002362 const char *filename = NULL;
Jason Evansd34f9e72010-02-11 13:19:21 -08002363
Jason Evansc4c25922017-01-15 16:56:30 -08002364 if (!config_prof) {
Jason Evansf4086432017-01-19 18:15:45 -08002365 return ENOENT;
Jason Evansc4c25922017-01-15 16:56:30 -08002366 }
Jason Evans7372b152012-02-10 20:22:09 -08002367
Jason Evans22ca8552010-03-02 11:57:30 -08002368 WRITEONLY();
2369 WRITE(filename, const char *);
Jason Evansd34f9e72010-02-11 13:19:21 -08002370
Jason Evansb2c0d632016-04-13 23:36:15 -07002371 if (prof_mdump(tsd, filename)) {
Jason Evans22ca8552010-03-02 11:57:30 -08002372 ret = EFAULT;
Jason Evansa1ee7832012-04-10 15:07:44 -07002373 goto label_return;
Jason Evans22ca8552010-03-02 11:57:30 -08002374 }
Jason Evansd34f9e72010-02-11 13:19:21 -08002375
2376 ret = 0;
Jason Evansa1ee7832012-04-10 15:07:44 -07002377label_return:
Jason Evansf4086432017-01-19 18:15:45 -08002378 return ret;
Jason Evansd34f9e72010-02-11 13:19:21 -08002379}
2380
Jason Evans602c8e02014-08-18 16:22:13 -07002381static int
Jason Evansb2c0d632016-04-13 23:36:15 -07002382prof_gdump_ctl(tsd_t *tsd, const size_t *mib, size_t miblen, void *oldp,
Jason Evansc4c25922017-01-15 16:56:30 -08002383 size_t *oldlenp, void *newp, size_t newlen) {
Jason Evans5b8ed5b2015-01-25 21:16:57 -08002384 int ret;
2385 bool oldval;
2386
Jason Evansc4c25922017-01-15 16:56:30 -08002387 if (!config_prof) {
Jason Evansf4086432017-01-19 18:15:45 -08002388 return ENOENT;
Jason Evansc4c25922017-01-15 16:56:30 -08002389 }
Jason Evans5b8ed5b2015-01-25 21:16:57 -08002390
2391 if (newp != NULL) {
2392 if (newlen != sizeof(bool)) {
2393 ret = EINVAL;
2394 goto label_return;
2395 }
Jason Evansc1e00ef2016-05-10 22:21:10 -07002396 oldval = prof_gdump_set(tsd_tsdn(tsd), *(bool *)newp);
Jason Evansc4c25922017-01-15 16:56:30 -08002397 } else {
Jason Evansc1e00ef2016-05-10 22:21:10 -07002398 oldval = prof_gdump_get(tsd_tsdn(tsd));
Jason Evansc4c25922017-01-15 16:56:30 -08002399 }
Jason Evans5b8ed5b2015-01-25 21:16:57 -08002400 READ(oldval, bool);
2401
2402 ret = 0;
2403label_return:
Jason Evansf4086432017-01-19 18:15:45 -08002404 return ret;
Jason Evans5b8ed5b2015-01-25 21:16:57 -08002405}
2406
2407static int
Jason Evansb2c0d632016-04-13 23:36:15 -07002408prof_reset_ctl(tsd_t *tsd, const size_t *mib, size_t miblen, void *oldp,
Jason Evansc4c25922017-01-15 16:56:30 -08002409 size_t *oldlenp, void *newp, size_t newlen) {
Jason Evans602c8e02014-08-18 16:22:13 -07002410 int ret;
2411 size_t lg_sample = lg_prof_sample;
2412
Jason Evansc4c25922017-01-15 16:56:30 -08002413 if (!config_prof) {
Jason Evansf4086432017-01-19 18:15:45 -08002414 return ENOENT;
Jason Evansc4c25922017-01-15 16:56:30 -08002415 }
Jason Evans602c8e02014-08-18 16:22:13 -07002416
2417 WRITEONLY();
2418 WRITE(lg_sample, size_t);
Jason Evansc4c25922017-01-15 16:56:30 -08002419 if (lg_sample >= (sizeof(uint64_t) << 3)) {
Jason Evans602c8e02014-08-18 16:22:13 -07002420 lg_sample = (sizeof(uint64_t) << 3) - 1;
Jason Evansc4c25922017-01-15 16:56:30 -08002421 }
Jason Evans602c8e02014-08-18 16:22:13 -07002422
Jason Evansb54d1602016-10-20 23:59:12 -07002423 prof_reset(tsd, lg_sample);
Jason Evans602c8e02014-08-18 16:22:13 -07002424
2425 ret = 0;
2426label_return:
Jason Evansf4086432017-01-19 18:15:45 -08002427 return ret;
Jason Evans602c8e02014-08-18 16:22:13 -07002428}
2429
Jason Evans7372b152012-02-10 20:22:09 -08002430CTL_RO_NL_CGEN(config_prof, prof_interval, prof_interval, uint64_t)
Jason Evans602c8e02014-08-18 16:22:13 -07002431CTL_RO_NL_CGEN(config_prof, lg_prof_sample, lg_prof_sample, size_t)
Jason Evansd34f9e72010-02-11 13:19:21 -08002432
2433/******************************************************************************/
2434
Jason Evansd778dd22017-01-03 12:40:54 -08002435CTL_RO_CGEN(config_stats, stats_allocated, ctl_stats->allocated, size_t)
2436CTL_RO_CGEN(config_stats, stats_active, ctl_stats->active, size_t)
2437CTL_RO_CGEN(config_stats, stats_metadata, ctl_stats->metadata, size_t)
2438CTL_RO_CGEN(config_stats, stats_resident, ctl_stats->resident, size_t)
2439CTL_RO_CGEN(config_stats, stats_mapped, ctl_stats->mapped, size_t)
2440CTL_RO_CGEN(config_stats, stats_retained, ctl_stats->retained, size_t)
Jason Evansd8a39002013-12-19 21:40:41 -08002441
Qi Wang2bee0c62017-05-12 12:30:33 -07002442CTL_RO_CGEN(config_stats, stats_background_thread_num_threads,
2443 ctl_stats->background_thread.num_threads, size_t)
2444CTL_RO_CGEN(config_stats, stats_background_thread_num_runs,
2445 ctl_stats->background_thread.num_runs, uint64_t)
2446CTL_RO_CGEN(config_stats, stats_background_thread_run_interval,
2447 nstime_ns(&ctl_stats->background_thread.run_interval), uint64_t)
2448
Jason Evans9eb1b1c2017-01-18 23:03:37 -08002449CTL_RO_GEN(stats_arenas_i_dss, arenas_i(mib[2])->dss, const char *)
Jason Evans6e62c622017-05-17 10:47:00 -07002450CTL_RO_GEN(stats_arenas_i_dirty_decay_ms, arenas_i(mib[2])->dirty_decay_ms,
Jason Evans64e458f2017-03-08 22:42:57 -08002451 ssize_t)
Jason Evans6e62c622017-05-17 10:47:00 -07002452CTL_RO_GEN(stats_arenas_i_muzzy_decay_ms, arenas_i(mib[2])->muzzy_decay_ms,
Jason Evans243f7a02016-02-19 20:09:31 -08002453 ssize_t)
Jason Evans9eb1b1c2017-01-18 23:03:37 -08002454CTL_RO_GEN(stats_arenas_i_nthreads, arenas_i(mib[2])->nthreads, unsigned)
Qi Wangbaf3e292017-05-16 13:56:00 -07002455CTL_RO_GEN(stats_arenas_i_uptime,
2456 nstime_ns(&arenas_i(mib[2])->astats->astats.uptime), uint64_t)
Jason Evans9eb1b1c2017-01-18 23:03:37 -08002457CTL_RO_GEN(stats_arenas_i_pactive, arenas_i(mib[2])->pactive, size_t)
2458CTL_RO_GEN(stats_arenas_i_pdirty, arenas_i(mib[2])->pdirty, size_t)
Jason Evans64e458f2017-03-08 22:42:57 -08002459CTL_RO_GEN(stats_arenas_i_pmuzzy, arenas_i(mib[2])->pmuzzy, size_t)
Jason Evansd8a39002013-12-19 21:40:41 -08002460CTL_RO_CGEN(config_stats, stats_arenas_i_mapped,
David Goldblattee202ef2017-03-13 16:18:40 -07002461 atomic_load_zu(&arenas_i(mib[2])->astats->astats.mapped, ATOMIC_RELAXED),
2462 size_t)
Jason Evans04c3c0f2016-05-03 22:11:35 -07002463CTL_RO_CGEN(config_stats, stats_arenas_i_retained,
David Goldblattee202ef2017-03-13 16:18:40 -07002464 atomic_load_zu(&arenas_i(mib[2])->astats->astats.retained, ATOMIC_RELAXED),
2465 size_t)
Jason Evans64e458f2017-03-08 22:42:57 -08002466
2467CTL_RO_CGEN(config_stats, stats_arenas_i_dirty_npurge,
2468 arena_stats_read_u64(&arenas_i(mib[2])->astats->astats.decay_dirty.npurge),
2469 uint64_t)
2470CTL_RO_CGEN(config_stats, stats_arenas_i_dirty_nmadvise,
2471 arena_stats_read_u64(
2472 &arenas_i(mib[2])->astats->astats.decay_dirty.nmadvise), uint64_t)
2473CTL_RO_CGEN(config_stats, stats_arenas_i_dirty_purged,
2474 arena_stats_read_u64(&arenas_i(mib[2])->astats->astats.decay_dirty.purged),
2475 uint64_t)
2476
2477CTL_RO_CGEN(config_stats, stats_arenas_i_muzzy_npurge,
2478 arena_stats_read_u64(&arenas_i(mib[2])->astats->astats.decay_muzzy.npurge),
2479 uint64_t)
2480CTL_RO_CGEN(config_stats, stats_arenas_i_muzzy_nmadvise,
2481 arena_stats_read_u64(
2482 &arenas_i(mib[2])->astats->astats.decay_muzzy.nmadvise), uint64_t)
2483CTL_RO_CGEN(config_stats, stats_arenas_i_muzzy_purged,
2484 arena_stats_read_u64(&arenas_i(mib[2])->astats->astats.decay_muzzy.purged),
2485 uint64_t)
2486
Jason Evansa0dd3a42016-12-22 16:39:10 -06002487CTL_RO_CGEN(config_stats, stats_arenas_i_base,
David Goldblattee202ef2017-03-13 16:18:40 -07002488 atomic_load_zu(&arenas_i(mib[2])->astats->astats.base, ATOMIC_RELAXED),
2489 size_t)
Jason Evansa0dd3a42016-12-22 16:39:10 -06002490CTL_RO_CGEN(config_stats, stats_arenas_i_internal,
David Goldblattee202ef2017-03-13 16:18:40 -07002491 atomic_load_zu(&arenas_i(mib[2])->astats->astats.internal, ATOMIC_RELAXED),
2492 size_t)
Jason Evans4403c9a2017-04-20 17:21:37 -07002493CTL_RO_CGEN(config_stats, stats_arenas_i_tcache_bytes,
David Goldblattee202ef2017-03-13 16:18:40 -07002494 atomic_load_zu(&arenas_i(mib[2])->astats->astats.tcache_bytes,
2495 ATOMIC_RELAXED), size_t)
Jason Evansa0dd3a42016-12-22 16:39:10 -06002496CTL_RO_CGEN(config_stats, stats_arenas_i_resident,
David Goldblattee202ef2017-03-13 16:18:40 -07002497 atomic_load_zu(&arenas_i(mib[2])->astats->astats.resident, ATOMIC_RELAXED),
2498 size_t)
Jason Evansd8a39002013-12-19 21:40:41 -08002499
Jason Evans7372b152012-02-10 20:22:09 -08002500CTL_RO_CGEN(config_stats, stats_arenas_i_small_allocated,
Jason Evans9eb1b1c2017-01-18 23:03:37 -08002501 arenas_i(mib[2])->astats->allocated_small, size_t)
Jason Evans7372b152012-02-10 20:22:09 -08002502CTL_RO_CGEN(config_stats, stats_arenas_i_small_nmalloc,
Jason Evans9eb1b1c2017-01-18 23:03:37 -08002503 arenas_i(mib[2])->astats->nmalloc_small, uint64_t)
Jason Evans7372b152012-02-10 20:22:09 -08002504CTL_RO_CGEN(config_stats, stats_arenas_i_small_ndalloc,
Jason Evans9eb1b1c2017-01-18 23:03:37 -08002505 arenas_i(mib[2])->astats->ndalloc_small, uint64_t)
Jason Evans7372b152012-02-10 20:22:09 -08002506CTL_RO_CGEN(config_stats, stats_arenas_i_small_nrequests,
Jason Evans9eb1b1c2017-01-18 23:03:37 -08002507 arenas_i(mib[2])->astats->nrequests_small, uint64_t)
Jason Evans7d63fed2016-05-31 14:50:21 -07002508CTL_RO_CGEN(config_stats, stats_arenas_i_large_allocated,
David Goldblattee202ef2017-03-13 16:18:40 -07002509 atomic_load_zu(&arenas_i(mib[2])->astats->astats.allocated_large,
2510 ATOMIC_RELAXED), size_t)
Jason Evans7d63fed2016-05-31 14:50:21 -07002511CTL_RO_CGEN(config_stats, stats_arenas_i_large_nmalloc,
David Goldblatt4fc2acf2017-03-08 15:56:31 -08002512 arena_stats_read_u64(&arenas_i(mib[2])->astats->astats.nmalloc_large),
2513 uint64_t)
Jason Evans7d63fed2016-05-31 14:50:21 -07002514CTL_RO_CGEN(config_stats, stats_arenas_i_large_ndalloc,
David Goldblatt4fc2acf2017-03-08 15:56:31 -08002515 arena_stats_read_u64(&arenas_i(mib[2])->astats->astats.ndalloc_large),
2516 uint64_t)
Jason Evans7d63fed2016-05-31 14:50:21 -07002517CTL_RO_CGEN(config_stats, stats_arenas_i_large_nrequests,
David Goldblatt4fc2acf2017-03-08 15:56:31 -08002518 arena_stats_read_u64(&arenas_i(mib[2])->astats->astats.nmalloc_large),
2519 uint64_t) /* Intentional. */
Jason Evans3c234352010-01-27 13:10:55 -08002520
Qi Wang0fb5c0e2017-03-10 12:14:05 -08002521/* Lock profiling related APIs below. */
Qi Wang64c5f5c2017-03-13 17:29:03 -07002522#define RO_MUTEX_CTL_GEN(n, l) \
Qi Wangca9074d2017-03-11 20:28:31 -08002523CTL_RO_CGEN(config_stats, stats_##n##_num_ops, \
2524 l.n_lock_ops, uint64_t) \
2525CTL_RO_CGEN(config_stats, stats_##n##_num_wait, \
2526 l.n_wait_times, uint64_t) \
2527CTL_RO_CGEN(config_stats, stats_##n##_num_spin_acq, \
2528 l.n_spin_acquired, uint64_t) \
2529CTL_RO_CGEN(config_stats, stats_##n##_num_owner_switch, \
2530 l.n_owner_switches, uint64_t) \
2531CTL_RO_CGEN(config_stats, stats_##n##_total_wait_time, \
Qi Wangf6698ec2017-03-17 17:42:10 -07002532 nstime_ns(&l.tot_wait_time), uint64_t) \
Qi Wangca9074d2017-03-11 20:28:31 -08002533CTL_RO_CGEN(config_stats, stats_##n##_max_wait_time, \
Qi Wangf6698ec2017-03-17 17:42:10 -07002534 nstime_ns(&l.max_wait_time), uint64_t) \
Qi Wangca9074d2017-03-11 20:28:31 -08002535CTL_RO_CGEN(config_stats, stats_##n##_max_num_thds, \
Qi Wangd3fde1c2017-03-21 11:56:38 -07002536 l.max_n_thds, uint32_t)
Qi Wang0fb5c0e2017-03-10 12:14:05 -08002537
Qi Wang64c5f5c2017-03-13 17:29:03 -07002538/* Global mutexes. */
Qi Wangd3fde1c2017-03-21 11:56:38 -07002539#define OP(mtx) \
2540 RO_MUTEX_CTL_GEN(mutexes_##mtx, \
2541 ctl_stats->mutex_prof_data[global_prof_mutex_##mtx])
David Goldblatt89e2d3c2017-04-24 17:09:56 -07002542MUTEX_PROF_GLOBAL_MUTEXES
Qi Wangd3fde1c2017-03-21 11:56:38 -07002543#undef OP
2544
2545/* Per arena mutexes */
2546#define OP(mtx) RO_MUTEX_CTL_GEN(arenas_i_mutexes_##mtx, \
2547 arenas_i(mib[2])->astats->astats.mutex_prof_data[arena_prof_mutex_##mtx])
David Goldblatt89e2d3c2017-04-24 17:09:56 -07002548MUTEX_PROF_ARENA_MUTEXES
Qi Wangd3fde1c2017-03-21 11:56:38 -07002549#undef OP
Qi Wangca9074d2017-03-11 20:28:31 -08002550
Qi Wang20b8c702017-03-15 14:00:57 -07002551/* tcache bin mutex */
Qi Wang64c5f5c2017-03-13 17:29:03 -07002552RO_MUTEX_CTL_GEN(arenas_i_bins_j_mutex,
2553 arenas_i(mib[2])->astats->bstats[mib[4]].mutex_data)
Qi Wang64c5f5c2017-03-13 17:29:03 -07002554#undef RO_MUTEX_CTL_GEN
2555
2556/* Resets all mutex stats, including global, arena and bin mutexes. */
2557static int
2558stats_mutexes_reset_ctl(tsd_t *tsd, const size_t *mib, size_t miblen,
2559 void *oldp, size_t *oldlenp, void *newp, size_t newlen) {
2560 if (!config_stats) {
2561 return ENOENT;
2562 }
2563
2564 tsdn_t *tsdn = tsd_tsdn(tsd);
2565
2566#define MUTEX_PROF_RESET(mtx) \
2567 malloc_mutex_lock(tsdn, &mtx); \
2568 malloc_mutex_prof_data_reset(tsdn, &mtx); \
2569 malloc_mutex_unlock(tsdn, &mtx);
2570
Qi Wang362e3562017-03-22 01:49:56 -07002571 /* Global mutexes: ctl and prof. */
2572 MUTEX_PROF_RESET(ctl_mtx);
Qi Wang5f5ed212017-05-12 16:26:59 -07002573 if (have_background_thread) {
2574 MUTEX_PROF_RESET(background_thread_lock);
2575 }
Qi Wang64c5f5c2017-03-13 17:29:03 -07002576 if (config_prof && opt_prof) {
2577 MUTEX_PROF_RESET(bt2gctx_mtx);
2578 }
Qi Wang362e3562017-03-22 01:49:56 -07002579
Qi Wang64c5f5c2017-03-13 17:29:03 -07002580
2581 /* Per arena mutexes. */
2582 unsigned n = narenas_total_get();
2583
2584 for (unsigned i = 0; i < n; i++) {
2585 arena_t *arena = arena_get(tsdn, i, false);
2586 if (!arena) {
2587 continue;
2588 }
2589 MUTEX_PROF_RESET(arena->large_mtx);
Jason Evans881fbf72017-04-16 22:31:16 -07002590 MUTEX_PROF_RESET(arena->extent_avail_mtx);
Qi Wang20b8c702017-03-15 14:00:57 -07002591 MUTEX_PROF_RESET(arena->extents_dirty.mtx);
2592 MUTEX_PROF_RESET(arena->extents_muzzy.mtx);
Qi Wang64c5f5c2017-03-13 17:29:03 -07002593 MUTEX_PROF_RESET(arena->extents_retained.mtx);
Qi Wang20b8c702017-03-15 14:00:57 -07002594 MUTEX_PROF_RESET(arena->decay_dirty.mtx);
2595 MUTEX_PROF_RESET(arena->decay_muzzy.mtx);
Jason Evans4403c9a2017-04-20 17:21:37 -07002596 MUTEX_PROF_RESET(arena->tcache_ql_mtx);
Qi Wang362e3562017-03-22 01:49:56 -07002597 MUTEX_PROF_RESET(arena->base->mtx);
Qi Wang64c5f5c2017-03-13 17:29:03 -07002598
2599 for (szind_t i = 0; i < NBINS; i++) {
2600 arena_bin_t *bin = &arena->bins[i];
2601 MUTEX_PROF_RESET(bin->lock);
2602 }
2603 }
2604#undef MUTEX_PROF_RESET
2605 return 0;
2606}
Qi Wang0fb5c0e2017-03-10 12:14:05 -08002607
Jason Evans7372b152012-02-10 20:22:09 -08002608CTL_RO_CGEN(config_stats, stats_arenas_i_bins_j_nmalloc,
Jason Evans9eb1b1c2017-01-18 23:03:37 -08002609 arenas_i(mib[2])->astats->bstats[mib[4]].nmalloc, uint64_t)
Jason Evans7372b152012-02-10 20:22:09 -08002610CTL_RO_CGEN(config_stats, stats_arenas_i_bins_j_ndalloc,
Jason Evans9eb1b1c2017-01-18 23:03:37 -08002611 arenas_i(mib[2])->astats->bstats[mib[4]].ndalloc, uint64_t)
Jason Evans7372b152012-02-10 20:22:09 -08002612CTL_RO_CGEN(config_stats, stats_arenas_i_bins_j_nrequests,
Jason Evans9eb1b1c2017-01-18 23:03:37 -08002613 arenas_i(mib[2])->astats->bstats[mib[4]].nrequests, uint64_t)
Jason Evans3c4d92e2014-10-12 22:53:59 -07002614CTL_RO_CGEN(config_stats, stats_arenas_i_bins_j_curregs,
Jason Evans9eb1b1c2017-01-18 23:03:37 -08002615 arenas_i(mib[2])->astats->bstats[mib[4]].curregs, size_t)
Jason Evans4403c9a2017-04-20 17:21:37 -07002616CTL_RO_CGEN(config_stats, stats_arenas_i_bins_j_nfills,
Jason Evans9eb1b1c2017-01-18 23:03:37 -08002617 arenas_i(mib[2])->astats->bstats[mib[4]].nfills, uint64_t)
Jason Evans4403c9a2017-04-20 17:21:37 -07002618CTL_RO_CGEN(config_stats, stats_arenas_i_bins_j_nflushes,
Jason Evans9eb1b1c2017-01-18 23:03:37 -08002619 arenas_i(mib[2])->astats->bstats[mib[4]].nflushes, uint64_t)
Jason Evans498856f2016-05-29 18:34:50 -07002620CTL_RO_CGEN(config_stats, stats_arenas_i_bins_j_nslabs,
Jason Evans9eb1b1c2017-01-18 23:03:37 -08002621 arenas_i(mib[2])->astats->bstats[mib[4]].nslabs, uint64_t)
Jason Evans498856f2016-05-29 18:34:50 -07002622CTL_RO_CGEN(config_stats, stats_arenas_i_bins_j_nreslabs,
Jason Evans9eb1b1c2017-01-18 23:03:37 -08002623 arenas_i(mib[2])->astats->bstats[mib[4]].reslabs, uint64_t)
Jason Evans498856f2016-05-29 18:34:50 -07002624CTL_RO_CGEN(config_stats, stats_arenas_i_bins_j_curslabs,
Jason Evans9eb1b1c2017-01-18 23:03:37 -08002625 arenas_i(mib[2])->astats->bstats[mib[4]].curslabs, size_t)
Jason Evans3c234352010-01-27 13:10:55 -08002626
Jason Evans609ae592012-10-11 13:53:15 -07002627static const ctl_named_node_t *
Jason Evansc1e00ef2016-05-10 22:21:10 -07002628stats_arenas_i_bins_j_index(tsdn_t *tsdn, const size_t *mib, size_t miblen,
Jason Evansc4c25922017-01-15 16:56:30 -08002629 size_t j) {
2630 if (j > NBINS) {
Jason Evansf4086432017-01-19 18:15:45 -08002631 return NULL;
Jason Evansc4c25922017-01-15 16:56:30 -08002632 }
Jason Evansf4086432017-01-19 18:15:45 -08002633 return super_stats_arenas_i_bins_j_node;
Jason Evans3c234352010-01-27 13:10:55 -08002634}
2635
Jason Evans7d63fed2016-05-31 14:50:21 -07002636CTL_RO_CGEN(config_stats, stats_arenas_i_lextents_j_nmalloc,
David Goldblatt4fc2acf2017-03-08 15:56:31 -08002637 arena_stats_read_u64(&arenas_i(mib[2])->astats->lstats[mib[4]].nmalloc),
2638 uint64_t)
Jason Evans7d63fed2016-05-31 14:50:21 -07002639CTL_RO_CGEN(config_stats, stats_arenas_i_lextents_j_ndalloc,
David Goldblatt4fc2acf2017-03-08 15:56:31 -08002640 arena_stats_read_u64(&arenas_i(mib[2])->astats->lstats[mib[4]].ndalloc),
2641 uint64_t)
Jason Evans7d63fed2016-05-31 14:50:21 -07002642CTL_RO_CGEN(config_stats, stats_arenas_i_lextents_j_nrequests,
Jason Evans64e458f2017-03-08 22:42:57 -08002643 arena_stats_read_u64(&arenas_i(mib[2])->astats->lstats[mib[4]].nrequests),
2644 uint64_t)
Jason Evans7d63fed2016-05-31 14:50:21 -07002645CTL_RO_CGEN(config_stats, stats_arenas_i_lextents_j_curlextents,
Jason Evans9eb1b1c2017-01-18 23:03:37 -08002646 arenas_i(mib[2])->astats->lstats[mib[4]].curlextents, size_t)
Jason Evans3c4d92e2014-10-12 22:53:59 -07002647
2648static const ctl_named_node_t *
Jason Evans7d63fed2016-05-31 14:50:21 -07002649stats_arenas_i_lextents_j_index(tsdn_t *tsdn, const size_t *mib, size_t miblen,
Jason Evansc4c25922017-01-15 16:56:30 -08002650 size_t j) {
2651 if (j > NSIZES - NBINS) {
Jason Evansf4086432017-01-19 18:15:45 -08002652 return NULL;
Jason Evansc4c25922017-01-15 16:56:30 -08002653 }
Jason Evansf4086432017-01-19 18:15:45 -08002654 return super_stats_arenas_i_lextents_j_node;
Jason Evans3c4d92e2014-10-12 22:53:59 -07002655}
2656
Jason Evans609ae592012-10-11 13:53:15 -07002657static const ctl_named_node_t *
Jason Evansc4c25922017-01-15 16:56:30 -08002658stats_arenas_i_index(tsdn_t *tsdn, const size_t *mib, size_t miblen, size_t i) {
Jason Evans3dc4e832017-01-03 07:27:42 -08002659 const ctl_named_node_t *ret;
2660 size_t a;
Jason Evans3c234352010-01-27 13:10:55 -08002661
Jason Evansc1e00ef2016-05-10 22:21:10 -07002662 malloc_mutex_lock(tsdn, &ctl_mtx);
Jason Evans9eb1b1c2017-01-18 23:03:37 -08002663 a = arenas_i2a_impl(i, true, true);
2664 if (a == UINT_MAX || !ctl_arenas->arenas[a]->initialized) {
Jason Evansfc4dcfa2010-11-24 15:44:21 -08002665 ret = NULL;
Jason Evansa1ee7832012-04-10 15:07:44 -07002666 goto label_return;
Jason Evansfc4dcfa2010-11-24 15:44:21 -08002667 }
2668
2669 ret = super_stats_arenas_i_node;
Jason Evansa1ee7832012-04-10 15:07:44 -07002670label_return:
Jason Evansc1e00ef2016-05-10 22:21:10 -07002671 malloc_mutex_unlock(tsdn, &ctl_mtx);
Jason Evansf4086432017-01-19 18:15:45 -08002672 return ret;
Jason Evans3c234352010-01-27 13:10:55 -08002673}