blob: ace10b02434cc7d5e20961efec4abf1f0a5693c7 [file] [log] [blame]
Jason Evansc0cc5db2017-01-19 21:41:41 -08001#define JEMALLOC_CTL_C_
David Goldblatt743d9402017-04-10 18:17:55 -07002#include "jemalloc/internal/jemalloc_preamble.h"
3#include "jemalloc/internal/jemalloc_internal_includes.h"
Jason Evans3c234352010-01-27 13:10:55 -08004
David Goldblattd9ec36e2017-04-11 14:43:12 -07005#include "jemalloc/internal/assert.h"
David Goldblatt89e2d3c2017-04-24 17:09:56 -07006#include "jemalloc/internal/ctl.h"
David Goldblatt93284bb2017-05-23 14:36:09 -07007#include "jemalloc/internal/extent_dss.h"
David Goldblatt98774e62017-05-23 14:42:32 -07008#include "jemalloc/internal/extent_mmap.h"
David Goldblatt18ecbfa2017-05-23 12:28:19 -07009#include "jemalloc/internal/mutex.h"
David Goldblatt418d96a2017-04-17 16:17:02 -070010#include "jemalloc/internal/nstime.h"
David Goldblatt31b43212017-04-19 15:09:01 -070011#include "jemalloc/internal/size_classes.h"
David Goldblattf692e6c2017-04-11 13:31:16 -070012#include "jemalloc/internal/util.h"
13
Jason Evans3c234352010-01-27 13:10:55 -080014/******************************************************************************/
15/* Data. */
16
Jason Evansfc4dcfa2010-11-24 15:44:21 -080017/*
18 * ctl_mtx protects the following:
Jason Evansd778dd22017-01-03 12:40:54 -080019 * - ctl_stats->*
Jason Evansfc4dcfa2010-11-24 15:44:21 -080020 */
Jason Evans3c234352010-01-27 13:10:55 -080021static malloc_mutex_t ctl_mtx;
22static bool ctl_initialized;
Jason Evansd778dd22017-01-03 12:40:54 -080023static ctl_stats_t *ctl_stats;
Jason Evans9eb1b1c2017-01-18 23:03:37 -080024static ctl_arenas_t *ctl_arenas;
Jason Evans3c234352010-01-27 13:10:55 -080025
26/******************************************************************************/
Mike Hommey461ad5c2012-04-20 08:38:42 +020027/* Helpers for named and indexed nodes. */
28
David Goldblatt4d2e4bf2017-04-21 09:37:34 -070029static const ctl_named_node_t *
Jason Evansc4c25922017-01-15 16:56:30 -080030ctl_named_node(const ctl_node_t *node) {
Mike Hommey461ad5c2012-04-20 08:38:42 +020031 return ((node->named) ? (const ctl_named_node_t *)node : NULL);
32}
33
David Goldblatt4d2e4bf2017-04-21 09:37:34 -070034static const ctl_named_node_t *
Jason Evansc4c25922017-01-15 16:56:30 -080035ctl_named_children(const ctl_named_node_t *node, size_t index) {
Mike Hommey461ad5c2012-04-20 08:38:42 +020036 const ctl_named_node_t *children = ctl_named_node(node->children);
37
38 return (children ? &children[index] : NULL);
39}
40
David Goldblatt4d2e4bf2017-04-21 09:37:34 -070041static const ctl_indexed_node_t *
Jason Evansc4c25922017-01-15 16:56:30 -080042ctl_indexed_node(const ctl_node_t *node) {
Jason Evans551ebc42014-10-03 10:16:09 -070043 return (!node->named ? (const ctl_indexed_node_t *)node : NULL);
Mike Hommey461ad5c2012-04-20 08:38:42 +020044}
45
46/******************************************************************************/
Jason Evans3c234352010-01-27 13:10:55 -080047/* Function prototypes for non-inline static functions. */
48
Jason Evansc0cc5db2017-01-19 21:41:41 -080049#define CTL_PROTO(n) \
Jason Evansb2c0d632016-04-13 23:36:15 -070050static int n##_ctl(tsd_t *tsd, const size_t *mib, size_t miblen, \
51 void *oldp, size_t *oldlenp, void *newp, size_t newlen);
Jason Evans3c234352010-01-27 13:10:55 -080052
Jason Evansc0cc5db2017-01-19 21:41:41 -080053#define INDEX_PROTO(n) \
Jason Evansc1e00ef2016-05-10 22:21:10 -070054static const ctl_named_node_t *n##_index(tsdn_t *tsdn, \
Jason Evansb2c0d632016-04-13 23:36:15 -070055 const size_t *mib, size_t miblen, size_t i);
Jason Evans3c234352010-01-27 13:10:55 -080056
Jason Evansa40bc7a2010-03-02 13:01:16 -080057CTL_PROTO(version)
Jason Evans3c234352010-01-27 13:10:55 -080058CTL_PROTO(epoch)
Qi Wangb693c782017-03-17 12:42:33 -070059CTL_PROTO(background_thread)
Jason Evansd4be8b72012-03-26 18:54:44 -070060CTL_PROTO(thread_tcache_enabled)
Jason Evanse7b8fa12012-03-16 17:09:32 -070061CTL_PROTO(thread_tcache_flush)
Jason Evans602c8e02014-08-18 16:22:13 -070062CTL_PROTO(thread_prof_name)
63CTL_PROTO(thread_prof_active)
Jason Evansb267d0f2010-08-13 15:42:29 -070064CTL_PROTO(thread_arena)
Jason Evans93443682010-10-20 17:39:18 -070065CTL_PROTO(thread_allocated)
Jason Evansecf229a2010-12-03 15:55:47 -080066CTL_PROTO(thread_allocatedp)
Jason Evans93443682010-10-20 17:39:18 -070067CTL_PROTO(thread_deallocated)
Jason Evansecf229a2010-12-03 15:55:47 -080068CTL_PROTO(thread_deallocatedp)
Jason Evansf2bc8522015-07-17 16:38:25 -070069CTL_PROTO(config_cache_oblivious)
Jason Evans3c234352010-01-27 13:10:55 -080070CTL_PROTO(config_debug)
Jason Evans3c234352010-01-27 13:10:55 -080071CTL_PROTO(config_fill)
72CTL_PROTO(config_lazy_lock)
Jason Evansf8290092016-02-07 14:23:22 -080073CTL_PROTO(config_malloc_conf)
Jason Evansd34f9e72010-02-11 13:19:21 -080074CTL_PROTO(config_prof)
75CTL_PROTO(config_prof_libgcc)
76CTL_PROTO(config_prof_libunwind)
Jason Evans3c234352010-01-27 13:10:55 -080077CTL_PROTO(config_stats)
Jason Evansc606a872017-05-30 09:54:49 -070078CTL_PROTO(config_thp)
Jason Evansb1476112012-04-05 13:36:17 -070079CTL_PROTO(config_utrace)
Jason Evans3c234352010-01-27 13:10:55 -080080CTL_PROTO(config_xmalloc)
81CTL_PROTO(opt_abort)
Qi Wangb86d2712017-05-25 15:30:11 -070082CTL_PROTO(opt_abort_conf)
Qi Wang8fdd9a52017-08-10 13:14:26 -070083CTL_PROTO(opt_metadata_thp)
Jason Evansb9ab04a2017-04-26 16:26:12 -070084CTL_PROTO(opt_retain)
Jason Evans609ae592012-10-11 13:53:15 -070085CTL_PROTO(opt_dss)
Jason Evanse7339702010-10-23 18:37:06 -070086CTL_PROTO(opt_narenas)
Qi Wangec532e22017-02-02 17:02:05 -080087CTL_PROTO(opt_percpu_arena)
Qi Wangb693c782017-03-17 12:42:33 -070088CTL_PROTO(opt_background_thread)
Jason Evans6e62c622017-05-17 10:47:00 -070089CTL_PROTO(opt_dirty_decay_ms)
90CTL_PROTO(opt_muzzy_decay_ms)
Jason Evanse7339702010-10-23 18:37:06 -070091CTL_PROTO(opt_stats_print)
Qi Wangd5ef5ae2017-05-27 15:35:36 -070092CTL_PROTO(opt_stats_print_opts)
Jason Evans3c234352010-01-27 13:10:55 -080093CTL_PROTO(opt_junk)
Jason Evanse7339702010-10-23 18:37:06 -070094CTL_PROTO(opt_zero)
Jason Evansb1476112012-04-05 13:36:17 -070095CTL_PROTO(opt_utrace)
Jason Evans3c234352010-01-27 13:10:55 -080096CTL_PROTO(opt_xmalloc)
Jason Evans3fa9a2f2010-03-07 15:34:14 -080097CTL_PROTO(opt_tcache)
Jason Evansf3ca7c82012-04-04 16:16:09 -070098CTL_PROTO(opt_lg_tcache_max)
Jason Evansd34f9e72010-02-11 13:19:21 -080099CTL_PROTO(opt_prof)
Jason Evanse7339702010-10-23 18:37:06 -0700100CTL_PROTO(opt_prof_prefix)
Jason Evansf18c9822010-03-31 18:43:24 -0700101CTL_PROTO(opt_prof_active)
Jason Evansfc12c0b2014-10-03 23:25:30 -0700102CTL_PROTO(opt_prof_thread_active_init)
Jason Evansb9477e72010-03-01 20:15:26 -0800103CTL_PROTO(opt_lg_prof_sample)
Jason Evansd34f9e72010-02-11 13:19:21 -0800104CTL_PROTO(opt_lg_prof_interval)
Jason Evanse7339702010-10-23 18:37:06 -0700105CTL_PROTO(opt_prof_gdump)
Jason Evans0b25fe72012-04-17 16:39:33 -0700106CTL_PROTO(opt_prof_final)
Jason Evansd34f9e72010-02-11 13:19:21 -0800107CTL_PROTO(opt_prof_leak)
Jason Evansa881cd22010-10-02 15:18:50 -0700108CTL_PROTO(opt_prof_accum)
Jason Evans1cb181e2015-01-29 15:30:47 -0800109CTL_PROTO(tcache_create)
110CTL_PROTO(tcache_flush)
111CTL_PROTO(tcache_destroy)
Jason Evansdc2125c2017-01-04 10:21:53 -0800112CTL_PROTO(arena_i_initialized)
Jason Evans243f7a02016-02-19 20:09:31 -0800113CTL_PROTO(arena_i_decay)
Jason Evans64e458f2017-03-08 22:42:57 -0800114CTL_PROTO(arena_i_purge)
Jason Evans19ff2ce2016-04-22 14:37:17 -0700115CTL_PROTO(arena_i_reset)
Jason Evansedf1baf2017-01-03 17:21:59 -0800116CTL_PROTO(arena_i_destroy)
Jason Evans609ae592012-10-11 13:53:15 -0700117CTL_PROTO(arena_i_dss)
Jason Evans6e62c622017-05-17 10:47:00 -0700118CTL_PROTO(arena_i_dirty_decay_ms)
119CTL_PROTO(arena_i_muzzy_decay_ms)
Jason Evans9c305c92016-05-31 15:03:51 -0700120CTL_PROTO(arena_i_extent_hooks)
Jason Evans609ae592012-10-11 13:53:15 -0700121INDEX_PROTO(arena_i)
Jason Evans3c234352010-01-27 13:10:55 -0800122CTL_PROTO(arenas_bin_i_size)
123CTL_PROTO(arenas_bin_i_nregs)
Jason Evans498856f2016-05-29 18:34:50 -0700124CTL_PROTO(arenas_bin_i_slab_size)
Jason Evans3c234352010-01-27 13:10:55 -0800125INDEX_PROTO(arenas_bin_i)
Jason Evans7d63fed2016-05-31 14:50:21 -0700126CTL_PROTO(arenas_lextent_i_size)
127INDEX_PROTO(arenas_lextent_i)
Jason Evans3c234352010-01-27 13:10:55 -0800128CTL_PROTO(arenas_narenas)
Jason Evans6e62c622017-05-17 10:47:00 -0700129CTL_PROTO(arenas_dirty_decay_ms)
130CTL_PROTO(arenas_muzzy_decay_ms)
Jason Evans3c234352010-01-27 13:10:55 -0800131CTL_PROTO(arenas_quantum)
Jason Evansae4c7b42012-04-02 07:04:34 -0700132CTL_PROTO(arenas_page)
Jason Evansdafde142010-03-17 16:27:39 -0700133CTL_PROTO(arenas_tcache_max)
Jason Evans3c234352010-01-27 13:10:55 -0800134CTL_PROTO(arenas_nbins)
Jason Evansdafde142010-03-17 16:27:39 -0700135CTL_PROTO(arenas_nhbins)
Jason Evans7d63fed2016-05-31 14:50:21 -0700136CTL_PROTO(arenas_nlextents)
Jason Evans0f04bb12017-01-03 08:21:29 -0800137CTL_PROTO(arenas_create)
Jason Evansfc12c0b2014-10-03 23:25:30 -0700138CTL_PROTO(prof_thread_active_init)
Jason Evansf18c9822010-03-31 18:43:24 -0700139CTL_PROTO(prof_active)
Jason Evansd34f9e72010-02-11 13:19:21 -0800140CTL_PROTO(prof_dump)
Jason Evans5b8ed5b2015-01-25 21:16:57 -0800141CTL_PROTO(prof_gdump)
Jason Evans602c8e02014-08-18 16:22:13 -0700142CTL_PROTO(prof_reset)
Jason Evansd34f9e72010-02-11 13:19:21 -0800143CTL_PROTO(prof_interval)
Jason Evans602c8e02014-08-18 16:22:13 -0700144CTL_PROTO(lg_prof_sample)
Jason Evans3c234352010-01-27 13:10:55 -0800145CTL_PROTO(stats_arenas_i_small_allocated)
146CTL_PROTO(stats_arenas_i_small_nmalloc)
147CTL_PROTO(stats_arenas_i_small_ndalloc)
Jason Evans86815df2010-03-13 20:32:56 -0800148CTL_PROTO(stats_arenas_i_small_nrequests)
Jason Evans7d63fed2016-05-31 14:50:21 -0700149CTL_PROTO(stats_arenas_i_large_allocated)
150CTL_PROTO(stats_arenas_i_large_nmalloc)
151CTL_PROTO(stats_arenas_i_large_ndalloc)
152CTL_PROTO(stats_arenas_i_large_nrequests)
Jason Evans86815df2010-03-13 20:32:56 -0800153CTL_PROTO(stats_arenas_i_bins_j_nmalloc)
154CTL_PROTO(stats_arenas_i_bins_j_ndalloc)
Jason Evans3c234352010-01-27 13:10:55 -0800155CTL_PROTO(stats_arenas_i_bins_j_nrequests)
Jason Evans3c4d92e2014-10-12 22:53:59 -0700156CTL_PROTO(stats_arenas_i_bins_j_curregs)
Jason Evans3c234352010-01-27 13:10:55 -0800157CTL_PROTO(stats_arenas_i_bins_j_nfills)
158CTL_PROTO(stats_arenas_i_bins_j_nflushes)
Jason Evans498856f2016-05-29 18:34:50 -0700159CTL_PROTO(stats_arenas_i_bins_j_nslabs)
160CTL_PROTO(stats_arenas_i_bins_j_nreslabs)
161CTL_PROTO(stats_arenas_i_bins_j_curslabs)
Jason Evans3c234352010-01-27 13:10:55 -0800162INDEX_PROTO(stats_arenas_i_bins_j)
Jason Evans7d63fed2016-05-31 14:50:21 -0700163CTL_PROTO(stats_arenas_i_lextents_j_nmalloc)
164CTL_PROTO(stats_arenas_i_lextents_j_ndalloc)
165CTL_PROTO(stats_arenas_i_lextents_j_nrequests)
166CTL_PROTO(stats_arenas_i_lextents_j_curlextents)
167INDEX_PROTO(stats_arenas_i_lextents_j)
Jason Evans597632b2011-03-18 13:41:33 -0700168CTL_PROTO(stats_arenas_i_nthreads)
Qi Wangbaf3e292017-05-16 13:56:00 -0700169CTL_PROTO(stats_arenas_i_uptime)
Jason Evans609ae592012-10-11 13:53:15 -0700170CTL_PROTO(stats_arenas_i_dss)
Jason Evans6e62c622017-05-17 10:47:00 -0700171CTL_PROTO(stats_arenas_i_dirty_decay_ms)
172CTL_PROTO(stats_arenas_i_muzzy_decay_ms)
Jason Evans3c234352010-01-27 13:10:55 -0800173CTL_PROTO(stats_arenas_i_pactive)
174CTL_PROTO(stats_arenas_i_pdirty)
Jason Evans64e458f2017-03-08 22:42:57 -0800175CTL_PROTO(stats_arenas_i_pmuzzy)
Jason Evans3c234352010-01-27 13:10:55 -0800176CTL_PROTO(stats_arenas_i_mapped)
Jason Evans04c3c0f2016-05-03 22:11:35 -0700177CTL_PROTO(stats_arenas_i_retained)
Jason Evans64e458f2017-03-08 22:42:57 -0800178CTL_PROTO(stats_arenas_i_dirty_npurge)
179CTL_PROTO(stats_arenas_i_dirty_nmadvise)
180CTL_PROTO(stats_arenas_i_dirty_purged)
181CTL_PROTO(stats_arenas_i_muzzy_npurge)
182CTL_PROTO(stats_arenas_i_muzzy_nmadvise)
183CTL_PROTO(stats_arenas_i_muzzy_purged)
Jason Evansa0dd3a42016-12-22 16:39:10 -0600184CTL_PROTO(stats_arenas_i_base)
185CTL_PROTO(stats_arenas_i_internal)
Qi Wang58424e62016-04-22 18:37:44 -0700186CTL_PROTO(stats_arenas_i_tcache_bytes)
Jason Evansa0dd3a42016-12-22 16:39:10 -0600187CTL_PROTO(stats_arenas_i_resident)
Jason Evans3c234352010-01-27 13:10:55 -0800188INDEX_PROTO(stats_arenas_i)
Jason Evans3c234352010-01-27 13:10:55 -0800189CTL_PROTO(stats_allocated)
190CTL_PROTO(stats_active)
Qi Wang2bee0c62017-05-12 12:30:33 -0700191CTL_PROTO(stats_background_thread_num_threads)
192CTL_PROTO(stats_background_thread_num_runs)
193CTL_PROTO(stats_background_thread_run_interval)
Jason Evans4581b972014-11-27 17:22:36 -0200194CTL_PROTO(stats_metadata)
Jason Evans4acd75a2015-03-23 17:25:57 -0700195CTL_PROTO(stats_resident)
Jason Evans3c234352010-01-27 13:10:55 -0800196CTL_PROTO(stats_mapped)
Jason Evans04c3c0f2016-05-03 22:11:35 -0700197CTL_PROTO(stats_retained)
Jason Evans3c234352010-01-27 13:10:55 -0800198
Qi Wang64c5f5c2017-03-13 17:29:03 -0700199#define MUTEX_STATS_CTL_PROTO_GEN(n) \
Qi Wangca9074d2017-03-11 20:28:31 -0800200CTL_PROTO(stats_##n##_num_ops) \
201CTL_PROTO(stats_##n##_num_wait) \
202CTL_PROTO(stats_##n##_num_spin_acq) \
203CTL_PROTO(stats_##n##_num_owner_switch) \
204CTL_PROTO(stats_##n##_total_wait_time) \
205CTL_PROTO(stats_##n##_max_wait_time) \
206CTL_PROTO(stats_##n##_max_num_thds)
Qi Wang0fb5c0e2017-03-10 12:14:05 -0800207
Qi Wang64c5f5c2017-03-13 17:29:03 -0700208/* Global mutexes. */
Qi Wangd3fde1c2017-03-21 11:56:38 -0700209#define OP(mtx) MUTEX_STATS_CTL_PROTO_GEN(mutexes_##mtx)
David Goldblatt89e2d3c2017-04-24 17:09:56 -0700210MUTEX_PROF_GLOBAL_MUTEXES
Qi Wangd3fde1c2017-03-21 11:56:38 -0700211#undef OP
212
213/* Per arena mutexes. */
214#define OP(mtx) MUTEX_STATS_CTL_PROTO_GEN(arenas_i_mutexes_##mtx)
David Goldblatt89e2d3c2017-04-24 17:09:56 -0700215MUTEX_PROF_ARENA_MUTEXES
Qi Wangd3fde1c2017-03-21 11:56:38 -0700216#undef OP
Qi Wangca9074d2017-03-11 20:28:31 -0800217
Qi Wang64c5f5c2017-03-13 17:29:03 -0700218/* Arena bin mutexes. */
219MUTEX_STATS_CTL_PROTO_GEN(arenas_i_bins_j_mutex)
Qi Wang64c5f5c2017-03-13 17:29:03 -0700220#undef MUTEX_STATS_CTL_PROTO_GEN
221
222CTL_PROTO(stats_mutexes_reset)
Qi Wang0fb5c0e2017-03-10 12:14:05 -0800223
Jason Evans3c234352010-01-27 13:10:55 -0800224/******************************************************************************/
225/* mallctl tree. */
226
Jason Evansc0cc5db2017-01-19 21:41:41 -0800227#define NAME(n) {true}, n
228#define CHILD(t, c) \
Jason Evans65f343a2012-04-23 19:31:45 -0700229 sizeof(c##_node) / sizeof(ctl_##t##_node_t), \
230 (ctl_node_t *)c##_node, \
231 NULL
Jason Evansc0cc5db2017-01-19 21:41:41 -0800232#define CTL(c) 0, NULL, c##_ctl
Jason Evans3c234352010-01-27 13:10:55 -0800233
234/*
235 * Only handles internal indexed nodes, since there are currently no external
236 * ones.
237 */
Jason Evansc0cc5db2017-01-19 21:41:41 -0800238#define INDEX(i) {false}, i##_index
Jason Evans3c234352010-01-27 13:10:55 -0800239
Jason Evans602c8e02014-08-18 16:22:13 -0700240static const ctl_named_node_t thread_tcache_node[] = {
Jason Evansd4be8b72012-03-26 18:54:44 -0700241 {NAME("enabled"), CTL(thread_tcache_enabled)},
Jason Evanse7b8fa12012-03-16 17:09:32 -0700242 {NAME("flush"), CTL(thread_tcache_flush)}
Jason Evans3c234352010-01-27 13:10:55 -0800243};
Jason Evans3c234352010-01-27 13:10:55 -0800244
Jason Evans602c8e02014-08-18 16:22:13 -0700245static const ctl_named_node_t thread_prof_node[] = {
246 {NAME("name"), CTL(thread_prof_name)},
247 {NAME("active"), CTL(thread_prof_active)}
248};
249
Mike Hommey461ad5c2012-04-20 08:38:42 +0200250static const ctl_named_node_t thread_node[] = {
Jason Evans7372b152012-02-10 20:22:09 -0800251 {NAME("arena"), CTL(thread_arena)},
Jason Evans93443682010-10-20 17:39:18 -0700252 {NAME("allocated"), CTL(thread_allocated)},
Jason Evansecf229a2010-12-03 15:55:47 -0800253 {NAME("allocatedp"), CTL(thread_allocatedp)},
254 {NAME("deallocated"), CTL(thread_deallocated)},
Jason Evanse7b8fa12012-03-16 17:09:32 -0700255 {NAME("deallocatedp"), CTL(thread_deallocatedp)},
Jason Evans602c8e02014-08-18 16:22:13 -0700256 {NAME("tcache"), CHILD(named, thread_tcache)},
257 {NAME("prof"), CHILD(named, thread_prof)}
Jason Evansb267d0f2010-08-13 15:42:29 -0700258};
Jason Evansb267d0f2010-08-13 15:42:29 -0700259
Mike Hommey461ad5c2012-04-20 08:38:42 +0200260static const ctl_named_node_t config_node[] = {
Jason Evansf2bc8522015-07-17 16:38:25 -0700261 {NAME("cache_oblivious"), CTL(config_cache_oblivious)},
Jason Evans3c4d92e2014-10-12 22:53:59 -0700262 {NAME("debug"), CTL(config_debug)},
263 {NAME("fill"), CTL(config_fill)},
264 {NAME("lazy_lock"), CTL(config_lazy_lock)},
Jason Evansf8290092016-02-07 14:23:22 -0800265 {NAME("malloc_conf"), CTL(config_malloc_conf)},
Jason Evans3c4d92e2014-10-12 22:53:59 -0700266 {NAME("prof"), CTL(config_prof)},
267 {NAME("prof_libgcc"), CTL(config_prof_libgcc)},
268 {NAME("prof_libunwind"), CTL(config_prof_libunwind)},
269 {NAME("stats"), CTL(config_stats)},
Jason Evansc606a872017-05-30 09:54:49 -0700270 {NAME("thp"), CTL(config_thp)},
Jason Evans3c4d92e2014-10-12 22:53:59 -0700271 {NAME("utrace"), CTL(config_utrace)},
Jason Evans3c4d92e2014-10-12 22:53:59 -0700272 {NAME("xmalloc"), CTL(config_xmalloc)}
Jason Evans3c234352010-01-27 13:10:55 -0800273};
274
Mike Hommey461ad5c2012-04-20 08:38:42 +0200275static const ctl_named_node_t opt_node[] = {
Jason Evans3c4d92e2014-10-12 22:53:59 -0700276 {NAME("abort"), CTL(opt_abort)},
Qi Wangb86d2712017-05-25 15:30:11 -0700277 {NAME("abort_conf"), CTL(opt_abort_conf)},
Qi Wang8fdd9a52017-08-10 13:14:26 -0700278 {NAME("metadata_thp"), CTL(opt_metadata_thp)},
Jason Evansb9ab04a2017-04-26 16:26:12 -0700279 {NAME("retain"), CTL(opt_retain)},
Jason Evans3c4d92e2014-10-12 22:53:59 -0700280 {NAME("dss"), CTL(opt_dss)},
Jason Evans3c4d92e2014-10-12 22:53:59 -0700281 {NAME("narenas"), CTL(opt_narenas)},
Qi Wangec532e22017-02-02 17:02:05 -0800282 {NAME("percpu_arena"), CTL(opt_percpu_arena)},
Qi Wangb693c782017-03-17 12:42:33 -0700283 {NAME("background_thread"), CTL(opt_background_thread)},
Jason Evans6e62c622017-05-17 10:47:00 -0700284 {NAME("dirty_decay_ms"), CTL(opt_dirty_decay_ms)},
285 {NAME("muzzy_decay_ms"), CTL(opt_muzzy_decay_ms)},
Jason Evans3c4d92e2014-10-12 22:53:59 -0700286 {NAME("stats_print"), CTL(opt_stats_print)},
Qi Wangd5ef5ae2017-05-27 15:35:36 -0700287 {NAME("stats_print_opts"), CTL(opt_stats_print_opts)},
Jason Evans3c4d92e2014-10-12 22:53:59 -0700288 {NAME("junk"), CTL(opt_junk)},
289 {NAME("zero"), CTL(opt_zero)},
Jason Evans3c4d92e2014-10-12 22:53:59 -0700290 {NAME("utrace"), CTL(opt_utrace)},
291 {NAME("xmalloc"), CTL(opt_xmalloc)},
292 {NAME("tcache"), CTL(opt_tcache)},
293 {NAME("lg_tcache_max"), CTL(opt_lg_tcache_max)},
294 {NAME("prof"), CTL(opt_prof)},
295 {NAME("prof_prefix"), CTL(opt_prof_prefix)},
296 {NAME("prof_active"), CTL(opt_prof_active)},
Jason Evansfc12c0b2014-10-03 23:25:30 -0700297 {NAME("prof_thread_active_init"), CTL(opt_prof_thread_active_init)},
Jason Evans3c4d92e2014-10-12 22:53:59 -0700298 {NAME("lg_prof_sample"), CTL(opt_lg_prof_sample)},
299 {NAME("lg_prof_interval"), CTL(opt_lg_prof_interval)},
300 {NAME("prof_gdump"), CTL(opt_prof_gdump)},
301 {NAME("prof_final"), CTL(opt_prof_final)},
302 {NAME("prof_leak"), CTL(opt_prof_leak)},
303 {NAME("prof_accum"), CTL(opt_prof_accum)}
Jason Evans3c234352010-01-27 13:10:55 -0800304};
305
Jason Evans1cb181e2015-01-29 15:30:47 -0800306static const ctl_named_node_t tcache_node[] = {
307 {NAME("create"), CTL(tcache_create)},
308 {NAME("flush"), CTL(tcache_flush)},
309 {NAME("destroy"), CTL(tcache_destroy)}
310};
311
Jason Evans609ae592012-10-11 13:53:15 -0700312static const ctl_named_node_t arena_i_node[] = {
Jason Evansdc2125c2017-01-04 10:21:53 -0800313 {NAME("initialized"), CTL(arena_i_initialized)},
Jason Evans243f7a02016-02-19 20:09:31 -0800314 {NAME("decay"), CTL(arena_i_decay)},
Jason Evans64e458f2017-03-08 22:42:57 -0800315 {NAME("purge"), CTL(arena_i_purge)},
Jason Evans19ff2ce2016-04-22 14:37:17 -0700316 {NAME("reset"), CTL(arena_i_reset)},
Jason Evansedf1baf2017-01-03 17:21:59 -0800317 {NAME("destroy"), CTL(arena_i_destroy)},
Jason Evans3c4d92e2014-10-12 22:53:59 -0700318 {NAME("dss"), CTL(arena_i_dss)},
Jason Evans6e62c622017-05-17 10:47:00 -0700319 {NAME("dirty_decay_ms"), CTL(arena_i_dirty_decay_ms)},
320 {NAME("muzzy_decay_ms"), CTL(arena_i_muzzy_decay_ms)},
Jason Evans9c305c92016-05-31 15:03:51 -0700321 {NAME("extent_hooks"), CTL(arena_i_extent_hooks)}
Jason Evans609ae592012-10-11 13:53:15 -0700322};
323static const ctl_named_node_t super_arena_i_node[] = {
Jason Evans3c4d92e2014-10-12 22:53:59 -0700324 {NAME(""), CHILD(named, arena_i)}
Jason Evans609ae592012-10-11 13:53:15 -0700325};
326
327static const ctl_indexed_node_t arena_node[] = {
328 {INDEX(arena_i)}
329};
330
Mike Hommey461ad5c2012-04-20 08:38:42 +0200331static const ctl_named_node_t arenas_bin_i_node[] = {
Jason Evans3c4d92e2014-10-12 22:53:59 -0700332 {NAME("size"), CTL(arenas_bin_i_size)},
333 {NAME("nregs"), CTL(arenas_bin_i_nregs)},
Jason Evans498856f2016-05-29 18:34:50 -0700334 {NAME("slab_size"), CTL(arenas_bin_i_slab_size)}
Jason Evans3c234352010-01-27 13:10:55 -0800335};
Mike Hommey461ad5c2012-04-20 08:38:42 +0200336static const ctl_named_node_t super_arenas_bin_i_node[] = {
Jason Evans3c4d92e2014-10-12 22:53:59 -0700337 {NAME(""), CHILD(named, arenas_bin_i)}
Jason Evans3c234352010-01-27 13:10:55 -0800338};
339
Mike Hommey461ad5c2012-04-20 08:38:42 +0200340static const ctl_indexed_node_t arenas_bin_node[] = {
Jason Evans3c234352010-01-27 13:10:55 -0800341 {INDEX(arenas_bin_i)}
342};
343
Jason Evans7d63fed2016-05-31 14:50:21 -0700344static const ctl_named_node_t arenas_lextent_i_node[] = {
345 {NAME("size"), CTL(arenas_lextent_i_size)}
Jason Evans3c4d92e2014-10-12 22:53:59 -0700346};
Jason Evans7d63fed2016-05-31 14:50:21 -0700347static const ctl_named_node_t super_arenas_lextent_i_node[] = {
348 {NAME(""), CHILD(named, arenas_lextent_i)}
Jason Evans3c4d92e2014-10-12 22:53:59 -0700349};
350
Jason Evans7d63fed2016-05-31 14:50:21 -0700351static const ctl_indexed_node_t arenas_lextent_node[] = {
352 {INDEX(arenas_lextent_i)}
Jason Evans3c4d92e2014-10-12 22:53:59 -0700353};
354
Mike Hommey461ad5c2012-04-20 08:38:42 +0200355static const ctl_named_node_t arenas_node[] = {
Jason Evans3c4d92e2014-10-12 22:53:59 -0700356 {NAME("narenas"), CTL(arenas_narenas)},
Jason Evans6e62c622017-05-17 10:47:00 -0700357 {NAME("dirty_decay_ms"), CTL(arenas_dirty_decay_ms)},
358 {NAME("muzzy_decay_ms"), CTL(arenas_muzzy_decay_ms)},
Jason Evans3c4d92e2014-10-12 22:53:59 -0700359 {NAME("quantum"), CTL(arenas_quantum)},
360 {NAME("page"), CTL(arenas_page)},
361 {NAME("tcache_max"), CTL(arenas_tcache_max)},
362 {NAME("nbins"), CTL(arenas_nbins)},
363 {NAME("nhbins"), CTL(arenas_nhbins)},
364 {NAME("bin"), CHILD(indexed, arenas_bin)},
Jason Evans7d63fed2016-05-31 14:50:21 -0700365 {NAME("nlextents"), CTL(arenas_nlextents)},
366 {NAME("lextent"), CHILD(indexed, arenas_lextent)},
Jason Evans0f04bb12017-01-03 08:21:29 -0800367 {NAME("create"), CTL(arenas_create)}
Jason Evans3c234352010-01-27 13:10:55 -0800368};
369
Mike Hommey461ad5c2012-04-20 08:38:42 +0200370static const ctl_named_node_t prof_node[] = {
Jason Evansfc12c0b2014-10-03 23:25:30 -0700371 {NAME("thread_active_init"), CTL(prof_thread_active_init)},
Jason Evansf18c9822010-03-31 18:43:24 -0700372 {NAME("active"), CTL(prof_active)},
Jason Evansd34f9e72010-02-11 13:19:21 -0800373 {NAME("dump"), CTL(prof_dump)},
Jason Evans5b8ed5b2015-01-25 21:16:57 -0800374 {NAME("gdump"), CTL(prof_gdump)},
Jason Evans602c8e02014-08-18 16:22:13 -0700375 {NAME("reset"), CTL(prof_reset)},
376 {NAME("interval"), CTL(prof_interval)},
377 {NAME("lg_sample"), CTL(lg_prof_sample)}
Jason Evansd34f9e72010-02-11 13:19:21 -0800378};
Jason Evansd34f9e72010-02-11 13:19:21 -0800379
Mike Hommey461ad5c2012-04-20 08:38:42 +0200380static const ctl_named_node_t stats_arenas_i_small_node[] = {
Jason Evans3c4d92e2014-10-12 22:53:59 -0700381 {NAME("allocated"), CTL(stats_arenas_i_small_allocated)},
382 {NAME("nmalloc"), CTL(stats_arenas_i_small_nmalloc)},
383 {NAME("ndalloc"), CTL(stats_arenas_i_small_ndalloc)},
384 {NAME("nrequests"), CTL(stats_arenas_i_small_nrequests)}
Jason Evans3c234352010-01-27 13:10:55 -0800385};
386
Jason Evans7d63fed2016-05-31 14:50:21 -0700387static const ctl_named_node_t stats_arenas_i_large_node[] = {
388 {NAME("allocated"), CTL(stats_arenas_i_large_allocated)},
389 {NAME("nmalloc"), CTL(stats_arenas_i_large_nmalloc)},
390 {NAME("ndalloc"), CTL(stats_arenas_i_large_ndalloc)},
391 {NAME("nrequests"), CTL(stats_arenas_i_large_nrequests)}
Jason Evanse2deab72014-05-15 22:22:27 -0700392};
393
Qi Wang64c5f5c2017-03-13 17:29:03 -0700394#define MUTEX_PROF_DATA_NODE(prefix) \
Qi Wangca9074d2017-03-11 20:28:31 -0800395static const ctl_named_node_t stats_##prefix##_node[] = { \
Qi Wang0fb5c0e2017-03-10 12:14:05 -0800396 {NAME("num_ops"), \
Qi Wangca9074d2017-03-11 20:28:31 -0800397 CTL(stats_##prefix##_num_ops)}, \
Qi Wang0fb5c0e2017-03-10 12:14:05 -0800398 {NAME("num_wait"), \
Qi Wangca9074d2017-03-11 20:28:31 -0800399 CTL(stats_##prefix##_num_wait)}, \
Qi Wang0fb5c0e2017-03-10 12:14:05 -0800400 {NAME("num_spin_acq"), \
Qi Wangca9074d2017-03-11 20:28:31 -0800401 CTL(stats_##prefix##_num_spin_acq)}, \
Qi Wang0fb5c0e2017-03-10 12:14:05 -0800402 {NAME("num_owner_switch"), \
Qi Wangca9074d2017-03-11 20:28:31 -0800403 CTL(stats_##prefix##_num_owner_switch)}, \
Qi Wang0fb5c0e2017-03-10 12:14:05 -0800404 {NAME("total_wait_time"), \
Qi Wangca9074d2017-03-11 20:28:31 -0800405 CTL(stats_##prefix##_total_wait_time)}, \
Qi Wang0fb5c0e2017-03-10 12:14:05 -0800406 {NAME("max_wait_time"), \
Qi Wangca9074d2017-03-11 20:28:31 -0800407 CTL(stats_##prefix##_max_wait_time)}, \
Qi Wang0fb5c0e2017-03-10 12:14:05 -0800408 {NAME("max_num_thds"), \
Qi Wangca9074d2017-03-11 20:28:31 -0800409 CTL(stats_##prefix##_max_num_thds)} \
Qi Wang0fb5c0e2017-03-10 12:14:05 -0800410 /* Note that # of current waiting thread not provided. */ \
411};
412
Qi Wang64c5f5c2017-03-13 17:29:03 -0700413MUTEX_PROF_DATA_NODE(arenas_i_bins_j_mutex)
Qi Wangca9074d2017-03-11 20:28:31 -0800414
Mike Hommey461ad5c2012-04-20 08:38:42 +0200415static const ctl_named_node_t stats_arenas_i_bins_j_node[] = {
Jason Evans3c4d92e2014-10-12 22:53:59 -0700416 {NAME("nmalloc"), CTL(stats_arenas_i_bins_j_nmalloc)},
417 {NAME("ndalloc"), CTL(stats_arenas_i_bins_j_ndalloc)},
418 {NAME("nrequests"), CTL(stats_arenas_i_bins_j_nrequests)},
419 {NAME("curregs"), CTL(stats_arenas_i_bins_j_curregs)},
420 {NAME("nfills"), CTL(stats_arenas_i_bins_j_nfills)},
421 {NAME("nflushes"), CTL(stats_arenas_i_bins_j_nflushes)},
Jason Evans498856f2016-05-29 18:34:50 -0700422 {NAME("nslabs"), CTL(stats_arenas_i_bins_j_nslabs)},
423 {NAME("nreslabs"), CTL(stats_arenas_i_bins_j_nreslabs)},
Qi Wanga4f176a2017-03-03 19:58:43 -0800424 {NAME("curslabs"), CTL(stats_arenas_i_bins_j_curslabs)},
Qi Wang64c5f5c2017-03-13 17:29:03 -0700425 {NAME("mutex"), CHILD(named, stats_arenas_i_bins_j_mutex)}
Jason Evans3c234352010-01-27 13:10:55 -0800426};
Qi Wang0fb5c0e2017-03-10 12:14:05 -0800427
Mike Hommey461ad5c2012-04-20 08:38:42 +0200428static const ctl_named_node_t super_stats_arenas_i_bins_j_node[] = {
Jason Evans3c4d92e2014-10-12 22:53:59 -0700429 {NAME(""), CHILD(named, stats_arenas_i_bins_j)}
Jason Evans3c234352010-01-27 13:10:55 -0800430};
431
Mike Hommey461ad5c2012-04-20 08:38:42 +0200432static const ctl_indexed_node_t stats_arenas_i_bins_node[] = {
Jason Evans3c234352010-01-27 13:10:55 -0800433 {INDEX(stats_arenas_i_bins_j)}
434};
435
Jason Evans7d63fed2016-05-31 14:50:21 -0700436static const ctl_named_node_t stats_arenas_i_lextents_j_node[] = {
437 {NAME("nmalloc"), CTL(stats_arenas_i_lextents_j_nmalloc)},
438 {NAME("ndalloc"), CTL(stats_arenas_i_lextents_j_ndalloc)},
439 {NAME("nrequests"), CTL(stats_arenas_i_lextents_j_nrequests)},
440 {NAME("curlextents"), CTL(stats_arenas_i_lextents_j_curlextents)}
Jason Evans3c4d92e2014-10-12 22:53:59 -0700441};
Jason Evans7d63fed2016-05-31 14:50:21 -0700442static const ctl_named_node_t super_stats_arenas_i_lextents_j_node[] = {
443 {NAME(""), CHILD(named, stats_arenas_i_lextents_j)}
Jason Evans3c4d92e2014-10-12 22:53:59 -0700444};
445
Jason Evans7d63fed2016-05-31 14:50:21 -0700446static const ctl_indexed_node_t stats_arenas_i_lextents_node[] = {
447 {INDEX(stats_arenas_i_lextents_j)}
Jason Evans3c4d92e2014-10-12 22:53:59 -0700448};
449
Qi Wangd3fde1c2017-03-21 11:56:38 -0700450#define OP(mtx) MUTEX_PROF_DATA_NODE(arenas_i_mutexes_##mtx)
David Goldblatt89e2d3c2017-04-24 17:09:56 -0700451MUTEX_PROF_ARENA_MUTEXES
Qi Wangd3fde1c2017-03-21 11:56:38 -0700452#undef OP
Qi Wang0fb5c0e2017-03-10 12:14:05 -0800453
Qi Wang64c5f5c2017-03-13 17:29:03 -0700454static const ctl_named_node_t stats_arenas_i_mutexes_node[] = {
Qi Wangd3fde1c2017-03-21 11:56:38 -0700455#define OP(mtx) {NAME(#mtx), CHILD(named, stats_arenas_i_mutexes_##mtx)},
David Goldblatt89e2d3c2017-04-24 17:09:56 -0700456MUTEX_PROF_ARENA_MUTEXES
Qi Wangd3fde1c2017-03-21 11:56:38 -0700457#undef OP
Qi Wang0fb5c0e2017-03-10 12:14:05 -0800458};
Qi Wang0fb5c0e2017-03-10 12:14:05 -0800459
Mike Hommey461ad5c2012-04-20 08:38:42 +0200460static const ctl_named_node_t stats_arenas_i_node[] = {
Jason Evans3c4d92e2014-10-12 22:53:59 -0700461 {NAME("nthreads"), CTL(stats_arenas_i_nthreads)},
Qi Wangbaf3e292017-05-16 13:56:00 -0700462 {NAME("uptime"), CTL(stats_arenas_i_uptime)},
Jason Evans3c4d92e2014-10-12 22:53:59 -0700463 {NAME("dss"), CTL(stats_arenas_i_dss)},
Jason Evans6e62c622017-05-17 10:47:00 -0700464 {NAME("dirty_decay_ms"), CTL(stats_arenas_i_dirty_decay_ms)},
465 {NAME("muzzy_decay_ms"), CTL(stats_arenas_i_muzzy_decay_ms)},
Jason Evans3c4d92e2014-10-12 22:53:59 -0700466 {NAME("pactive"), CTL(stats_arenas_i_pactive)},
467 {NAME("pdirty"), CTL(stats_arenas_i_pdirty)},
Jason Evans64e458f2017-03-08 22:42:57 -0800468 {NAME("pmuzzy"), CTL(stats_arenas_i_pmuzzy)},
Jason Evans3c4d92e2014-10-12 22:53:59 -0700469 {NAME("mapped"), CTL(stats_arenas_i_mapped)},
Jason Evans04c3c0f2016-05-03 22:11:35 -0700470 {NAME("retained"), CTL(stats_arenas_i_retained)},
Jason Evans64e458f2017-03-08 22:42:57 -0800471 {NAME("dirty_npurge"), CTL(stats_arenas_i_dirty_npurge)},
472 {NAME("dirty_nmadvise"), CTL(stats_arenas_i_dirty_nmadvise)},
473 {NAME("dirty_purged"), CTL(stats_arenas_i_dirty_purged)},
474 {NAME("muzzy_npurge"), CTL(stats_arenas_i_muzzy_npurge)},
475 {NAME("muzzy_nmadvise"), CTL(stats_arenas_i_muzzy_nmadvise)},
476 {NAME("muzzy_purged"), CTL(stats_arenas_i_muzzy_purged)},
Jason Evansa0dd3a42016-12-22 16:39:10 -0600477 {NAME("base"), CTL(stats_arenas_i_base)},
478 {NAME("internal"), CTL(stats_arenas_i_internal)},
Qi Wang58424e62016-04-22 18:37:44 -0700479 {NAME("tcache_bytes"), CTL(stats_arenas_i_tcache_bytes)},
Jason Evansa0dd3a42016-12-22 16:39:10 -0600480 {NAME("resident"), CTL(stats_arenas_i_resident)},
Jason Evans3c4d92e2014-10-12 22:53:59 -0700481 {NAME("small"), CHILD(named, stats_arenas_i_small)},
Jason Evans7d63fed2016-05-31 14:50:21 -0700482 {NAME("large"), CHILD(named, stats_arenas_i_large)},
Jason Evans3c4d92e2014-10-12 22:53:59 -0700483 {NAME("bins"), CHILD(indexed, stats_arenas_i_bins)},
Qi Wang0fb5c0e2017-03-10 12:14:05 -0800484 {NAME("lextents"), CHILD(indexed, stats_arenas_i_lextents)},
Qi Wang64c5f5c2017-03-13 17:29:03 -0700485 {NAME("mutexes"), CHILD(named, stats_arenas_i_mutexes)}
Jason Evans3c234352010-01-27 13:10:55 -0800486};
Mike Hommey461ad5c2012-04-20 08:38:42 +0200487static const ctl_named_node_t super_stats_arenas_i_node[] = {
Jason Evans3c4d92e2014-10-12 22:53:59 -0700488 {NAME(""), CHILD(named, stats_arenas_i)}
Jason Evans3c234352010-01-27 13:10:55 -0800489};
490
Mike Hommey461ad5c2012-04-20 08:38:42 +0200491static const ctl_indexed_node_t stats_arenas_node[] = {
Jason Evans3c234352010-01-27 13:10:55 -0800492 {INDEX(stats_arenas_i)}
493};
494
Qi Wang2bee0c62017-05-12 12:30:33 -0700495static const ctl_named_node_t stats_background_thread_node[] = {
496 {NAME("num_threads"), CTL(stats_background_thread_num_threads)},
497 {NAME("num_runs"), CTL(stats_background_thread_num_runs)},
498 {NAME("run_interval"), CTL(stats_background_thread_run_interval)}
499};
500
Qi Wangd3fde1c2017-03-21 11:56:38 -0700501#define OP(mtx) MUTEX_PROF_DATA_NODE(mutexes_##mtx)
David Goldblatt89e2d3c2017-04-24 17:09:56 -0700502MUTEX_PROF_GLOBAL_MUTEXES
Qi Wangd3fde1c2017-03-21 11:56:38 -0700503#undef OP
504
Qi Wang64c5f5c2017-03-13 17:29:03 -0700505static const ctl_named_node_t stats_mutexes_node[] = {
Qi Wangd3fde1c2017-03-21 11:56:38 -0700506#define OP(mtx) {NAME(#mtx), CHILD(named, stats_mutexes_##mtx)},
David Goldblatt89e2d3c2017-04-24 17:09:56 -0700507MUTEX_PROF_GLOBAL_MUTEXES
Qi Wangd3fde1c2017-03-21 11:56:38 -0700508#undef OP
Qi Wang64c5f5c2017-03-13 17:29:03 -0700509 {NAME("reset"), CTL(stats_mutexes_reset)}
Qi Wangca9074d2017-03-11 20:28:31 -0800510};
Qi Wangd3fde1c2017-03-21 11:56:38 -0700511#undef MUTEX_PROF_DATA_NODE
Qi Wangca9074d2017-03-11 20:28:31 -0800512
Mike Hommey461ad5c2012-04-20 08:38:42 +0200513static const ctl_named_node_t stats_node[] = {
Jason Evans3c4d92e2014-10-12 22:53:59 -0700514 {NAME("allocated"), CTL(stats_allocated)},
515 {NAME("active"), CTL(stats_active)},
Jason Evans4581b972014-11-27 17:22:36 -0200516 {NAME("metadata"), CTL(stats_metadata)},
Jason Evans4acd75a2015-03-23 17:25:57 -0700517 {NAME("resident"), CTL(stats_resident)},
Jason Evans3c4d92e2014-10-12 22:53:59 -0700518 {NAME("mapped"), CTL(stats_mapped)},
Jason Evans04c3c0f2016-05-03 22:11:35 -0700519 {NAME("retained"), CTL(stats_retained)},
Qi Wang2bee0c62017-05-12 12:30:33 -0700520 {NAME("background_thread"),
521 CHILD(named, stats_background_thread)},
Qi Wang64c5f5c2017-03-13 17:29:03 -0700522 {NAME("mutexes"), CHILD(named, stats_mutexes)},
Jason Evans3c4d92e2014-10-12 22:53:59 -0700523 {NAME("arenas"), CHILD(indexed, stats_arenas)}
Jason Evans3c234352010-01-27 13:10:55 -0800524};
525
Mike Hommey461ad5c2012-04-20 08:38:42 +0200526static const ctl_named_node_t root_node[] = {
Jason Evansa40bc7a2010-03-02 13:01:16 -0800527 {NAME("version"), CTL(version)},
Jason Evans3c234352010-01-27 13:10:55 -0800528 {NAME("epoch"), CTL(epoch)},
Qi Wangb693c782017-03-17 12:42:33 -0700529 {NAME("background_thread"), CTL(background_thread)},
Jason Evans65f343a2012-04-23 19:31:45 -0700530 {NAME("thread"), CHILD(named, thread)},
531 {NAME("config"), CHILD(named, config)},
532 {NAME("opt"), CHILD(named, opt)},
Jason Evans1cb181e2015-01-29 15:30:47 -0800533 {NAME("tcache"), CHILD(named, tcache)},
Jason Evans609ae592012-10-11 13:53:15 -0700534 {NAME("arena"), CHILD(indexed, arena)},
Jason Evans65f343a2012-04-23 19:31:45 -0700535 {NAME("arenas"), CHILD(named, arenas)},
536 {NAME("prof"), CHILD(named, prof)},
537 {NAME("stats"), CHILD(named, stats)}
Jason Evans3c234352010-01-27 13:10:55 -0800538};
Mike Hommey461ad5c2012-04-20 08:38:42 +0200539static const ctl_named_node_t super_root_node[] = {
Jason Evans65f343a2012-04-23 19:31:45 -0700540 {NAME(""), CHILD(named, root)}
Jason Evans3c234352010-01-27 13:10:55 -0800541};
542
543#undef NAME
544#undef CHILD
545#undef CTL
546#undef INDEX
547
548/******************************************************************************/
549
David Goldblatt4fc2acf2017-03-08 15:56:31 -0800550/*
551 * Sets *dst + *src non-atomically. This is safe, since everything is
552 * synchronized by the ctl mutex.
553 */
554static void
555accum_arena_stats_u64(arena_stats_u64_t *dst, arena_stats_u64_t *src) {
556#ifdef JEMALLOC_ATOMIC_U64
557 uint64_t cur_dst = atomic_load_u64(dst, ATOMIC_RELAXED);
558 uint64_t cur_src = atomic_load_u64(src, ATOMIC_RELAXED);
559 atomic_store_u64(dst, cur_dst + cur_src, ATOMIC_RELAXED);
560#else
561 *dst += *src;
562#endif
563}
564
565/* Likewise: with ctl mutex synchronization, reading is simple. */
566static uint64_t
567arena_stats_read_u64(arena_stats_u64_t *p) {
568#ifdef JEMALLOC_ATOMIC_U64
569 return atomic_load_u64(p, ATOMIC_RELAXED);
570#else
571 return *p;
572#endif
573}
574
David Goldblattee202ef2017-03-13 16:18:40 -0700575static void accum_atomic_zu(atomic_zu_t *dst, atomic_zu_t *src) {
576 size_t cur_dst = atomic_load_zu(dst, ATOMIC_RELAXED);
577 size_t cur_src = atomic_load_zu(src, ATOMIC_RELAXED);
578 atomic_store_zu(dst, cur_dst + cur_src, ATOMIC_RELAXED);
579}
580
David Goldblatt4fc2acf2017-03-08 15:56:31 -0800581/******************************************************************************/
582
Jason Evans3dc4e832017-01-03 07:27:42 -0800583static unsigned
Jason Evansc4c25922017-01-15 16:56:30 -0800584arenas_i2a_impl(size_t i, bool compat, bool validate) {
Jason Evans3dc4e832017-01-03 07:27:42 -0800585 unsigned a;
586
Jason Evans3dc4e832017-01-03 07:27:42 -0800587 switch (i) {
588 case MALLCTL_ARENAS_ALL:
589 a = 0;
590 break;
Jason Evansedf1baf2017-01-03 17:21:59 -0800591 case MALLCTL_ARENAS_DESTROYED:
592 a = 1;
593 break;
Jason Evans3dc4e832017-01-03 07:27:42 -0800594 default:
Jason Evans9eb1b1c2017-01-18 23:03:37 -0800595 if (compat && i == ctl_arenas->narenas) {
Jason Evans3dc4e832017-01-03 07:27:42 -0800596 /*
597 * Provide deprecated backward compatibility for
598 * accessing the merged stats at index narenas rather
599 * than via MALLCTL_ARENAS_ALL. This is scheduled for
600 * removal in 6.0.0.
601 */
602 a = 0;
Jason Evansc4c25922017-01-15 16:56:30 -0800603 } else if (validate && i >= ctl_arenas->narenas) {
Jason Evans3dc4e832017-01-03 07:27:42 -0800604 a = UINT_MAX;
Jason Evansc4c25922017-01-15 16:56:30 -0800605 } else {
Jason Evans3dc4e832017-01-03 07:27:42 -0800606 /*
607 * This function should never be called for an index
608 * more than one past the range of indices that have
Jason Evans9eb1b1c2017-01-18 23:03:37 -0800609 * initialized ctl data.
Jason Evans3dc4e832017-01-03 07:27:42 -0800610 */
Jason Evans9eb1b1c2017-01-18 23:03:37 -0800611 assert(i < ctl_arenas->narenas || (!validate && i ==
612 ctl_arenas->narenas));
Jason Evansedf1baf2017-01-03 17:21:59 -0800613 a = (unsigned)i + 2;
Jason Evans3dc4e832017-01-03 07:27:42 -0800614 }
615 break;
616 }
617
Jason Evansf4086432017-01-19 18:15:45 -0800618 return a;
Jason Evans3dc4e832017-01-03 07:27:42 -0800619}
620
Jason Evansedf1baf2017-01-03 17:21:59 -0800621static unsigned
Jason Evansc4c25922017-01-15 16:56:30 -0800622arenas_i2a(size_t i) {
Jason Evansf4086432017-01-19 18:15:45 -0800623 return arenas_i2a_impl(i, true, false);
Jason Evansedf1baf2017-01-03 17:21:59 -0800624}
625
Jason Evans9eb1b1c2017-01-18 23:03:37 -0800626static ctl_arena_t *
Qi Wang57beeb22017-06-22 18:58:40 -0700627arenas_i_impl(tsd_t *tsd, size_t i, bool compat, bool init) {
Jason Evans9eb1b1c2017-01-18 23:03:37 -0800628 ctl_arena_t *ret;
Jason Evansd778dd22017-01-03 12:40:54 -0800629
630 assert(!compat || !init);
631
Jason Evans9eb1b1c2017-01-18 23:03:37 -0800632 ret = ctl_arenas->arenas[arenas_i2a_impl(i, compat, false)];
Jason Evansd778dd22017-01-03 12:40:54 -0800633 if (init && ret == NULL) {
Jason Evans9eb1b1c2017-01-18 23:03:37 -0800634 if (config_stats) {
635 struct container_s {
636 ctl_arena_t ctl_arena;
637 ctl_arena_stats_t astats;
638 };
639 struct container_s *cont =
Qi Wang57beeb22017-06-22 18:58:40 -0700640 (struct container_s *)base_alloc(tsd_tsdn(tsd),
641 b0get(), sizeof(struct container_s), QUANTUM);
Jason Evans9eb1b1c2017-01-18 23:03:37 -0800642 if (cont == NULL) {
643 return NULL;
644 }
645 ret = &cont->ctl_arena;
646 ret->astats = &cont->astats;
647 } else {
Qi Wang57beeb22017-06-22 18:58:40 -0700648 ret = (ctl_arena_t *)base_alloc(tsd_tsdn(tsd), b0get(),
Jason Evans9eb1b1c2017-01-18 23:03:37 -0800649 sizeof(ctl_arena_t), QUANTUM);
650 if (ret == NULL) {
651 return NULL;
652 }
653 }
Jason Evansedf1baf2017-01-03 17:21:59 -0800654 ret->arena_ind = (unsigned)i;
Jason Evans9eb1b1c2017-01-18 23:03:37 -0800655 ctl_arenas->arenas[arenas_i2a_impl(i, compat, false)] = ret;
Jason Evansd778dd22017-01-03 12:40:54 -0800656 }
657
Jason Evans9eb1b1c2017-01-18 23:03:37 -0800658 assert(ret == NULL || arenas_i2a(ret->arena_ind) == arenas_i2a(i));
Jason Evansf4086432017-01-19 18:15:45 -0800659 return ret;
Jason Evansd778dd22017-01-03 12:40:54 -0800660}
661
Jason Evans9eb1b1c2017-01-18 23:03:37 -0800662static ctl_arena_t *
Jason Evansc4c25922017-01-15 16:56:30 -0800663arenas_i(size_t i) {
Qi Wang57beeb22017-06-22 18:58:40 -0700664 ctl_arena_t *ret = arenas_i_impl(tsd_fetch(), i, true, false);
Jason Evansd778dd22017-01-03 12:40:54 -0800665 assert(ret != NULL);
Jason Evansf4086432017-01-19 18:15:45 -0800666 return ret;
Jason Evans3dc4e832017-01-03 07:27:42 -0800667}
668
Jason Evans3c234352010-01-27 13:10:55 -0800669static void
Jason Evansc4c25922017-01-15 16:56:30 -0800670ctl_arena_clear(ctl_arena_t *ctl_arena) {
Jason Evans9eb1b1c2017-01-18 23:03:37 -0800671 ctl_arena->nthreads = 0;
672 ctl_arena->dss = dss_prec_names[dss_prec_limit];
Jason Evans6e62c622017-05-17 10:47:00 -0700673 ctl_arena->dirty_decay_ms = -1;
674 ctl_arena->muzzy_decay_ms = -1;
Jason Evans9eb1b1c2017-01-18 23:03:37 -0800675 ctl_arena->pactive = 0;
676 ctl_arena->pdirty = 0;
Jason Evans64e458f2017-03-08 22:42:57 -0800677 ctl_arena->pmuzzy = 0;
Jason Evans7372b152012-02-10 20:22:09 -0800678 if (config_stats) {
Jason Evans9eb1b1c2017-01-18 23:03:37 -0800679 memset(&ctl_arena->astats->astats, 0, sizeof(arena_stats_t));
680 ctl_arena->astats->allocated_small = 0;
681 ctl_arena->astats->nmalloc_small = 0;
682 ctl_arena->astats->ndalloc_small = 0;
683 ctl_arena->astats->nrequests_small = 0;
684 memset(ctl_arena->astats->bstats, 0, NBINS *
685 sizeof(malloc_bin_stats_t));
686 memset(ctl_arena->astats->lstats, 0, (NSIZES - NBINS) *
Jason Evans7d63fed2016-05-31 14:50:21 -0700687 sizeof(malloc_large_stats_t));
Jason Evans7372b152012-02-10 20:22:09 -0800688 }
Jason Evans3c234352010-01-27 13:10:55 -0800689}
690
Jason Evans86815df2010-03-13 20:32:56 -0800691static void
Jason Evansc4c25922017-01-15 16:56:30 -0800692ctl_arena_stats_amerge(tsdn_t *tsdn, ctl_arena_t *ctl_arena, arena_t *arena) {
Jason Evans86815df2010-03-13 20:32:56 -0800693 unsigned i;
694
Jason Evans3c07f802016-02-27 20:40:13 -0800695 if (config_stats) {
Jason Evans9eb1b1c2017-01-18 23:03:37 -0800696 arena_stats_merge(tsdn, arena, &ctl_arena->nthreads,
Jason Evans6e62c622017-05-17 10:47:00 -0700697 &ctl_arena->dss, &ctl_arena->dirty_decay_ms,
698 &ctl_arena->muzzy_decay_ms, &ctl_arena->pactive,
Jason Evans64e458f2017-03-08 22:42:57 -0800699 &ctl_arena->pdirty, &ctl_arena->pmuzzy,
Jason Evans9eb1b1c2017-01-18 23:03:37 -0800700 &ctl_arena->astats->astats, ctl_arena->astats->bstats,
701 ctl_arena->astats->lstats);
Jason Evans86815df2010-03-13 20:32:56 -0800702
Jason Evans3c07f802016-02-27 20:40:13 -0800703 for (i = 0; i < NBINS; i++) {
Jason Evans9eb1b1c2017-01-18 23:03:37 -0800704 ctl_arena->astats->allocated_small +=
705 ctl_arena->astats->bstats[i].curregs *
David Goldblatt8261e582017-05-30 10:45:37 -0700706 sz_index2size(i);
Jason Evans9eb1b1c2017-01-18 23:03:37 -0800707 ctl_arena->astats->nmalloc_small +=
708 ctl_arena->astats->bstats[i].nmalloc;
709 ctl_arena->astats->ndalloc_small +=
710 ctl_arena->astats->bstats[i].ndalloc;
711 ctl_arena->astats->nrequests_small +=
712 ctl_arena->astats->bstats[i].nrequests;
Jason Evans3c07f802016-02-27 20:40:13 -0800713 }
714 } else {
Jason Evans9eb1b1c2017-01-18 23:03:37 -0800715 arena_basic_stats_merge(tsdn, arena, &ctl_arena->nthreads,
Jason Evans6e62c622017-05-17 10:47:00 -0700716 &ctl_arena->dss, &ctl_arena->dirty_decay_ms,
717 &ctl_arena->muzzy_decay_ms, &ctl_arena->pactive,
Jason Evans64e458f2017-03-08 22:42:57 -0800718 &ctl_arena->pdirty, &ctl_arena->pmuzzy);
Jason Evans86815df2010-03-13 20:32:56 -0800719 }
Jason Evans86815df2010-03-13 20:32:56 -0800720}
721
722static void
Jason Evans9eb1b1c2017-01-18 23:03:37 -0800723ctl_arena_stats_sdmerge(ctl_arena_t *ctl_sdarena, ctl_arena_t *ctl_arena,
Jason Evansc4c25922017-01-15 16:56:30 -0800724 bool destroyed) {
Jason Evans86815df2010-03-13 20:32:56 -0800725 unsigned i;
726
Jason Evansedf1baf2017-01-03 17:21:59 -0800727 if (!destroyed) {
Jason Evans9eb1b1c2017-01-18 23:03:37 -0800728 ctl_sdarena->nthreads += ctl_arena->nthreads;
729 ctl_sdarena->pactive += ctl_arena->pactive;
730 ctl_sdarena->pdirty += ctl_arena->pdirty;
Jason Evans64e458f2017-03-08 22:42:57 -0800731 ctl_sdarena->pmuzzy += ctl_arena->pmuzzy;
Jason Evansedf1baf2017-01-03 17:21:59 -0800732 } else {
Jason Evans9eb1b1c2017-01-18 23:03:37 -0800733 assert(ctl_arena->nthreads == 0);
734 assert(ctl_arena->pactive == 0);
735 assert(ctl_arena->pdirty == 0);
Jason Evans64e458f2017-03-08 22:42:57 -0800736 assert(ctl_arena->pmuzzy == 0);
Jason Evansedf1baf2017-01-03 17:21:59 -0800737 }
Jason Evans86815df2010-03-13 20:32:56 -0800738
Jason Evans3c07f802016-02-27 20:40:13 -0800739 if (config_stats) {
Jason Evans9eb1b1c2017-01-18 23:03:37 -0800740 ctl_arena_stats_t *sdstats = ctl_sdarena->astats;
741 ctl_arena_stats_t *astats = ctl_arena->astats;
742
Jason Evansedf1baf2017-01-03 17:21:59 -0800743 if (!destroyed) {
David Goldblattee202ef2017-03-13 16:18:40 -0700744 accum_atomic_zu(&sdstats->astats.mapped,
745 &astats->astats.mapped);
746 accum_atomic_zu(&sdstats->astats.retained,
747 &astats->astats.retained);
Jason Evansedf1baf2017-01-03 17:21:59 -0800748 }
Jason Evans64e458f2017-03-08 22:42:57 -0800749
750 accum_arena_stats_u64(&sdstats->astats.decay_dirty.npurge,
751 &astats->astats.decay_dirty.npurge);
752 accum_arena_stats_u64(&sdstats->astats.decay_dirty.nmadvise,
753 &astats->astats.decay_dirty.nmadvise);
754 accum_arena_stats_u64(&sdstats->astats.decay_dirty.purged,
755 &astats->astats.decay_dirty.purged);
756
757 accum_arena_stats_u64(&sdstats->astats.decay_muzzy.npurge,
758 &astats->astats.decay_muzzy.npurge);
759 accum_arena_stats_u64(&sdstats->astats.decay_muzzy.nmadvise,
760 &astats->astats.decay_muzzy.nmadvise);
761 accum_arena_stats_u64(&sdstats->astats.decay_muzzy.purged,
762 &astats->astats.decay_muzzy.purged);
Jason Evans86815df2010-03-13 20:32:56 -0800763
Qi Wangd3fde1c2017-03-21 11:56:38 -0700764#define OP(mtx) malloc_mutex_prof_merge( \
765 &(sdstats->astats.mutex_prof_data[ \
766 arena_prof_mutex_##mtx]), \
767 &(astats->astats.mutex_prof_data[ \
768 arena_prof_mutex_##mtx]));
David Goldblatt89e2d3c2017-04-24 17:09:56 -0700769MUTEX_PROF_ARENA_MUTEXES
Qi Wangd3fde1c2017-03-21 11:56:38 -0700770#undef OP
Jason Evansedf1baf2017-01-03 17:21:59 -0800771 if (!destroyed) {
David Goldblattee202ef2017-03-13 16:18:40 -0700772 accum_atomic_zu(&sdstats->astats.base,
773 &astats->astats.base);
774 accum_atomic_zu(&sdstats->astats.internal,
775 &astats->astats.internal);
776 accum_atomic_zu(&sdstats->astats.resident,
777 &astats->astats.resident);
Jason Evansc4c25922017-01-15 16:56:30 -0800778 } else {
David Goldblattee202ef2017-03-13 16:18:40 -0700779 assert(atomic_load_zu(
780 &astats->astats.internal, ATOMIC_RELAXED) == 0);
Jason Evansc4c25922017-01-15 16:56:30 -0800781 }
Jason Evans4581b972014-11-27 17:22:36 -0200782
Jason Evansc4c25922017-01-15 16:56:30 -0800783 if (!destroyed) {
Jason Evansedf1baf2017-01-03 17:21:59 -0800784 sdstats->allocated_small += astats->allocated_small;
Jason Evansc4c25922017-01-15 16:56:30 -0800785 } else {
Jason Evansedf1baf2017-01-03 17:21:59 -0800786 assert(astats->allocated_small == 0);
Jason Evansc4c25922017-01-15 16:56:30 -0800787 }
Jason Evansedf1baf2017-01-03 17:21:59 -0800788 sdstats->nmalloc_small += astats->nmalloc_small;
789 sdstats->ndalloc_small += astats->ndalloc_small;
790 sdstats->nrequests_small += astats->nrequests_small;
Jason Evans86815df2010-03-13 20:32:56 -0800791
Jason Evansedf1baf2017-01-03 17:21:59 -0800792 if (!destroyed) {
David Goldblattee202ef2017-03-13 16:18:40 -0700793 accum_atomic_zu(&sdstats->astats.allocated_large,
794 &astats->astats.allocated_large);
Jason Evansc4c25922017-01-15 16:56:30 -0800795 } else {
David Goldblattee202ef2017-03-13 16:18:40 -0700796 assert(atomic_load_zu(&astats->astats.allocated_large,
797 ATOMIC_RELAXED) == 0);
Jason Evansc4c25922017-01-15 16:56:30 -0800798 }
David Goldblatt4fc2acf2017-03-08 15:56:31 -0800799 accum_arena_stats_u64(&sdstats->astats.nmalloc_large,
800 &astats->astats.nmalloc_large);
801 accum_arena_stats_u64(&sdstats->astats.ndalloc_large,
802 &astats->astats.ndalloc_large);
803 accum_arena_stats_u64(&sdstats->astats.nrequests_large,
804 &astats->astats.nrequests_large);
Jason Evans86815df2010-03-13 20:32:56 -0800805
Jason Evans4403c9a2017-04-20 17:21:37 -0700806 accum_atomic_zu(&sdstats->astats.tcache_bytes,
807 &astats->astats.tcache_bytes);
Qi Wang58424e62016-04-22 18:37:44 -0700808
Qi Wangbaf3e292017-05-16 13:56:00 -0700809 if (ctl_arena->arena_ind == 0) {
810 sdstats->astats.uptime = astats->astats.uptime;
811 }
812
Jason Evans3c07f802016-02-27 20:40:13 -0800813 for (i = 0; i < NBINS; i++) {
Jason Evansedf1baf2017-01-03 17:21:59 -0800814 sdstats->bstats[i].nmalloc += astats->bstats[i].nmalloc;
815 sdstats->bstats[i].ndalloc += astats->bstats[i].ndalloc;
816 sdstats->bstats[i].nrequests +=
Jason Evans3c07f802016-02-27 20:40:13 -0800817 astats->bstats[i].nrequests;
Jason Evansedf1baf2017-01-03 17:21:59 -0800818 if (!destroyed) {
819 sdstats->bstats[i].curregs +=
820 astats->bstats[i].curregs;
Jason Evansc4c25922017-01-15 16:56:30 -0800821 } else {
Jason Evansedf1baf2017-01-03 17:21:59 -0800822 assert(astats->bstats[i].curregs == 0);
Jason Evansc4c25922017-01-15 16:56:30 -0800823 }
Jason Evans4403c9a2017-04-20 17:21:37 -0700824 sdstats->bstats[i].nfills += astats->bstats[i].nfills;
825 sdstats->bstats[i].nflushes +=
826 astats->bstats[i].nflushes;
Jason Evansedf1baf2017-01-03 17:21:59 -0800827 sdstats->bstats[i].nslabs += astats->bstats[i].nslabs;
828 sdstats->bstats[i].reslabs += astats->bstats[i].reslabs;
829 if (!destroyed) {
830 sdstats->bstats[i].curslabs +=
831 astats->bstats[i].curslabs;
Jason Evansc4c25922017-01-15 16:56:30 -0800832 } else {
Jason Evansedf1baf2017-01-03 17:21:59 -0800833 assert(astats->bstats[i].curslabs == 0);
Jason Evansc4c25922017-01-15 16:56:30 -0800834 }
Qi Wang64c5f5c2017-03-13 17:29:03 -0700835 malloc_mutex_prof_merge(&sdstats->bstats[i].mutex_data,
836 &astats->bstats[i].mutex_data);
Jason Evans7372b152012-02-10 20:22:09 -0800837 }
Jason Evans3c4d92e2014-10-12 22:53:59 -0700838
Jason Evansed2c2422016-05-28 00:17:28 -0700839 for (i = 0; i < NSIZES - NBINS; i++) {
David Goldblatt4fc2acf2017-03-08 15:56:31 -0800840 accum_arena_stats_u64(&sdstats->lstats[i].nmalloc,
841 &astats->lstats[i].nmalloc);
842 accum_arena_stats_u64(&sdstats->lstats[i].ndalloc,
843 &astats->lstats[i].ndalloc);
844 accum_arena_stats_u64(&sdstats->lstats[i].nrequests,
845 &astats->lstats[i].nrequests);
Jason Evansedf1baf2017-01-03 17:21:59 -0800846 if (!destroyed) {
847 sdstats->lstats[i].curlextents +=
848 astats->lstats[i].curlextents;
Jason Evansc4c25922017-01-15 16:56:30 -0800849 } else {
Jason Evansedf1baf2017-01-03 17:21:59 -0800850 assert(astats->lstats[i].curlextents == 0);
Jason Evansc4c25922017-01-15 16:56:30 -0800851 }
Jason Evans3c07f802016-02-27 20:40:13 -0800852 }
Jason Evans3c4d92e2014-10-12 22:53:59 -0700853 }
Jason Evans86815df2010-03-13 20:32:56 -0800854}
Jason Evans86815df2010-03-13 20:32:56 -0800855
Jason Evans3c234352010-01-27 13:10:55 -0800856static void
Jason Evans9eb1b1c2017-01-18 23:03:37 -0800857ctl_arena_refresh(tsdn_t *tsdn, arena_t *arena, ctl_arena_t *ctl_sdarena,
Jason Evansc4c25922017-01-15 16:56:30 -0800858 unsigned i, bool destroyed) {
Jason Evans9eb1b1c2017-01-18 23:03:37 -0800859 ctl_arena_t *ctl_arena = arenas_i(i);
Jason Evans3c234352010-01-27 13:10:55 -0800860
Jason Evans9eb1b1c2017-01-18 23:03:37 -0800861 ctl_arena_clear(ctl_arena);
862 ctl_arena_stats_amerge(tsdn, ctl_arena, arena);
Jason Evans3c07f802016-02-27 20:40:13 -0800863 /* Merge into sum stats as well. */
Jason Evans9eb1b1c2017-01-18 23:03:37 -0800864 ctl_arena_stats_sdmerge(ctl_sdarena, ctl_arena, destroyed);
Jason Evans3c234352010-01-27 13:10:55 -0800865}
866
Jason Evansedf1baf2017-01-03 17:21:59 -0800867static unsigned
Qi Wang57beeb22017-06-22 18:58:40 -0700868ctl_arena_init(tsd_t *tsd, extent_hooks_t *extent_hooks) {
Jason Evansedf1baf2017-01-03 17:21:59 -0800869 unsigned arena_ind;
Jason Evans9eb1b1c2017-01-18 23:03:37 -0800870 ctl_arena_t *ctl_arena;
Jason Evansedf1baf2017-01-03 17:21:59 -0800871
Jason Evans9eb1b1c2017-01-18 23:03:37 -0800872 if ((ctl_arena = ql_last(&ctl_arenas->destroyed, destroyed_link)) !=
873 NULL) {
874 ql_remove(&ctl_arenas->destroyed, ctl_arena, destroyed_link);
875 arena_ind = ctl_arena->arena_ind;
Jason Evansc4c25922017-01-15 16:56:30 -0800876 } else {
Jason Evans9eb1b1c2017-01-18 23:03:37 -0800877 arena_ind = ctl_arenas->narenas;
Jason Evansc4c25922017-01-15 16:56:30 -0800878 }
Jason Evansd778dd22017-01-03 12:40:54 -0800879
880 /* Trigger stats allocation. */
Qi Wang57beeb22017-06-22 18:58:40 -0700881 if (arenas_i_impl(tsd, arena_ind, false, true) == NULL) {
Jason Evansf4086432017-01-19 18:15:45 -0800882 return UINT_MAX;
Jason Evansc4c25922017-01-15 16:56:30 -0800883 }
Jason Evans609ae592012-10-11 13:53:15 -0700884
Jason Evans8bb31982014-10-07 23:14:57 -0700885 /* Initialize new arena. */
Qi Wang57beeb22017-06-22 18:58:40 -0700886 if (arena_init(tsd_tsdn(tsd), arena_ind, extent_hooks) == NULL) {
Jason Evansf4086432017-01-19 18:15:45 -0800887 return UINT_MAX;
Jason Evansc4c25922017-01-15 16:56:30 -0800888 }
Jason Evans609ae592012-10-11 13:53:15 -0700889
Jason Evansc4c25922017-01-15 16:56:30 -0800890 if (arena_ind == ctl_arenas->narenas) {
Jason Evans9eb1b1c2017-01-18 23:03:37 -0800891 ctl_arenas->narenas++;
Jason Evansc4c25922017-01-15 16:56:30 -0800892 }
Jason Evansedf1baf2017-01-03 17:21:59 -0800893
Jason Evansf4086432017-01-19 18:15:45 -0800894 return arena_ind;
Jason Evans609ae592012-10-11 13:53:15 -0700895}
896
Jason Evans3c234352010-01-27 13:10:55 -0800897static void
Qi Wang2bee0c62017-05-12 12:30:33 -0700898ctl_background_thread_stats_read(tsdn_t *tsdn) {
899 background_thread_stats_t *stats = &ctl_stats->background_thread;
900 if (!have_background_thread ||
901 background_thread_stats_read(tsdn, stats)) {
902 memset(stats, 0, sizeof(background_thread_stats_t));
903 nstime_init(&stats->run_interval, 0);
904 }
905}
906
907static void
Jason Evansc4c25922017-01-15 16:56:30 -0800908ctl_refresh(tsdn_t *tsdn) {
Jason Evans3c234352010-01-27 13:10:55 -0800909 unsigned i;
Jason Evans9eb1b1c2017-01-18 23:03:37 -0800910 ctl_arena_t *ctl_sarena = arenas_i(MALLCTL_ARENAS_ALL);
911 VARIABLE_ARRAY(arena_t *, tarenas, ctl_arenas->narenas);
Jason Evans3c234352010-01-27 13:10:55 -0800912
Jason Evans3c234352010-01-27 13:10:55 -0800913 /*
Jason Evans13668262010-01-31 03:57:29 -0800914 * Clear sum stats, since they will be merged into by
Jason Evans3c234352010-01-27 13:10:55 -0800915 * ctl_arena_refresh().
916 */
Jason Evans9eb1b1c2017-01-18 23:03:37 -0800917 ctl_arena_clear(ctl_sarena);
Jason Evans3c234352010-01-27 13:10:55 -0800918
Jason Evans9eb1b1c2017-01-18 23:03:37 -0800919 for (i = 0; i < ctl_arenas->narenas; i++) {
Jason Evansc1e00ef2016-05-10 22:21:10 -0700920 tarenas[i] = arena_get(tsdn, i, false);
Jason Evans9eb1b1c2017-01-18 23:03:37 -0800921 }
Jason Evans8bb31982014-10-07 23:14:57 -0700922
Jason Evans9eb1b1c2017-01-18 23:03:37 -0800923 for (i = 0; i < ctl_arenas->narenas; i++) {
924 ctl_arena_t *ctl_arena = arenas_i(i);
Jason Evans3c234352010-01-27 13:10:55 -0800925 bool initialized = (tarenas[i] != NULL);
926
Jason Evans9eb1b1c2017-01-18 23:03:37 -0800927 ctl_arena->initialized = initialized;
928 if (initialized) {
929 ctl_arena_refresh(tsdn, tarenas[i], ctl_sarena, i,
930 false);
931 }
Jason Evans3c234352010-01-27 13:10:55 -0800932 }
933
Jason Evans7372b152012-02-10 20:22:09 -0800934 if (config_stats) {
Jason Evans9eb1b1c2017-01-18 23:03:37 -0800935 ctl_stats->allocated = ctl_sarena->astats->allocated_small +
David Goldblattee202ef2017-03-13 16:18:40 -0700936 atomic_load_zu(&ctl_sarena->astats->astats.allocated_large,
937 ATOMIC_RELAXED);
Jason Evans9eb1b1c2017-01-18 23:03:37 -0800938 ctl_stats->active = (ctl_sarena->pactive << LG_PAGE);
David Goldblattee202ef2017-03-13 16:18:40 -0700939 ctl_stats->metadata = atomic_load_zu(
940 &ctl_sarena->astats->astats.base, ATOMIC_RELAXED) +
941 atomic_load_zu(&ctl_sarena->astats->astats.internal,
942 ATOMIC_RELAXED);
943 ctl_stats->resident = atomic_load_zu(
944 &ctl_sarena->astats->astats.resident, ATOMIC_RELAXED);
945 ctl_stats->mapped = atomic_load_zu(
946 &ctl_sarena->astats->astats.mapped, ATOMIC_RELAXED);
947 ctl_stats->retained = atomic_load_zu(
948 &ctl_sarena->astats->astats.retained, ATOMIC_RELAXED);
Qi Wangca9074d2017-03-11 20:28:31 -0800949
Qi Wang2bee0c62017-05-12 12:30:33 -0700950 ctl_background_thread_stats_read(tsdn);
951
Qi Wangd3fde1c2017-03-21 11:56:38 -0700952#define READ_GLOBAL_MUTEX_PROF_DATA(i, mtx) \
Qi Wangca9074d2017-03-11 20:28:31 -0800953 malloc_mutex_lock(tsdn, &mtx); \
Qi Wangd3fde1c2017-03-21 11:56:38 -0700954 malloc_mutex_prof_read(tsdn, &ctl_stats->mutex_prof_data[i], &mtx); \
Qi Wangca9074d2017-03-11 20:28:31 -0800955 malloc_mutex_unlock(tsdn, &mtx);
956
Qi Wangbd2006a2017-03-12 01:28:52 -0800957 if (config_prof && opt_prof) {
Qi Wangd3fde1c2017-03-21 11:56:38 -0700958 READ_GLOBAL_MUTEX_PROF_DATA(global_prof_mutex_prof,
959 bt2gctx_mtx);
Qi Wangbd2006a2017-03-12 01:28:52 -0800960 }
Qi Wang5f5ed212017-05-12 16:26:59 -0700961 if (have_background_thread) {
962 READ_GLOBAL_MUTEX_PROF_DATA(
963 global_prof_mutex_background_thread,
964 background_thread_lock);
965 } else {
966 memset(&ctl_stats->mutex_prof_data[
967 global_prof_mutex_background_thread], 0,
968 sizeof(mutex_prof_data_t));
969 }
Qi Wangca9074d2017-03-11 20:28:31 -0800970 /* We own ctl mutex already. */
Qi Wangd3fde1c2017-03-21 11:56:38 -0700971 malloc_mutex_prof_read(tsdn,
972 &ctl_stats->mutex_prof_data[global_prof_mutex_ctl],
973 &ctl_mtx);
Qi Wangca9074d2017-03-11 20:28:31 -0800974#undef READ_GLOBAL_MUTEX_PROF_DATA
Jason Evans7372b152012-02-10 20:22:09 -0800975 }
Jason Evans9eb1b1c2017-01-18 23:03:37 -0800976 ctl_arenas->epoch++;
Jason Evans3c234352010-01-27 13:10:55 -0800977}
978
979static bool
Qi Wang57beeb22017-06-22 18:58:40 -0700980ctl_init(tsd_t *tsd) {
Jason Evansfc4dcfa2010-11-24 15:44:21 -0800981 bool ret;
Qi Wang57beeb22017-06-22 18:58:40 -0700982 tsdn_t *tsdn = tsd_tsdn(tsd);
Jason Evans3c234352010-01-27 13:10:55 -0800983
Jason Evansc1e00ef2016-05-10 22:21:10 -0700984 malloc_mutex_lock(tsdn, &ctl_mtx);
Jason Evans551ebc42014-10-03 10:16:09 -0700985 if (!ctl_initialized) {
Jason Evans9eb1b1c2017-01-18 23:03:37 -0800986 ctl_arena_t *ctl_sarena, *ctl_darena;
Jason Evansd778dd22017-01-03 12:40:54 -0800987 unsigned i;
988
Jason Evans3c234352010-01-27 13:10:55 -0800989 /*
Jason Evans9eb1b1c2017-01-18 23:03:37 -0800990 * Allocate demand-zeroed space for pointers to the full
991 * range of supported arena indices.
Jason Evans3c234352010-01-27 13:10:55 -0800992 */
Jason Evans9eb1b1c2017-01-18 23:03:37 -0800993 if (ctl_arenas == NULL) {
994 ctl_arenas = (ctl_arenas_t *)base_alloc(tsdn,
995 b0get(), sizeof(ctl_arenas_t), QUANTUM);
996 if (ctl_arenas == NULL) {
997 ret = true;
998 goto label_return;
999 }
1000 }
1001
1002 if (config_stats && ctl_stats == NULL) {
Jason Evansd778dd22017-01-03 12:40:54 -08001003 ctl_stats = (ctl_stats_t *)base_alloc(tsdn, b0get(),
1004 sizeof(ctl_stats_t), QUANTUM);
1005 if (ctl_stats == NULL) {
1006 ret = true;
1007 goto label_return;
1008 }
1009 }
1010
1011 /*
Jason Evans9eb1b1c2017-01-18 23:03:37 -08001012 * Allocate space for the current full range of arenas
1013 * here rather than doing it lazily elsewhere, in order
1014 * to limit when OOM-caused errors can occur.
Jason Evansd778dd22017-01-03 12:40:54 -08001015 */
Qi Wang57beeb22017-06-22 18:58:40 -07001016 if ((ctl_sarena = arenas_i_impl(tsd, MALLCTL_ARENAS_ALL, false,
Jason Evans9eb1b1c2017-01-18 23:03:37 -08001017 true)) == NULL) {
1018 ret = true;
1019 goto label_return;
1020 }
1021 ctl_sarena->initialized = true;
1022
Qi Wang57beeb22017-06-22 18:58:40 -07001023 if ((ctl_darena = arenas_i_impl(tsd, MALLCTL_ARENAS_DESTROYED,
Jason Evansd778dd22017-01-03 12:40:54 -08001024 false, true)) == NULL) {
Jason Evansfc4dcfa2010-11-24 15:44:21 -08001025 ret = true;
Jason Evansa1ee7832012-04-10 15:07:44 -07001026 goto label_return;
Jason Evansfc4dcfa2010-11-24 15:44:21 -08001027 }
Jason Evans9eb1b1c2017-01-18 23:03:37 -08001028 ctl_arena_clear(ctl_darena);
Jason Evansedf1baf2017-01-03 17:21:59 -08001029 /*
Jason Evans9eb1b1c2017-01-18 23:03:37 -08001030 * Don't toggle ctl_darena to initialized until an arena is
1031 * actually destroyed, so that arena.<i>.initialized can be used
1032 * to query whether the stats are relevant.
Jason Evansedf1baf2017-01-03 17:21:59 -08001033 */
1034
Jason Evans9eb1b1c2017-01-18 23:03:37 -08001035 ctl_arenas->narenas = narenas_total_get();
1036 for (i = 0; i < ctl_arenas->narenas; i++) {
Qi Wang57beeb22017-06-22 18:58:40 -07001037 if (arenas_i_impl(tsd, i, false, true) == NULL) {
Jason Evansd778dd22017-01-03 12:40:54 -08001038 ret = true;
1039 goto label_return;
1040 }
1041 }
Jason Evans3c234352010-01-27 13:10:55 -08001042
Jason Evans9eb1b1c2017-01-18 23:03:37 -08001043 ql_new(&ctl_arenas->destroyed);
Jason Evansc1e00ef2016-05-10 22:21:10 -07001044 ctl_refresh(tsdn);
Jason Evans9eb1b1c2017-01-18 23:03:37 -08001045
Jason Evans3c234352010-01-27 13:10:55 -08001046 ctl_initialized = true;
1047 }
1048
Jason Evansfc4dcfa2010-11-24 15:44:21 -08001049 ret = false;
Jason Evansa1ee7832012-04-10 15:07:44 -07001050label_return:
Jason Evansc1e00ef2016-05-10 22:21:10 -07001051 malloc_mutex_unlock(tsdn, &ctl_mtx);
Jason Evansf4086432017-01-19 18:15:45 -08001052 return ret;
Jason Evans3c234352010-01-27 13:10:55 -08001053}
1054
1055static int
Jason Evansc1e00ef2016-05-10 22:21:10 -07001056ctl_lookup(tsdn_t *tsdn, const char *name, ctl_node_t const **nodesp,
Jason Evansc4c25922017-01-15 16:56:30 -08001057 size_t *mibp, size_t *depthp) {
Jason Evans3c234352010-01-27 13:10:55 -08001058 int ret;
1059 const char *elm, *tdot, *dot;
1060 size_t elen, i, j;
Mike Hommey461ad5c2012-04-20 08:38:42 +02001061 const ctl_named_node_t *node;
Jason Evans3c234352010-01-27 13:10:55 -08001062
1063 elm = name;
1064 /* Equivalent to strchrnul(). */
1065 dot = ((tdot = strchr(elm, '.')) != NULL) ? tdot : strchr(elm, '\0');
1066 elen = (size_t)((uintptr_t)dot - (uintptr_t)elm);
1067 if (elen == 0) {
1068 ret = ENOENT;
Jason Evansa1ee7832012-04-10 15:07:44 -07001069 goto label_return;
Jason Evans3c234352010-01-27 13:10:55 -08001070 }
1071 node = super_root_node;
1072 for (i = 0; i < *depthp; i++) {
Mike Hommey461ad5c2012-04-20 08:38:42 +02001073 assert(node);
1074 assert(node->nchildren > 0);
1075 if (ctl_named_node(node->children) != NULL) {
1076 const ctl_named_node_t *pnode = node;
Jason Evans3c234352010-01-27 13:10:55 -08001077
1078 /* Children are named. */
Mike Hommey461ad5c2012-04-20 08:38:42 +02001079 for (j = 0; j < node->nchildren; j++) {
1080 const ctl_named_node_t *child =
1081 ctl_named_children(node, j);
1082 if (strlen(child->name) == elen &&
1083 strncmp(elm, child->name, elen) == 0) {
Jason Evans3c234352010-01-27 13:10:55 -08001084 node = child;
Jason Evansc4c25922017-01-15 16:56:30 -08001085 if (nodesp != NULL) {
Mike Hommey461ad5c2012-04-20 08:38:42 +02001086 nodesp[i] =
1087 (const ctl_node_t *)node;
Jason Evansc4c25922017-01-15 16:56:30 -08001088 }
Jason Evans3c234352010-01-27 13:10:55 -08001089 mibp[i] = j;
1090 break;
1091 }
1092 }
1093 if (node == pnode) {
1094 ret = ENOENT;
Jason Evansa1ee7832012-04-10 15:07:44 -07001095 goto label_return;
Jason Evans3c234352010-01-27 13:10:55 -08001096 }
1097 } else {
Jason Evans41b6afb2012-02-02 22:04:57 -08001098 uintmax_t index;
Mike Hommey461ad5c2012-04-20 08:38:42 +02001099 const ctl_indexed_node_t *inode;
Jason Evans3c234352010-01-27 13:10:55 -08001100
1101 /* Children are indexed. */
Jason Evans41b6afb2012-02-02 22:04:57 -08001102 index = malloc_strtoumax(elm, NULL, 10);
1103 if (index == UINTMAX_MAX || index > SIZE_T_MAX) {
Jason Evans3c234352010-01-27 13:10:55 -08001104 ret = ENOENT;
Jason Evansa1ee7832012-04-10 15:07:44 -07001105 goto label_return;
Jason Evans3c234352010-01-27 13:10:55 -08001106 }
1107
Mike Hommey461ad5c2012-04-20 08:38:42 +02001108 inode = ctl_indexed_node(node->children);
Jason Evansc1e00ef2016-05-10 22:21:10 -07001109 node = inode->index(tsdn, mibp, *depthp, (size_t)index);
Jason Evans3c234352010-01-27 13:10:55 -08001110 if (node == NULL) {
1111 ret = ENOENT;
Jason Evansa1ee7832012-04-10 15:07:44 -07001112 goto label_return;
Jason Evans3c234352010-01-27 13:10:55 -08001113 }
1114
Jason Evansc4c25922017-01-15 16:56:30 -08001115 if (nodesp != NULL) {
Mike Hommey461ad5c2012-04-20 08:38:42 +02001116 nodesp[i] = (const ctl_node_t *)node;
Jason Evansc4c25922017-01-15 16:56:30 -08001117 }
Jason Evans3c234352010-01-27 13:10:55 -08001118 mibp[i] = (size_t)index;
1119 }
1120
1121 if (node->ctl != NULL) {
1122 /* Terminal node. */
1123 if (*dot != '\0') {
1124 /*
1125 * The name contains more elements than are
1126 * in this path through the tree.
1127 */
1128 ret = ENOENT;
Jason Evansa1ee7832012-04-10 15:07:44 -07001129 goto label_return;
Jason Evans3c234352010-01-27 13:10:55 -08001130 }
1131 /* Complete lookup successful. */
1132 *depthp = i + 1;
1133 break;
1134 }
1135
1136 /* Update elm. */
1137 if (*dot == '\0') {
1138 /* No more elements. */
1139 ret = ENOENT;
Jason Evansa1ee7832012-04-10 15:07:44 -07001140 goto label_return;
Jason Evans3c234352010-01-27 13:10:55 -08001141 }
1142 elm = &dot[1];
1143 dot = ((tdot = strchr(elm, '.')) != NULL) ? tdot :
1144 strchr(elm, '\0');
1145 elen = (size_t)((uintptr_t)dot - (uintptr_t)elm);
1146 }
1147
1148 ret = 0;
Jason Evansa1ee7832012-04-10 15:07:44 -07001149label_return:
Jason Evansf4086432017-01-19 18:15:45 -08001150 return ret;
Jason Evans3c234352010-01-27 13:10:55 -08001151}
1152
1153int
Jason Evansb2c0d632016-04-13 23:36:15 -07001154ctl_byname(tsd_t *tsd, const char *name, void *oldp, size_t *oldlenp,
Jason Evansc4c25922017-01-15 16:56:30 -08001155 void *newp, size_t newlen) {
Jason Evans3c234352010-01-27 13:10:55 -08001156 int ret;
1157 size_t depth;
1158 ctl_node_t const *nodes[CTL_MAX_DEPTH];
1159 size_t mib[CTL_MAX_DEPTH];
Mike Hommey461ad5c2012-04-20 08:38:42 +02001160 const ctl_named_node_t *node;
Jason Evans3c234352010-01-27 13:10:55 -08001161
Qi Wang57beeb22017-06-22 18:58:40 -07001162 if (!ctl_initialized && ctl_init(tsd)) {
Jason Evans3c234352010-01-27 13:10:55 -08001163 ret = EAGAIN;
Jason Evansa1ee7832012-04-10 15:07:44 -07001164 goto label_return;
Jason Evans3c234352010-01-27 13:10:55 -08001165 }
1166
1167 depth = CTL_MAX_DEPTH;
Jason Evansc1e00ef2016-05-10 22:21:10 -07001168 ret = ctl_lookup(tsd_tsdn(tsd), name, nodes, mib, &depth);
Jason Evansc4c25922017-01-15 16:56:30 -08001169 if (ret != 0) {
Jason Evansa1ee7832012-04-10 15:07:44 -07001170 goto label_return;
Jason Evansc4c25922017-01-15 16:56:30 -08001171 }
Jason Evans3c234352010-01-27 13:10:55 -08001172
Mike Hommey461ad5c2012-04-20 08:38:42 +02001173 node = ctl_named_node(nodes[depth-1]);
Jason Evansc4c25922017-01-15 16:56:30 -08001174 if (node != NULL && node->ctl) {
Jason Evansb2c0d632016-04-13 23:36:15 -07001175 ret = node->ctl(tsd, mib, depth, oldp, oldlenp, newp, newlen);
Qi Wangaa1de062017-03-01 14:43:35 -08001176 } else {
Jason Evans3c234352010-01-27 13:10:55 -08001177 /* The name refers to a partial path through the ctl tree. */
1178 ret = ENOENT;
Jason Evans3c234352010-01-27 13:10:55 -08001179 }
Jason Evans3c234352010-01-27 13:10:55 -08001180
Jason Evansa1ee7832012-04-10 15:07:44 -07001181label_return:
Jason Evans3c234352010-01-27 13:10:55 -08001182 return(ret);
1183}
1184
1185int
Qi Wang57beeb22017-06-22 18:58:40 -07001186ctl_nametomib(tsd_t *tsd, const char *name, size_t *mibp, size_t *miblenp) {
Jason Evans3c234352010-01-27 13:10:55 -08001187 int ret;
1188
Qi Wang57beeb22017-06-22 18:58:40 -07001189 if (!ctl_initialized && ctl_init(tsd)) {
Jason Evans3c234352010-01-27 13:10:55 -08001190 ret = EAGAIN;
Jason Evansa1ee7832012-04-10 15:07:44 -07001191 goto label_return;
Jason Evans3c234352010-01-27 13:10:55 -08001192 }
1193
Qi Wang57beeb22017-06-22 18:58:40 -07001194 ret = ctl_lookup(tsd_tsdn(tsd), name, NULL, mibp, miblenp);
Jason Evansa1ee7832012-04-10 15:07:44 -07001195label_return:
Jason Evans3c234352010-01-27 13:10:55 -08001196 return(ret);
1197}
1198
1199int
Jason Evansb2c0d632016-04-13 23:36:15 -07001200ctl_bymib(tsd_t *tsd, const size_t *mib, size_t miblen, void *oldp,
Jason Evansc4c25922017-01-15 16:56:30 -08001201 size_t *oldlenp, void *newp, size_t newlen) {
Jason Evans3c234352010-01-27 13:10:55 -08001202 int ret;
Mike Hommey461ad5c2012-04-20 08:38:42 +02001203 const ctl_named_node_t *node;
Jason Evans3c234352010-01-27 13:10:55 -08001204 size_t i;
1205
Qi Wang57beeb22017-06-22 18:58:40 -07001206 if (!ctl_initialized && ctl_init(tsd)) {
Jason Evans3c234352010-01-27 13:10:55 -08001207 ret = EAGAIN;
Jason Evansa1ee7832012-04-10 15:07:44 -07001208 goto label_return;
Jason Evans3c234352010-01-27 13:10:55 -08001209 }
1210
1211 /* Iterate down the tree. */
1212 node = super_root_node;
1213 for (i = 0; i < miblen; i++) {
Mike Hommey461ad5c2012-04-20 08:38:42 +02001214 assert(node);
1215 assert(node->nchildren > 0);
1216 if (ctl_named_node(node->children) != NULL) {
Jason Evans3c234352010-01-27 13:10:55 -08001217 /* Children are named. */
Jason Evans6edbedd2017-01-04 07:51:49 -08001218 if (node->nchildren <= mib[i]) {
Jason Evans3c234352010-01-27 13:10:55 -08001219 ret = ENOENT;
Jason Evansa1ee7832012-04-10 15:07:44 -07001220 goto label_return;
Jason Evans3c234352010-01-27 13:10:55 -08001221 }
Mike Hommey461ad5c2012-04-20 08:38:42 +02001222 node = ctl_named_children(node, mib[i]);
Jason Evans3c234352010-01-27 13:10:55 -08001223 } else {
Mike Hommey461ad5c2012-04-20 08:38:42 +02001224 const ctl_indexed_node_t *inode;
Jason Evans3c234352010-01-27 13:10:55 -08001225
1226 /* Indexed element. */
Mike Hommey461ad5c2012-04-20 08:38:42 +02001227 inode = ctl_indexed_node(node->children);
Jason Evansc1e00ef2016-05-10 22:21:10 -07001228 node = inode->index(tsd_tsdn(tsd), mib, miblen, mib[i]);
Jason Evans3c234352010-01-27 13:10:55 -08001229 if (node == NULL) {
1230 ret = ENOENT;
Jason Evansa1ee7832012-04-10 15:07:44 -07001231 goto label_return;
Jason Evans3c234352010-01-27 13:10:55 -08001232 }
1233 }
1234 }
1235
1236 /* Call the ctl function. */
Jason Evansc4c25922017-01-15 16:56:30 -08001237 if (node && node->ctl) {
Jason Evansb2c0d632016-04-13 23:36:15 -07001238 ret = node->ctl(tsd, mib, miblen, oldp, oldlenp, newp, newlen);
Jason Evansc4c25922017-01-15 16:56:30 -08001239 } else {
Jason Evans3c234352010-01-27 13:10:55 -08001240 /* Partial MIB. */
1241 ret = ENOENT;
Jason Evans3c234352010-01-27 13:10:55 -08001242 }
Jason Evans3c234352010-01-27 13:10:55 -08001243
Jason Evansa1ee7832012-04-10 15:07:44 -07001244label_return:
Jason Evans3c234352010-01-27 13:10:55 -08001245 return(ret);
1246}
1247
1248bool
Jason Evansc4c25922017-01-15 16:56:30 -08001249ctl_boot(void) {
David Goldblatt26c792e2017-05-15 15:38:15 -07001250 if (malloc_mutex_init(&ctl_mtx, "ctl", WITNESS_RANK_CTL,
1251 malloc_mutex_rank_exclusive)) {
Jason Evansf4086432017-01-19 18:15:45 -08001252 return true;
Jason Evansc4c25922017-01-15 16:56:30 -08001253 }
Jason Evans3c234352010-01-27 13:10:55 -08001254
1255 ctl_initialized = false;
1256
Jason Evansf4086432017-01-19 18:15:45 -08001257 return false;
Jason Evans3c234352010-01-27 13:10:55 -08001258}
1259
Jason Evans20f1fc92012-10-09 14:46:22 -07001260void
Jason Evansc4c25922017-01-15 16:56:30 -08001261ctl_prefork(tsdn_t *tsdn) {
Jason Evansc1e00ef2016-05-10 22:21:10 -07001262 malloc_mutex_prefork(tsdn, &ctl_mtx);
Jason Evans20f1fc92012-10-09 14:46:22 -07001263}
1264
1265void
Jason Evansc4c25922017-01-15 16:56:30 -08001266ctl_postfork_parent(tsdn_t *tsdn) {
Jason Evansc1e00ef2016-05-10 22:21:10 -07001267 malloc_mutex_postfork_parent(tsdn, &ctl_mtx);
Jason Evans20f1fc92012-10-09 14:46:22 -07001268}
1269
1270void
Jason Evansc4c25922017-01-15 16:56:30 -08001271ctl_postfork_child(tsdn_t *tsdn) {
Jason Evansc1e00ef2016-05-10 22:21:10 -07001272 malloc_mutex_postfork_child(tsdn, &ctl_mtx);
Jason Evans20f1fc92012-10-09 14:46:22 -07001273}
1274
Jason Evans3c234352010-01-27 13:10:55 -08001275/******************************************************************************/
1276/* *_ctl() functions. */
1277
Jason Evansc0cc5db2017-01-19 21:41:41 -08001278#define READONLY() do { \
Jason Evans3c234352010-01-27 13:10:55 -08001279 if (newp != NULL || newlen != 0) { \
1280 ret = EPERM; \
Jason Evans6b9ed672012-04-25 13:12:46 -07001281 goto label_return; \
Jason Evans3c234352010-01-27 13:10:55 -08001282 } \
1283} while (0)
1284
Jason Evansc0cc5db2017-01-19 21:41:41 -08001285#define WRITEONLY() do { \
Jason Evans3c234352010-01-27 13:10:55 -08001286 if (oldp != NULL || oldlenp != NULL) { \
1287 ret = EPERM; \
Jason Evans6b9ed672012-04-25 13:12:46 -07001288 goto label_return; \
Jason Evans3c234352010-01-27 13:10:55 -08001289 } \
1290} while (0)
1291
Jason Evansc0cc5db2017-01-19 21:41:41 -08001292#define READ_XOR_WRITE() do { \
Jason Evansfc12c0b2014-10-03 23:25:30 -07001293 if ((oldp != NULL && oldlenp != NULL) && (newp != NULL || \
1294 newlen != 0)) { \
1295 ret = EPERM; \
1296 goto label_return; \
1297 } \
1298} while (0)
1299
Jason Evansc0cc5db2017-01-19 21:41:41 -08001300#define READ(v, t) do { \
Jason Evans3c234352010-01-27 13:10:55 -08001301 if (oldp != NULL && oldlenp != NULL) { \
1302 if (*oldlenp != sizeof(t)) { \
1303 size_t copylen = (sizeof(t) <= *oldlenp) \
1304 ? sizeof(t) : *oldlenp; \
Jason Evans6eb84fb2012-11-29 22:13:04 -08001305 memcpy(oldp, (void *)&(v), copylen); \
Jason Evans3c234352010-01-27 13:10:55 -08001306 ret = EINVAL; \
Jason Evans6b9ed672012-04-25 13:12:46 -07001307 goto label_return; \
Jason Evansb49a3342015-07-28 11:28:19 -04001308 } \
1309 *(t *)oldp = (v); \
Jason Evans3c234352010-01-27 13:10:55 -08001310 } \
1311} while (0)
1312
Jason Evansc0cc5db2017-01-19 21:41:41 -08001313#define WRITE(v, t) do { \
Jason Evans3c234352010-01-27 13:10:55 -08001314 if (newp != NULL) { \
1315 if (newlen != sizeof(t)) { \
1316 ret = EINVAL; \
Jason Evans6b9ed672012-04-25 13:12:46 -07001317 goto label_return; \
Jason Evans3c234352010-01-27 13:10:55 -08001318 } \
Jason Evans6eb84fb2012-11-29 22:13:04 -08001319 (v) = *(t *)newp; \
Jason Evans3c234352010-01-27 13:10:55 -08001320 } \
1321} while (0)
1322
Jason Evansc0cc5db2017-01-19 21:41:41 -08001323#define MIB_UNSIGNED(v, i) do { \
Jason Evans6edbedd2017-01-04 07:51:49 -08001324 if (mib[i] > UINT_MAX) { \
1325 ret = EFAULT; \
1326 goto label_return; \
1327 } \
1328 v = (unsigned)mib[i]; \
1329} while (0)
1330
Jason Evans7372b152012-02-10 20:22:09 -08001331/*
1332 * There's a lot of code duplication in the following macros due to limitations
1333 * in how nested cpp macros are expanded.
1334 */
Jason Evansc0cc5db2017-01-19 21:41:41 -08001335#define CTL_RO_CLGEN(c, l, n, v, t) \
Jason Evans7372b152012-02-10 20:22:09 -08001336static int \
Jason Evansb2c0d632016-04-13 23:36:15 -07001337n##_ctl(tsd_t *tsd, const size_t *mib, size_t miblen, void *oldp, \
Jason Evansc4c25922017-01-15 16:56:30 -08001338 size_t *oldlenp, void *newp, size_t newlen) { \
Jason Evans7372b152012-02-10 20:22:09 -08001339 int ret; \
1340 t oldval; \
1341 \
Jason Evansc4c25922017-01-15 16:56:30 -08001342 if (!(c)) { \
Jason Evansf4086432017-01-19 18:15:45 -08001343 return ENOENT; \
Jason Evansc4c25922017-01-15 16:56:30 -08001344 } \
1345 if (l) { \
Jason Evansc1e00ef2016-05-10 22:21:10 -07001346 malloc_mutex_lock(tsd_tsdn(tsd), &ctl_mtx); \
Jason Evansc4c25922017-01-15 16:56:30 -08001347 } \
Jason Evans7372b152012-02-10 20:22:09 -08001348 READONLY(); \
Jason Evans6eb84fb2012-11-29 22:13:04 -08001349 oldval = (v); \
Jason Evans7372b152012-02-10 20:22:09 -08001350 READ(oldval, t); \
1351 \
1352 ret = 0; \
Jason Evans6b9ed672012-04-25 13:12:46 -07001353label_return: \
Jason Evansc4c25922017-01-15 16:56:30 -08001354 if (l) { \
Jason Evansc1e00ef2016-05-10 22:21:10 -07001355 malloc_mutex_unlock(tsd_tsdn(tsd), &ctl_mtx); \
Jason Evansc4c25922017-01-15 16:56:30 -08001356 } \
Jason Evansf4086432017-01-19 18:15:45 -08001357 return ret; \
Jason Evans7372b152012-02-10 20:22:09 -08001358}
1359
Jason Evansc0cc5db2017-01-19 21:41:41 -08001360#define CTL_RO_CGEN(c, n, v, t) \
Jason Evans7372b152012-02-10 20:22:09 -08001361static int \
Jason Evansb2c0d632016-04-13 23:36:15 -07001362n##_ctl(tsd_t *tsd, const size_t *mib, size_t miblen, void *oldp, \
Jason Evansc4c25922017-01-15 16:56:30 -08001363 size_t *oldlenp, void *newp, size_t newlen) { \
Jason Evans7372b152012-02-10 20:22:09 -08001364 int ret; \
1365 t oldval; \
1366 \
Jason Evansc4c25922017-01-15 16:56:30 -08001367 if (!(c)) { \
Jason Evansf4086432017-01-19 18:15:45 -08001368 return ENOENT; \
Jason Evansc4c25922017-01-15 16:56:30 -08001369 } \
Jason Evansc1e00ef2016-05-10 22:21:10 -07001370 malloc_mutex_lock(tsd_tsdn(tsd), &ctl_mtx); \
Jason Evans7372b152012-02-10 20:22:09 -08001371 READONLY(); \
Jason Evans6eb84fb2012-11-29 22:13:04 -08001372 oldval = (v); \
Jason Evans7372b152012-02-10 20:22:09 -08001373 READ(oldval, t); \
1374 \
1375 ret = 0; \
Jason Evans6b9ed672012-04-25 13:12:46 -07001376label_return: \
Jason Evansc1e00ef2016-05-10 22:21:10 -07001377 malloc_mutex_unlock(tsd_tsdn(tsd), &ctl_mtx); \
Jason Evansf4086432017-01-19 18:15:45 -08001378 return ret; \
Jason Evans7372b152012-02-10 20:22:09 -08001379}
1380
Jason Evansc0cc5db2017-01-19 21:41:41 -08001381#define CTL_RO_GEN(n, v, t) \
Jason Evans3c234352010-01-27 13:10:55 -08001382static int \
Jason Evansb2c0d632016-04-13 23:36:15 -07001383n##_ctl(tsd_t *tsd, const size_t *mib, size_t miblen, void *oldp, \
Jason Evansc4c25922017-01-15 16:56:30 -08001384 size_t *oldlenp, void *newp, size_t newlen) { \
Jason Evans3c234352010-01-27 13:10:55 -08001385 int ret; \
1386 t oldval; \
1387 \
Jason Evansc1e00ef2016-05-10 22:21:10 -07001388 malloc_mutex_lock(tsd_tsdn(tsd), &ctl_mtx); \
Jason Evansfc4dcfa2010-11-24 15:44:21 -08001389 READONLY(); \
Jason Evans6eb84fb2012-11-29 22:13:04 -08001390 oldval = (v); \
Jason Evansfc4dcfa2010-11-24 15:44:21 -08001391 READ(oldval, t); \
1392 \
1393 ret = 0; \
Jason Evans6b9ed672012-04-25 13:12:46 -07001394label_return: \
Jason Evansc1e00ef2016-05-10 22:21:10 -07001395 malloc_mutex_unlock(tsd_tsdn(tsd), &ctl_mtx); \
Jason Evansf4086432017-01-19 18:15:45 -08001396 return ret; \
Jason Evansfc4dcfa2010-11-24 15:44:21 -08001397}
1398
1399/*
1400 * ctl_mtx is not acquired, under the assumption that no pertinent data will
1401 * mutate during the call.
1402 */
Jason Evansc0cc5db2017-01-19 21:41:41 -08001403#define CTL_RO_NL_CGEN(c, n, v, t) \
Jason Evans7372b152012-02-10 20:22:09 -08001404static int \
Jason Evansb2c0d632016-04-13 23:36:15 -07001405n##_ctl(tsd_t *tsd, const size_t *mib, size_t miblen, void *oldp, \
Jason Evansc4c25922017-01-15 16:56:30 -08001406 size_t *oldlenp, void *newp, size_t newlen) { \
Jason Evans7372b152012-02-10 20:22:09 -08001407 int ret; \
1408 t oldval; \
1409 \
Jason Evansc4c25922017-01-15 16:56:30 -08001410 if (!(c)) { \
Jason Evansf4086432017-01-19 18:15:45 -08001411 return ENOENT; \
Jason Evansc4c25922017-01-15 16:56:30 -08001412 } \
Jason Evans7372b152012-02-10 20:22:09 -08001413 READONLY(); \
Jason Evans6eb84fb2012-11-29 22:13:04 -08001414 oldval = (v); \
Jason Evans7372b152012-02-10 20:22:09 -08001415 READ(oldval, t); \
1416 \
1417 ret = 0; \
Jason Evans6b9ed672012-04-25 13:12:46 -07001418label_return: \
Jason Evansf4086432017-01-19 18:15:45 -08001419 return ret; \
Jason Evans7372b152012-02-10 20:22:09 -08001420}
1421
Jason Evansc0cc5db2017-01-19 21:41:41 -08001422#define CTL_RO_NL_GEN(n, v, t) \
Jason Evansfc4dcfa2010-11-24 15:44:21 -08001423static int \
Jason Evansb2c0d632016-04-13 23:36:15 -07001424n##_ctl(tsd_t *tsd, const size_t *mib, size_t miblen, void *oldp, \
Jason Evansc4c25922017-01-15 16:56:30 -08001425 size_t *oldlenp, void *newp, size_t newlen) { \
Jason Evansfc4dcfa2010-11-24 15:44:21 -08001426 int ret; \
1427 t oldval; \
1428 \
Jason Evans3c234352010-01-27 13:10:55 -08001429 READONLY(); \
Jason Evans6eb84fb2012-11-29 22:13:04 -08001430 oldval = (v); \
Jason Evans3c234352010-01-27 13:10:55 -08001431 READ(oldval, t); \
1432 \
1433 ret = 0; \
Jason Evans6b9ed672012-04-25 13:12:46 -07001434label_return: \
Jason Evansf4086432017-01-19 18:15:45 -08001435 return ret; \
Jason Evans3c234352010-01-27 13:10:55 -08001436}
1437
Jason Evansc0cc5db2017-01-19 21:41:41 -08001438#define CTL_TSD_RO_NL_CGEN(c, n, m, t) \
Jason Evans5460aa62014-09-22 21:09:23 -07001439static int \
Jason Evansb2c0d632016-04-13 23:36:15 -07001440n##_ctl(tsd_t *tsd, const size_t *mib, size_t miblen, void *oldp, \
Jason Evansc4c25922017-01-15 16:56:30 -08001441 size_t *oldlenp, void *newp, size_t newlen) { \
Jason Evans5460aa62014-09-22 21:09:23 -07001442 int ret; \
1443 t oldval; \
Jason Evans5460aa62014-09-22 21:09:23 -07001444 \
Jason Evansc4c25922017-01-15 16:56:30 -08001445 if (!(c)) { \
Jason Evansf4086432017-01-19 18:15:45 -08001446 return ENOENT; \
Jason Evansc4c25922017-01-15 16:56:30 -08001447 } \
Jason Evans5460aa62014-09-22 21:09:23 -07001448 READONLY(); \
Jason Evans5460aa62014-09-22 21:09:23 -07001449 oldval = (m(tsd)); \
1450 READ(oldval, t); \
1451 \
1452 ret = 0; \
1453label_return: \
Jason Evansf4086432017-01-19 18:15:45 -08001454 return ret; \
Jason Evans5460aa62014-09-22 21:09:23 -07001455}
1456
Jason Evansc0cc5db2017-01-19 21:41:41 -08001457#define CTL_RO_CONFIG_GEN(n, t) \
Jason Evans3c234352010-01-27 13:10:55 -08001458static int \
Jason Evansb2c0d632016-04-13 23:36:15 -07001459n##_ctl(tsd_t *tsd, const size_t *mib, size_t miblen, void *oldp, \
Jason Evansc4c25922017-01-15 16:56:30 -08001460 size_t *oldlenp, void *newp, size_t newlen) { \
Jason Evans3c234352010-01-27 13:10:55 -08001461 int ret; \
Jason Evansf8290092016-02-07 14:23:22 -08001462 t oldval; \
Jason Evans3c234352010-01-27 13:10:55 -08001463 \
1464 READONLY(); \
Jason Evans7372b152012-02-10 20:22:09 -08001465 oldval = n; \
Jason Evansf8290092016-02-07 14:23:22 -08001466 READ(oldval, t); \
Jason Evans3c234352010-01-27 13:10:55 -08001467 \
1468 ret = 0; \
Jason Evans6b9ed672012-04-25 13:12:46 -07001469label_return: \
Jason Evansf4086432017-01-19 18:15:45 -08001470 return ret; \
Jason Evans3c234352010-01-27 13:10:55 -08001471}
1472
Jason Evansd8a39002013-12-19 21:40:41 -08001473/******************************************************************************/
1474
Jason Evansfc4dcfa2010-11-24 15:44:21 -08001475CTL_RO_NL_GEN(version, JEMALLOC_VERSION, const char *)
Jason Evansa40bc7a2010-03-02 13:01:16 -08001476
Jason Evans3c234352010-01-27 13:10:55 -08001477static int
Jason Evansb2c0d632016-04-13 23:36:15 -07001478epoch_ctl(tsd_t *tsd, const size_t *mib, size_t miblen, void *oldp,
Jason Evansc4c25922017-01-15 16:56:30 -08001479 size_t *oldlenp, void *newp, size_t newlen) {
Jason Evans3c234352010-01-27 13:10:55 -08001480 int ret;
Jason Evans3ab682d2013-10-19 17:19:49 -07001481 UNUSED uint64_t newval;
Jason Evans3c234352010-01-27 13:10:55 -08001482
Jason Evansc1e00ef2016-05-10 22:21:10 -07001483 malloc_mutex_lock(tsd_tsdn(tsd), &ctl_mtx);
Jason Evans3c234352010-01-27 13:10:55 -08001484 WRITE(newval, uint64_t);
Jason Evansc4c25922017-01-15 16:56:30 -08001485 if (newp != NULL) {
Jason Evansc1e00ef2016-05-10 22:21:10 -07001486 ctl_refresh(tsd_tsdn(tsd));
Jason Evansc4c25922017-01-15 16:56:30 -08001487 }
Jason Evans9eb1b1c2017-01-18 23:03:37 -08001488 READ(ctl_arenas->epoch, uint64_t);
Jason Evans3c234352010-01-27 13:10:55 -08001489
1490 ret = 0;
Jason Evansa1ee7832012-04-10 15:07:44 -07001491label_return:
Jason Evansc1e00ef2016-05-10 22:21:10 -07001492 malloc_mutex_unlock(tsd_tsdn(tsd), &ctl_mtx);
Jason Evansf4086432017-01-19 18:15:45 -08001493 return ret;
Jason Evans3c234352010-01-27 13:10:55 -08001494}
1495
Qi Wangb693c782017-03-17 12:42:33 -07001496static int
1497background_thread_ctl(tsd_t *tsd, const size_t *mib, size_t miblen,
1498 void *oldp, size_t *oldlenp, void *newp, size_t newlen) {
1499 int ret;
1500 bool oldval;
1501
1502 if (!have_background_thread) {
1503 return ENOENT;
1504 }
Qi Wang340071f2017-06-01 12:52:09 -07001505 background_thread_ctl_init(tsd_tsdn(tsd));
Qi Wangb693c782017-03-17 12:42:33 -07001506
Qi Wang73713fb2017-06-07 15:49:09 -07001507 malloc_mutex_lock(tsd_tsdn(tsd), &ctl_mtx);
Qi Wangb693c782017-03-17 12:42:33 -07001508 malloc_mutex_lock(tsd_tsdn(tsd), &background_thread_lock);
1509 if (newp == NULL) {
1510 oldval = background_thread_enabled();
1511 READ(oldval, bool);
1512 } else {
1513 if (newlen != sizeof(bool)) {
1514 ret = EINVAL;
1515 goto label_return;
1516 }
1517 oldval = background_thread_enabled();
1518 READ(oldval, bool);
1519
1520 bool newval = *(bool *)newp;
1521 if (newval == oldval) {
1522 ret = 0;
1523 goto label_return;
1524 }
1525
1526 background_thread_enabled_set(tsd_tsdn(tsd), newval);
1527 if (newval) {
Qi Wanga4d6fe72017-06-14 12:12:23 -07001528 if (!can_enable_background_thread) {
1529 malloc_printf("<jemalloc>: Error in dlsym("
1530 "RTLD_NEXT, \"pthread_create\"). Cannot "
1531 "enable background_thread\n");
1532 ret = EFAULT;
1533 goto label_return;
1534 }
Qi Wangb693c782017-03-17 12:42:33 -07001535 if (background_threads_enable(tsd)) {
1536 ret = EFAULT;
1537 goto label_return;
1538 }
1539 } else {
1540 if (background_threads_disable(tsd)) {
1541 ret = EFAULT;
1542 goto label_return;
1543 }
1544 }
1545 }
1546 ret = 0;
1547label_return:
1548 malloc_mutex_unlock(tsd_tsdn(tsd), &background_thread_lock);
Qi Wang73713fb2017-06-07 15:49:09 -07001549 malloc_mutex_unlock(tsd_tsdn(tsd), &ctl_mtx);
1550
Qi Wangb693c782017-03-17 12:42:33 -07001551 return ret;
1552}
1553
Jason Evansd8a39002013-12-19 21:40:41 -08001554/******************************************************************************/
Jason Evansd4be8b72012-03-26 18:54:44 -07001555
Jason Evansf8290092016-02-07 14:23:22 -08001556CTL_RO_CONFIG_GEN(config_cache_oblivious, bool)
1557CTL_RO_CONFIG_GEN(config_debug, bool)
1558CTL_RO_CONFIG_GEN(config_fill, bool)
1559CTL_RO_CONFIG_GEN(config_lazy_lock, bool)
1560CTL_RO_CONFIG_GEN(config_malloc_conf, const char *)
Jason Evansf8290092016-02-07 14:23:22 -08001561CTL_RO_CONFIG_GEN(config_prof, bool)
1562CTL_RO_CONFIG_GEN(config_prof_libgcc, bool)
1563CTL_RO_CONFIG_GEN(config_prof_libunwind, bool)
1564CTL_RO_CONFIG_GEN(config_stats, bool)
Jason Evansc606a872017-05-30 09:54:49 -07001565CTL_RO_CONFIG_GEN(config_thp, bool)
Jason Evansf8290092016-02-07 14:23:22 -08001566CTL_RO_CONFIG_GEN(config_utrace, bool)
Jason Evansf8290092016-02-07 14:23:22 -08001567CTL_RO_CONFIG_GEN(config_xmalloc, bool)
Jason Evansd4be8b72012-03-26 18:54:44 -07001568
Jason Evansd8a39002013-12-19 21:40:41 -08001569/******************************************************************************/
Jason Evansd4be8b72012-03-26 18:54:44 -07001570
Jason Evansd8a39002013-12-19 21:40:41 -08001571CTL_RO_NL_GEN(opt_abort, opt_abort, bool)
Qi Wangb86d2712017-05-25 15:30:11 -07001572CTL_RO_NL_GEN(opt_abort_conf, opt_abort_conf, bool)
Qi Wang47b20bb2017-08-24 14:29:28 -07001573CTL_RO_NL_GEN(opt_metadata_thp, metadata_thp_mode_names[opt_metadata_thp],
1574 const char *)
Jason Evansb9ab04a2017-04-26 16:26:12 -07001575CTL_RO_NL_GEN(opt_retain, opt_retain, bool)
Jason Evansd8a39002013-12-19 21:40:41 -08001576CTL_RO_NL_GEN(opt_dss, opt_dss, const char *)
Jason Evans8f683b92016-02-24 11:03:40 -08001577CTL_RO_NL_GEN(opt_narenas, opt_narenas, unsigned)
Jason Evansb5112322017-05-31 16:45:14 -07001578CTL_RO_NL_GEN(opt_percpu_arena, percpu_arena_mode_names[opt_percpu_arena],
1579 const char *)
Qi Wangb693c782017-03-17 12:42:33 -07001580CTL_RO_NL_GEN(opt_background_thread, opt_background_thread, bool)
Jason Evans6e62c622017-05-17 10:47:00 -07001581CTL_RO_NL_GEN(opt_dirty_decay_ms, opt_dirty_decay_ms, ssize_t)
1582CTL_RO_NL_GEN(opt_muzzy_decay_ms, opt_muzzy_decay_ms, ssize_t)
Jason Evansd8a39002013-12-19 21:40:41 -08001583CTL_RO_NL_GEN(opt_stats_print, opt_stats_print, bool)
Qi Wangd5ef5ae2017-05-27 15:35:36 -07001584CTL_RO_NL_GEN(opt_stats_print_opts, opt_stats_print_opts, const char *)
Guilherme Goncalves2c5cb612014-12-08 19:12:41 -02001585CTL_RO_NL_CGEN(config_fill, opt_junk, opt_junk, const char *)
Jason Evansd8a39002013-12-19 21:40:41 -08001586CTL_RO_NL_CGEN(config_fill, opt_zero, opt_zero, bool)
1587CTL_RO_NL_CGEN(config_utrace, opt_utrace, opt_utrace, bool)
Jason Evansd8a39002013-12-19 21:40:41 -08001588CTL_RO_NL_CGEN(config_xmalloc, opt_xmalloc, opt_xmalloc, bool)
Jason Evans4403c9a2017-04-20 17:21:37 -07001589CTL_RO_NL_GEN(opt_tcache, opt_tcache, bool)
1590CTL_RO_NL_GEN(opt_lg_tcache_max, opt_lg_tcache_max, ssize_t)
Jason Evansd8a39002013-12-19 21:40:41 -08001591CTL_RO_NL_CGEN(config_prof, opt_prof, opt_prof, bool)
1592CTL_RO_NL_CGEN(config_prof, opt_prof_prefix, opt_prof_prefix, const char *)
Jason Evansfc12c0b2014-10-03 23:25:30 -07001593CTL_RO_NL_CGEN(config_prof, opt_prof_active, opt_prof_active, bool)
1594CTL_RO_NL_CGEN(config_prof, opt_prof_thread_active_init,
1595 opt_prof_thread_active_init, bool)
Jason Evansd8a39002013-12-19 21:40:41 -08001596CTL_RO_NL_CGEN(config_prof, opt_lg_prof_sample, opt_lg_prof_sample, size_t)
1597CTL_RO_NL_CGEN(config_prof, opt_prof_accum, opt_prof_accum, bool)
1598CTL_RO_NL_CGEN(config_prof, opt_lg_prof_interval, opt_lg_prof_interval, ssize_t)
1599CTL_RO_NL_CGEN(config_prof, opt_prof_gdump, opt_prof_gdump, bool)
1600CTL_RO_NL_CGEN(config_prof, opt_prof_final, opt_prof_final, bool)
1601CTL_RO_NL_CGEN(config_prof, opt_prof_leak, opt_prof_leak, bool)
Jason Evansd4be8b72012-03-26 18:54:44 -07001602
Jason Evansd8a39002013-12-19 21:40:41 -08001603/******************************************************************************/
Jason Evans3c234352010-01-27 13:10:55 -08001604
Jason Evansb267d0f2010-08-13 15:42:29 -07001605static int
Jason Evansb2c0d632016-04-13 23:36:15 -07001606thread_arena_ctl(tsd_t *tsd, const size_t *mib, size_t miblen, void *oldp,
Jason Evansc4c25922017-01-15 16:56:30 -08001607 size_t *oldlenp, void *newp, size_t newlen) {
Jason Evansb267d0f2010-08-13 15:42:29 -07001608 int ret;
Jason Evans1cb181e2015-01-29 15:30:47 -08001609 arena_t *oldarena;
Jason Evansb267d0f2010-08-13 15:42:29 -07001610 unsigned newind, oldind;
1611
Jason Evans90827a32016-05-03 15:00:42 -07001612 oldarena = arena_choose(tsd, NULL);
Jason Evansc4c25922017-01-15 16:56:30 -08001613 if (oldarena == NULL) {
Jason Evansf4086432017-01-19 18:15:45 -08001614 return EAGAIN;
Jason Evansc4c25922017-01-15 16:56:30 -08001615 }
Jason Evansa0dd3a42016-12-22 16:39:10 -06001616 newind = oldind = arena_ind_get(oldarena);
Jason Evansa7153a02011-03-14 11:39:49 -07001617 WRITE(newind, unsigned);
1618 READ(oldind, unsigned);
Qi Wangec532e22017-02-02 17:02:05 -08001619
Jason Evansb267d0f2010-08-13 15:42:29 -07001620 if (newind != oldind) {
Jason Evans1cb181e2015-01-29 15:30:47 -08001621 arena_t *newarena;
1622
Jason Evansb6c08672016-10-03 10:37:12 -07001623 if (newind >= narenas_total_get()) {
Jason Evansb267d0f2010-08-13 15:42:29 -07001624 /* New arena index is out of range. */
1625 ret = EFAULT;
Jason Evansa1ee7832012-04-10 15:07:44 -07001626 goto label_return;
Jason Evansb267d0f2010-08-13 15:42:29 -07001627 }
1628
Qi Wangec532e22017-02-02 17:02:05 -08001629 if (have_percpu_arena &&
Jason Evansb5112322017-05-31 16:45:14 -07001630 PERCPU_ARENA_ENABLED(opt_percpu_arena)) {
1631 if (newind < percpu_arena_ind_limit(opt_percpu_arena)) {
Qi Wangec532e22017-02-02 17:02:05 -08001632 /*
1633 * If perCPU arena is enabled, thread_arena
1634 * control is not allowed for the auto arena
1635 * range.
1636 */
1637 ret = EPERM;
1638 goto label_return;
1639 }
1640 }
1641
Jason Evansb267d0f2010-08-13 15:42:29 -07001642 /* Initialize arena if necessary. */
Jason Evansc1e00ef2016-05-10 22:21:10 -07001643 newarena = arena_get(tsd_tsdn(tsd), newind, true);
Jason Evans1cb181e2015-01-29 15:30:47 -08001644 if (newarena == NULL) {
Jason Evansb267d0f2010-08-13 15:42:29 -07001645 ret = EAGAIN;
Jason Evansa1ee7832012-04-10 15:07:44 -07001646 goto label_return;
Jason Evansb267d0f2010-08-13 15:42:29 -07001647 }
Jason Evans8bb31982014-10-07 23:14:57 -07001648 /* Set new arena/tcache associations. */
1649 arena_migrate(tsd, oldind, newind);
Jason Evans4403c9a2017-04-20 17:21:37 -07001650 if (tcache_available(tsd)) {
1651 tcache_arena_reassociate(tsd_tsdn(tsd),
1652 tsd_tcachep_get(tsd), newarena);
Jason Evans624f2f32010-12-29 12:21:05 -08001653 }
Jason Evansb267d0f2010-08-13 15:42:29 -07001654 }
1655
1656 ret = 0;
Jason Evansa1ee7832012-04-10 15:07:44 -07001657label_return:
Jason Evansf4086432017-01-19 18:15:45 -08001658 return ret;
Jason Evansb267d0f2010-08-13 15:42:29 -07001659}
Jason Evansb267d0f2010-08-13 15:42:29 -07001660
Jason Evans5460aa62014-09-22 21:09:23 -07001661CTL_TSD_RO_NL_CGEN(config_stats, thread_allocated, tsd_thread_allocated_get,
1662 uint64_t)
1663CTL_TSD_RO_NL_CGEN(config_stats, thread_allocatedp, tsd_thread_allocatedp_get,
1664 uint64_t *)
1665CTL_TSD_RO_NL_CGEN(config_stats, thread_deallocated, tsd_thread_deallocated_get,
1666 uint64_t)
1667CTL_TSD_RO_NL_CGEN(config_stats, thread_deallocatedp,
1668 tsd_thread_deallocatedp_get, uint64_t *)
Jason Evans93443682010-10-20 17:39:18 -07001669
Jason Evansd8a39002013-12-19 21:40:41 -08001670static int
Jason Evansb2c0d632016-04-13 23:36:15 -07001671thread_tcache_enabled_ctl(tsd_t *tsd, const size_t *mib, size_t miblen,
Jason Evansc4c25922017-01-15 16:56:30 -08001672 void *oldp, size_t *oldlenp, void *newp, size_t newlen) {
Jason Evansd8a39002013-12-19 21:40:41 -08001673 int ret;
1674 bool oldval;
Jason Evans3c234352010-01-27 13:10:55 -08001675
Qi Wangfde3e202017-03-27 21:50:38 -07001676 oldval = tcache_enabled_get(tsd);
Jason Evansd8a39002013-12-19 21:40:41 -08001677 if (newp != NULL) {
1678 if (newlen != sizeof(bool)) {
1679 ret = EINVAL;
1680 goto label_return;
1681 }
Qi Wangfde3e202017-03-27 21:50:38 -07001682 tcache_enabled_set(tsd, *(bool *)newp);
Jason Evansd8a39002013-12-19 21:40:41 -08001683 }
1684 READ(oldval, bool);
Jason Evans3c234352010-01-27 13:10:55 -08001685
Jason Evansd8a39002013-12-19 21:40:41 -08001686 ret = 0;
1687label_return:
Jason Evansf4086432017-01-19 18:15:45 -08001688 return ret;
Jason Evansd8a39002013-12-19 21:40:41 -08001689}
1690
1691static int
Jason Evansb2c0d632016-04-13 23:36:15 -07001692thread_tcache_flush_ctl(tsd_t *tsd, const size_t *mib, size_t miblen,
Jason Evansc4c25922017-01-15 16:56:30 -08001693 void *oldp, size_t *oldlenp, void *newp, size_t newlen) {
Jason Evansd8a39002013-12-19 21:40:41 -08001694 int ret;
1695
Jason Evans4403c9a2017-04-20 17:21:37 -07001696 if (!tcache_available(tsd)) {
1697 ret = EFAULT;
1698 goto label_return;
Jason Evansc4c25922017-01-15 16:56:30 -08001699 }
Jason Evansd8a39002013-12-19 21:40:41 -08001700
1701 READONLY();
1702 WRITEONLY();
1703
Qi Wangae93fb02017-06-15 15:16:18 -07001704 tcache_flush(tsd);
Jason Evansd8a39002013-12-19 21:40:41 -08001705
1706 ret = 0;
1707label_return:
Jason Evansf4086432017-01-19 18:15:45 -08001708 return ret;
Jason Evansd8a39002013-12-19 21:40:41 -08001709}
Jason Evans3c234352010-01-27 13:10:55 -08001710
Jason Evans602c8e02014-08-18 16:22:13 -07001711static int
Jason Evansb2c0d632016-04-13 23:36:15 -07001712thread_prof_name_ctl(tsd_t *tsd, const size_t *mib, size_t miblen, void *oldp,
Jason Evansc4c25922017-01-15 16:56:30 -08001713 size_t *oldlenp, void *newp, size_t newlen) {
Jason Evans602c8e02014-08-18 16:22:13 -07001714 int ret;
Jason Evans602c8e02014-08-18 16:22:13 -07001715
Jason Evansc4c25922017-01-15 16:56:30 -08001716 if (!config_prof) {
Jason Evansf4086432017-01-19 18:15:45 -08001717 return ENOENT;
Jason Evansc4c25922017-01-15 16:56:30 -08001718 }
Jason Evans602c8e02014-08-18 16:22:13 -07001719
Jason Evansfc12c0b2014-10-03 23:25:30 -07001720 READ_XOR_WRITE();
1721
Jason Evans602c8e02014-08-18 16:22:13 -07001722 if (newp != NULL) {
1723 if (newlen != sizeof(const char *)) {
1724 ret = EINVAL;
1725 goto label_return;
1726 }
Jason Evans5460aa62014-09-22 21:09:23 -07001727
Jason Evansfc12c0b2014-10-03 23:25:30 -07001728 if ((ret = prof_thread_name_set(tsd, *(const char **)newp)) !=
Jason Evansc4c25922017-01-15 16:56:30 -08001729 0) {
Jason Evans602c8e02014-08-18 16:22:13 -07001730 goto label_return;
Jason Evansc4c25922017-01-15 16:56:30 -08001731 }
Jason Evansfc12c0b2014-10-03 23:25:30 -07001732 } else {
Jason Evansb2c0d632016-04-13 23:36:15 -07001733 const char *oldname = prof_thread_name_get(tsd);
Jason Evansfc12c0b2014-10-03 23:25:30 -07001734 READ(oldname, const char *);
Jason Evans602c8e02014-08-18 16:22:13 -07001735 }
Jason Evans602c8e02014-08-18 16:22:13 -07001736
1737 ret = 0;
1738label_return:
Jason Evansf4086432017-01-19 18:15:45 -08001739 return ret;
Jason Evans602c8e02014-08-18 16:22:13 -07001740}
1741
1742static int
Jason Evansb2c0d632016-04-13 23:36:15 -07001743thread_prof_active_ctl(tsd_t *tsd, const size_t *mib, size_t miblen, void *oldp,
Jason Evansc4c25922017-01-15 16:56:30 -08001744 size_t *oldlenp, void *newp, size_t newlen) {
Jason Evans602c8e02014-08-18 16:22:13 -07001745 int ret;
1746 bool oldval;
1747
Jason Evansc4c25922017-01-15 16:56:30 -08001748 if (!config_prof) {
Jason Evansf4086432017-01-19 18:15:45 -08001749 return ENOENT;
Jason Evansc4c25922017-01-15 16:56:30 -08001750 }
Jason Evans602c8e02014-08-18 16:22:13 -07001751
Jason Evansb2c0d632016-04-13 23:36:15 -07001752 oldval = prof_thread_active_get(tsd);
Jason Evans602c8e02014-08-18 16:22:13 -07001753 if (newp != NULL) {
1754 if (newlen != sizeof(bool)) {
1755 ret = EINVAL;
1756 goto label_return;
1757 }
Jason Evansb2c0d632016-04-13 23:36:15 -07001758 if (prof_thread_active_set(tsd, *(bool *)newp)) {
Jason Evans602c8e02014-08-18 16:22:13 -07001759 ret = EAGAIN;
1760 goto label_return;
1761 }
1762 }
1763 READ(oldval, bool);
1764
1765 ret = 0;
1766label_return:
Jason Evansf4086432017-01-19 18:15:45 -08001767 return ret;
Jason Evans602c8e02014-08-18 16:22:13 -07001768}
1769
Jason Evans3c234352010-01-27 13:10:55 -08001770/******************************************************************************/
1771
Jason Evans1cb181e2015-01-29 15:30:47 -08001772static int
Jason Evansb2c0d632016-04-13 23:36:15 -07001773tcache_create_ctl(tsd_t *tsd, const size_t *mib, size_t miblen, void *oldp,
Jason Evansc4c25922017-01-15 16:56:30 -08001774 size_t *oldlenp, void *newp, size_t newlen) {
Jason Evans1cb181e2015-01-29 15:30:47 -08001775 int ret;
Jason Evans1cb181e2015-01-29 15:30:47 -08001776 unsigned tcache_ind;
1777
Jason Evans1cb181e2015-01-29 15:30:47 -08001778 READONLY();
Jason Evansb54d1602016-10-20 23:59:12 -07001779 if (tcaches_create(tsd, &tcache_ind)) {
Jason Evans1cb181e2015-01-29 15:30:47 -08001780 ret = EFAULT;
1781 goto label_return;
1782 }
1783 READ(tcache_ind, unsigned);
1784
1785 ret = 0;
1786label_return:
Jason Evansf4086432017-01-19 18:15:45 -08001787 return ret;
Jason Evans1cb181e2015-01-29 15:30:47 -08001788}
1789
1790static int
Jason Evansb2c0d632016-04-13 23:36:15 -07001791tcache_flush_ctl(tsd_t *tsd, const size_t *mib, size_t miblen, void *oldp,
Jason Evansc4c25922017-01-15 16:56:30 -08001792 size_t *oldlenp, void *newp, size_t newlen) {
Jason Evans1cb181e2015-01-29 15:30:47 -08001793 int ret;
Jason Evans1cb181e2015-01-29 15:30:47 -08001794 unsigned tcache_ind;
1795
Jason Evans1cb181e2015-01-29 15:30:47 -08001796 WRITEONLY();
1797 tcache_ind = UINT_MAX;
1798 WRITE(tcache_ind, unsigned);
1799 if (tcache_ind == UINT_MAX) {
1800 ret = EFAULT;
1801 goto label_return;
1802 }
1803 tcaches_flush(tsd, tcache_ind);
1804
1805 ret = 0;
1806label_return:
Jason Evansf4086432017-01-19 18:15:45 -08001807 return ret;
Jason Evans1cb181e2015-01-29 15:30:47 -08001808}
1809
1810static int
Jason Evansb2c0d632016-04-13 23:36:15 -07001811tcache_destroy_ctl(tsd_t *tsd, const size_t *mib, size_t miblen, void *oldp,
Jason Evansc4c25922017-01-15 16:56:30 -08001812 size_t *oldlenp, void *newp, size_t newlen) {
Jason Evans1cb181e2015-01-29 15:30:47 -08001813 int ret;
Jason Evans1cb181e2015-01-29 15:30:47 -08001814 unsigned tcache_ind;
1815
Jason Evans1cb181e2015-01-29 15:30:47 -08001816 WRITEONLY();
1817 tcache_ind = UINT_MAX;
1818 WRITE(tcache_ind, unsigned);
1819 if (tcache_ind == UINT_MAX) {
1820 ret = EFAULT;
1821 goto label_return;
1822 }
1823 tcaches_destroy(tsd, tcache_ind);
1824
1825 ret = 0;
1826label_return:
Jason Evansf4086432017-01-19 18:15:45 -08001827 return ret;
Jason Evans1cb181e2015-01-29 15:30:47 -08001828}
1829
1830/******************************************************************************/
1831
Jason Evansdc2125c2017-01-04 10:21:53 -08001832static int
1833arena_i_initialized_ctl(tsd_t *tsd, const size_t *mib, size_t miblen,
Jason Evansc4c25922017-01-15 16:56:30 -08001834 void *oldp, size_t *oldlenp, void *newp, size_t newlen) {
Jason Evansdc2125c2017-01-04 10:21:53 -08001835 int ret;
1836 tsdn_t *tsdn = tsd_tsdn(tsd);
1837 unsigned arena_ind;
1838 bool initialized;
1839
1840 READONLY();
1841 MIB_UNSIGNED(arena_ind, 1);
1842
1843 malloc_mutex_lock(tsdn, &ctl_mtx);
Jason Evans9eb1b1c2017-01-18 23:03:37 -08001844 initialized = arenas_i(arena_ind)->initialized;
Jason Evansdc2125c2017-01-04 10:21:53 -08001845 malloc_mutex_unlock(tsdn, &ctl_mtx);
1846
1847 READ(initialized, bool);
1848
1849 ret = 0;
1850label_return:
Jason Evansf4086432017-01-19 18:15:45 -08001851 return ret;
Jason Evansdc2125c2017-01-04 10:21:53 -08001852}
1853
Jason Evans34457f52012-11-03 21:18:28 -07001854static void
Jason Evans64e458f2017-03-08 22:42:57 -08001855arena_i_decay(tsdn_t *tsdn, unsigned arena_ind, bool all) {
Jason Evansc1e00ef2016-05-10 22:21:10 -07001856 malloc_mutex_lock(tsdn, &ctl_mtx);
Jason Evans243f7a02016-02-19 20:09:31 -08001857 {
Jason Evans9eb1b1c2017-01-18 23:03:37 -08001858 unsigned narenas = ctl_arenas->narenas;
Jason Evans609ae592012-10-11 13:53:15 -07001859
Jason Evans3dc4e832017-01-03 07:27:42 -08001860 /*
1861 * Access via index narenas is deprecated, and scheduled for
1862 * removal in 6.0.0.
1863 */
1864 if (arena_ind == MALLCTL_ARENAS_ALL || arena_ind == narenas) {
Jason Evans243f7a02016-02-19 20:09:31 -08001865 unsigned i;
Jason Evans243f7a02016-02-19 20:09:31 -08001866 VARIABLE_ARRAY(arena_t *, tarenas, narenas);
1867
Jason Evansc4c25922017-01-15 16:56:30 -08001868 for (i = 0; i < narenas; i++) {
Jason Evansc1e00ef2016-05-10 22:21:10 -07001869 tarenas[i] = arena_get(tsdn, i, false);
Jason Evansc4c25922017-01-15 16:56:30 -08001870 }
Jason Evans243f7a02016-02-19 20:09:31 -08001871
1872 /*
1873 * No further need to hold ctl_mtx, since narenas and
1874 * tarenas contain everything needed below.
1875 */
Jason Evansc1e00ef2016-05-10 22:21:10 -07001876 malloc_mutex_unlock(tsdn, &ctl_mtx);
Jason Evans243f7a02016-02-19 20:09:31 -08001877
1878 for (i = 0; i < narenas; i++) {
Jason Evansc4c25922017-01-15 16:56:30 -08001879 if (tarenas[i] != NULL) {
Qi Wangb693c782017-03-17 12:42:33 -07001880 arena_decay(tsdn, tarenas[i], false,
1881 all);
Jason Evansc4c25922017-01-15 16:56:30 -08001882 }
Jason Evans243f7a02016-02-19 20:09:31 -08001883 }
1884 } else {
1885 arena_t *tarena;
1886
1887 assert(arena_ind < narenas);
1888
Jason Evansc1e00ef2016-05-10 22:21:10 -07001889 tarena = arena_get(tsdn, arena_ind, false);
Jason Evans243f7a02016-02-19 20:09:31 -08001890
1891 /* No further need to hold ctl_mtx. */
Jason Evansc1e00ef2016-05-10 22:21:10 -07001892 malloc_mutex_unlock(tsdn, &ctl_mtx);
Jason Evans243f7a02016-02-19 20:09:31 -08001893
Jason Evansc4c25922017-01-15 16:56:30 -08001894 if (tarena != NULL) {
Qi Wangb693c782017-03-17 12:42:33 -07001895 arena_decay(tsdn, tarena, false, all);
Jason Evansc4c25922017-01-15 16:56:30 -08001896 }
Jason Evans609ae592012-10-11 13:53:15 -07001897 }
1898 }
Jason Evans609ae592012-10-11 13:53:15 -07001899}
1900
1901static int
Jason Evansb2c0d632016-04-13 23:36:15 -07001902arena_i_decay_ctl(tsd_t *tsd, const size_t *mib, size_t miblen, void *oldp,
Jason Evansc4c25922017-01-15 16:56:30 -08001903 size_t *oldlenp, void *newp, size_t newlen) {
Jason Evans243f7a02016-02-19 20:09:31 -08001904 int ret;
Jason Evans6edbedd2017-01-04 07:51:49 -08001905 unsigned arena_ind;
Jason Evans243f7a02016-02-19 20:09:31 -08001906
1907 READONLY();
1908 WRITEONLY();
Jason Evans6edbedd2017-01-04 07:51:49 -08001909 MIB_UNSIGNED(arena_ind, 1);
Jason Evans64e458f2017-03-08 22:42:57 -08001910 arena_i_decay(tsd_tsdn(tsd), arena_ind, false);
1911
1912 ret = 0;
1913label_return:
1914 return ret;
1915}
1916
1917static int
1918arena_i_purge_ctl(tsd_t *tsd, const size_t *mib, size_t miblen, void *oldp,
1919 size_t *oldlenp, void *newp, size_t newlen) {
1920 int ret;
1921 unsigned arena_ind;
1922
1923 READONLY();
1924 WRITEONLY();
1925 MIB_UNSIGNED(arena_ind, 1);
1926 arena_i_decay(tsd_tsdn(tsd), arena_ind, true);
Jason Evans609ae592012-10-11 13:53:15 -07001927
Jason Evans34457f52012-11-03 21:18:28 -07001928 ret = 0;
Jason Evans609ae592012-10-11 13:53:15 -07001929label_return:
Jason Evansf4086432017-01-19 18:15:45 -08001930 return ret;
Jason Evans609ae592012-10-11 13:53:15 -07001931}
1932
1933static int
Jason Evansedf1baf2017-01-03 17:21:59 -08001934arena_i_reset_destroy_helper(tsd_t *tsd, const size_t *mib, size_t miblen,
1935 void *oldp, size_t *oldlenp, void *newp, size_t newlen, unsigned *arena_ind,
Jason Evansc4c25922017-01-15 16:56:30 -08001936 arena_t **arena) {
Jason Evansedf1baf2017-01-03 17:21:59 -08001937 int ret;
1938
1939 READONLY();
1940 WRITEONLY();
1941 MIB_UNSIGNED(*arena_ind, 1);
1942
Jason Evansedf1baf2017-01-03 17:21:59 -08001943 *arena = arena_get(tsd_tsdn(tsd), *arena_ind, false);
Qi Wang5aa46f02017-04-20 15:19:02 -07001944 if (*arena == NULL || arena_is_auto(*arena)) {
Jason Evansedf1baf2017-01-03 17:21:59 -08001945 ret = EFAULT;
1946 goto label_return;
1947 }
1948
1949 ret = 0;
1950label_return:
Jason Evansf4086432017-01-19 18:15:45 -08001951 return ret;
Jason Evansedf1baf2017-01-03 17:21:59 -08001952}
1953
Qi Wangb693c782017-03-17 12:42:33 -07001954static void
1955arena_reset_prepare_background_thread(tsd_t *tsd, unsigned arena_ind) {
1956 /* Temporarily disable the background thread during arena reset. */
1957 if (have_background_thread) {
1958 malloc_mutex_lock(tsd_tsdn(tsd), &background_thread_lock);
1959 if (background_thread_enabled()) {
1960 unsigned ind = arena_ind % ncpus;
1961 background_thread_info_t *info =
1962 &background_thread_info[ind];
Qi Wang394df952017-06-09 15:45:25 -07001963 assert(info->state == background_thread_started);
Qi Wang464cb602017-06-08 22:46:31 -07001964 malloc_mutex_lock(tsd_tsdn(tsd), &info->mtx);
Qi Wang394df952017-06-09 15:45:25 -07001965 info->state = background_thread_paused;
Qi Wang464cb602017-06-08 22:46:31 -07001966 malloc_mutex_unlock(tsd_tsdn(tsd), &info->mtx);
Qi Wangb693c782017-03-17 12:42:33 -07001967 }
1968 }
1969}
1970
1971static void
1972arena_reset_finish_background_thread(tsd_t *tsd, unsigned arena_ind) {
1973 if (have_background_thread) {
1974 if (background_thread_enabled()) {
1975 unsigned ind = arena_ind % ncpus;
1976 background_thread_info_t *info =
1977 &background_thread_info[ind];
Jason Evansd49ac4c2017-06-23 10:40:02 -07001978 assert(info->state == background_thread_paused);
Qi Wang464cb602017-06-08 22:46:31 -07001979 malloc_mutex_lock(tsd_tsdn(tsd), &info->mtx);
Qi Wang394df952017-06-09 15:45:25 -07001980 info->state = background_thread_started;
Qi Wang464cb602017-06-08 22:46:31 -07001981 malloc_mutex_unlock(tsd_tsdn(tsd), &info->mtx);
Qi Wangb693c782017-03-17 12:42:33 -07001982 }
1983 malloc_mutex_unlock(tsd_tsdn(tsd), &background_thread_lock);
1984 }
1985}
1986
Jason Evansedf1baf2017-01-03 17:21:59 -08001987static int
Jason Evans19ff2ce2016-04-22 14:37:17 -07001988arena_i_reset_ctl(tsd_t *tsd, const size_t *mib, size_t miblen, void *oldp,
Jason Evansc4c25922017-01-15 16:56:30 -08001989 size_t *oldlenp, void *newp, size_t newlen) {
Jason Evans19ff2ce2016-04-22 14:37:17 -07001990 int ret;
1991 unsigned arena_ind;
1992 arena_t *arena;
1993
Jason Evansedf1baf2017-01-03 17:21:59 -08001994 ret = arena_i_reset_destroy_helper(tsd, mib, miblen, oldp, oldlenp,
1995 newp, newlen, &arena_ind, &arena);
Jason Evansc4c25922017-01-15 16:56:30 -08001996 if (ret != 0) {
Jason Evansf4086432017-01-19 18:15:45 -08001997 return ret;
Jason Evansc4c25922017-01-15 16:56:30 -08001998 }
Jason Evans19ff2ce2016-04-22 14:37:17 -07001999
Qi Wangb693c782017-03-17 12:42:33 -07002000 arena_reset_prepare_background_thread(tsd, arena_ind);
Jason Evansedf1baf2017-01-03 17:21:59 -08002001 arena_reset(tsd, arena);
Qi Wangb693c782017-03-17 12:42:33 -07002002 arena_reset_finish_background_thread(tsd, arena_ind);
Jason Evans19ff2ce2016-04-22 14:37:17 -07002003
Jason Evansf4086432017-01-19 18:15:45 -08002004 return ret;
Jason Evansedf1baf2017-01-03 17:21:59 -08002005}
2006
2007static int
2008arena_i_destroy_ctl(tsd_t *tsd, const size_t *mib, size_t miblen, void *oldp,
Jason Evansc4c25922017-01-15 16:56:30 -08002009 size_t *oldlenp, void *newp, size_t newlen) {
Jason Evansedf1baf2017-01-03 17:21:59 -08002010 int ret;
2011 unsigned arena_ind;
2012 arena_t *arena;
Jason Evans9eb1b1c2017-01-18 23:03:37 -08002013 ctl_arena_t *ctl_darena, *ctl_arena;
Jason Evansedf1baf2017-01-03 17:21:59 -08002014
2015 ret = arena_i_reset_destroy_helper(tsd, mib, miblen, oldp, oldlenp,
2016 newp, newlen, &arena_ind, &arena);
Jason Evansc4c25922017-01-15 16:56:30 -08002017 if (ret != 0) {
Jason Evansedf1baf2017-01-03 17:21:59 -08002018 goto label_return;
Jason Evansc4c25922017-01-15 16:56:30 -08002019 }
Jason Evansedf1baf2017-01-03 17:21:59 -08002020
2021 if (arena_nthreads_get(arena, false) != 0 || arena_nthreads_get(arena,
2022 true) != 0) {
Jason Evans3dc4e832017-01-03 07:27:42 -08002023 ret = EFAULT;
2024 goto label_return;
2025 }
Jason Evans19ff2ce2016-04-22 14:37:17 -07002026
Qi Wangb693c782017-03-17 12:42:33 -07002027 arena_reset_prepare_background_thread(tsd, arena_ind);
Jason Evansedf1baf2017-01-03 17:21:59 -08002028 /* Merge stats after resetting and purging arena. */
Jason Evans19ff2ce2016-04-22 14:37:17 -07002029 arena_reset(tsd, arena);
Qi Wangb693c782017-03-17 12:42:33 -07002030 arena_decay(tsd_tsdn(tsd), arena, false, true);
Jason Evans9eb1b1c2017-01-18 23:03:37 -08002031 ctl_darena = arenas_i(MALLCTL_ARENAS_DESTROYED);
2032 ctl_darena->initialized = true;
2033 ctl_arena_refresh(tsd_tsdn(tsd), arena, ctl_darena, arena_ind, true);
Jason Evansedf1baf2017-01-03 17:21:59 -08002034 /* Destroy arena. */
2035 arena_destroy(tsd, arena);
Jason Evans9eb1b1c2017-01-18 23:03:37 -08002036 ctl_arena = arenas_i(arena_ind);
2037 ctl_arena->initialized = false;
Jason Evansedf1baf2017-01-03 17:21:59 -08002038 /* Record arena index for later recycling via arenas.create. */
Jason Evans9eb1b1c2017-01-18 23:03:37 -08002039 ql_elm_new(ctl_arena, destroyed_link);
2040 ql_tail_insert(&ctl_arenas->destroyed, ctl_arena, destroyed_link);
Qi Wangb693c782017-03-17 12:42:33 -07002041 arena_reset_finish_background_thread(tsd, arena_ind);
Jason Evans19ff2ce2016-04-22 14:37:17 -07002042
Jason Evansedf1baf2017-01-03 17:21:59 -08002043 assert(ret == 0);
Jason Evans19ff2ce2016-04-22 14:37:17 -07002044label_return:
Jason Evansf4086432017-01-19 18:15:45 -08002045 return ret;
Jason Evans19ff2ce2016-04-22 14:37:17 -07002046}
2047
2048static int
Jason Evansb2c0d632016-04-13 23:36:15 -07002049arena_i_dss_ctl(tsd_t *tsd, const size_t *mib, size_t miblen, void *oldp,
Jason Evansc4c25922017-01-15 16:56:30 -08002050 size_t *oldlenp, void *newp, size_t newlen) {
Jason Evans586c8ed2014-08-15 12:20:20 -07002051 int ret;
2052 const char *dss = NULL;
Jason Evans6edbedd2017-01-04 07:51:49 -08002053 unsigned arena_ind;
Jason Evans609ae592012-10-11 13:53:15 -07002054 dss_prec_t dss_prec_old = dss_prec_limit;
2055 dss_prec_t dss_prec = dss_prec_limit;
2056
Jason Evansc1e00ef2016-05-10 22:21:10 -07002057 malloc_mutex_lock(tsd_tsdn(tsd), &ctl_mtx);
Jason Evans609ae592012-10-11 13:53:15 -07002058 WRITE(dss, const char *);
Jason Evans6edbedd2017-01-04 07:51:49 -08002059 MIB_UNSIGNED(arena_ind, 1);
Jason Evans586c8ed2014-08-15 12:20:20 -07002060 if (dss != NULL) {
2061 int i;
2062 bool match = false;
2063
2064 for (i = 0; i < dss_prec_limit; i++) {
2065 if (strcmp(dss_prec_names[i], dss) == 0) {
2066 dss_prec = i;
2067 match = true;
2068 break;
2069 }
Jason Evans609ae592012-10-11 13:53:15 -07002070 }
Jason Evans586c8ed2014-08-15 12:20:20 -07002071
Jason Evans551ebc42014-10-03 10:16:09 -07002072 if (!match) {
Jason Evans586c8ed2014-08-15 12:20:20 -07002073 ret = EINVAL;
2074 goto label_return;
2075 }
Jason Evans609ae592012-10-11 13:53:15 -07002076 }
2077
Jason Evans3dc4e832017-01-03 07:27:42 -08002078 /*
2079 * Access via index narenas is deprecated, and scheduled for removal in
2080 * 6.0.0.
2081 */
Jason Evansd778dd22017-01-03 12:40:54 -08002082 if (arena_ind == MALLCTL_ARENAS_ALL || arena_ind ==
Jason Evans9eb1b1c2017-01-18 23:03:37 -08002083 ctl_arenas->narenas) {
Jason Evans3dc4e832017-01-03 07:27:42 -08002084 if (dss_prec != dss_prec_limit &&
2085 extent_dss_prec_set(dss_prec)) {
2086 ret = EFAULT;
2087 goto label_return;
2088 }
2089 dss_prec_old = extent_dss_prec_get();
2090 } else {
Jason Evansc1e00ef2016-05-10 22:21:10 -07002091 arena_t *arena = arena_get(tsd_tsdn(tsd), arena_ind, false);
Jason Evans586c8ed2014-08-15 12:20:20 -07002092 if (arena == NULL || (dss_prec != dss_prec_limit &&
Jason Evansb7795222017-02-12 16:34:36 -08002093 arena_dss_prec_set(arena, dss_prec))) {
Jason Evans586c8ed2014-08-15 12:20:20 -07002094 ret = EFAULT;
2095 goto label_return;
2096 }
Jason Evansb7795222017-02-12 16:34:36 -08002097 dss_prec_old = arena_dss_prec_get(arena);
Jason Evans609ae592012-10-11 13:53:15 -07002098 }
Jason Evans586c8ed2014-08-15 12:20:20 -07002099
Jason Evans609ae592012-10-11 13:53:15 -07002100 dss = dss_prec_names[dss_prec_old];
2101 READ(dss, const char *);
Jason Evans609ae592012-10-11 13:53:15 -07002102
2103 ret = 0;
2104label_return:
Jason Evansc1e00ef2016-05-10 22:21:10 -07002105 malloc_mutex_unlock(tsd_tsdn(tsd), &ctl_mtx);
Jason Evansf4086432017-01-19 18:15:45 -08002106 return ret;
Jason Evans609ae592012-10-11 13:53:15 -07002107}
2108
aravindfb7fe502014-05-05 15:16:56 -07002109static int
Jason Evans6e62c622017-05-17 10:47:00 -07002110arena_i_decay_ms_ctl_impl(tsd_t *tsd, const size_t *mib, size_t miblen,
Jason Evans64e458f2017-03-08 22:42:57 -08002111 void *oldp, size_t *oldlenp, void *newp, size_t newlen, bool dirty) {
Jason Evans243f7a02016-02-19 20:09:31 -08002112 int ret;
Jason Evans6edbedd2017-01-04 07:51:49 -08002113 unsigned arena_ind;
Jason Evans243f7a02016-02-19 20:09:31 -08002114 arena_t *arena;
2115
Jason Evans6edbedd2017-01-04 07:51:49 -08002116 MIB_UNSIGNED(arena_ind, 1);
Jason Evansc1e00ef2016-05-10 22:21:10 -07002117 arena = arena_get(tsd_tsdn(tsd), arena_ind, false);
Jason Evans243f7a02016-02-19 20:09:31 -08002118 if (arena == NULL) {
2119 ret = EFAULT;
2120 goto label_return;
2121 }
2122
2123 if (oldp != NULL && oldlenp != NULL) {
Jason Evans6e62c622017-05-17 10:47:00 -07002124 size_t oldval = dirty ? arena_dirty_decay_ms_get(arena) :
2125 arena_muzzy_decay_ms_get(arena);
Jason Evans243f7a02016-02-19 20:09:31 -08002126 READ(oldval, ssize_t);
2127 }
2128 if (newp != NULL) {
2129 if (newlen != sizeof(ssize_t)) {
2130 ret = EINVAL;
2131 goto label_return;
2132 }
Jason Evans6e62c622017-05-17 10:47:00 -07002133 if (dirty ? arena_dirty_decay_ms_set(tsd_tsdn(tsd), arena,
2134 *(ssize_t *)newp) : arena_muzzy_decay_ms_set(tsd_tsdn(tsd),
2135 arena, *(ssize_t *)newp)) {
Jason Evans243f7a02016-02-19 20:09:31 -08002136 ret = EFAULT;
2137 goto label_return;
2138 }
2139 }
2140
2141 ret = 0;
2142label_return:
Jason Evansf4086432017-01-19 18:15:45 -08002143 return ret;
Jason Evans243f7a02016-02-19 20:09:31 -08002144}
2145
2146static int
Jason Evans6e62c622017-05-17 10:47:00 -07002147arena_i_dirty_decay_ms_ctl(tsd_t *tsd, const size_t *mib, size_t miblen,
Jason Evans64e458f2017-03-08 22:42:57 -08002148 void *oldp, size_t *oldlenp, void *newp, size_t newlen) {
Jason Evans6e62c622017-05-17 10:47:00 -07002149 return arena_i_decay_ms_ctl_impl(tsd, mib, miblen, oldp, oldlenp, newp,
2150 newlen, true);
Jason Evans64e458f2017-03-08 22:42:57 -08002151}
2152
2153static int
Jason Evans6e62c622017-05-17 10:47:00 -07002154arena_i_muzzy_decay_ms_ctl(tsd_t *tsd, const size_t *mib, size_t miblen,
Jason Evans64e458f2017-03-08 22:42:57 -08002155 void *oldp, size_t *oldlenp, void *newp, size_t newlen) {
Jason Evans6e62c622017-05-17 10:47:00 -07002156 return arena_i_decay_ms_ctl_impl(tsd, mib, miblen, oldp, oldlenp, newp,
2157 newlen, false);
Jason Evans64e458f2017-03-08 22:42:57 -08002158}
2159
2160static int
Jason Evans9c305c92016-05-31 15:03:51 -07002161arena_i_extent_hooks_ctl(tsd_t *tsd, const size_t *mib, size_t miblen,
Jason Evansc4c25922017-01-15 16:56:30 -08002162 void *oldp, size_t *oldlenp, void *newp, size_t newlen) {
Jason Evansb49a3342015-07-28 11:28:19 -04002163 int ret;
Jason Evans6edbedd2017-01-04 07:51:49 -08002164 unsigned arena_ind;
Jason Evansb49a3342015-07-28 11:28:19 -04002165 arena_t *arena;
2166
Jason Evansc1e00ef2016-05-10 22:21:10 -07002167 malloc_mutex_lock(tsd_tsdn(tsd), &ctl_mtx);
Jason Evans6edbedd2017-01-04 07:51:49 -08002168 MIB_UNSIGNED(arena_ind, 1);
Jason Evansb49a3342015-07-28 11:28:19 -04002169 if (arena_ind < narenas_total_get() && (arena =
Jason Evansc1e00ef2016-05-10 22:21:10 -07002170 arena_get(tsd_tsdn(tsd), arena_ind, false)) != NULL) {
Jason Evansb49a3342015-07-28 11:28:19 -04002171 if (newp != NULL) {
Jason Evansf02fec82016-06-03 19:39:14 -07002172 extent_hooks_t *old_extent_hooks;
2173 extent_hooks_t *new_extent_hooks
2174 JEMALLOC_CC_SILENCE_INIT(NULL);
Jason Evansf8f05422016-06-03 12:05:53 -07002175 WRITE(new_extent_hooks, extent_hooks_t *);
Qi Wang3a813942017-06-02 16:27:05 -07002176 old_extent_hooks = extent_hooks_set(tsd, arena,
Jason Evansf8f05422016-06-03 12:05:53 -07002177 new_extent_hooks);
2178 READ(old_extent_hooks, extent_hooks_t *);
Jason Evansb49a3342015-07-28 11:28:19 -04002179 } else {
Jason Evansf8f05422016-06-03 12:05:53 -07002180 extent_hooks_t *old_extent_hooks =
2181 extent_hooks_get(arena);
2182 READ(old_extent_hooks, extent_hooks_t *);
Jason Evansb49a3342015-07-28 11:28:19 -04002183 }
2184 } else {
2185 ret = EFAULT;
2186 goto label_return;
2187 }
2188 ret = 0;
2189label_return:
Jason Evansc1e00ef2016-05-10 22:21:10 -07002190 malloc_mutex_unlock(tsd_tsdn(tsd), &ctl_mtx);
Jason Evansf4086432017-01-19 18:15:45 -08002191 return ret;
aravindfb7fe502014-05-05 15:16:56 -07002192}
2193
Jason Evans609ae592012-10-11 13:53:15 -07002194static const ctl_named_node_t *
Jason Evansc4c25922017-01-15 16:56:30 -08002195arena_i_index(tsdn_t *tsdn, const size_t *mib, size_t miblen, size_t i) {
Jason Evansb2c0d632016-04-13 23:36:15 -07002196 const ctl_named_node_t *ret;
Jason Evans609ae592012-10-11 13:53:15 -07002197
Jason Evansc1e00ef2016-05-10 22:21:10 -07002198 malloc_mutex_lock(tsdn, &ctl_mtx);
Jason Evansedf1baf2017-01-03 17:21:59 -08002199 switch (i) {
2200 case MALLCTL_ARENAS_ALL:
2201 case MALLCTL_ARENAS_DESTROYED:
2202 break;
2203 default:
Jason Evans9eb1b1c2017-01-18 23:03:37 -08002204 if (i > ctl_arenas->narenas) {
Jason Evansedf1baf2017-01-03 17:21:59 -08002205 ret = NULL;
2206 goto label_return;
2207 }
2208 break;
Jason Evans609ae592012-10-11 13:53:15 -07002209 }
2210
2211 ret = super_arena_i_node;
2212label_return:
Jason Evansc1e00ef2016-05-10 22:21:10 -07002213 malloc_mutex_unlock(tsdn, &ctl_mtx);
Jason Evansf4086432017-01-19 18:15:45 -08002214 return ret;
Jason Evans609ae592012-10-11 13:53:15 -07002215}
2216
Jason Evans609ae592012-10-11 13:53:15 -07002217/******************************************************************************/
2218
Jason Evans609ae592012-10-11 13:53:15 -07002219static int
Jason Evansb2c0d632016-04-13 23:36:15 -07002220arenas_narenas_ctl(tsd_t *tsd, const size_t *mib, size_t miblen, void *oldp,
Jason Evansc4c25922017-01-15 16:56:30 -08002221 size_t *oldlenp, void *newp, size_t newlen) {
Jason Evans609ae592012-10-11 13:53:15 -07002222 int ret;
2223 unsigned narenas;
2224
Jason Evansc1e00ef2016-05-10 22:21:10 -07002225 malloc_mutex_lock(tsd_tsdn(tsd), &ctl_mtx);
Jason Evans609ae592012-10-11 13:53:15 -07002226 READONLY();
2227 if (*oldlenp != sizeof(unsigned)) {
2228 ret = EINVAL;
2229 goto label_return;
2230 }
Jason Evans9eb1b1c2017-01-18 23:03:37 -08002231 narenas = ctl_arenas->narenas;
Jason Evans609ae592012-10-11 13:53:15 -07002232 READ(narenas, unsigned);
2233
2234 ret = 0;
2235label_return:
Jason Evansc1e00ef2016-05-10 22:21:10 -07002236 malloc_mutex_unlock(tsd_tsdn(tsd), &ctl_mtx);
Jason Evansf4086432017-01-19 18:15:45 -08002237 return ret;
Jason Evans609ae592012-10-11 13:53:15 -07002238}
Jason Evans3c234352010-01-27 13:10:55 -08002239
2240static int
Jason Evans6e62c622017-05-17 10:47:00 -07002241arenas_decay_ms_ctl_impl(tsd_t *tsd, const size_t *mib, size_t miblen,
Jason Evans64e458f2017-03-08 22:42:57 -08002242 void *oldp, size_t *oldlenp, void *newp, size_t newlen, bool dirty) {
Jason Evans243f7a02016-02-19 20:09:31 -08002243 int ret;
2244
2245 if (oldp != NULL && oldlenp != NULL) {
Jason Evans6e62c622017-05-17 10:47:00 -07002246 size_t oldval = (dirty ? arena_dirty_decay_ms_default_get() :
2247 arena_muzzy_decay_ms_default_get());
Jason Evans243f7a02016-02-19 20:09:31 -08002248 READ(oldval, ssize_t);
2249 }
2250 if (newp != NULL) {
2251 if (newlen != sizeof(ssize_t)) {
2252 ret = EINVAL;
2253 goto label_return;
2254 }
Jason Evans6e62c622017-05-17 10:47:00 -07002255 if (dirty ? arena_dirty_decay_ms_default_set(*(ssize_t *)newp)
2256 : arena_muzzy_decay_ms_default_set(*(ssize_t *)newp)) {
Jason Evans243f7a02016-02-19 20:09:31 -08002257 ret = EFAULT;
2258 goto label_return;
2259 }
2260 }
2261
2262 ret = 0;
2263label_return:
Jason Evansf4086432017-01-19 18:15:45 -08002264 return ret;
Jason Evans243f7a02016-02-19 20:09:31 -08002265}
2266
Jason Evans64e458f2017-03-08 22:42:57 -08002267static int
Jason Evans6e62c622017-05-17 10:47:00 -07002268arenas_dirty_decay_ms_ctl(tsd_t *tsd, const size_t *mib, size_t miblen,
Jason Evans64e458f2017-03-08 22:42:57 -08002269 void *oldp, size_t *oldlenp, void *newp, size_t newlen) {
Jason Evans6e62c622017-05-17 10:47:00 -07002270 return arenas_decay_ms_ctl_impl(tsd, mib, miblen, oldp, oldlenp, newp,
Jason Evans64e458f2017-03-08 22:42:57 -08002271 newlen, true);
2272}
2273
2274static int
Jason Evans6e62c622017-05-17 10:47:00 -07002275arenas_muzzy_decay_ms_ctl(tsd_t *tsd, const size_t *mib, size_t miblen,
Jason Evans64e458f2017-03-08 22:42:57 -08002276 void *oldp, size_t *oldlenp, void *newp, size_t newlen) {
Jason Evans6e62c622017-05-17 10:47:00 -07002277 return arenas_decay_ms_ctl_impl(tsd, mib, miblen, oldp, oldlenp, newp,
Jason Evans64e458f2017-03-08 22:42:57 -08002278 newlen, false);
2279}
2280
Jason Evansfc4dcfa2010-11-24 15:44:21 -08002281CTL_RO_NL_GEN(arenas_quantum, QUANTUM, size_t)
Jason Evansae4c7b42012-04-02 07:04:34 -07002282CTL_RO_NL_GEN(arenas_page, PAGE, size_t)
Jason Evans4403c9a2017-04-20 17:21:37 -07002283CTL_RO_NL_GEN(arenas_tcache_max, tcache_maxclass, size_t)
Jason Evansb1726102012-02-28 16:50:47 -08002284CTL_RO_NL_GEN(arenas_nbins, NBINS, unsigned)
Jason Evans4403c9a2017-04-20 17:21:37 -07002285CTL_RO_NL_GEN(arenas_nhbins, nhbins, unsigned)
Jason Evansd8a39002013-12-19 21:40:41 -08002286CTL_RO_NL_GEN(arenas_bin_i_size, arena_bin_info[mib[2]].reg_size, size_t)
2287CTL_RO_NL_GEN(arenas_bin_i_nregs, arena_bin_info[mib[2]].nregs, uint32_t)
Jason Evans498856f2016-05-29 18:34:50 -07002288CTL_RO_NL_GEN(arenas_bin_i_slab_size, arena_bin_info[mib[2]].slab_size, size_t)
Jason Evansd8a39002013-12-19 21:40:41 -08002289static const ctl_named_node_t *
Jason Evansc4c25922017-01-15 16:56:30 -08002290arenas_bin_i_index(tsdn_t *tsdn, const size_t *mib, size_t miblen, size_t i) {
2291 if (i > NBINS) {
Jason Evansf4086432017-01-19 18:15:45 -08002292 return NULL;
Jason Evansc4c25922017-01-15 16:56:30 -08002293 }
Jason Evansf4086432017-01-19 18:15:45 -08002294 return super_arenas_bin_i_node;
Jason Evansd8a39002013-12-19 21:40:41 -08002295}
2296
Jason Evans7d63fed2016-05-31 14:50:21 -07002297CTL_RO_NL_GEN(arenas_nlextents, NSIZES - NBINS, unsigned)
David Goldblatt8261e582017-05-30 10:45:37 -07002298CTL_RO_NL_GEN(arenas_lextent_i_size, sz_index2size(NBINS+(szind_t)mib[2]),
2299 size_t)
Jason Evans3c4d92e2014-10-12 22:53:59 -07002300static const ctl_named_node_t *
Jason Evansc4c25922017-01-15 16:56:30 -08002301arenas_lextent_i_index(tsdn_t *tsdn, const size_t *mib, size_t miblen,
2302 size_t i) {
2303 if (i > NSIZES - NBINS) {
Jason Evansf4086432017-01-19 18:15:45 -08002304 return NULL;
Jason Evansc4c25922017-01-15 16:56:30 -08002305 }
Jason Evansf4086432017-01-19 18:15:45 -08002306 return super_arenas_lextent_i_node;
Jason Evans3c4d92e2014-10-12 22:53:59 -07002307}
2308
Jason Evans6005f072010-09-30 16:55:08 -07002309static int
Jason Evans0f04bb12017-01-03 08:21:29 -08002310arenas_create_ctl(tsd_t *tsd, const size_t *mib, size_t miblen, void *oldp,
Jason Evansc4c25922017-01-15 16:56:30 -08002311 size_t *oldlenp, void *newp, size_t newlen) {
Jason Evans609ae592012-10-11 13:53:15 -07002312 int ret;
Jason Evansa0dd3a42016-12-22 16:39:10 -06002313 extent_hooks_t *extent_hooks;
Jason Evansedf1baf2017-01-03 17:21:59 -08002314 unsigned arena_ind;
Jason Evans609ae592012-10-11 13:53:15 -07002315
Jason Evansc1e00ef2016-05-10 22:21:10 -07002316 malloc_mutex_lock(tsd_tsdn(tsd), &ctl_mtx);
Jason Evansa0dd3a42016-12-22 16:39:10 -06002317
2318 extent_hooks = (extent_hooks_t *)&extent_hooks_default;
2319 WRITE(extent_hooks, extent_hooks_t *);
Qi Wang57beeb22017-06-22 18:58:40 -07002320 if ((arena_ind = ctl_arena_init(tsd, extent_hooks)) == UINT_MAX) {
Jason Evans609ae592012-10-11 13:53:15 -07002321 ret = EAGAIN;
2322 goto label_return;
2323 }
Jason Evansedf1baf2017-01-03 17:21:59 -08002324 READ(arena_ind, unsigned);
Jason Evans609ae592012-10-11 13:53:15 -07002325
Jason Evans6005f072010-09-30 16:55:08 -07002326 ret = 0;
Jason Evansa1ee7832012-04-10 15:07:44 -07002327label_return:
Jason Evansc1e00ef2016-05-10 22:21:10 -07002328 malloc_mutex_unlock(tsd_tsdn(tsd), &ctl_mtx);
Jason Evansf4086432017-01-19 18:15:45 -08002329 return ret;
Jason Evans6005f072010-09-30 16:55:08 -07002330}
2331
Jason Evans3c234352010-01-27 13:10:55 -08002332/******************************************************************************/
2333
Jason Evansd34f9e72010-02-11 13:19:21 -08002334static int
Jason Evansb2c0d632016-04-13 23:36:15 -07002335prof_thread_active_init_ctl(tsd_t *tsd, const size_t *mib, size_t miblen,
Jason Evansc4c25922017-01-15 16:56:30 -08002336 void *oldp, size_t *oldlenp, void *newp, size_t newlen) {
Jason Evansb2c0d632016-04-13 23:36:15 -07002337 int ret;
2338 bool oldval;
2339
Jason Evansc4c25922017-01-15 16:56:30 -08002340 if (!config_prof) {
Jason Evansf4086432017-01-19 18:15:45 -08002341 return ENOENT;
Jason Evansc4c25922017-01-15 16:56:30 -08002342 }
Jason Evansb2c0d632016-04-13 23:36:15 -07002343
2344 if (newp != NULL) {
2345 if (newlen != sizeof(bool)) {
2346 ret = EINVAL;
2347 goto label_return;
2348 }
Jason Evansc1e00ef2016-05-10 22:21:10 -07002349 oldval = prof_thread_active_init_set(tsd_tsdn(tsd),
2350 *(bool *)newp);
Jason Evansc4c25922017-01-15 16:56:30 -08002351 } else {
Jason Evansc1e00ef2016-05-10 22:21:10 -07002352 oldval = prof_thread_active_init_get(tsd_tsdn(tsd));
Jason Evansc4c25922017-01-15 16:56:30 -08002353 }
Jason Evansb2c0d632016-04-13 23:36:15 -07002354 READ(oldval, bool);
2355
2356 ret = 0;
2357label_return:
Jason Evansf4086432017-01-19 18:15:45 -08002358 return ret;
Jason Evansb2c0d632016-04-13 23:36:15 -07002359}
2360
2361static int
2362prof_active_ctl(tsd_t *tsd, const size_t *mib, size_t miblen, void *oldp,
Jason Evansc4c25922017-01-15 16:56:30 -08002363 size_t *oldlenp, void *newp, size_t newlen) {
Jason Evansfc12c0b2014-10-03 23:25:30 -07002364 int ret;
2365 bool oldval;
2366
Jason Evansc4c25922017-01-15 16:56:30 -08002367 if (!config_prof) {
Jason Evansf4086432017-01-19 18:15:45 -08002368 return ENOENT;
Jason Evansc4c25922017-01-15 16:56:30 -08002369 }
Jason Evansfc12c0b2014-10-03 23:25:30 -07002370
2371 if (newp != NULL) {
2372 if (newlen != sizeof(bool)) {
2373 ret = EINVAL;
2374 goto label_return;
2375 }
Jason Evansc1e00ef2016-05-10 22:21:10 -07002376 oldval = prof_active_set(tsd_tsdn(tsd), *(bool *)newp);
Jason Evansc4c25922017-01-15 16:56:30 -08002377 } else {
Jason Evansc1e00ef2016-05-10 22:21:10 -07002378 oldval = prof_active_get(tsd_tsdn(tsd));
Jason Evansc4c25922017-01-15 16:56:30 -08002379 }
Jason Evansfc12c0b2014-10-03 23:25:30 -07002380 READ(oldval, bool);
2381
2382 ret = 0;
2383label_return:
Jason Evansf4086432017-01-19 18:15:45 -08002384 return ret;
Jason Evansfc12c0b2014-10-03 23:25:30 -07002385}
2386
2387static int
Jason Evansb2c0d632016-04-13 23:36:15 -07002388prof_dump_ctl(tsd_t *tsd, const size_t *mib, size_t miblen, void *oldp,
Jason Evansc4c25922017-01-15 16:56:30 -08002389 size_t *oldlenp, void *newp, size_t newlen) {
Jason Evansd34f9e72010-02-11 13:19:21 -08002390 int ret;
Jason Evans22ca8552010-03-02 11:57:30 -08002391 const char *filename = NULL;
Jason Evansd34f9e72010-02-11 13:19:21 -08002392
Jason Evansc4c25922017-01-15 16:56:30 -08002393 if (!config_prof) {
Jason Evansf4086432017-01-19 18:15:45 -08002394 return ENOENT;
Jason Evansc4c25922017-01-15 16:56:30 -08002395 }
Jason Evans7372b152012-02-10 20:22:09 -08002396
Jason Evans22ca8552010-03-02 11:57:30 -08002397 WRITEONLY();
2398 WRITE(filename, const char *);
Jason Evansd34f9e72010-02-11 13:19:21 -08002399
Jason Evansb2c0d632016-04-13 23:36:15 -07002400 if (prof_mdump(tsd, filename)) {
Jason Evans22ca8552010-03-02 11:57:30 -08002401 ret = EFAULT;
Jason Evansa1ee7832012-04-10 15:07:44 -07002402 goto label_return;
Jason Evans22ca8552010-03-02 11:57:30 -08002403 }
Jason Evansd34f9e72010-02-11 13:19:21 -08002404
2405 ret = 0;
Jason Evansa1ee7832012-04-10 15:07:44 -07002406label_return:
Jason Evansf4086432017-01-19 18:15:45 -08002407 return ret;
Jason Evansd34f9e72010-02-11 13:19:21 -08002408}
2409
Jason Evans602c8e02014-08-18 16:22:13 -07002410static int
Jason Evansb2c0d632016-04-13 23:36:15 -07002411prof_gdump_ctl(tsd_t *tsd, const size_t *mib, size_t miblen, void *oldp,
Jason Evansc4c25922017-01-15 16:56:30 -08002412 size_t *oldlenp, void *newp, size_t newlen) {
Jason Evans5b8ed5b2015-01-25 21:16:57 -08002413 int ret;
2414 bool oldval;
2415
Jason Evansc4c25922017-01-15 16:56:30 -08002416 if (!config_prof) {
Jason Evansf4086432017-01-19 18:15:45 -08002417 return ENOENT;
Jason Evansc4c25922017-01-15 16:56:30 -08002418 }
Jason Evans5b8ed5b2015-01-25 21:16:57 -08002419
2420 if (newp != NULL) {
2421 if (newlen != sizeof(bool)) {
2422 ret = EINVAL;
2423 goto label_return;
2424 }
Jason Evansc1e00ef2016-05-10 22:21:10 -07002425 oldval = prof_gdump_set(tsd_tsdn(tsd), *(bool *)newp);
Jason Evansc4c25922017-01-15 16:56:30 -08002426 } else {
Jason Evansc1e00ef2016-05-10 22:21:10 -07002427 oldval = prof_gdump_get(tsd_tsdn(tsd));
Jason Evansc4c25922017-01-15 16:56:30 -08002428 }
Jason Evans5b8ed5b2015-01-25 21:16:57 -08002429 READ(oldval, bool);
2430
2431 ret = 0;
2432label_return:
Jason Evansf4086432017-01-19 18:15:45 -08002433 return ret;
Jason Evans5b8ed5b2015-01-25 21:16:57 -08002434}
2435
2436static int
Jason Evansb2c0d632016-04-13 23:36:15 -07002437prof_reset_ctl(tsd_t *tsd, const size_t *mib, size_t miblen, void *oldp,
Jason Evansc4c25922017-01-15 16:56:30 -08002438 size_t *oldlenp, void *newp, size_t newlen) {
Jason Evans602c8e02014-08-18 16:22:13 -07002439 int ret;
2440 size_t lg_sample = lg_prof_sample;
2441
Jason Evansc4c25922017-01-15 16:56:30 -08002442 if (!config_prof) {
Jason Evansf4086432017-01-19 18:15:45 -08002443 return ENOENT;
Jason Evansc4c25922017-01-15 16:56:30 -08002444 }
Jason Evans602c8e02014-08-18 16:22:13 -07002445
2446 WRITEONLY();
2447 WRITE(lg_sample, size_t);
Jason Evansc4c25922017-01-15 16:56:30 -08002448 if (lg_sample >= (sizeof(uint64_t) << 3)) {
Jason Evans602c8e02014-08-18 16:22:13 -07002449 lg_sample = (sizeof(uint64_t) << 3) - 1;
Jason Evansc4c25922017-01-15 16:56:30 -08002450 }
Jason Evans602c8e02014-08-18 16:22:13 -07002451
Jason Evansb54d1602016-10-20 23:59:12 -07002452 prof_reset(tsd, lg_sample);
Jason Evans602c8e02014-08-18 16:22:13 -07002453
2454 ret = 0;
2455label_return:
Jason Evansf4086432017-01-19 18:15:45 -08002456 return ret;
Jason Evans602c8e02014-08-18 16:22:13 -07002457}
2458
Jason Evans7372b152012-02-10 20:22:09 -08002459CTL_RO_NL_CGEN(config_prof, prof_interval, prof_interval, uint64_t)
Jason Evans602c8e02014-08-18 16:22:13 -07002460CTL_RO_NL_CGEN(config_prof, lg_prof_sample, lg_prof_sample, size_t)
Jason Evansd34f9e72010-02-11 13:19:21 -08002461
2462/******************************************************************************/
2463
Jason Evansd778dd22017-01-03 12:40:54 -08002464CTL_RO_CGEN(config_stats, stats_allocated, ctl_stats->allocated, size_t)
2465CTL_RO_CGEN(config_stats, stats_active, ctl_stats->active, size_t)
2466CTL_RO_CGEN(config_stats, stats_metadata, ctl_stats->metadata, size_t)
2467CTL_RO_CGEN(config_stats, stats_resident, ctl_stats->resident, size_t)
2468CTL_RO_CGEN(config_stats, stats_mapped, ctl_stats->mapped, size_t)
2469CTL_RO_CGEN(config_stats, stats_retained, ctl_stats->retained, size_t)
Jason Evansd8a39002013-12-19 21:40:41 -08002470
Qi Wang2bee0c62017-05-12 12:30:33 -07002471CTL_RO_CGEN(config_stats, stats_background_thread_num_threads,
2472 ctl_stats->background_thread.num_threads, size_t)
2473CTL_RO_CGEN(config_stats, stats_background_thread_num_runs,
2474 ctl_stats->background_thread.num_runs, uint64_t)
2475CTL_RO_CGEN(config_stats, stats_background_thread_run_interval,
2476 nstime_ns(&ctl_stats->background_thread.run_interval), uint64_t)
2477
Jason Evans9eb1b1c2017-01-18 23:03:37 -08002478CTL_RO_GEN(stats_arenas_i_dss, arenas_i(mib[2])->dss, const char *)
Jason Evans6e62c622017-05-17 10:47:00 -07002479CTL_RO_GEN(stats_arenas_i_dirty_decay_ms, arenas_i(mib[2])->dirty_decay_ms,
Jason Evans64e458f2017-03-08 22:42:57 -08002480 ssize_t)
Jason Evans6e62c622017-05-17 10:47:00 -07002481CTL_RO_GEN(stats_arenas_i_muzzy_decay_ms, arenas_i(mib[2])->muzzy_decay_ms,
Jason Evans243f7a02016-02-19 20:09:31 -08002482 ssize_t)
Jason Evans9eb1b1c2017-01-18 23:03:37 -08002483CTL_RO_GEN(stats_arenas_i_nthreads, arenas_i(mib[2])->nthreads, unsigned)
Qi Wangbaf3e292017-05-16 13:56:00 -07002484CTL_RO_GEN(stats_arenas_i_uptime,
2485 nstime_ns(&arenas_i(mib[2])->astats->astats.uptime), uint64_t)
Jason Evans9eb1b1c2017-01-18 23:03:37 -08002486CTL_RO_GEN(stats_arenas_i_pactive, arenas_i(mib[2])->pactive, size_t)
2487CTL_RO_GEN(stats_arenas_i_pdirty, arenas_i(mib[2])->pdirty, size_t)
Jason Evans64e458f2017-03-08 22:42:57 -08002488CTL_RO_GEN(stats_arenas_i_pmuzzy, arenas_i(mib[2])->pmuzzy, size_t)
Jason Evansd8a39002013-12-19 21:40:41 -08002489CTL_RO_CGEN(config_stats, stats_arenas_i_mapped,
David Goldblattee202ef2017-03-13 16:18:40 -07002490 atomic_load_zu(&arenas_i(mib[2])->astats->astats.mapped, ATOMIC_RELAXED),
2491 size_t)
Jason Evans04c3c0f2016-05-03 22:11:35 -07002492CTL_RO_CGEN(config_stats, stats_arenas_i_retained,
David Goldblattee202ef2017-03-13 16:18:40 -07002493 atomic_load_zu(&arenas_i(mib[2])->astats->astats.retained, ATOMIC_RELAXED),
2494 size_t)
Jason Evans64e458f2017-03-08 22:42:57 -08002495
2496CTL_RO_CGEN(config_stats, stats_arenas_i_dirty_npurge,
2497 arena_stats_read_u64(&arenas_i(mib[2])->astats->astats.decay_dirty.npurge),
2498 uint64_t)
2499CTL_RO_CGEN(config_stats, stats_arenas_i_dirty_nmadvise,
2500 arena_stats_read_u64(
2501 &arenas_i(mib[2])->astats->astats.decay_dirty.nmadvise), uint64_t)
2502CTL_RO_CGEN(config_stats, stats_arenas_i_dirty_purged,
2503 arena_stats_read_u64(&arenas_i(mib[2])->astats->astats.decay_dirty.purged),
2504 uint64_t)
2505
2506CTL_RO_CGEN(config_stats, stats_arenas_i_muzzy_npurge,
2507 arena_stats_read_u64(&arenas_i(mib[2])->astats->astats.decay_muzzy.npurge),
2508 uint64_t)
2509CTL_RO_CGEN(config_stats, stats_arenas_i_muzzy_nmadvise,
2510 arena_stats_read_u64(
2511 &arenas_i(mib[2])->astats->astats.decay_muzzy.nmadvise), uint64_t)
2512CTL_RO_CGEN(config_stats, stats_arenas_i_muzzy_purged,
2513 arena_stats_read_u64(&arenas_i(mib[2])->astats->astats.decay_muzzy.purged),
2514 uint64_t)
2515
Jason Evansa0dd3a42016-12-22 16:39:10 -06002516CTL_RO_CGEN(config_stats, stats_arenas_i_base,
David Goldblattee202ef2017-03-13 16:18:40 -07002517 atomic_load_zu(&arenas_i(mib[2])->astats->astats.base, ATOMIC_RELAXED),
2518 size_t)
Jason Evansa0dd3a42016-12-22 16:39:10 -06002519CTL_RO_CGEN(config_stats, stats_arenas_i_internal,
David Goldblattee202ef2017-03-13 16:18:40 -07002520 atomic_load_zu(&arenas_i(mib[2])->astats->astats.internal, ATOMIC_RELAXED),
2521 size_t)
Jason Evans4403c9a2017-04-20 17:21:37 -07002522CTL_RO_CGEN(config_stats, stats_arenas_i_tcache_bytes,
David Goldblattee202ef2017-03-13 16:18:40 -07002523 atomic_load_zu(&arenas_i(mib[2])->astats->astats.tcache_bytes,
2524 ATOMIC_RELAXED), size_t)
Jason Evansa0dd3a42016-12-22 16:39:10 -06002525CTL_RO_CGEN(config_stats, stats_arenas_i_resident,
David Goldblattee202ef2017-03-13 16:18:40 -07002526 atomic_load_zu(&arenas_i(mib[2])->astats->astats.resident, ATOMIC_RELAXED),
2527 size_t)
Jason Evansd8a39002013-12-19 21:40:41 -08002528
Jason Evans7372b152012-02-10 20:22:09 -08002529CTL_RO_CGEN(config_stats, stats_arenas_i_small_allocated,
Jason Evans9eb1b1c2017-01-18 23:03:37 -08002530 arenas_i(mib[2])->astats->allocated_small, size_t)
Jason Evans7372b152012-02-10 20:22:09 -08002531CTL_RO_CGEN(config_stats, stats_arenas_i_small_nmalloc,
Jason Evans9eb1b1c2017-01-18 23:03:37 -08002532 arenas_i(mib[2])->astats->nmalloc_small, uint64_t)
Jason Evans7372b152012-02-10 20:22:09 -08002533CTL_RO_CGEN(config_stats, stats_arenas_i_small_ndalloc,
Jason Evans9eb1b1c2017-01-18 23:03:37 -08002534 arenas_i(mib[2])->astats->ndalloc_small, uint64_t)
Jason Evans7372b152012-02-10 20:22:09 -08002535CTL_RO_CGEN(config_stats, stats_arenas_i_small_nrequests,
Jason Evans9eb1b1c2017-01-18 23:03:37 -08002536 arenas_i(mib[2])->astats->nrequests_small, uint64_t)
Jason Evans7d63fed2016-05-31 14:50:21 -07002537CTL_RO_CGEN(config_stats, stats_arenas_i_large_allocated,
David Goldblattee202ef2017-03-13 16:18:40 -07002538 atomic_load_zu(&arenas_i(mib[2])->astats->astats.allocated_large,
2539 ATOMIC_RELAXED), size_t)
Jason Evans7d63fed2016-05-31 14:50:21 -07002540CTL_RO_CGEN(config_stats, stats_arenas_i_large_nmalloc,
David Goldblatt4fc2acf2017-03-08 15:56:31 -08002541 arena_stats_read_u64(&arenas_i(mib[2])->astats->astats.nmalloc_large),
2542 uint64_t)
Jason Evans7d63fed2016-05-31 14:50:21 -07002543CTL_RO_CGEN(config_stats, stats_arenas_i_large_ndalloc,
David Goldblatt4fc2acf2017-03-08 15:56:31 -08002544 arena_stats_read_u64(&arenas_i(mib[2])->astats->astats.ndalloc_large),
2545 uint64_t)
Jason Evans7d63fed2016-05-31 14:50:21 -07002546CTL_RO_CGEN(config_stats, stats_arenas_i_large_nrequests,
David Goldblatt4fc2acf2017-03-08 15:56:31 -08002547 arena_stats_read_u64(&arenas_i(mib[2])->astats->astats.nmalloc_large),
2548 uint64_t) /* Intentional. */
Jason Evans3c234352010-01-27 13:10:55 -08002549
Qi Wang0fb5c0e2017-03-10 12:14:05 -08002550/* Lock profiling related APIs below. */
Qi Wang64c5f5c2017-03-13 17:29:03 -07002551#define RO_MUTEX_CTL_GEN(n, l) \
Qi Wangca9074d2017-03-11 20:28:31 -08002552CTL_RO_CGEN(config_stats, stats_##n##_num_ops, \
2553 l.n_lock_ops, uint64_t) \
2554CTL_RO_CGEN(config_stats, stats_##n##_num_wait, \
2555 l.n_wait_times, uint64_t) \
2556CTL_RO_CGEN(config_stats, stats_##n##_num_spin_acq, \
2557 l.n_spin_acquired, uint64_t) \
2558CTL_RO_CGEN(config_stats, stats_##n##_num_owner_switch, \
2559 l.n_owner_switches, uint64_t) \
2560CTL_RO_CGEN(config_stats, stats_##n##_total_wait_time, \
Qi Wangf6698ec2017-03-17 17:42:10 -07002561 nstime_ns(&l.tot_wait_time), uint64_t) \
Qi Wangca9074d2017-03-11 20:28:31 -08002562CTL_RO_CGEN(config_stats, stats_##n##_max_wait_time, \
Qi Wangf6698ec2017-03-17 17:42:10 -07002563 nstime_ns(&l.max_wait_time), uint64_t) \
Qi Wangca9074d2017-03-11 20:28:31 -08002564CTL_RO_CGEN(config_stats, stats_##n##_max_num_thds, \
Qi Wangd3fde1c2017-03-21 11:56:38 -07002565 l.max_n_thds, uint32_t)
Qi Wang0fb5c0e2017-03-10 12:14:05 -08002566
Qi Wang64c5f5c2017-03-13 17:29:03 -07002567/* Global mutexes. */
Qi Wangd3fde1c2017-03-21 11:56:38 -07002568#define OP(mtx) \
2569 RO_MUTEX_CTL_GEN(mutexes_##mtx, \
2570 ctl_stats->mutex_prof_data[global_prof_mutex_##mtx])
David Goldblatt89e2d3c2017-04-24 17:09:56 -07002571MUTEX_PROF_GLOBAL_MUTEXES
Qi Wangd3fde1c2017-03-21 11:56:38 -07002572#undef OP
2573
2574/* Per arena mutexes */
2575#define OP(mtx) RO_MUTEX_CTL_GEN(arenas_i_mutexes_##mtx, \
2576 arenas_i(mib[2])->astats->astats.mutex_prof_data[arena_prof_mutex_##mtx])
David Goldblatt89e2d3c2017-04-24 17:09:56 -07002577MUTEX_PROF_ARENA_MUTEXES
Qi Wangd3fde1c2017-03-21 11:56:38 -07002578#undef OP
Qi Wangca9074d2017-03-11 20:28:31 -08002579
Qi Wang20b8c702017-03-15 14:00:57 -07002580/* tcache bin mutex */
Qi Wang64c5f5c2017-03-13 17:29:03 -07002581RO_MUTEX_CTL_GEN(arenas_i_bins_j_mutex,
2582 arenas_i(mib[2])->astats->bstats[mib[4]].mutex_data)
Qi Wang64c5f5c2017-03-13 17:29:03 -07002583#undef RO_MUTEX_CTL_GEN
2584
2585/* Resets all mutex stats, including global, arena and bin mutexes. */
2586static int
2587stats_mutexes_reset_ctl(tsd_t *tsd, const size_t *mib, size_t miblen,
2588 void *oldp, size_t *oldlenp, void *newp, size_t newlen) {
2589 if (!config_stats) {
2590 return ENOENT;
2591 }
2592
2593 tsdn_t *tsdn = tsd_tsdn(tsd);
2594
2595#define MUTEX_PROF_RESET(mtx) \
2596 malloc_mutex_lock(tsdn, &mtx); \
2597 malloc_mutex_prof_data_reset(tsdn, &mtx); \
2598 malloc_mutex_unlock(tsdn, &mtx);
2599
Qi Wang362e3562017-03-22 01:49:56 -07002600 /* Global mutexes: ctl and prof. */
2601 MUTEX_PROF_RESET(ctl_mtx);
Qi Wang5f5ed212017-05-12 16:26:59 -07002602 if (have_background_thread) {
2603 MUTEX_PROF_RESET(background_thread_lock);
2604 }
Qi Wang64c5f5c2017-03-13 17:29:03 -07002605 if (config_prof && opt_prof) {
2606 MUTEX_PROF_RESET(bt2gctx_mtx);
2607 }
Qi Wang362e3562017-03-22 01:49:56 -07002608
Qi Wang64c5f5c2017-03-13 17:29:03 -07002609
2610 /* Per arena mutexes. */
2611 unsigned n = narenas_total_get();
2612
2613 for (unsigned i = 0; i < n; i++) {
2614 arena_t *arena = arena_get(tsdn, i, false);
2615 if (!arena) {
2616 continue;
2617 }
2618 MUTEX_PROF_RESET(arena->large_mtx);
Jason Evans881fbf72017-04-16 22:31:16 -07002619 MUTEX_PROF_RESET(arena->extent_avail_mtx);
Qi Wang20b8c702017-03-15 14:00:57 -07002620 MUTEX_PROF_RESET(arena->extents_dirty.mtx);
2621 MUTEX_PROF_RESET(arena->extents_muzzy.mtx);
Qi Wang64c5f5c2017-03-13 17:29:03 -07002622 MUTEX_PROF_RESET(arena->extents_retained.mtx);
Qi Wang20b8c702017-03-15 14:00:57 -07002623 MUTEX_PROF_RESET(arena->decay_dirty.mtx);
2624 MUTEX_PROF_RESET(arena->decay_muzzy.mtx);
Jason Evans4403c9a2017-04-20 17:21:37 -07002625 MUTEX_PROF_RESET(arena->tcache_ql_mtx);
Qi Wang362e3562017-03-22 01:49:56 -07002626 MUTEX_PROF_RESET(arena->base->mtx);
Qi Wang64c5f5c2017-03-13 17:29:03 -07002627
2628 for (szind_t i = 0; i < NBINS; i++) {
2629 arena_bin_t *bin = &arena->bins[i];
2630 MUTEX_PROF_RESET(bin->lock);
2631 }
2632 }
2633#undef MUTEX_PROF_RESET
2634 return 0;
2635}
Qi Wang0fb5c0e2017-03-10 12:14:05 -08002636
Jason Evans7372b152012-02-10 20:22:09 -08002637CTL_RO_CGEN(config_stats, stats_arenas_i_bins_j_nmalloc,
Jason Evans9eb1b1c2017-01-18 23:03:37 -08002638 arenas_i(mib[2])->astats->bstats[mib[4]].nmalloc, uint64_t)
Jason Evans7372b152012-02-10 20:22:09 -08002639CTL_RO_CGEN(config_stats, stats_arenas_i_bins_j_ndalloc,
Jason Evans9eb1b1c2017-01-18 23:03:37 -08002640 arenas_i(mib[2])->astats->bstats[mib[4]].ndalloc, uint64_t)
Jason Evans7372b152012-02-10 20:22:09 -08002641CTL_RO_CGEN(config_stats, stats_arenas_i_bins_j_nrequests,
Jason Evans9eb1b1c2017-01-18 23:03:37 -08002642 arenas_i(mib[2])->astats->bstats[mib[4]].nrequests, uint64_t)
Jason Evans3c4d92e2014-10-12 22:53:59 -07002643CTL_RO_CGEN(config_stats, stats_arenas_i_bins_j_curregs,
Jason Evans9eb1b1c2017-01-18 23:03:37 -08002644 arenas_i(mib[2])->astats->bstats[mib[4]].curregs, size_t)
Jason Evans4403c9a2017-04-20 17:21:37 -07002645CTL_RO_CGEN(config_stats, stats_arenas_i_bins_j_nfills,
Jason Evans9eb1b1c2017-01-18 23:03:37 -08002646 arenas_i(mib[2])->astats->bstats[mib[4]].nfills, uint64_t)
Jason Evans4403c9a2017-04-20 17:21:37 -07002647CTL_RO_CGEN(config_stats, stats_arenas_i_bins_j_nflushes,
Jason Evans9eb1b1c2017-01-18 23:03:37 -08002648 arenas_i(mib[2])->astats->bstats[mib[4]].nflushes, uint64_t)
Jason Evans498856f2016-05-29 18:34:50 -07002649CTL_RO_CGEN(config_stats, stats_arenas_i_bins_j_nslabs,
Jason Evans9eb1b1c2017-01-18 23:03:37 -08002650 arenas_i(mib[2])->astats->bstats[mib[4]].nslabs, uint64_t)
Jason Evans498856f2016-05-29 18:34:50 -07002651CTL_RO_CGEN(config_stats, stats_arenas_i_bins_j_nreslabs,
Jason Evans9eb1b1c2017-01-18 23:03:37 -08002652 arenas_i(mib[2])->astats->bstats[mib[4]].reslabs, uint64_t)
Jason Evans498856f2016-05-29 18:34:50 -07002653CTL_RO_CGEN(config_stats, stats_arenas_i_bins_j_curslabs,
Jason Evans9eb1b1c2017-01-18 23:03:37 -08002654 arenas_i(mib[2])->astats->bstats[mib[4]].curslabs, size_t)
Jason Evans3c234352010-01-27 13:10:55 -08002655
Jason Evans609ae592012-10-11 13:53:15 -07002656static const ctl_named_node_t *
Jason Evansc1e00ef2016-05-10 22:21:10 -07002657stats_arenas_i_bins_j_index(tsdn_t *tsdn, const size_t *mib, size_t miblen,
Jason Evansc4c25922017-01-15 16:56:30 -08002658 size_t j) {
2659 if (j > NBINS) {
Jason Evansf4086432017-01-19 18:15:45 -08002660 return NULL;
Jason Evansc4c25922017-01-15 16:56:30 -08002661 }
Jason Evansf4086432017-01-19 18:15:45 -08002662 return super_stats_arenas_i_bins_j_node;
Jason Evans3c234352010-01-27 13:10:55 -08002663}
2664
Jason Evans7d63fed2016-05-31 14:50:21 -07002665CTL_RO_CGEN(config_stats, stats_arenas_i_lextents_j_nmalloc,
David Goldblatt4fc2acf2017-03-08 15:56:31 -08002666 arena_stats_read_u64(&arenas_i(mib[2])->astats->lstats[mib[4]].nmalloc),
2667 uint64_t)
Jason Evans7d63fed2016-05-31 14:50:21 -07002668CTL_RO_CGEN(config_stats, stats_arenas_i_lextents_j_ndalloc,
David Goldblatt4fc2acf2017-03-08 15:56:31 -08002669 arena_stats_read_u64(&arenas_i(mib[2])->astats->lstats[mib[4]].ndalloc),
2670 uint64_t)
Jason Evans7d63fed2016-05-31 14:50:21 -07002671CTL_RO_CGEN(config_stats, stats_arenas_i_lextents_j_nrequests,
Jason Evans64e458f2017-03-08 22:42:57 -08002672 arena_stats_read_u64(&arenas_i(mib[2])->astats->lstats[mib[4]].nrequests),
2673 uint64_t)
Jason Evans7d63fed2016-05-31 14:50:21 -07002674CTL_RO_CGEN(config_stats, stats_arenas_i_lextents_j_curlextents,
Jason Evans9eb1b1c2017-01-18 23:03:37 -08002675 arenas_i(mib[2])->astats->lstats[mib[4]].curlextents, size_t)
Jason Evans3c4d92e2014-10-12 22:53:59 -07002676
2677static const ctl_named_node_t *
Jason Evans7d63fed2016-05-31 14:50:21 -07002678stats_arenas_i_lextents_j_index(tsdn_t *tsdn, const size_t *mib, size_t miblen,
Jason Evansc4c25922017-01-15 16:56:30 -08002679 size_t j) {
2680 if (j > NSIZES - NBINS) {
Jason Evansf4086432017-01-19 18:15:45 -08002681 return NULL;
Jason Evansc4c25922017-01-15 16:56:30 -08002682 }
Jason Evansf4086432017-01-19 18:15:45 -08002683 return super_stats_arenas_i_lextents_j_node;
Jason Evans3c4d92e2014-10-12 22:53:59 -07002684}
2685
Jason Evans609ae592012-10-11 13:53:15 -07002686static const ctl_named_node_t *
Jason Evansc4c25922017-01-15 16:56:30 -08002687stats_arenas_i_index(tsdn_t *tsdn, const size_t *mib, size_t miblen, size_t i) {
Jason Evans3dc4e832017-01-03 07:27:42 -08002688 const ctl_named_node_t *ret;
2689 size_t a;
Jason Evans3c234352010-01-27 13:10:55 -08002690
Jason Evansc1e00ef2016-05-10 22:21:10 -07002691 malloc_mutex_lock(tsdn, &ctl_mtx);
Jason Evans9eb1b1c2017-01-18 23:03:37 -08002692 a = arenas_i2a_impl(i, true, true);
2693 if (a == UINT_MAX || !ctl_arenas->arenas[a]->initialized) {
Jason Evansfc4dcfa2010-11-24 15:44:21 -08002694 ret = NULL;
Jason Evansa1ee7832012-04-10 15:07:44 -07002695 goto label_return;
Jason Evansfc4dcfa2010-11-24 15:44:21 -08002696 }
2697
2698 ret = super_stats_arenas_i_node;
Jason Evansa1ee7832012-04-10 15:07:44 -07002699label_return:
Jason Evansc1e00ef2016-05-10 22:21:10 -07002700 malloc_mutex_unlock(tsdn, &ctl_mtx);
Jason Evansf4086432017-01-19 18:15:45 -08002701 return ret;
Jason Evans3c234352010-01-27 13:10:55 -08002702}