blob: aaf6e35a270977a992f37b3844929b8f8287544a [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 Evansb1476112012-04-05 13:36:17 -070078CTL_PROTO(config_utrace)
Jason Evans3c234352010-01-27 13:10:55 -080079CTL_PROTO(config_xmalloc)
80CTL_PROTO(opt_abort)
Qi Wangb86d2712017-05-25 15:30:11 -070081CTL_PROTO(opt_abort_conf)
Qi Wang8fdd9a52017-08-10 13:14:26 -070082CTL_PROTO(opt_metadata_thp)
Jason Evansb9ab04a2017-04-26 16:26:12 -070083CTL_PROTO(opt_retain)
Jason Evans609ae592012-10-11 13:53:15 -070084CTL_PROTO(opt_dss)
Jason Evanse7339702010-10-23 18:37:06 -070085CTL_PROTO(opt_narenas)
Qi Wangec532e22017-02-02 17:02:05 -080086CTL_PROTO(opt_percpu_arena)
Qi Wangb693c782017-03-17 12:42:33 -070087CTL_PROTO(opt_background_thread)
Jason Evans6e62c622017-05-17 10:47:00 -070088CTL_PROTO(opt_dirty_decay_ms)
89CTL_PROTO(opt_muzzy_decay_ms)
Jason Evanse7339702010-10-23 18:37:06 -070090CTL_PROTO(opt_stats_print)
Qi Wangd5ef5ae2017-05-27 15:35:36 -070091CTL_PROTO(opt_stats_print_opts)
Jason Evans3c234352010-01-27 13:10:55 -080092CTL_PROTO(opt_junk)
Jason Evanse7339702010-10-23 18:37:06 -070093CTL_PROTO(opt_zero)
Jason Evansb1476112012-04-05 13:36:17 -070094CTL_PROTO(opt_utrace)
Jason Evans3c234352010-01-27 13:10:55 -080095CTL_PROTO(opt_xmalloc)
Jason Evans3fa9a2f2010-03-07 15:34:14 -080096CTL_PROTO(opt_tcache)
Qi Wange4f090e2018-02-16 14:19:19 -080097CTL_PROTO(opt_thp)
Qi Wangfac70682017-11-09 13:51:39 -080098CTL_PROTO(opt_lg_extent_max_active_fit)
Jason Evansf3ca7c82012-04-04 16:16:09 -070099CTL_PROTO(opt_lg_tcache_max)
Jason Evansd34f9e72010-02-11 13:19:21 -0800100CTL_PROTO(opt_prof)
Jason Evanse7339702010-10-23 18:37:06 -0700101CTL_PROTO(opt_prof_prefix)
Jason Evansf18c9822010-03-31 18:43:24 -0700102CTL_PROTO(opt_prof_active)
Jason Evansfc12c0b2014-10-03 23:25:30 -0700103CTL_PROTO(opt_prof_thread_active_init)
Jason Evansb9477e72010-03-01 20:15:26 -0800104CTL_PROTO(opt_lg_prof_sample)
Jason Evansd34f9e72010-02-11 13:19:21 -0800105CTL_PROTO(opt_lg_prof_interval)
Jason Evanse7339702010-10-23 18:37:06 -0700106CTL_PROTO(opt_prof_gdump)
Jason Evans0b25fe72012-04-17 16:39:33 -0700107CTL_PROTO(opt_prof_final)
Jason Evansd34f9e72010-02-11 13:19:21 -0800108CTL_PROTO(opt_prof_leak)
Jason Evansa881cd22010-10-02 15:18:50 -0700109CTL_PROTO(opt_prof_accum)
Jason Evans1cb181e2015-01-29 15:30:47 -0800110CTL_PROTO(tcache_create)
111CTL_PROTO(tcache_flush)
112CTL_PROTO(tcache_destroy)
Jason Evansdc2125c2017-01-04 10:21:53 -0800113CTL_PROTO(arena_i_initialized)
Jason Evans243f7a02016-02-19 20:09:31 -0800114CTL_PROTO(arena_i_decay)
Jason Evans64e458f2017-03-08 22:42:57 -0800115CTL_PROTO(arena_i_purge)
Jason Evans19ff2ce2016-04-22 14:37:17 -0700116CTL_PROTO(arena_i_reset)
Jason Evansedf1baf2017-01-03 17:21:59 -0800117CTL_PROTO(arena_i_destroy)
Jason Evans609ae592012-10-11 13:53:15 -0700118CTL_PROTO(arena_i_dss)
Jason Evans6e62c622017-05-17 10:47:00 -0700119CTL_PROTO(arena_i_dirty_decay_ms)
120CTL_PROTO(arena_i_muzzy_decay_ms)
Jason Evans9c305c92016-05-31 15:03:51 -0700121CTL_PROTO(arena_i_extent_hooks)
Qi Wange422fa82017-11-02 17:48:39 -0700122CTL_PROTO(arena_i_retain_grow_limit)
Jason Evans609ae592012-10-11 13:53:15 -0700123INDEX_PROTO(arena_i)
Jason Evans3c234352010-01-27 13:10:55 -0800124CTL_PROTO(arenas_bin_i_size)
125CTL_PROTO(arenas_bin_i_nregs)
Jason Evans498856f2016-05-29 18:34:50 -0700126CTL_PROTO(arenas_bin_i_slab_size)
Jason Evans3c234352010-01-27 13:10:55 -0800127INDEX_PROTO(arenas_bin_i)
Jason Evans7d63fed2016-05-31 14:50:21 -0700128CTL_PROTO(arenas_lextent_i_size)
129INDEX_PROTO(arenas_lextent_i)
Jason Evans3c234352010-01-27 13:10:55 -0800130CTL_PROTO(arenas_narenas)
Jason Evans6e62c622017-05-17 10:47:00 -0700131CTL_PROTO(arenas_dirty_decay_ms)
132CTL_PROTO(arenas_muzzy_decay_ms)
Jason Evans3c234352010-01-27 13:10:55 -0800133CTL_PROTO(arenas_quantum)
Jason Evansae4c7b42012-04-02 07:04:34 -0700134CTL_PROTO(arenas_page)
Jason Evansdafde142010-03-17 16:27:39 -0700135CTL_PROTO(arenas_tcache_max)
Jason Evans3c234352010-01-27 13:10:55 -0800136CTL_PROTO(arenas_nbins)
Jason Evansdafde142010-03-17 16:27:39 -0700137CTL_PROTO(arenas_nhbins)
Jason Evans7d63fed2016-05-31 14:50:21 -0700138CTL_PROTO(arenas_nlextents)
Jason Evans0f04bb12017-01-03 08:21:29 -0800139CTL_PROTO(arenas_create)
Jason Evansfc12c0b2014-10-03 23:25:30 -0700140CTL_PROTO(prof_thread_active_init)
Jason Evansf18c9822010-03-31 18:43:24 -0700141CTL_PROTO(prof_active)
Jason Evansd34f9e72010-02-11 13:19:21 -0800142CTL_PROTO(prof_dump)
Jason Evans5b8ed5b2015-01-25 21:16:57 -0800143CTL_PROTO(prof_gdump)
Jason Evans602c8e02014-08-18 16:22:13 -0700144CTL_PROTO(prof_reset)
Jason Evansd34f9e72010-02-11 13:19:21 -0800145CTL_PROTO(prof_interval)
Jason Evans602c8e02014-08-18 16:22:13 -0700146CTL_PROTO(lg_prof_sample)
Jason Evans3c234352010-01-27 13:10:55 -0800147CTL_PROTO(stats_arenas_i_small_allocated)
148CTL_PROTO(stats_arenas_i_small_nmalloc)
149CTL_PROTO(stats_arenas_i_small_ndalloc)
Jason Evans86815df2010-03-13 20:32:56 -0800150CTL_PROTO(stats_arenas_i_small_nrequests)
Jason Evans7d63fed2016-05-31 14:50:21 -0700151CTL_PROTO(stats_arenas_i_large_allocated)
152CTL_PROTO(stats_arenas_i_large_nmalloc)
153CTL_PROTO(stats_arenas_i_large_ndalloc)
154CTL_PROTO(stats_arenas_i_large_nrequests)
Jason Evans86815df2010-03-13 20:32:56 -0800155CTL_PROTO(stats_arenas_i_bins_j_nmalloc)
156CTL_PROTO(stats_arenas_i_bins_j_ndalloc)
Jason Evans3c234352010-01-27 13:10:55 -0800157CTL_PROTO(stats_arenas_i_bins_j_nrequests)
Jason Evans3c4d92e2014-10-12 22:53:59 -0700158CTL_PROTO(stats_arenas_i_bins_j_curregs)
Jason Evans3c234352010-01-27 13:10:55 -0800159CTL_PROTO(stats_arenas_i_bins_j_nfills)
160CTL_PROTO(stats_arenas_i_bins_j_nflushes)
Jason Evans498856f2016-05-29 18:34:50 -0700161CTL_PROTO(stats_arenas_i_bins_j_nslabs)
162CTL_PROTO(stats_arenas_i_bins_j_nreslabs)
163CTL_PROTO(stats_arenas_i_bins_j_curslabs)
Jason Evans3c234352010-01-27 13:10:55 -0800164INDEX_PROTO(stats_arenas_i_bins_j)
Jason Evans7d63fed2016-05-31 14:50:21 -0700165CTL_PROTO(stats_arenas_i_lextents_j_nmalloc)
166CTL_PROTO(stats_arenas_i_lextents_j_ndalloc)
167CTL_PROTO(stats_arenas_i_lextents_j_nrequests)
168CTL_PROTO(stats_arenas_i_lextents_j_curlextents)
169INDEX_PROTO(stats_arenas_i_lextents_j)
Jason Evans597632b2011-03-18 13:41:33 -0700170CTL_PROTO(stats_arenas_i_nthreads)
Qi Wangbaf3e292017-05-16 13:56:00 -0700171CTL_PROTO(stats_arenas_i_uptime)
Jason Evans609ae592012-10-11 13:53:15 -0700172CTL_PROTO(stats_arenas_i_dss)
Jason Evans6e62c622017-05-17 10:47:00 -0700173CTL_PROTO(stats_arenas_i_dirty_decay_ms)
174CTL_PROTO(stats_arenas_i_muzzy_decay_ms)
Jason Evans3c234352010-01-27 13:10:55 -0800175CTL_PROTO(stats_arenas_i_pactive)
176CTL_PROTO(stats_arenas_i_pdirty)
Jason Evans64e458f2017-03-08 22:42:57 -0800177CTL_PROTO(stats_arenas_i_pmuzzy)
Jason Evans3c234352010-01-27 13:10:55 -0800178CTL_PROTO(stats_arenas_i_mapped)
Jason Evans04c3c0f2016-05-03 22:11:35 -0700179CTL_PROTO(stats_arenas_i_retained)
Jason Evans64e458f2017-03-08 22:42:57 -0800180CTL_PROTO(stats_arenas_i_dirty_npurge)
181CTL_PROTO(stats_arenas_i_dirty_nmadvise)
182CTL_PROTO(stats_arenas_i_dirty_purged)
183CTL_PROTO(stats_arenas_i_muzzy_npurge)
184CTL_PROTO(stats_arenas_i_muzzy_nmadvise)
185CTL_PROTO(stats_arenas_i_muzzy_purged)
Jason Evansa0dd3a42016-12-22 16:39:10 -0600186CTL_PROTO(stats_arenas_i_base)
187CTL_PROTO(stats_arenas_i_internal)
Qi Wange55c3ca2017-08-25 13:24:49 -0700188CTL_PROTO(stats_arenas_i_metadata_thp)
Qi Wang58424e62016-04-22 18:37:44 -0700189CTL_PROTO(stats_arenas_i_tcache_bytes)
Jason Evansa0dd3a42016-12-22 16:39:10 -0600190CTL_PROTO(stats_arenas_i_resident)
Jason Evans3c234352010-01-27 13:10:55 -0800191INDEX_PROTO(stats_arenas_i)
Jason Evans3c234352010-01-27 13:10:55 -0800192CTL_PROTO(stats_allocated)
193CTL_PROTO(stats_active)
Qi Wang2bee0c62017-05-12 12:30:33 -0700194CTL_PROTO(stats_background_thread_num_threads)
195CTL_PROTO(stats_background_thread_num_runs)
196CTL_PROTO(stats_background_thread_run_interval)
Jason Evans4581b972014-11-27 17:22:36 -0200197CTL_PROTO(stats_metadata)
Qi Wange55c3ca2017-08-25 13:24:49 -0700198CTL_PROTO(stats_metadata_thp)
Jason Evans4acd75a2015-03-23 17:25:57 -0700199CTL_PROTO(stats_resident)
Jason Evans3c234352010-01-27 13:10:55 -0800200CTL_PROTO(stats_mapped)
Jason Evans04c3c0f2016-05-03 22:11:35 -0700201CTL_PROTO(stats_retained)
Jason Evans3c234352010-01-27 13:10:55 -0800202
Qi Wang64c5f5c2017-03-13 17:29:03 -0700203#define MUTEX_STATS_CTL_PROTO_GEN(n) \
Qi Wangca9074d2017-03-11 20:28:31 -0800204CTL_PROTO(stats_##n##_num_ops) \
205CTL_PROTO(stats_##n##_num_wait) \
206CTL_PROTO(stats_##n##_num_spin_acq) \
207CTL_PROTO(stats_##n##_num_owner_switch) \
208CTL_PROTO(stats_##n##_total_wait_time) \
209CTL_PROTO(stats_##n##_max_wait_time) \
210CTL_PROTO(stats_##n##_max_num_thds)
Qi Wang0fb5c0e2017-03-10 12:14:05 -0800211
Qi Wang64c5f5c2017-03-13 17:29:03 -0700212/* Global mutexes. */
Qi Wangd3fde1c2017-03-21 11:56:38 -0700213#define OP(mtx) MUTEX_STATS_CTL_PROTO_GEN(mutexes_##mtx)
David Goldblatt89e2d3c2017-04-24 17:09:56 -0700214MUTEX_PROF_GLOBAL_MUTEXES
Qi Wangd3fde1c2017-03-21 11:56:38 -0700215#undef OP
216
217/* Per arena mutexes. */
218#define OP(mtx) MUTEX_STATS_CTL_PROTO_GEN(arenas_i_mutexes_##mtx)
David Goldblatt89e2d3c2017-04-24 17:09:56 -0700219MUTEX_PROF_ARENA_MUTEXES
Qi Wangd3fde1c2017-03-21 11:56:38 -0700220#undef OP
Qi Wangca9074d2017-03-11 20:28:31 -0800221
Qi Wang64c5f5c2017-03-13 17:29:03 -0700222/* Arena bin mutexes. */
223MUTEX_STATS_CTL_PROTO_GEN(arenas_i_bins_j_mutex)
Qi Wang64c5f5c2017-03-13 17:29:03 -0700224#undef MUTEX_STATS_CTL_PROTO_GEN
225
226CTL_PROTO(stats_mutexes_reset)
Qi Wang0fb5c0e2017-03-10 12:14:05 -0800227
Jason Evans3c234352010-01-27 13:10:55 -0800228/******************************************************************************/
229/* mallctl tree. */
230
Jason Evansc0cc5db2017-01-19 21:41:41 -0800231#define NAME(n) {true}, n
232#define CHILD(t, c) \
Jason Evans65f343a2012-04-23 19:31:45 -0700233 sizeof(c##_node) / sizeof(ctl_##t##_node_t), \
234 (ctl_node_t *)c##_node, \
235 NULL
Jason Evansc0cc5db2017-01-19 21:41:41 -0800236#define CTL(c) 0, NULL, c##_ctl
Jason Evans3c234352010-01-27 13:10:55 -0800237
238/*
239 * Only handles internal indexed nodes, since there are currently no external
240 * ones.
241 */
Jason Evansc0cc5db2017-01-19 21:41:41 -0800242#define INDEX(i) {false}, i##_index
Jason Evans3c234352010-01-27 13:10:55 -0800243
Jason Evans602c8e02014-08-18 16:22:13 -0700244static const ctl_named_node_t thread_tcache_node[] = {
Jason Evansd4be8b72012-03-26 18:54:44 -0700245 {NAME("enabled"), CTL(thread_tcache_enabled)},
Jason Evanse7b8fa12012-03-16 17:09:32 -0700246 {NAME("flush"), CTL(thread_tcache_flush)}
Jason Evans3c234352010-01-27 13:10:55 -0800247};
Jason Evans3c234352010-01-27 13:10:55 -0800248
Jason Evans602c8e02014-08-18 16:22:13 -0700249static const ctl_named_node_t thread_prof_node[] = {
250 {NAME("name"), CTL(thread_prof_name)},
251 {NAME("active"), CTL(thread_prof_active)}
252};
253
Mike Hommey461ad5c2012-04-20 08:38:42 +0200254static const ctl_named_node_t thread_node[] = {
Jason Evans7372b152012-02-10 20:22:09 -0800255 {NAME("arena"), CTL(thread_arena)},
Jason Evans93443682010-10-20 17:39:18 -0700256 {NAME("allocated"), CTL(thread_allocated)},
Jason Evansecf229a2010-12-03 15:55:47 -0800257 {NAME("allocatedp"), CTL(thread_allocatedp)},
258 {NAME("deallocated"), CTL(thread_deallocated)},
Jason Evanse7b8fa12012-03-16 17:09:32 -0700259 {NAME("deallocatedp"), CTL(thread_deallocatedp)},
Jason Evans602c8e02014-08-18 16:22:13 -0700260 {NAME("tcache"), CHILD(named, thread_tcache)},
261 {NAME("prof"), CHILD(named, thread_prof)}
Jason Evansb267d0f2010-08-13 15:42:29 -0700262};
Jason Evansb267d0f2010-08-13 15:42:29 -0700263
Mike Hommey461ad5c2012-04-20 08:38:42 +0200264static const ctl_named_node_t config_node[] = {
Jason Evansf2bc8522015-07-17 16:38:25 -0700265 {NAME("cache_oblivious"), CTL(config_cache_oblivious)},
Jason Evans3c4d92e2014-10-12 22:53:59 -0700266 {NAME("debug"), CTL(config_debug)},
267 {NAME("fill"), CTL(config_fill)},
268 {NAME("lazy_lock"), CTL(config_lazy_lock)},
Jason Evansf8290092016-02-07 14:23:22 -0800269 {NAME("malloc_conf"), CTL(config_malloc_conf)},
Jason Evans3c4d92e2014-10-12 22:53:59 -0700270 {NAME("prof"), CTL(config_prof)},
271 {NAME("prof_libgcc"), CTL(config_prof_libgcc)},
272 {NAME("prof_libunwind"), CTL(config_prof_libunwind)},
273 {NAME("stats"), CTL(config_stats)},
Jason Evans3c4d92e2014-10-12 22:53:59 -0700274 {NAME("utrace"), CTL(config_utrace)},
Jason Evans3c4d92e2014-10-12 22:53:59 -0700275 {NAME("xmalloc"), CTL(config_xmalloc)}
Jason Evans3c234352010-01-27 13:10:55 -0800276};
277
Mike Hommey461ad5c2012-04-20 08:38:42 +0200278static const ctl_named_node_t opt_node[] = {
Jason Evans3c4d92e2014-10-12 22:53:59 -0700279 {NAME("abort"), CTL(opt_abort)},
Qi Wangb86d2712017-05-25 15:30:11 -0700280 {NAME("abort_conf"), CTL(opt_abort_conf)},
Qi Wang8fdd9a52017-08-10 13:14:26 -0700281 {NAME("metadata_thp"), CTL(opt_metadata_thp)},
Jason Evansb9ab04a2017-04-26 16:26:12 -0700282 {NAME("retain"), CTL(opt_retain)},
Jason Evans3c4d92e2014-10-12 22:53:59 -0700283 {NAME("dss"), CTL(opt_dss)},
Jason Evans3c4d92e2014-10-12 22:53:59 -0700284 {NAME("narenas"), CTL(opt_narenas)},
Qi Wangec532e22017-02-02 17:02:05 -0800285 {NAME("percpu_arena"), CTL(opt_percpu_arena)},
Qi Wangb693c782017-03-17 12:42:33 -0700286 {NAME("background_thread"), CTL(opt_background_thread)},
Jason Evans6e62c622017-05-17 10:47:00 -0700287 {NAME("dirty_decay_ms"), CTL(opt_dirty_decay_ms)},
288 {NAME("muzzy_decay_ms"), CTL(opt_muzzy_decay_ms)},
Jason Evans3c4d92e2014-10-12 22:53:59 -0700289 {NAME("stats_print"), CTL(opt_stats_print)},
Qi Wangd5ef5ae2017-05-27 15:35:36 -0700290 {NAME("stats_print_opts"), CTL(opt_stats_print_opts)},
Jason Evans3c4d92e2014-10-12 22:53:59 -0700291 {NAME("junk"), CTL(opt_junk)},
292 {NAME("zero"), CTL(opt_zero)},
Jason Evans3c4d92e2014-10-12 22:53:59 -0700293 {NAME("utrace"), CTL(opt_utrace)},
294 {NAME("xmalloc"), CTL(opt_xmalloc)},
295 {NAME("tcache"), CTL(opt_tcache)},
Qi Wange4f090e2018-02-16 14:19:19 -0800296 {NAME("thp"), CTL(opt_thp)},
Qi Wangfac70682017-11-09 13:51:39 -0800297 {NAME("lg_extent_max_active_fit"), CTL(opt_lg_extent_max_active_fit)},
Jason Evans3c4d92e2014-10-12 22:53:59 -0700298 {NAME("lg_tcache_max"), CTL(opt_lg_tcache_max)},
299 {NAME("prof"), CTL(opt_prof)},
300 {NAME("prof_prefix"), CTL(opt_prof_prefix)},
301 {NAME("prof_active"), CTL(opt_prof_active)},
Jason Evansfc12c0b2014-10-03 23:25:30 -0700302 {NAME("prof_thread_active_init"), CTL(opt_prof_thread_active_init)},
Jason Evans3c4d92e2014-10-12 22:53:59 -0700303 {NAME("lg_prof_sample"), CTL(opt_lg_prof_sample)},
304 {NAME("lg_prof_interval"), CTL(opt_lg_prof_interval)},
305 {NAME("prof_gdump"), CTL(opt_prof_gdump)},
306 {NAME("prof_final"), CTL(opt_prof_final)},
307 {NAME("prof_leak"), CTL(opt_prof_leak)},
308 {NAME("prof_accum"), CTL(opt_prof_accum)}
Jason Evans3c234352010-01-27 13:10:55 -0800309};
310
Jason Evans1cb181e2015-01-29 15:30:47 -0800311static const ctl_named_node_t tcache_node[] = {
312 {NAME("create"), CTL(tcache_create)},
313 {NAME("flush"), CTL(tcache_flush)},
314 {NAME("destroy"), CTL(tcache_destroy)}
315};
316
Jason Evans609ae592012-10-11 13:53:15 -0700317static const ctl_named_node_t arena_i_node[] = {
Jason Evansdc2125c2017-01-04 10:21:53 -0800318 {NAME("initialized"), CTL(arena_i_initialized)},
Jason Evans243f7a02016-02-19 20:09:31 -0800319 {NAME("decay"), CTL(arena_i_decay)},
Jason Evans64e458f2017-03-08 22:42:57 -0800320 {NAME("purge"), CTL(arena_i_purge)},
Jason Evans19ff2ce2016-04-22 14:37:17 -0700321 {NAME("reset"), CTL(arena_i_reset)},
Jason Evansedf1baf2017-01-03 17:21:59 -0800322 {NAME("destroy"), CTL(arena_i_destroy)},
Jason Evans3c4d92e2014-10-12 22:53:59 -0700323 {NAME("dss"), CTL(arena_i_dss)},
Jason Evans6e62c622017-05-17 10:47:00 -0700324 {NAME("dirty_decay_ms"), CTL(arena_i_dirty_decay_ms)},
325 {NAME("muzzy_decay_ms"), CTL(arena_i_muzzy_decay_ms)},
Qi Wange422fa82017-11-02 17:48:39 -0700326 {NAME("extent_hooks"), CTL(arena_i_extent_hooks)},
327 {NAME("retain_grow_limit"), CTL(arena_i_retain_grow_limit)}
Jason Evans609ae592012-10-11 13:53:15 -0700328};
329static const ctl_named_node_t super_arena_i_node[] = {
Jason Evans3c4d92e2014-10-12 22:53:59 -0700330 {NAME(""), CHILD(named, arena_i)}
Jason Evans609ae592012-10-11 13:53:15 -0700331};
332
333static const ctl_indexed_node_t arena_node[] = {
334 {INDEX(arena_i)}
335};
336
Mike Hommey461ad5c2012-04-20 08:38:42 +0200337static const ctl_named_node_t arenas_bin_i_node[] = {
Jason Evans3c4d92e2014-10-12 22:53:59 -0700338 {NAME("size"), CTL(arenas_bin_i_size)},
339 {NAME("nregs"), CTL(arenas_bin_i_nregs)},
Jason Evans498856f2016-05-29 18:34:50 -0700340 {NAME("slab_size"), CTL(arenas_bin_i_slab_size)}
Jason Evans3c234352010-01-27 13:10:55 -0800341};
Mike Hommey461ad5c2012-04-20 08:38:42 +0200342static const ctl_named_node_t super_arenas_bin_i_node[] = {
Jason Evans3c4d92e2014-10-12 22:53:59 -0700343 {NAME(""), CHILD(named, arenas_bin_i)}
Jason Evans3c234352010-01-27 13:10:55 -0800344};
345
Mike Hommey461ad5c2012-04-20 08:38:42 +0200346static const ctl_indexed_node_t arenas_bin_node[] = {
Jason Evans3c234352010-01-27 13:10:55 -0800347 {INDEX(arenas_bin_i)}
348};
349
Jason Evans7d63fed2016-05-31 14:50:21 -0700350static const ctl_named_node_t arenas_lextent_i_node[] = {
351 {NAME("size"), CTL(arenas_lextent_i_size)}
Jason Evans3c4d92e2014-10-12 22:53:59 -0700352};
Jason Evans7d63fed2016-05-31 14:50:21 -0700353static const ctl_named_node_t super_arenas_lextent_i_node[] = {
354 {NAME(""), CHILD(named, arenas_lextent_i)}
Jason Evans3c4d92e2014-10-12 22:53:59 -0700355};
356
Jason Evans7d63fed2016-05-31 14:50:21 -0700357static const ctl_indexed_node_t arenas_lextent_node[] = {
358 {INDEX(arenas_lextent_i)}
Jason Evans3c4d92e2014-10-12 22:53:59 -0700359};
360
Mike Hommey461ad5c2012-04-20 08:38:42 +0200361static const ctl_named_node_t arenas_node[] = {
Jason Evans3c4d92e2014-10-12 22:53:59 -0700362 {NAME("narenas"), CTL(arenas_narenas)},
Jason Evans6e62c622017-05-17 10:47:00 -0700363 {NAME("dirty_decay_ms"), CTL(arenas_dirty_decay_ms)},
364 {NAME("muzzy_decay_ms"), CTL(arenas_muzzy_decay_ms)},
Jason Evans3c4d92e2014-10-12 22:53:59 -0700365 {NAME("quantum"), CTL(arenas_quantum)},
366 {NAME("page"), CTL(arenas_page)},
367 {NAME("tcache_max"), CTL(arenas_tcache_max)},
368 {NAME("nbins"), CTL(arenas_nbins)},
369 {NAME("nhbins"), CTL(arenas_nhbins)},
370 {NAME("bin"), CHILD(indexed, arenas_bin)},
Jason Evans7d63fed2016-05-31 14:50:21 -0700371 {NAME("nlextents"), CTL(arenas_nlextents)},
372 {NAME("lextent"), CHILD(indexed, arenas_lextent)},
Jason Evans0f04bb12017-01-03 08:21:29 -0800373 {NAME("create"), CTL(arenas_create)}
Jason Evans3c234352010-01-27 13:10:55 -0800374};
375
Mike Hommey461ad5c2012-04-20 08:38:42 +0200376static const ctl_named_node_t prof_node[] = {
Jason Evansfc12c0b2014-10-03 23:25:30 -0700377 {NAME("thread_active_init"), CTL(prof_thread_active_init)},
Jason Evansf18c9822010-03-31 18:43:24 -0700378 {NAME("active"), CTL(prof_active)},
Jason Evansd34f9e72010-02-11 13:19:21 -0800379 {NAME("dump"), CTL(prof_dump)},
Jason Evans5b8ed5b2015-01-25 21:16:57 -0800380 {NAME("gdump"), CTL(prof_gdump)},
Jason Evans602c8e02014-08-18 16:22:13 -0700381 {NAME("reset"), CTL(prof_reset)},
382 {NAME("interval"), CTL(prof_interval)},
383 {NAME("lg_sample"), CTL(lg_prof_sample)}
Jason Evansd34f9e72010-02-11 13:19:21 -0800384};
Jason Evansd34f9e72010-02-11 13:19:21 -0800385
Mike Hommey461ad5c2012-04-20 08:38:42 +0200386static const ctl_named_node_t stats_arenas_i_small_node[] = {
Jason Evans3c4d92e2014-10-12 22:53:59 -0700387 {NAME("allocated"), CTL(stats_arenas_i_small_allocated)},
388 {NAME("nmalloc"), CTL(stats_arenas_i_small_nmalloc)},
389 {NAME("ndalloc"), CTL(stats_arenas_i_small_ndalloc)},
390 {NAME("nrequests"), CTL(stats_arenas_i_small_nrequests)}
Jason Evans3c234352010-01-27 13:10:55 -0800391};
392
Jason Evans7d63fed2016-05-31 14:50:21 -0700393static const ctl_named_node_t stats_arenas_i_large_node[] = {
394 {NAME("allocated"), CTL(stats_arenas_i_large_allocated)},
395 {NAME("nmalloc"), CTL(stats_arenas_i_large_nmalloc)},
396 {NAME("ndalloc"), CTL(stats_arenas_i_large_ndalloc)},
397 {NAME("nrequests"), CTL(stats_arenas_i_large_nrequests)}
Jason Evanse2deab72014-05-15 22:22:27 -0700398};
399
Qi Wang64c5f5c2017-03-13 17:29:03 -0700400#define MUTEX_PROF_DATA_NODE(prefix) \
Qi Wangca9074d2017-03-11 20:28:31 -0800401static const ctl_named_node_t stats_##prefix##_node[] = { \
Qi Wang0fb5c0e2017-03-10 12:14:05 -0800402 {NAME("num_ops"), \
Qi Wangca9074d2017-03-11 20:28:31 -0800403 CTL(stats_##prefix##_num_ops)}, \
Qi Wang0fb5c0e2017-03-10 12:14:05 -0800404 {NAME("num_wait"), \
Qi Wangca9074d2017-03-11 20:28:31 -0800405 CTL(stats_##prefix##_num_wait)}, \
Qi Wang0fb5c0e2017-03-10 12:14:05 -0800406 {NAME("num_spin_acq"), \
Qi Wangca9074d2017-03-11 20:28:31 -0800407 CTL(stats_##prefix##_num_spin_acq)}, \
Qi Wang0fb5c0e2017-03-10 12:14:05 -0800408 {NAME("num_owner_switch"), \
Qi Wangca9074d2017-03-11 20:28:31 -0800409 CTL(stats_##prefix##_num_owner_switch)}, \
Qi Wang0fb5c0e2017-03-10 12:14:05 -0800410 {NAME("total_wait_time"), \
Qi Wangca9074d2017-03-11 20:28:31 -0800411 CTL(stats_##prefix##_total_wait_time)}, \
Qi Wang0fb5c0e2017-03-10 12:14:05 -0800412 {NAME("max_wait_time"), \
Qi Wangca9074d2017-03-11 20:28:31 -0800413 CTL(stats_##prefix##_max_wait_time)}, \
Qi Wang0fb5c0e2017-03-10 12:14:05 -0800414 {NAME("max_num_thds"), \
Qi Wangca9074d2017-03-11 20:28:31 -0800415 CTL(stats_##prefix##_max_num_thds)} \
Qi Wang0fb5c0e2017-03-10 12:14:05 -0800416 /* Note that # of current waiting thread not provided. */ \
417};
418
Qi Wang64c5f5c2017-03-13 17:29:03 -0700419MUTEX_PROF_DATA_NODE(arenas_i_bins_j_mutex)
Qi Wangca9074d2017-03-11 20:28:31 -0800420
Mike Hommey461ad5c2012-04-20 08:38:42 +0200421static const ctl_named_node_t stats_arenas_i_bins_j_node[] = {
Jason Evans3c4d92e2014-10-12 22:53:59 -0700422 {NAME("nmalloc"), CTL(stats_arenas_i_bins_j_nmalloc)},
423 {NAME("ndalloc"), CTL(stats_arenas_i_bins_j_ndalloc)},
424 {NAME("nrequests"), CTL(stats_arenas_i_bins_j_nrequests)},
425 {NAME("curregs"), CTL(stats_arenas_i_bins_j_curregs)},
426 {NAME("nfills"), CTL(stats_arenas_i_bins_j_nfills)},
427 {NAME("nflushes"), CTL(stats_arenas_i_bins_j_nflushes)},
Jason Evans498856f2016-05-29 18:34:50 -0700428 {NAME("nslabs"), CTL(stats_arenas_i_bins_j_nslabs)},
429 {NAME("nreslabs"), CTL(stats_arenas_i_bins_j_nreslabs)},
Qi Wanga4f176a2017-03-03 19:58:43 -0800430 {NAME("curslabs"), CTL(stats_arenas_i_bins_j_curslabs)},
Qi Wang64c5f5c2017-03-13 17:29:03 -0700431 {NAME("mutex"), CHILD(named, stats_arenas_i_bins_j_mutex)}
Jason Evans3c234352010-01-27 13:10:55 -0800432};
Qi Wang0fb5c0e2017-03-10 12:14:05 -0800433
Mike Hommey461ad5c2012-04-20 08:38:42 +0200434static const ctl_named_node_t super_stats_arenas_i_bins_j_node[] = {
Jason Evans3c4d92e2014-10-12 22:53:59 -0700435 {NAME(""), CHILD(named, stats_arenas_i_bins_j)}
Jason Evans3c234352010-01-27 13:10:55 -0800436};
437
Mike Hommey461ad5c2012-04-20 08:38:42 +0200438static const ctl_indexed_node_t stats_arenas_i_bins_node[] = {
Jason Evans3c234352010-01-27 13:10:55 -0800439 {INDEX(stats_arenas_i_bins_j)}
440};
441
Jason Evans7d63fed2016-05-31 14:50:21 -0700442static const ctl_named_node_t stats_arenas_i_lextents_j_node[] = {
443 {NAME("nmalloc"), CTL(stats_arenas_i_lextents_j_nmalloc)},
444 {NAME("ndalloc"), CTL(stats_arenas_i_lextents_j_ndalloc)},
445 {NAME("nrequests"), CTL(stats_arenas_i_lextents_j_nrequests)},
446 {NAME("curlextents"), CTL(stats_arenas_i_lextents_j_curlextents)}
Jason Evans3c4d92e2014-10-12 22:53:59 -0700447};
Jason Evans7d63fed2016-05-31 14:50:21 -0700448static const ctl_named_node_t super_stats_arenas_i_lextents_j_node[] = {
449 {NAME(""), CHILD(named, stats_arenas_i_lextents_j)}
Jason Evans3c4d92e2014-10-12 22:53:59 -0700450};
451
Jason Evans7d63fed2016-05-31 14:50:21 -0700452static const ctl_indexed_node_t stats_arenas_i_lextents_node[] = {
453 {INDEX(stats_arenas_i_lextents_j)}
Jason Evans3c4d92e2014-10-12 22:53:59 -0700454};
455
Qi Wangd3fde1c2017-03-21 11:56:38 -0700456#define OP(mtx) MUTEX_PROF_DATA_NODE(arenas_i_mutexes_##mtx)
David Goldblatt89e2d3c2017-04-24 17:09:56 -0700457MUTEX_PROF_ARENA_MUTEXES
Qi Wangd3fde1c2017-03-21 11:56:38 -0700458#undef OP
Qi Wang0fb5c0e2017-03-10 12:14:05 -0800459
Qi Wang64c5f5c2017-03-13 17:29:03 -0700460static const ctl_named_node_t stats_arenas_i_mutexes_node[] = {
Qi Wangd3fde1c2017-03-21 11:56:38 -0700461#define OP(mtx) {NAME(#mtx), CHILD(named, stats_arenas_i_mutexes_##mtx)},
David Goldblatt89e2d3c2017-04-24 17:09:56 -0700462MUTEX_PROF_ARENA_MUTEXES
Qi Wangd3fde1c2017-03-21 11:56:38 -0700463#undef OP
Qi Wang0fb5c0e2017-03-10 12:14:05 -0800464};
Qi Wang0fb5c0e2017-03-10 12:14:05 -0800465
Mike Hommey461ad5c2012-04-20 08:38:42 +0200466static const ctl_named_node_t stats_arenas_i_node[] = {
Jason Evans3c4d92e2014-10-12 22:53:59 -0700467 {NAME("nthreads"), CTL(stats_arenas_i_nthreads)},
Qi Wangbaf3e292017-05-16 13:56:00 -0700468 {NAME("uptime"), CTL(stats_arenas_i_uptime)},
Jason Evans3c4d92e2014-10-12 22:53:59 -0700469 {NAME("dss"), CTL(stats_arenas_i_dss)},
Jason Evans6e62c622017-05-17 10:47:00 -0700470 {NAME("dirty_decay_ms"), CTL(stats_arenas_i_dirty_decay_ms)},
471 {NAME("muzzy_decay_ms"), CTL(stats_arenas_i_muzzy_decay_ms)},
Jason Evans3c4d92e2014-10-12 22:53:59 -0700472 {NAME("pactive"), CTL(stats_arenas_i_pactive)},
473 {NAME("pdirty"), CTL(stats_arenas_i_pdirty)},
Jason Evans64e458f2017-03-08 22:42:57 -0800474 {NAME("pmuzzy"), CTL(stats_arenas_i_pmuzzy)},
Jason Evans3c4d92e2014-10-12 22:53:59 -0700475 {NAME("mapped"), CTL(stats_arenas_i_mapped)},
Jason Evans04c3c0f2016-05-03 22:11:35 -0700476 {NAME("retained"), CTL(stats_arenas_i_retained)},
Jason Evans64e458f2017-03-08 22:42:57 -0800477 {NAME("dirty_npurge"), CTL(stats_arenas_i_dirty_npurge)},
478 {NAME("dirty_nmadvise"), CTL(stats_arenas_i_dirty_nmadvise)},
479 {NAME("dirty_purged"), CTL(stats_arenas_i_dirty_purged)},
480 {NAME("muzzy_npurge"), CTL(stats_arenas_i_muzzy_npurge)},
481 {NAME("muzzy_nmadvise"), CTL(stats_arenas_i_muzzy_nmadvise)},
482 {NAME("muzzy_purged"), CTL(stats_arenas_i_muzzy_purged)},
Jason Evansa0dd3a42016-12-22 16:39:10 -0600483 {NAME("base"), CTL(stats_arenas_i_base)},
484 {NAME("internal"), CTL(stats_arenas_i_internal)},
Qi Wange55c3ca2017-08-25 13:24:49 -0700485 {NAME("metadata_thp"), CTL(stats_arenas_i_metadata_thp)},
Qi Wang58424e62016-04-22 18:37:44 -0700486 {NAME("tcache_bytes"), CTL(stats_arenas_i_tcache_bytes)},
Jason Evansa0dd3a42016-12-22 16:39:10 -0600487 {NAME("resident"), CTL(stats_arenas_i_resident)},
Jason Evans3c4d92e2014-10-12 22:53:59 -0700488 {NAME("small"), CHILD(named, stats_arenas_i_small)},
Jason Evans7d63fed2016-05-31 14:50:21 -0700489 {NAME("large"), CHILD(named, stats_arenas_i_large)},
Jason Evans3c4d92e2014-10-12 22:53:59 -0700490 {NAME("bins"), CHILD(indexed, stats_arenas_i_bins)},
Qi Wang0fb5c0e2017-03-10 12:14:05 -0800491 {NAME("lextents"), CHILD(indexed, stats_arenas_i_lextents)},
Qi Wang64c5f5c2017-03-13 17:29:03 -0700492 {NAME("mutexes"), CHILD(named, stats_arenas_i_mutexes)}
Jason Evans3c234352010-01-27 13:10:55 -0800493};
Mike Hommey461ad5c2012-04-20 08:38:42 +0200494static const ctl_named_node_t super_stats_arenas_i_node[] = {
Jason Evans3c4d92e2014-10-12 22:53:59 -0700495 {NAME(""), CHILD(named, stats_arenas_i)}
Jason Evans3c234352010-01-27 13:10:55 -0800496};
497
Mike Hommey461ad5c2012-04-20 08:38:42 +0200498static const ctl_indexed_node_t stats_arenas_node[] = {
Jason Evans3c234352010-01-27 13:10:55 -0800499 {INDEX(stats_arenas_i)}
500};
501
Qi Wang2bee0c62017-05-12 12:30:33 -0700502static const ctl_named_node_t stats_background_thread_node[] = {
503 {NAME("num_threads"), CTL(stats_background_thread_num_threads)},
504 {NAME("num_runs"), CTL(stats_background_thread_num_runs)},
505 {NAME("run_interval"), CTL(stats_background_thread_run_interval)}
506};
507
Qi Wangd3fde1c2017-03-21 11:56:38 -0700508#define OP(mtx) MUTEX_PROF_DATA_NODE(mutexes_##mtx)
David Goldblatt89e2d3c2017-04-24 17:09:56 -0700509MUTEX_PROF_GLOBAL_MUTEXES
Qi Wangd3fde1c2017-03-21 11:56:38 -0700510#undef OP
511
Qi Wang64c5f5c2017-03-13 17:29:03 -0700512static const ctl_named_node_t stats_mutexes_node[] = {
Qi Wangd3fde1c2017-03-21 11:56:38 -0700513#define OP(mtx) {NAME(#mtx), CHILD(named, stats_mutexes_##mtx)},
David Goldblatt89e2d3c2017-04-24 17:09:56 -0700514MUTEX_PROF_GLOBAL_MUTEXES
Qi Wangd3fde1c2017-03-21 11:56:38 -0700515#undef OP
Qi Wang64c5f5c2017-03-13 17:29:03 -0700516 {NAME("reset"), CTL(stats_mutexes_reset)}
Qi Wangca9074d2017-03-11 20:28:31 -0800517};
Qi Wangd3fde1c2017-03-21 11:56:38 -0700518#undef MUTEX_PROF_DATA_NODE
Qi Wangca9074d2017-03-11 20:28:31 -0800519
Mike Hommey461ad5c2012-04-20 08:38:42 +0200520static const ctl_named_node_t stats_node[] = {
Jason Evans3c4d92e2014-10-12 22:53:59 -0700521 {NAME("allocated"), CTL(stats_allocated)},
522 {NAME("active"), CTL(stats_active)},
Jason Evans4581b972014-11-27 17:22:36 -0200523 {NAME("metadata"), CTL(stats_metadata)},
Qi Wange55c3ca2017-08-25 13:24:49 -0700524 {NAME("metadata_thp"), CTL(stats_metadata_thp)},
Jason Evans4acd75a2015-03-23 17:25:57 -0700525 {NAME("resident"), CTL(stats_resident)},
Jason Evans3c4d92e2014-10-12 22:53:59 -0700526 {NAME("mapped"), CTL(stats_mapped)},
Jason Evans04c3c0f2016-05-03 22:11:35 -0700527 {NAME("retained"), CTL(stats_retained)},
Qi Wang2bee0c62017-05-12 12:30:33 -0700528 {NAME("background_thread"),
529 CHILD(named, stats_background_thread)},
Qi Wang64c5f5c2017-03-13 17:29:03 -0700530 {NAME("mutexes"), CHILD(named, stats_mutexes)},
Jason Evans3c4d92e2014-10-12 22:53:59 -0700531 {NAME("arenas"), CHILD(indexed, stats_arenas)}
Jason Evans3c234352010-01-27 13:10:55 -0800532};
533
Mike Hommey461ad5c2012-04-20 08:38:42 +0200534static const ctl_named_node_t root_node[] = {
Jason Evansa40bc7a2010-03-02 13:01:16 -0800535 {NAME("version"), CTL(version)},
Jason Evans3c234352010-01-27 13:10:55 -0800536 {NAME("epoch"), CTL(epoch)},
Qi Wangb693c782017-03-17 12:42:33 -0700537 {NAME("background_thread"), CTL(background_thread)},
Jason Evans65f343a2012-04-23 19:31:45 -0700538 {NAME("thread"), CHILD(named, thread)},
539 {NAME("config"), CHILD(named, config)},
540 {NAME("opt"), CHILD(named, opt)},
Jason Evans1cb181e2015-01-29 15:30:47 -0800541 {NAME("tcache"), CHILD(named, tcache)},
Jason Evans609ae592012-10-11 13:53:15 -0700542 {NAME("arena"), CHILD(indexed, arena)},
Jason Evans65f343a2012-04-23 19:31:45 -0700543 {NAME("arenas"), CHILD(named, arenas)},
544 {NAME("prof"), CHILD(named, prof)},
545 {NAME("stats"), CHILD(named, stats)}
Jason Evans3c234352010-01-27 13:10:55 -0800546};
Mike Hommey461ad5c2012-04-20 08:38:42 +0200547static const ctl_named_node_t super_root_node[] = {
Jason Evans65f343a2012-04-23 19:31:45 -0700548 {NAME(""), CHILD(named, root)}
Jason Evans3c234352010-01-27 13:10:55 -0800549};
550
551#undef NAME
552#undef CHILD
553#undef CTL
554#undef INDEX
555
556/******************************************************************************/
557
David Goldblatt4fc2acf2017-03-08 15:56:31 -0800558/*
559 * Sets *dst + *src non-atomically. This is safe, since everything is
560 * synchronized by the ctl mutex.
561 */
562static void
David T. Goldblatt7f1b02e2017-11-04 12:50:19 -0700563ctl_accum_arena_stats_u64(arena_stats_u64_t *dst, arena_stats_u64_t *src) {
David Goldblatt4fc2acf2017-03-08 15:56:31 -0800564#ifdef JEMALLOC_ATOMIC_U64
565 uint64_t cur_dst = atomic_load_u64(dst, ATOMIC_RELAXED);
566 uint64_t cur_src = atomic_load_u64(src, ATOMIC_RELAXED);
567 atomic_store_u64(dst, cur_dst + cur_src, ATOMIC_RELAXED);
568#else
569 *dst += *src;
570#endif
571}
572
573/* Likewise: with ctl mutex synchronization, reading is simple. */
574static uint64_t
David T. Goldblatt7f1b02e2017-11-04 12:50:19 -0700575ctl_arena_stats_read_u64(arena_stats_u64_t *p) {
David Goldblatt4fc2acf2017-03-08 15:56:31 -0800576#ifdef JEMALLOC_ATOMIC_U64
577 return atomic_load_u64(p, ATOMIC_RELAXED);
578#else
579 return *p;
580#endif
581}
582
David T. Goldblatt7f1b02e2017-11-04 12:50:19 -0700583static void
584accum_atomic_zu(atomic_zu_t *dst, atomic_zu_t *src) {
David Goldblattee202ef2017-03-13 16:18:40 -0700585 size_t cur_dst = atomic_load_zu(dst, ATOMIC_RELAXED);
586 size_t cur_src = atomic_load_zu(src, ATOMIC_RELAXED);
587 atomic_store_zu(dst, cur_dst + cur_src, ATOMIC_RELAXED);
588}
589
David Goldblatt4fc2acf2017-03-08 15:56:31 -0800590/******************************************************************************/
591
Jason Evans3dc4e832017-01-03 07:27:42 -0800592static unsigned
Jason Evansc4c25922017-01-15 16:56:30 -0800593arenas_i2a_impl(size_t i, bool compat, bool validate) {
Jason Evans3dc4e832017-01-03 07:27:42 -0800594 unsigned a;
595
Jason Evans3dc4e832017-01-03 07:27:42 -0800596 switch (i) {
597 case MALLCTL_ARENAS_ALL:
598 a = 0;
599 break;
Jason Evansedf1baf2017-01-03 17:21:59 -0800600 case MALLCTL_ARENAS_DESTROYED:
601 a = 1;
602 break;
Jason Evans3dc4e832017-01-03 07:27:42 -0800603 default:
Jason Evans9eb1b1c2017-01-18 23:03:37 -0800604 if (compat && i == ctl_arenas->narenas) {
Jason Evans3dc4e832017-01-03 07:27:42 -0800605 /*
606 * Provide deprecated backward compatibility for
607 * accessing the merged stats at index narenas rather
608 * than via MALLCTL_ARENAS_ALL. This is scheduled for
609 * removal in 6.0.0.
610 */
611 a = 0;
Jason Evansc4c25922017-01-15 16:56:30 -0800612 } else if (validate && i >= ctl_arenas->narenas) {
Jason Evans3dc4e832017-01-03 07:27:42 -0800613 a = UINT_MAX;
Jason Evansc4c25922017-01-15 16:56:30 -0800614 } else {
Jason Evans3dc4e832017-01-03 07:27:42 -0800615 /*
616 * This function should never be called for an index
617 * more than one past the range of indices that have
Jason Evans9eb1b1c2017-01-18 23:03:37 -0800618 * initialized ctl data.
Jason Evans3dc4e832017-01-03 07:27:42 -0800619 */
Jason Evans9eb1b1c2017-01-18 23:03:37 -0800620 assert(i < ctl_arenas->narenas || (!validate && i ==
621 ctl_arenas->narenas));
Jason Evansedf1baf2017-01-03 17:21:59 -0800622 a = (unsigned)i + 2;
Jason Evans3dc4e832017-01-03 07:27:42 -0800623 }
624 break;
625 }
626
Jason Evansf4086432017-01-19 18:15:45 -0800627 return a;
Jason Evans3dc4e832017-01-03 07:27:42 -0800628}
629
Jason Evansedf1baf2017-01-03 17:21:59 -0800630static unsigned
Jason Evansc4c25922017-01-15 16:56:30 -0800631arenas_i2a(size_t i) {
Jason Evansf4086432017-01-19 18:15:45 -0800632 return arenas_i2a_impl(i, true, false);
Jason Evansedf1baf2017-01-03 17:21:59 -0800633}
634
Jason Evans9eb1b1c2017-01-18 23:03:37 -0800635static ctl_arena_t *
Qi Wang57beeb22017-06-22 18:58:40 -0700636arenas_i_impl(tsd_t *tsd, size_t i, bool compat, bool init) {
Jason Evans9eb1b1c2017-01-18 23:03:37 -0800637 ctl_arena_t *ret;
Jason Evansd778dd22017-01-03 12:40:54 -0800638
639 assert(!compat || !init);
640
Jason Evans9eb1b1c2017-01-18 23:03:37 -0800641 ret = ctl_arenas->arenas[arenas_i2a_impl(i, compat, false)];
Jason Evansd778dd22017-01-03 12:40:54 -0800642 if (init && ret == NULL) {
Jason Evans9eb1b1c2017-01-18 23:03:37 -0800643 if (config_stats) {
644 struct container_s {
645 ctl_arena_t ctl_arena;
646 ctl_arena_stats_t astats;
647 };
648 struct container_s *cont =
Qi Wang57beeb22017-06-22 18:58:40 -0700649 (struct container_s *)base_alloc(tsd_tsdn(tsd),
650 b0get(), sizeof(struct container_s), QUANTUM);
Jason Evans9eb1b1c2017-01-18 23:03:37 -0800651 if (cont == NULL) {
652 return NULL;
653 }
654 ret = &cont->ctl_arena;
655 ret->astats = &cont->astats;
656 } else {
Qi Wang57beeb22017-06-22 18:58:40 -0700657 ret = (ctl_arena_t *)base_alloc(tsd_tsdn(tsd), b0get(),
Jason Evans9eb1b1c2017-01-18 23:03:37 -0800658 sizeof(ctl_arena_t), QUANTUM);
659 if (ret == NULL) {
660 return NULL;
661 }
662 }
Jason Evansedf1baf2017-01-03 17:21:59 -0800663 ret->arena_ind = (unsigned)i;
Jason Evans9eb1b1c2017-01-18 23:03:37 -0800664 ctl_arenas->arenas[arenas_i2a_impl(i, compat, false)] = ret;
Jason Evansd778dd22017-01-03 12:40:54 -0800665 }
666
Jason Evans9eb1b1c2017-01-18 23:03:37 -0800667 assert(ret == NULL || arenas_i2a(ret->arena_ind) == arenas_i2a(i));
Jason Evansf4086432017-01-19 18:15:45 -0800668 return ret;
Jason Evansd778dd22017-01-03 12:40:54 -0800669}
670
Jason Evans9eb1b1c2017-01-18 23:03:37 -0800671static ctl_arena_t *
Jason Evansc4c25922017-01-15 16:56:30 -0800672arenas_i(size_t i) {
Qi Wang57beeb22017-06-22 18:58:40 -0700673 ctl_arena_t *ret = arenas_i_impl(tsd_fetch(), i, true, false);
Jason Evansd778dd22017-01-03 12:40:54 -0800674 assert(ret != NULL);
Jason Evansf4086432017-01-19 18:15:45 -0800675 return ret;
Jason Evans3dc4e832017-01-03 07:27:42 -0800676}
677
Jason Evans3c234352010-01-27 13:10:55 -0800678static void
Jason Evansc4c25922017-01-15 16:56:30 -0800679ctl_arena_clear(ctl_arena_t *ctl_arena) {
Jason Evans9eb1b1c2017-01-18 23:03:37 -0800680 ctl_arena->nthreads = 0;
681 ctl_arena->dss = dss_prec_names[dss_prec_limit];
Jason Evans6e62c622017-05-17 10:47:00 -0700682 ctl_arena->dirty_decay_ms = -1;
683 ctl_arena->muzzy_decay_ms = -1;
Jason Evans9eb1b1c2017-01-18 23:03:37 -0800684 ctl_arena->pactive = 0;
685 ctl_arena->pdirty = 0;
Jason Evans64e458f2017-03-08 22:42:57 -0800686 ctl_arena->pmuzzy = 0;
Jason Evans7372b152012-02-10 20:22:09 -0800687 if (config_stats) {
Jason Evans9eb1b1c2017-01-18 23:03:37 -0800688 memset(&ctl_arena->astats->astats, 0, sizeof(arena_stats_t));
689 ctl_arena->astats->allocated_small = 0;
690 ctl_arena->astats->nmalloc_small = 0;
691 ctl_arena->astats->ndalloc_small = 0;
692 ctl_arena->astats->nrequests_small = 0;
693 memset(ctl_arena->astats->bstats, 0, NBINS *
David T. Goldblatt7f1b02e2017-11-04 12:50:19 -0700694 sizeof(bin_stats_t));
Jason Evans9eb1b1c2017-01-18 23:03:37 -0800695 memset(ctl_arena->astats->lstats, 0, (NSIZES - NBINS) *
David T. Goldblatt7f1b02e2017-11-04 12:50:19 -0700696 sizeof(arena_stats_large_t));
Jason Evans7372b152012-02-10 20:22:09 -0800697 }
Jason Evans3c234352010-01-27 13:10:55 -0800698}
699
Jason Evans86815df2010-03-13 20:32:56 -0800700static void
Jason Evansc4c25922017-01-15 16:56:30 -0800701ctl_arena_stats_amerge(tsdn_t *tsdn, ctl_arena_t *ctl_arena, arena_t *arena) {
Jason Evans86815df2010-03-13 20:32:56 -0800702 unsigned i;
703
Jason Evans3c07f802016-02-27 20:40:13 -0800704 if (config_stats) {
Jason Evans9eb1b1c2017-01-18 23:03:37 -0800705 arena_stats_merge(tsdn, arena, &ctl_arena->nthreads,
Jason Evans6e62c622017-05-17 10:47:00 -0700706 &ctl_arena->dss, &ctl_arena->dirty_decay_ms,
707 &ctl_arena->muzzy_decay_ms, &ctl_arena->pactive,
Jason Evans64e458f2017-03-08 22:42:57 -0800708 &ctl_arena->pdirty, &ctl_arena->pmuzzy,
Jason Evans9eb1b1c2017-01-18 23:03:37 -0800709 &ctl_arena->astats->astats, ctl_arena->astats->bstats,
710 ctl_arena->astats->lstats);
Jason Evans86815df2010-03-13 20:32:56 -0800711
Jason Evans3c07f802016-02-27 20:40:13 -0800712 for (i = 0; i < NBINS; i++) {
Jason Evans9eb1b1c2017-01-18 23:03:37 -0800713 ctl_arena->astats->allocated_small +=
714 ctl_arena->astats->bstats[i].curregs *
David Goldblatt8261e582017-05-30 10:45:37 -0700715 sz_index2size(i);
Jason Evans9eb1b1c2017-01-18 23:03:37 -0800716 ctl_arena->astats->nmalloc_small +=
717 ctl_arena->astats->bstats[i].nmalloc;
718 ctl_arena->astats->ndalloc_small +=
719 ctl_arena->astats->bstats[i].ndalloc;
720 ctl_arena->astats->nrequests_small +=
721 ctl_arena->astats->bstats[i].nrequests;
Jason Evans3c07f802016-02-27 20:40:13 -0800722 }
723 } else {
Jason Evans9eb1b1c2017-01-18 23:03:37 -0800724 arena_basic_stats_merge(tsdn, arena, &ctl_arena->nthreads,
Jason Evans6e62c622017-05-17 10:47:00 -0700725 &ctl_arena->dss, &ctl_arena->dirty_decay_ms,
726 &ctl_arena->muzzy_decay_ms, &ctl_arena->pactive,
Jason Evans64e458f2017-03-08 22:42:57 -0800727 &ctl_arena->pdirty, &ctl_arena->pmuzzy);
Jason Evans86815df2010-03-13 20:32:56 -0800728 }
Jason Evans86815df2010-03-13 20:32:56 -0800729}
730
731static void
Jason Evans9eb1b1c2017-01-18 23:03:37 -0800732ctl_arena_stats_sdmerge(ctl_arena_t *ctl_sdarena, ctl_arena_t *ctl_arena,
Jason Evansc4c25922017-01-15 16:56:30 -0800733 bool destroyed) {
Jason Evans86815df2010-03-13 20:32:56 -0800734 unsigned i;
735
Jason Evansedf1baf2017-01-03 17:21:59 -0800736 if (!destroyed) {
Jason Evans9eb1b1c2017-01-18 23:03:37 -0800737 ctl_sdarena->nthreads += ctl_arena->nthreads;
738 ctl_sdarena->pactive += ctl_arena->pactive;
739 ctl_sdarena->pdirty += ctl_arena->pdirty;
Jason Evans64e458f2017-03-08 22:42:57 -0800740 ctl_sdarena->pmuzzy += ctl_arena->pmuzzy;
Jason Evansedf1baf2017-01-03 17:21:59 -0800741 } else {
Jason Evans9eb1b1c2017-01-18 23:03:37 -0800742 assert(ctl_arena->nthreads == 0);
743 assert(ctl_arena->pactive == 0);
744 assert(ctl_arena->pdirty == 0);
Jason Evans64e458f2017-03-08 22:42:57 -0800745 assert(ctl_arena->pmuzzy == 0);
Jason Evansedf1baf2017-01-03 17:21:59 -0800746 }
Jason Evans86815df2010-03-13 20:32:56 -0800747
Jason Evans3c07f802016-02-27 20:40:13 -0800748 if (config_stats) {
Jason Evans9eb1b1c2017-01-18 23:03:37 -0800749 ctl_arena_stats_t *sdstats = ctl_sdarena->astats;
750 ctl_arena_stats_t *astats = ctl_arena->astats;
751
Jason Evansedf1baf2017-01-03 17:21:59 -0800752 if (!destroyed) {
David Goldblattee202ef2017-03-13 16:18:40 -0700753 accum_atomic_zu(&sdstats->astats.mapped,
754 &astats->astats.mapped);
755 accum_atomic_zu(&sdstats->astats.retained,
756 &astats->astats.retained);
Jason Evansedf1baf2017-01-03 17:21:59 -0800757 }
Jason Evans64e458f2017-03-08 22:42:57 -0800758
David T. Goldblatt7f1b02e2017-11-04 12:50:19 -0700759 ctl_accum_arena_stats_u64(&sdstats->astats.decay_dirty.npurge,
Jason Evans64e458f2017-03-08 22:42:57 -0800760 &astats->astats.decay_dirty.npurge);
David T. Goldblatt7f1b02e2017-11-04 12:50:19 -0700761 ctl_accum_arena_stats_u64(&sdstats->astats.decay_dirty.nmadvise,
Jason Evans64e458f2017-03-08 22:42:57 -0800762 &astats->astats.decay_dirty.nmadvise);
David T. Goldblatt7f1b02e2017-11-04 12:50:19 -0700763 ctl_accum_arena_stats_u64(&sdstats->astats.decay_dirty.purged,
Jason Evans64e458f2017-03-08 22:42:57 -0800764 &astats->astats.decay_dirty.purged);
765
David T. Goldblatt7f1b02e2017-11-04 12:50:19 -0700766 ctl_accum_arena_stats_u64(&sdstats->astats.decay_muzzy.npurge,
Jason Evans64e458f2017-03-08 22:42:57 -0800767 &astats->astats.decay_muzzy.npurge);
David T. Goldblatt7f1b02e2017-11-04 12:50:19 -0700768 ctl_accum_arena_stats_u64(&sdstats->astats.decay_muzzy.nmadvise,
Jason Evans64e458f2017-03-08 22:42:57 -0800769 &astats->astats.decay_muzzy.nmadvise);
David T. Goldblatt7f1b02e2017-11-04 12:50:19 -0700770 ctl_accum_arena_stats_u64(&sdstats->astats.decay_muzzy.purged,
Jason Evans64e458f2017-03-08 22:42:57 -0800771 &astats->astats.decay_muzzy.purged);
Jason Evans86815df2010-03-13 20:32:56 -0800772
Qi Wangd3fde1c2017-03-21 11:56:38 -0700773#define OP(mtx) malloc_mutex_prof_merge( \
774 &(sdstats->astats.mutex_prof_data[ \
775 arena_prof_mutex_##mtx]), \
776 &(astats->astats.mutex_prof_data[ \
777 arena_prof_mutex_##mtx]));
David Goldblatt89e2d3c2017-04-24 17:09:56 -0700778MUTEX_PROF_ARENA_MUTEXES
Qi Wangd3fde1c2017-03-21 11:56:38 -0700779#undef OP
Jason Evansedf1baf2017-01-03 17:21:59 -0800780 if (!destroyed) {
David Goldblattee202ef2017-03-13 16:18:40 -0700781 accum_atomic_zu(&sdstats->astats.base,
782 &astats->astats.base);
783 accum_atomic_zu(&sdstats->astats.internal,
784 &astats->astats.internal);
785 accum_atomic_zu(&sdstats->astats.resident,
786 &astats->astats.resident);
Qi Wange55c3ca2017-08-25 13:24:49 -0700787 accum_atomic_zu(&sdstats->astats.metadata_thp,
788 &astats->astats.metadata_thp);
Jason Evansc4c25922017-01-15 16:56:30 -0800789 } else {
David Goldblattee202ef2017-03-13 16:18:40 -0700790 assert(atomic_load_zu(
791 &astats->astats.internal, ATOMIC_RELAXED) == 0);
Jason Evansc4c25922017-01-15 16:56:30 -0800792 }
Jason Evans4581b972014-11-27 17:22:36 -0200793
Jason Evansc4c25922017-01-15 16:56:30 -0800794 if (!destroyed) {
Jason Evansedf1baf2017-01-03 17:21:59 -0800795 sdstats->allocated_small += astats->allocated_small;
Jason Evansc4c25922017-01-15 16:56:30 -0800796 } else {
Jason Evansedf1baf2017-01-03 17:21:59 -0800797 assert(astats->allocated_small == 0);
Jason Evansc4c25922017-01-15 16:56:30 -0800798 }
Jason Evansedf1baf2017-01-03 17:21:59 -0800799 sdstats->nmalloc_small += astats->nmalloc_small;
800 sdstats->ndalloc_small += astats->ndalloc_small;
801 sdstats->nrequests_small += astats->nrequests_small;
Jason Evans86815df2010-03-13 20:32:56 -0800802
Jason Evansedf1baf2017-01-03 17:21:59 -0800803 if (!destroyed) {
David Goldblattee202ef2017-03-13 16:18:40 -0700804 accum_atomic_zu(&sdstats->astats.allocated_large,
805 &astats->astats.allocated_large);
Jason Evansc4c25922017-01-15 16:56:30 -0800806 } else {
David Goldblattee202ef2017-03-13 16:18:40 -0700807 assert(atomic_load_zu(&astats->astats.allocated_large,
808 ATOMIC_RELAXED) == 0);
Jason Evansc4c25922017-01-15 16:56:30 -0800809 }
David T. Goldblatt7f1b02e2017-11-04 12:50:19 -0700810 ctl_accum_arena_stats_u64(&sdstats->astats.nmalloc_large,
David Goldblatt4fc2acf2017-03-08 15:56:31 -0800811 &astats->astats.nmalloc_large);
David T. Goldblatt7f1b02e2017-11-04 12:50:19 -0700812 ctl_accum_arena_stats_u64(&sdstats->astats.ndalloc_large,
David Goldblatt4fc2acf2017-03-08 15:56:31 -0800813 &astats->astats.ndalloc_large);
David T. Goldblatt7f1b02e2017-11-04 12:50:19 -0700814 ctl_accum_arena_stats_u64(&sdstats->astats.nrequests_large,
David Goldblatt4fc2acf2017-03-08 15:56:31 -0800815 &astats->astats.nrequests_large);
Jason Evans86815df2010-03-13 20:32:56 -0800816
Jason Evans4403c9a2017-04-20 17:21:37 -0700817 accum_atomic_zu(&sdstats->astats.tcache_bytes,
818 &astats->astats.tcache_bytes);
Qi Wang58424e62016-04-22 18:37:44 -0700819
Qi Wangbaf3e292017-05-16 13:56:00 -0700820 if (ctl_arena->arena_ind == 0) {
821 sdstats->astats.uptime = astats->astats.uptime;
822 }
823
Jason Evans3c07f802016-02-27 20:40:13 -0800824 for (i = 0; i < NBINS; i++) {
Jason Evansedf1baf2017-01-03 17:21:59 -0800825 sdstats->bstats[i].nmalloc += astats->bstats[i].nmalloc;
826 sdstats->bstats[i].ndalloc += astats->bstats[i].ndalloc;
827 sdstats->bstats[i].nrequests +=
Jason Evans3c07f802016-02-27 20:40:13 -0800828 astats->bstats[i].nrequests;
Jason Evansedf1baf2017-01-03 17:21:59 -0800829 if (!destroyed) {
830 sdstats->bstats[i].curregs +=
831 astats->bstats[i].curregs;
Jason Evansc4c25922017-01-15 16:56:30 -0800832 } else {
Jason Evansedf1baf2017-01-03 17:21:59 -0800833 assert(astats->bstats[i].curregs == 0);
Jason Evansc4c25922017-01-15 16:56:30 -0800834 }
Jason Evans4403c9a2017-04-20 17:21:37 -0700835 sdstats->bstats[i].nfills += astats->bstats[i].nfills;
836 sdstats->bstats[i].nflushes +=
837 astats->bstats[i].nflushes;
Jason Evansedf1baf2017-01-03 17:21:59 -0800838 sdstats->bstats[i].nslabs += astats->bstats[i].nslabs;
839 sdstats->bstats[i].reslabs += astats->bstats[i].reslabs;
840 if (!destroyed) {
841 sdstats->bstats[i].curslabs +=
842 astats->bstats[i].curslabs;
Jason Evansc4c25922017-01-15 16:56:30 -0800843 } else {
Jason Evansedf1baf2017-01-03 17:21:59 -0800844 assert(astats->bstats[i].curslabs == 0);
Jason Evansc4c25922017-01-15 16:56:30 -0800845 }
Qi Wang64c5f5c2017-03-13 17:29:03 -0700846 malloc_mutex_prof_merge(&sdstats->bstats[i].mutex_data,
847 &astats->bstats[i].mutex_data);
Jason Evans7372b152012-02-10 20:22:09 -0800848 }
Jason Evans3c4d92e2014-10-12 22:53:59 -0700849
Jason Evansed2c2422016-05-28 00:17:28 -0700850 for (i = 0; i < NSIZES - NBINS; i++) {
David T. Goldblatt7f1b02e2017-11-04 12:50:19 -0700851 ctl_accum_arena_stats_u64(&sdstats->lstats[i].nmalloc,
David Goldblatt4fc2acf2017-03-08 15:56:31 -0800852 &astats->lstats[i].nmalloc);
David T. Goldblatt7f1b02e2017-11-04 12:50:19 -0700853 ctl_accum_arena_stats_u64(&sdstats->lstats[i].ndalloc,
David Goldblatt4fc2acf2017-03-08 15:56:31 -0800854 &astats->lstats[i].ndalloc);
David T. Goldblatt7f1b02e2017-11-04 12:50:19 -0700855 ctl_accum_arena_stats_u64(&sdstats->lstats[i].nrequests,
David Goldblatt4fc2acf2017-03-08 15:56:31 -0800856 &astats->lstats[i].nrequests);
Jason Evansedf1baf2017-01-03 17:21:59 -0800857 if (!destroyed) {
858 sdstats->lstats[i].curlextents +=
859 astats->lstats[i].curlextents;
Jason Evansc4c25922017-01-15 16:56:30 -0800860 } else {
Jason Evansedf1baf2017-01-03 17:21:59 -0800861 assert(astats->lstats[i].curlextents == 0);
Jason Evansc4c25922017-01-15 16:56:30 -0800862 }
Jason Evans3c07f802016-02-27 20:40:13 -0800863 }
Jason Evans3c4d92e2014-10-12 22:53:59 -0700864 }
Jason Evans86815df2010-03-13 20:32:56 -0800865}
Jason Evans86815df2010-03-13 20:32:56 -0800866
Jason Evans3c234352010-01-27 13:10:55 -0800867static void
Jason Evans9eb1b1c2017-01-18 23:03:37 -0800868ctl_arena_refresh(tsdn_t *tsdn, arena_t *arena, ctl_arena_t *ctl_sdarena,
Jason Evansc4c25922017-01-15 16:56:30 -0800869 unsigned i, bool destroyed) {
Jason Evans9eb1b1c2017-01-18 23:03:37 -0800870 ctl_arena_t *ctl_arena = arenas_i(i);
Jason Evans3c234352010-01-27 13:10:55 -0800871
Jason Evans9eb1b1c2017-01-18 23:03:37 -0800872 ctl_arena_clear(ctl_arena);
873 ctl_arena_stats_amerge(tsdn, ctl_arena, arena);
Jason Evans3c07f802016-02-27 20:40:13 -0800874 /* Merge into sum stats as well. */
Jason Evans9eb1b1c2017-01-18 23:03:37 -0800875 ctl_arena_stats_sdmerge(ctl_sdarena, ctl_arena, destroyed);
Jason Evans3c234352010-01-27 13:10:55 -0800876}
877
Jason Evansedf1baf2017-01-03 17:21:59 -0800878static unsigned
Qi Wang57beeb22017-06-22 18:58:40 -0700879ctl_arena_init(tsd_t *tsd, extent_hooks_t *extent_hooks) {
Jason Evansedf1baf2017-01-03 17:21:59 -0800880 unsigned arena_ind;
Jason Evans9eb1b1c2017-01-18 23:03:37 -0800881 ctl_arena_t *ctl_arena;
Jason Evansedf1baf2017-01-03 17:21:59 -0800882
Jason Evans9eb1b1c2017-01-18 23:03:37 -0800883 if ((ctl_arena = ql_last(&ctl_arenas->destroyed, destroyed_link)) !=
884 NULL) {
885 ql_remove(&ctl_arenas->destroyed, ctl_arena, destroyed_link);
886 arena_ind = ctl_arena->arena_ind;
Jason Evansc4c25922017-01-15 16:56:30 -0800887 } else {
Jason Evans9eb1b1c2017-01-18 23:03:37 -0800888 arena_ind = ctl_arenas->narenas;
Jason Evansc4c25922017-01-15 16:56:30 -0800889 }
Jason Evansd778dd22017-01-03 12:40:54 -0800890
891 /* Trigger stats allocation. */
Qi Wang57beeb22017-06-22 18:58:40 -0700892 if (arenas_i_impl(tsd, arena_ind, false, true) == NULL) {
Jason Evansf4086432017-01-19 18:15:45 -0800893 return UINT_MAX;
Jason Evansc4c25922017-01-15 16:56:30 -0800894 }
Jason Evans609ae592012-10-11 13:53:15 -0700895
Jason Evans8bb31982014-10-07 23:14:57 -0700896 /* Initialize new arena. */
Qi Wang57beeb22017-06-22 18:58:40 -0700897 if (arena_init(tsd_tsdn(tsd), arena_ind, extent_hooks) == NULL) {
Jason Evansf4086432017-01-19 18:15:45 -0800898 return UINT_MAX;
Jason Evansc4c25922017-01-15 16:56:30 -0800899 }
Jason Evans609ae592012-10-11 13:53:15 -0700900
Jason Evansc4c25922017-01-15 16:56:30 -0800901 if (arena_ind == ctl_arenas->narenas) {
Jason Evans9eb1b1c2017-01-18 23:03:37 -0800902 ctl_arenas->narenas++;
Jason Evansc4c25922017-01-15 16:56:30 -0800903 }
Jason Evansedf1baf2017-01-03 17:21:59 -0800904
Jason Evansf4086432017-01-19 18:15:45 -0800905 return arena_ind;
Jason Evans609ae592012-10-11 13:53:15 -0700906}
907
Jason Evans3c234352010-01-27 13:10:55 -0800908static void
Qi Wang2bee0c62017-05-12 12:30:33 -0700909ctl_background_thread_stats_read(tsdn_t *tsdn) {
910 background_thread_stats_t *stats = &ctl_stats->background_thread;
911 if (!have_background_thread ||
912 background_thread_stats_read(tsdn, stats)) {
913 memset(stats, 0, sizeof(background_thread_stats_t));
914 nstime_init(&stats->run_interval, 0);
915 }
916}
917
918static void
Jason Evansc4c25922017-01-15 16:56:30 -0800919ctl_refresh(tsdn_t *tsdn) {
Jason Evans3c234352010-01-27 13:10:55 -0800920 unsigned i;
Jason Evans9eb1b1c2017-01-18 23:03:37 -0800921 ctl_arena_t *ctl_sarena = arenas_i(MALLCTL_ARENAS_ALL);
922 VARIABLE_ARRAY(arena_t *, tarenas, ctl_arenas->narenas);
Jason Evans3c234352010-01-27 13:10:55 -0800923
Jason Evans3c234352010-01-27 13:10:55 -0800924 /*
Jason Evans13668262010-01-31 03:57:29 -0800925 * Clear sum stats, since they will be merged into by
Jason Evans3c234352010-01-27 13:10:55 -0800926 * ctl_arena_refresh().
927 */
Jason Evans9eb1b1c2017-01-18 23:03:37 -0800928 ctl_arena_clear(ctl_sarena);
Jason Evans3c234352010-01-27 13:10:55 -0800929
Jason Evans9eb1b1c2017-01-18 23:03:37 -0800930 for (i = 0; i < ctl_arenas->narenas; i++) {
Jason Evansc1e00ef2016-05-10 22:21:10 -0700931 tarenas[i] = arena_get(tsdn, i, false);
Jason Evans9eb1b1c2017-01-18 23:03:37 -0800932 }
Jason Evans8bb31982014-10-07 23:14:57 -0700933
Jason Evans9eb1b1c2017-01-18 23:03:37 -0800934 for (i = 0; i < ctl_arenas->narenas; i++) {
935 ctl_arena_t *ctl_arena = arenas_i(i);
Jason Evans3c234352010-01-27 13:10:55 -0800936 bool initialized = (tarenas[i] != NULL);
937
Jason Evans9eb1b1c2017-01-18 23:03:37 -0800938 ctl_arena->initialized = initialized;
939 if (initialized) {
940 ctl_arena_refresh(tsdn, tarenas[i], ctl_sarena, i,
941 false);
942 }
Jason Evans3c234352010-01-27 13:10:55 -0800943 }
944
Jason Evans7372b152012-02-10 20:22:09 -0800945 if (config_stats) {
Jason Evans9eb1b1c2017-01-18 23:03:37 -0800946 ctl_stats->allocated = ctl_sarena->astats->allocated_small +
David Goldblattee202ef2017-03-13 16:18:40 -0700947 atomic_load_zu(&ctl_sarena->astats->astats.allocated_large,
948 ATOMIC_RELAXED);
Jason Evans9eb1b1c2017-01-18 23:03:37 -0800949 ctl_stats->active = (ctl_sarena->pactive << LG_PAGE);
David Goldblattee202ef2017-03-13 16:18:40 -0700950 ctl_stats->metadata = atomic_load_zu(
951 &ctl_sarena->astats->astats.base, ATOMIC_RELAXED) +
952 atomic_load_zu(&ctl_sarena->astats->astats.internal,
953 ATOMIC_RELAXED);
Qi Wange55c3ca2017-08-25 13:24:49 -0700954 ctl_stats->metadata_thp = atomic_load_zu(
955 &ctl_sarena->astats->astats.metadata_thp, ATOMIC_RELAXED);
David Goldblattee202ef2017-03-13 16:18:40 -0700956 ctl_stats->resident = atomic_load_zu(
957 &ctl_sarena->astats->astats.resident, ATOMIC_RELAXED);
958 ctl_stats->mapped = atomic_load_zu(
959 &ctl_sarena->astats->astats.mapped, ATOMIC_RELAXED);
960 ctl_stats->retained = atomic_load_zu(
961 &ctl_sarena->astats->astats.retained, ATOMIC_RELAXED);
Qi Wangca9074d2017-03-11 20:28:31 -0800962
Qi Wang2bee0c62017-05-12 12:30:33 -0700963 ctl_background_thread_stats_read(tsdn);
964
Qi Wangd3fde1c2017-03-21 11:56:38 -0700965#define READ_GLOBAL_MUTEX_PROF_DATA(i, mtx) \
Qi Wangca9074d2017-03-11 20:28:31 -0800966 malloc_mutex_lock(tsdn, &mtx); \
Qi Wangd3fde1c2017-03-21 11:56:38 -0700967 malloc_mutex_prof_read(tsdn, &ctl_stats->mutex_prof_data[i], &mtx); \
Qi Wangca9074d2017-03-11 20:28:31 -0800968 malloc_mutex_unlock(tsdn, &mtx);
969
Qi Wangbd2006a2017-03-12 01:28:52 -0800970 if (config_prof && opt_prof) {
Qi Wangd3fde1c2017-03-21 11:56:38 -0700971 READ_GLOBAL_MUTEX_PROF_DATA(global_prof_mutex_prof,
972 bt2gctx_mtx);
Qi Wangbd2006a2017-03-12 01:28:52 -0800973 }
Qi Wang5f5ed212017-05-12 16:26:59 -0700974 if (have_background_thread) {
975 READ_GLOBAL_MUTEX_PROF_DATA(
976 global_prof_mutex_background_thread,
977 background_thread_lock);
978 } else {
979 memset(&ctl_stats->mutex_prof_data[
980 global_prof_mutex_background_thread], 0,
981 sizeof(mutex_prof_data_t));
982 }
Qi Wangca9074d2017-03-11 20:28:31 -0800983 /* We own ctl mutex already. */
Qi Wangd3fde1c2017-03-21 11:56:38 -0700984 malloc_mutex_prof_read(tsdn,
985 &ctl_stats->mutex_prof_data[global_prof_mutex_ctl],
986 &ctl_mtx);
Qi Wangca9074d2017-03-11 20:28:31 -0800987#undef READ_GLOBAL_MUTEX_PROF_DATA
Jason Evans7372b152012-02-10 20:22:09 -0800988 }
Jason Evans9eb1b1c2017-01-18 23:03:37 -0800989 ctl_arenas->epoch++;
Jason Evans3c234352010-01-27 13:10:55 -0800990}
991
992static bool
Qi Wang57beeb22017-06-22 18:58:40 -0700993ctl_init(tsd_t *tsd) {
Jason Evansfc4dcfa2010-11-24 15:44:21 -0800994 bool ret;
Qi Wang57beeb22017-06-22 18:58:40 -0700995 tsdn_t *tsdn = tsd_tsdn(tsd);
Jason Evans3c234352010-01-27 13:10:55 -0800996
Jason Evansc1e00ef2016-05-10 22:21:10 -0700997 malloc_mutex_lock(tsdn, &ctl_mtx);
Jason Evans551ebc42014-10-03 10:16:09 -0700998 if (!ctl_initialized) {
Jason Evans9eb1b1c2017-01-18 23:03:37 -0800999 ctl_arena_t *ctl_sarena, *ctl_darena;
Jason Evansd778dd22017-01-03 12:40:54 -08001000 unsigned i;
1001
Jason Evans3c234352010-01-27 13:10:55 -08001002 /*
Jason Evans9eb1b1c2017-01-18 23:03:37 -08001003 * Allocate demand-zeroed space for pointers to the full
1004 * range of supported arena indices.
Jason Evans3c234352010-01-27 13:10:55 -08001005 */
Jason Evans9eb1b1c2017-01-18 23:03:37 -08001006 if (ctl_arenas == NULL) {
1007 ctl_arenas = (ctl_arenas_t *)base_alloc(tsdn,
1008 b0get(), sizeof(ctl_arenas_t), QUANTUM);
1009 if (ctl_arenas == NULL) {
1010 ret = true;
1011 goto label_return;
1012 }
1013 }
1014
1015 if (config_stats && ctl_stats == NULL) {
Jason Evansd778dd22017-01-03 12:40:54 -08001016 ctl_stats = (ctl_stats_t *)base_alloc(tsdn, b0get(),
1017 sizeof(ctl_stats_t), QUANTUM);
1018 if (ctl_stats == NULL) {
1019 ret = true;
1020 goto label_return;
1021 }
1022 }
1023
1024 /*
Jason Evans9eb1b1c2017-01-18 23:03:37 -08001025 * Allocate space for the current full range of arenas
1026 * here rather than doing it lazily elsewhere, in order
1027 * to limit when OOM-caused errors can occur.
Jason Evansd778dd22017-01-03 12:40:54 -08001028 */
Qi Wang57beeb22017-06-22 18:58:40 -07001029 if ((ctl_sarena = arenas_i_impl(tsd, MALLCTL_ARENAS_ALL, false,
Jason Evans9eb1b1c2017-01-18 23:03:37 -08001030 true)) == NULL) {
1031 ret = true;
1032 goto label_return;
1033 }
1034 ctl_sarena->initialized = true;
1035
Qi Wang57beeb22017-06-22 18:58:40 -07001036 if ((ctl_darena = arenas_i_impl(tsd, MALLCTL_ARENAS_DESTROYED,
Jason Evansd778dd22017-01-03 12:40:54 -08001037 false, true)) == NULL) {
Jason Evansfc4dcfa2010-11-24 15:44:21 -08001038 ret = true;
Jason Evansa1ee7832012-04-10 15:07:44 -07001039 goto label_return;
Jason Evansfc4dcfa2010-11-24 15:44:21 -08001040 }
Jason Evans9eb1b1c2017-01-18 23:03:37 -08001041 ctl_arena_clear(ctl_darena);
Jason Evansedf1baf2017-01-03 17:21:59 -08001042 /*
Jason Evans9eb1b1c2017-01-18 23:03:37 -08001043 * Don't toggle ctl_darena to initialized until an arena is
1044 * actually destroyed, so that arena.<i>.initialized can be used
1045 * to query whether the stats are relevant.
Jason Evansedf1baf2017-01-03 17:21:59 -08001046 */
1047
Jason Evans9eb1b1c2017-01-18 23:03:37 -08001048 ctl_arenas->narenas = narenas_total_get();
1049 for (i = 0; i < ctl_arenas->narenas; i++) {
Qi Wang57beeb22017-06-22 18:58:40 -07001050 if (arenas_i_impl(tsd, i, false, true) == NULL) {
Jason Evansd778dd22017-01-03 12:40:54 -08001051 ret = true;
1052 goto label_return;
1053 }
1054 }
Jason Evans3c234352010-01-27 13:10:55 -08001055
Jason Evans9eb1b1c2017-01-18 23:03:37 -08001056 ql_new(&ctl_arenas->destroyed);
Jason Evansc1e00ef2016-05-10 22:21:10 -07001057 ctl_refresh(tsdn);
Jason Evans9eb1b1c2017-01-18 23:03:37 -08001058
Jason Evans3c234352010-01-27 13:10:55 -08001059 ctl_initialized = true;
1060 }
1061
Jason Evansfc4dcfa2010-11-24 15:44:21 -08001062 ret = false;
Jason Evansa1ee7832012-04-10 15:07:44 -07001063label_return:
Jason Evansc1e00ef2016-05-10 22:21:10 -07001064 malloc_mutex_unlock(tsdn, &ctl_mtx);
Jason Evansf4086432017-01-19 18:15:45 -08001065 return ret;
Jason Evans3c234352010-01-27 13:10:55 -08001066}
1067
1068static int
Jason Evansc1e00ef2016-05-10 22:21:10 -07001069ctl_lookup(tsdn_t *tsdn, const char *name, ctl_node_t const **nodesp,
Jason Evansc4c25922017-01-15 16:56:30 -08001070 size_t *mibp, size_t *depthp) {
Jason Evans3c234352010-01-27 13:10:55 -08001071 int ret;
1072 const char *elm, *tdot, *dot;
1073 size_t elen, i, j;
Mike Hommey461ad5c2012-04-20 08:38:42 +02001074 const ctl_named_node_t *node;
Jason Evans3c234352010-01-27 13:10:55 -08001075
1076 elm = name;
1077 /* Equivalent to strchrnul(). */
1078 dot = ((tdot = strchr(elm, '.')) != NULL) ? tdot : strchr(elm, '\0');
1079 elen = (size_t)((uintptr_t)dot - (uintptr_t)elm);
1080 if (elen == 0) {
1081 ret = ENOENT;
Jason Evansa1ee7832012-04-10 15:07:44 -07001082 goto label_return;
Jason Evans3c234352010-01-27 13:10:55 -08001083 }
1084 node = super_root_node;
1085 for (i = 0; i < *depthp; i++) {
Mike Hommey461ad5c2012-04-20 08:38:42 +02001086 assert(node);
1087 assert(node->nchildren > 0);
1088 if (ctl_named_node(node->children) != NULL) {
1089 const ctl_named_node_t *pnode = node;
Jason Evans3c234352010-01-27 13:10:55 -08001090
1091 /* Children are named. */
Mike Hommey461ad5c2012-04-20 08:38:42 +02001092 for (j = 0; j < node->nchildren; j++) {
1093 const ctl_named_node_t *child =
1094 ctl_named_children(node, j);
1095 if (strlen(child->name) == elen &&
1096 strncmp(elm, child->name, elen) == 0) {
Jason Evans3c234352010-01-27 13:10:55 -08001097 node = child;
Jason Evansc4c25922017-01-15 16:56:30 -08001098 if (nodesp != NULL) {
Mike Hommey461ad5c2012-04-20 08:38:42 +02001099 nodesp[i] =
1100 (const ctl_node_t *)node;
Jason Evansc4c25922017-01-15 16:56:30 -08001101 }
Jason Evans3c234352010-01-27 13:10:55 -08001102 mibp[i] = j;
1103 break;
1104 }
1105 }
1106 if (node == pnode) {
1107 ret = ENOENT;
Jason Evansa1ee7832012-04-10 15:07:44 -07001108 goto label_return;
Jason Evans3c234352010-01-27 13:10:55 -08001109 }
1110 } else {
Jason Evans41b6afb2012-02-02 22:04:57 -08001111 uintmax_t index;
Mike Hommey461ad5c2012-04-20 08:38:42 +02001112 const ctl_indexed_node_t *inode;
Jason Evans3c234352010-01-27 13:10:55 -08001113
1114 /* Children are indexed. */
Jason Evans41b6afb2012-02-02 22:04:57 -08001115 index = malloc_strtoumax(elm, NULL, 10);
1116 if (index == UINTMAX_MAX || index > SIZE_T_MAX) {
Jason Evans3c234352010-01-27 13:10:55 -08001117 ret = ENOENT;
Jason Evansa1ee7832012-04-10 15:07:44 -07001118 goto label_return;
Jason Evans3c234352010-01-27 13:10:55 -08001119 }
1120
Mike Hommey461ad5c2012-04-20 08:38:42 +02001121 inode = ctl_indexed_node(node->children);
Jason Evansc1e00ef2016-05-10 22:21:10 -07001122 node = inode->index(tsdn, mibp, *depthp, (size_t)index);
Jason Evans3c234352010-01-27 13:10:55 -08001123 if (node == NULL) {
1124 ret = ENOENT;
Jason Evansa1ee7832012-04-10 15:07:44 -07001125 goto label_return;
Jason Evans3c234352010-01-27 13:10:55 -08001126 }
1127
Jason Evansc4c25922017-01-15 16:56:30 -08001128 if (nodesp != NULL) {
Mike Hommey461ad5c2012-04-20 08:38:42 +02001129 nodesp[i] = (const ctl_node_t *)node;
Jason Evansc4c25922017-01-15 16:56:30 -08001130 }
Jason Evans3c234352010-01-27 13:10:55 -08001131 mibp[i] = (size_t)index;
1132 }
1133
1134 if (node->ctl != NULL) {
1135 /* Terminal node. */
1136 if (*dot != '\0') {
1137 /*
1138 * The name contains more elements than are
1139 * in this path through the tree.
1140 */
1141 ret = ENOENT;
Jason Evansa1ee7832012-04-10 15:07:44 -07001142 goto label_return;
Jason Evans3c234352010-01-27 13:10:55 -08001143 }
1144 /* Complete lookup successful. */
1145 *depthp = i + 1;
1146 break;
1147 }
1148
1149 /* Update elm. */
1150 if (*dot == '\0') {
1151 /* No more elements. */
1152 ret = ENOENT;
Jason Evansa1ee7832012-04-10 15:07:44 -07001153 goto label_return;
Jason Evans3c234352010-01-27 13:10:55 -08001154 }
1155 elm = &dot[1];
1156 dot = ((tdot = strchr(elm, '.')) != NULL) ? tdot :
1157 strchr(elm, '\0');
1158 elen = (size_t)((uintptr_t)dot - (uintptr_t)elm);
1159 }
1160
1161 ret = 0;
Jason Evansa1ee7832012-04-10 15:07:44 -07001162label_return:
Jason Evansf4086432017-01-19 18:15:45 -08001163 return ret;
Jason Evans3c234352010-01-27 13:10:55 -08001164}
1165
1166int
Jason Evansb2c0d632016-04-13 23:36:15 -07001167ctl_byname(tsd_t *tsd, const char *name, void *oldp, size_t *oldlenp,
Jason Evansc4c25922017-01-15 16:56:30 -08001168 void *newp, size_t newlen) {
Jason Evans3c234352010-01-27 13:10:55 -08001169 int ret;
1170 size_t depth;
1171 ctl_node_t const *nodes[CTL_MAX_DEPTH];
1172 size_t mib[CTL_MAX_DEPTH];
Mike Hommey461ad5c2012-04-20 08:38:42 +02001173 const ctl_named_node_t *node;
Jason Evans3c234352010-01-27 13:10:55 -08001174
Qi Wang57beeb22017-06-22 18:58:40 -07001175 if (!ctl_initialized && ctl_init(tsd)) {
Jason Evans3c234352010-01-27 13:10:55 -08001176 ret = EAGAIN;
Jason Evansa1ee7832012-04-10 15:07:44 -07001177 goto label_return;
Jason Evans3c234352010-01-27 13:10:55 -08001178 }
1179
1180 depth = CTL_MAX_DEPTH;
Jason Evansc1e00ef2016-05-10 22:21:10 -07001181 ret = ctl_lookup(tsd_tsdn(tsd), name, nodes, mib, &depth);
Jason Evansc4c25922017-01-15 16:56:30 -08001182 if (ret != 0) {
Jason Evansa1ee7832012-04-10 15:07:44 -07001183 goto label_return;
Jason Evansc4c25922017-01-15 16:56:30 -08001184 }
Jason Evans3c234352010-01-27 13:10:55 -08001185
Mike Hommey461ad5c2012-04-20 08:38:42 +02001186 node = ctl_named_node(nodes[depth-1]);
Jason Evansc4c25922017-01-15 16:56:30 -08001187 if (node != NULL && node->ctl) {
Jason Evansb2c0d632016-04-13 23:36:15 -07001188 ret = node->ctl(tsd, mib, depth, oldp, oldlenp, newp, newlen);
Qi Wangaa1de062017-03-01 14:43:35 -08001189 } else {
Jason Evans3c234352010-01-27 13:10:55 -08001190 /* The name refers to a partial path through the ctl tree. */
1191 ret = ENOENT;
Jason Evans3c234352010-01-27 13:10:55 -08001192 }
Jason Evans3c234352010-01-27 13:10:55 -08001193
Jason Evansa1ee7832012-04-10 15:07:44 -07001194label_return:
Jason Evans3c234352010-01-27 13:10:55 -08001195 return(ret);
1196}
1197
1198int
Qi Wang57beeb22017-06-22 18:58:40 -07001199ctl_nametomib(tsd_t *tsd, const char *name, size_t *mibp, size_t *miblenp) {
Jason Evans3c234352010-01-27 13:10:55 -08001200 int ret;
1201
Qi Wang57beeb22017-06-22 18:58:40 -07001202 if (!ctl_initialized && ctl_init(tsd)) {
Jason Evans3c234352010-01-27 13:10:55 -08001203 ret = EAGAIN;
Jason Evansa1ee7832012-04-10 15:07:44 -07001204 goto label_return;
Jason Evans3c234352010-01-27 13:10:55 -08001205 }
1206
Qi Wang57beeb22017-06-22 18:58:40 -07001207 ret = ctl_lookup(tsd_tsdn(tsd), name, NULL, mibp, miblenp);
Jason Evansa1ee7832012-04-10 15:07:44 -07001208label_return:
Jason Evans3c234352010-01-27 13:10:55 -08001209 return(ret);
1210}
1211
1212int
Jason Evansb2c0d632016-04-13 23:36:15 -07001213ctl_bymib(tsd_t *tsd, const size_t *mib, size_t miblen, void *oldp,
Jason Evansc4c25922017-01-15 16:56:30 -08001214 size_t *oldlenp, void *newp, size_t newlen) {
Jason Evans3c234352010-01-27 13:10:55 -08001215 int ret;
Mike Hommey461ad5c2012-04-20 08:38:42 +02001216 const ctl_named_node_t *node;
Jason Evans3c234352010-01-27 13:10:55 -08001217 size_t i;
1218
Qi Wang57beeb22017-06-22 18:58:40 -07001219 if (!ctl_initialized && ctl_init(tsd)) {
Jason Evans3c234352010-01-27 13:10:55 -08001220 ret = EAGAIN;
Jason Evansa1ee7832012-04-10 15:07:44 -07001221 goto label_return;
Jason Evans3c234352010-01-27 13:10:55 -08001222 }
1223
1224 /* Iterate down the tree. */
1225 node = super_root_node;
1226 for (i = 0; i < miblen; i++) {
Mike Hommey461ad5c2012-04-20 08:38:42 +02001227 assert(node);
1228 assert(node->nchildren > 0);
1229 if (ctl_named_node(node->children) != NULL) {
Jason Evans3c234352010-01-27 13:10:55 -08001230 /* Children are named. */
Jason Evans6edbedd2017-01-04 07:51:49 -08001231 if (node->nchildren <= mib[i]) {
Jason Evans3c234352010-01-27 13:10:55 -08001232 ret = ENOENT;
Jason Evansa1ee7832012-04-10 15:07:44 -07001233 goto label_return;
Jason Evans3c234352010-01-27 13:10:55 -08001234 }
Mike Hommey461ad5c2012-04-20 08:38:42 +02001235 node = ctl_named_children(node, mib[i]);
Jason Evans3c234352010-01-27 13:10:55 -08001236 } else {
Mike Hommey461ad5c2012-04-20 08:38:42 +02001237 const ctl_indexed_node_t *inode;
Jason Evans3c234352010-01-27 13:10:55 -08001238
1239 /* Indexed element. */
Mike Hommey461ad5c2012-04-20 08:38:42 +02001240 inode = ctl_indexed_node(node->children);
Jason Evansc1e00ef2016-05-10 22:21:10 -07001241 node = inode->index(tsd_tsdn(tsd), mib, miblen, mib[i]);
Jason Evans3c234352010-01-27 13:10:55 -08001242 if (node == NULL) {
1243 ret = ENOENT;
Jason Evansa1ee7832012-04-10 15:07:44 -07001244 goto label_return;
Jason Evans3c234352010-01-27 13:10:55 -08001245 }
1246 }
1247 }
1248
1249 /* Call the ctl function. */
Jason Evansc4c25922017-01-15 16:56:30 -08001250 if (node && node->ctl) {
Jason Evansb2c0d632016-04-13 23:36:15 -07001251 ret = node->ctl(tsd, mib, miblen, oldp, oldlenp, newp, newlen);
Jason Evansc4c25922017-01-15 16:56:30 -08001252 } else {
Jason Evans3c234352010-01-27 13:10:55 -08001253 /* Partial MIB. */
1254 ret = ENOENT;
Jason Evans3c234352010-01-27 13:10:55 -08001255 }
Jason Evans3c234352010-01-27 13:10:55 -08001256
Jason Evansa1ee7832012-04-10 15:07:44 -07001257label_return:
Jason Evans3c234352010-01-27 13:10:55 -08001258 return(ret);
1259}
1260
1261bool
Jason Evansc4c25922017-01-15 16:56:30 -08001262ctl_boot(void) {
David Goldblatt26c792e2017-05-15 15:38:15 -07001263 if (malloc_mutex_init(&ctl_mtx, "ctl", WITNESS_RANK_CTL,
1264 malloc_mutex_rank_exclusive)) {
Jason Evansf4086432017-01-19 18:15:45 -08001265 return true;
Jason Evansc4c25922017-01-15 16:56:30 -08001266 }
Jason Evans3c234352010-01-27 13:10:55 -08001267
1268 ctl_initialized = false;
1269
Jason Evansf4086432017-01-19 18:15:45 -08001270 return false;
Jason Evans3c234352010-01-27 13:10:55 -08001271}
1272
Jason Evans20f1fc92012-10-09 14:46:22 -07001273void
Jason Evansc4c25922017-01-15 16:56:30 -08001274ctl_prefork(tsdn_t *tsdn) {
Jason Evansc1e00ef2016-05-10 22:21:10 -07001275 malloc_mutex_prefork(tsdn, &ctl_mtx);
Jason Evans20f1fc92012-10-09 14:46:22 -07001276}
1277
1278void
Jason Evansc4c25922017-01-15 16:56:30 -08001279ctl_postfork_parent(tsdn_t *tsdn) {
Jason Evansc1e00ef2016-05-10 22:21:10 -07001280 malloc_mutex_postfork_parent(tsdn, &ctl_mtx);
Jason Evans20f1fc92012-10-09 14:46:22 -07001281}
1282
1283void
Jason Evansc4c25922017-01-15 16:56:30 -08001284ctl_postfork_child(tsdn_t *tsdn) {
Jason Evansc1e00ef2016-05-10 22:21:10 -07001285 malloc_mutex_postfork_child(tsdn, &ctl_mtx);
Jason Evans20f1fc92012-10-09 14:46:22 -07001286}
1287
Jason Evans3c234352010-01-27 13:10:55 -08001288/******************************************************************************/
1289/* *_ctl() functions. */
1290
Jason Evansc0cc5db2017-01-19 21:41:41 -08001291#define READONLY() do { \
Jason Evans3c234352010-01-27 13:10:55 -08001292 if (newp != NULL || newlen != 0) { \
1293 ret = EPERM; \
Jason Evans6b9ed672012-04-25 13:12:46 -07001294 goto label_return; \
Jason Evans3c234352010-01-27 13:10:55 -08001295 } \
1296} while (0)
1297
Jason Evansc0cc5db2017-01-19 21:41:41 -08001298#define WRITEONLY() do { \
Jason Evans3c234352010-01-27 13:10:55 -08001299 if (oldp != NULL || oldlenp != NULL) { \
1300 ret = EPERM; \
Jason Evans6b9ed672012-04-25 13:12:46 -07001301 goto label_return; \
Jason Evans3c234352010-01-27 13:10:55 -08001302 } \
1303} while (0)
1304
Jason Evansc0cc5db2017-01-19 21:41:41 -08001305#define READ_XOR_WRITE() do { \
Jason Evansfc12c0b2014-10-03 23:25:30 -07001306 if ((oldp != NULL && oldlenp != NULL) && (newp != NULL || \
1307 newlen != 0)) { \
1308 ret = EPERM; \
1309 goto label_return; \
1310 } \
1311} while (0)
1312
Jason Evansc0cc5db2017-01-19 21:41:41 -08001313#define READ(v, t) do { \
Jason Evans3c234352010-01-27 13:10:55 -08001314 if (oldp != NULL && oldlenp != NULL) { \
1315 if (*oldlenp != sizeof(t)) { \
1316 size_t copylen = (sizeof(t) <= *oldlenp) \
1317 ? sizeof(t) : *oldlenp; \
Jason Evans6eb84fb2012-11-29 22:13:04 -08001318 memcpy(oldp, (void *)&(v), copylen); \
Jason Evans3c234352010-01-27 13:10:55 -08001319 ret = EINVAL; \
Jason Evans6b9ed672012-04-25 13:12:46 -07001320 goto label_return; \
Jason Evansb49a3342015-07-28 11:28:19 -04001321 } \
1322 *(t *)oldp = (v); \
Jason Evans3c234352010-01-27 13:10:55 -08001323 } \
1324} while (0)
1325
Jason Evansc0cc5db2017-01-19 21:41:41 -08001326#define WRITE(v, t) do { \
Jason Evans3c234352010-01-27 13:10:55 -08001327 if (newp != NULL) { \
1328 if (newlen != sizeof(t)) { \
1329 ret = EINVAL; \
Jason Evans6b9ed672012-04-25 13:12:46 -07001330 goto label_return; \
Jason Evans3c234352010-01-27 13:10:55 -08001331 } \
Jason Evans6eb84fb2012-11-29 22:13:04 -08001332 (v) = *(t *)newp; \
Jason Evans3c234352010-01-27 13:10:55 -08001333 } \
1334} while (0)
1335
Jason Evansc0cc5db2017-01-19 21:41:41 -08001336#define MIB_UNSIGNED(v, i) do { \
Jason Evans6edbedd2017-01-04 07:51:49 -08001337 if (mib[i] > UINT_MAX) { \
1338 ret = EFAULT; \
1339 goto label_return; \
1340 } \
1341 v = (unsigned)mib[i]; \
1342} while (0)
1343
Jason Evans7372b152012-02-10 20:22:09 -08001344/*
1345 * There's a lot of code duplication in the following macros due to limitations
1346 * in how nested cpp macros are expanded.
1347 */
Jason Evansc0cc5db2017-01-19 21:41:41 -08001348#define CTL_RO_CLGEN(c, l, n, v, t) \
Jason Evans7372b152012-02-10 20:22:09 -08001349static int \
Jason Evansb2c0d632016-04-13 23:36:15 -07001350n##_ctl(tsd_t *tsd, const size_t *mib, size_t miblen, void *oldp, \
Jason Evansc4c25922017-01-15 16:56:30 -08001351 size_t *oldlenp, void *newp, size_t newlen) { \
Jason Evans7372b152012-02-10 20:22:09 -08001352 int ret; \
1353 t oldval; \
1354 \
Jason Evansc4c25922017-01-15 16:56:30 -08001355 if (!(c)) { \
Jason Evansf4086432017-01-19 18:15:45 -08001356 return ENOENT; \
Jason Evansc4c25922017-01-15 16:56:30 -08001357 } \
1358 if (l) { \
Jason Evansc1e00ef2016-05-10 22:21:10 -07001359 malloc_mutex_lock(tsd_tsdn(tsd), &ctl_mtx); \
Jason Evansc4c25922017-01-15 16:56:30 -08001360 } \
Jason Evans7372b152012-02-10 20:22:09 -08001361 READONLY(); \
Jason Evans6eb84fb2012-11-29 22:13:04 -08001362 oldval = (v); \
Jason Evans7372b152012-02-10 20:22:09 -08001363 READ(oldval, t); \
1364 \
1365 ret = 0; \
Jason Evans6b9ed672012-04-25 13:12:46 -07001366label_return: \
Jason Evansc4c25922017-01-15 16:56:30 -08001367 if (l) { \
Jason Evansc1e00ef2016-05-10 22:21:10 -07001368 malloc_mutex_unlock(tsd_tsdn(tsd), &ctl_mtx); \
Jason Evansc4c25922017-01-15 16:56:30 -08001369 } \
Jason Evansf4086432017-01-19 18:15:45 -08001370 return ret; \
Jason Evans7372b152012-02-10 20:22:09 -08001371}
1372
Jason Evansc0cc5db2017-01-19 21:41:41 -08001373#define CTL_RO_CGEN(c, n, v, t) \
Jason Evans7372b152012-02-10 20:22:09 -08001374static int \
Jason Evansb2c0d632016-04-13 23:36:15 -07001375n##_ctl(tsd_t *tsd, const size_t *mib, size_t miblen, void *oldp, \
Jason Evansc4c25922017-01-15 16:56:30 -08001376 size_t *oldlenp, void *newp, size_t newlen) { \
Jason Evans7372b152012-02-10 20:22:09 -08001377 int ret; \
1378 t oldval; \
1379 \
Jason Evansc4c25922017-01-15 16:56:30 -08001380 if (!(c)) { \
Jason Evansf4086432017-01-19 18:15:45 -08001381 return ENOENT; \
Jason Evansc4c25922017-01-15 16:56:30 -08001382 } \
Jason Evansc1e00ef2016-05-10 22:21:10 -07001383 malloc_mutex_lock(tsd_tsdn(tsd), &ctl_mtx); \
Jason Evans7372b152012-02-10 20:22:09 -08001384 READONLY(); \
Jason Evans6eb84fb2012-11-29 22:13:04 -08001385 oldval = (v); \
Jason Evans7372b152012-02-10 20:22:09 -08001386 READ(oldval, t); \
1387 \
1388 ret = 0; \
Jason Evans6b9ed672012-04-25 13:12:46 -07001389label_return: \
Jason Evansc1e00ef2016-05-10 22:21:10 -07001390 malloc_mutex_unlock(tsd_tsdn(tsd), &ctl_mtx); \
Jason Evansf4086432017-01-19 18:15:45 -08001391 return ret; \
Jason Evans7372b152012-02-10 20:22:09 -08001392}
1393
Jason Evansc0cc5db2017-01-19 21:41:41 -08001394#define CTL_RO_GEN(n, v, t) \
Jason Evans3c234352010-01-27 13:10:55 -08001395static int \
Jason Evansb2c0d632016-04-13 23:36:15 -07001396n##_ctl(tsd_t *tsd, const size_t *mib, size_t miblen, void *oldp, \
Jason Evansc4c25922017-01-15 16:56:30 -08001397 size_t *oldlenp, void *newp, size_t newlen) { \
Jason Evans3c234352010-01-27 13:10:55 -08001398 int ret; \
1399 t oldval; \
1400 \
Jason Evansc1e00ef2016-05-10 22:21:10 -07001401 malloc_mutex_lock(tsd_tsdn(tsd), &ctl_mtx); \
Jason Evansfc4dcfa2010-11-24 15:44:21 -08001402 READONLY(); \
Jason Evans6eb84fb2012-11-29 22:13:04 -08001403 oldval = (v); \
Jason Evansfc4dcfa2010-11-24 15:44:21 -08001404 READ(oldval, t); \
1405 \
1406 ret = 0; \
Jason Evans6b9ed672012-04-25 13:12:46 -07001407label_return: \
Jason Evansc1e00ef2016-05-10 22:21:10 -07001408 malloc_mutex_unlock(tsd_tsdn(tsd), &ctl_mtx); \
Jason Evansf4086432017-01-19 18:15:45 -08001409 return ret; \
Jason Evansfc4dcfa2010-11-24 15:44:21 -08001410}
1411
1412/*
1413 * ctl_mtx is not acquired, under the assumption that no pertinent data will
1414 * mutate during the call.
1415 */
Jason Evansc0cc5db2017-01-19 21:41:41 -08001416#define CTL_RO_NL_CGEN(c, n, v, t) \
Jason Evans7372b152012-02-10 20:22:09 -08001417static int \
Jason Evansb2c0d632016-04-13 23:36:15 -07001418n##_ctl(tsd_t *tsd, const size_t *mib, size_t miblen, void *oldp, \
Jason Evansc4c25922017-01-15 16:56:30 -08001419 size_t *oldlenp, void *newp, size_t newlen) { \
Jason Evans7372b152012-02-10 20:22:09 -08001420 int ret; \
1421 t oldval; \
1422 \
Jason Evansc4c25922017-01-15 16:56:30 -08001423 if (!(c)) { \
Jason Evansf4086432017-01-19 18:15:45 -08001424 return ENOENT; \
Jason Evansc4c25922017-01-15 16:56:30 -08001425 } \
Jason Evans7372b152012-02-10 20:22:09 -08001426 READONLY(); \
Jason Evans6eb84fb2012-11-29 22:13:04 -08001427 oldval = (v); \
Jason Evans7372b152012-02-10 20:22:09 -08001428 READ(oldval, t); \
1429 \
1430 ret = 0; \
Jason Evans6b9ed672012-04-25 13:12:46 -07001431label_return: \
Jason Evansf4086432017-01-19 18:15:45 -08001432 return ret; \
Jason Evans7372b152012-02-10 20:22:09 -08001433}
1434
Jason Evansc0cc5db2017-01-19 21:41:41 -08001435#define CTL_RO_NL_GEN(n, v, t) \
Jason Evansfc4dcfa2010-11-24 15:44:21 -08001436static int \
Jason Evansb2c0d632016-04-13 23:36:15 -07001437n##_ctl(tsd_t *tsd, const size_t *mib, size_t miblen, void *oldp, \
Jason Evansc4c25922017-01-15 16:56:30 -08001438 size_t *oldlenp, void *newp, size_t newlen) { \
Jason Evansfc4dcfa2010-11-24 15:44:21 -08001439 int ret; \
1440 t oldval; \
1441 \
Jason Evans3c234352010-01-27 13:10:55 -08001442 READONLY(); \
Jason Evans6eb84fb2012-11-29 22:13:04 -08001443 oldval = (v); \
Jason Evans3c234352010-01-27 13:10:55 -08001444 READ(oldval, t); \
1445 \
1446 ret = 0; \
Jason Evans6b9ed672012-04-25 13:12:46 -07001447label_return: \
Jason Evansf4086432017-01-19 18:15:45 -08001448 return ret; \
Jason Evans3c234352010-01-27 13:10:55 -08001449}
1450
Jason Evansc0cc5db2017-01-19 21:41:41 -08001451#define CTL_TSD_RO_NL_CGEN(c, n, m, t) \
Jason Evans5460aa62014-09-22 21:09:23 -07001452static int \
Jason Evansb2c0d632016-04-13 23:36:15 -07001453n##_ctl(tsd_t *tsd, const size_t *mib, size_t miblen, void *oldp, \
Jason Evansc4c25922017-01-15 16:56:30 -08001454 size_t *oldlenp, void *newp, size_t newlen) { \
Jason Evans5460aa62014-09-22 21:09:23 -07001455 int ret; \
1456 t oldval; \
Jason Evans5460aa62014-09-22 21:09:23 -07001457 \
Jason Evansc4c25922017-01-15 16:56:30 -08001458 if (!(c)) { \
Jason Evansf4086432017-01-19 18:15:45 -08001459 return ENOENT; \
Jason Evansc4c25922017-01-15 16:56:30 -08001460 } \
Jason Evans5460aa62014-09-22 21:09:23 -07001461 READONLY(); \
Jason Evans5460aa62014-09-22 21:09:23 -07001462 oldval = (m(tsd)); \
1463 READ(oldval, t); \
1464 \
1465 ret = 0; \
1466label_return: \
Jason Evansf4086432017-01-19 18:15:45 -08001467 return ret; \
Jason Evans5460aa62014-09-22 21:09:23 -07001468}
1469
Jason Evansc0cc5db2017-01-19 21:41:41 -08001470#define CTL_RO_CONFIG_GEN(n, t) \
Jason Evans3c234352010-01-27 13:10:55 -08001471static int \
Jason Evansb2c0d632016-04-13 23:36:15 -07001472n##_ctl(tsd_t *tsd, const size_t *mib, size_t miblen, void *oldp, \
Jason Evansc4c25922017-01-15 16:56:30 -08001473 size_t *oldlenp, void *newp, size_t newlen) { \
Jason Evans3c234352010-01-27 13:10:55 -08001474 int ret; \
Jason Evansf8290092016-02-07 14:23:22 -08001475 t oldval; \
Jason Evans3c234352010-01-27 13:10:55 -08001476 \
1477 READONLY(); \
Jason Evans7372b152012-02-10 20:22:09 -08001478 oldval = n; \
Jason Evansf8290092016-02-07 14:23:22 -08001479 READ(oldval, t); \
Jason Evans3c234352010-01-27 13:10:55 -08001480 \
1481 ret = 0; \
Jason Evans6b9ed672012-04-25 13:12:46 -07001482label_return: \
Jason Evansf4086432017-01-19 18:15:45 -08001483 return ret; \
Jason Evans3c234352010-01-27 13:10:55 -08001484}
1485
Jason Evansd8a39002013-12-19 21:40:41 -08001486/******************************************************************************/
1487
Jason Evansfc4dcfa2010-11-24 15:44:21 -08001488CTL_RO_NL_GEN(version, JEMALLOC_VERSION, const char *)
Jason Evansa40bc7a2010-03-02 13:01:16 -08001489
Jason Evans3c234352010-01-27 13:10:55 -08001490static int
Jason Evansb2c0d632016-04-13 23:36:15 -07001491epoch_ctl(tsd_t *tsd, const size_t *mib, size_t miblen, void *oldp,
Jason Evansc4c25922017-01-15 16:56:30 -08001492 size_t *oldlenp, void *newp, size_t newlen) {
Jason Evans3c234352010-01-27 13:10:55 -08001493 int ret;
Jason Evans3ab682d2013-10-19 17:19:49 -07001494 UNUSED uint64_t newval;
Jason Evans3c234352010-01-27 13:10:55 -08001495
Jason Evansc1e00ef2016-05-10 22:21:10 -07001496 malloc_mutex_lock(tsd_tsdn(tsd), &ctl_mtx);
Jason Evans3c234352010-01-27 13:10:55 -08001497 WRITE(newval, uint64_t);
Jason Evansc4c25922017-01-15 16:56:30 -08001498 if (newp != NULL) {
Jason Evansc1e00ef2016-05-10 22:21:10 -07001499 ctl_refresh(tsd_tsdn(tsd));
Jason Evansc4c25922017-01-15 16:56:30 -08001500 }
Jason Evans9eb1b1c2017-01-18 23:03:37 -08001501 READ(ctl_arenas->epoch, uint64_t);
Jason Evans3c234352010-01-27 13:10:55 -08001502
1503 ret = 0;
Jason Evansa1ee7832012-04-10 15:07:44 -07001504label_return:
Jason Evansc1e00ef2016-05-10 22:21:10 -07001505 malloc_mutex_unlock(tsd_tsdn(tsd), &ctl_mtx);
Jason Evansf4086432017-01-19 18:15:45 -08001506 return ret;
Jason Evans3c234352010-01-27 13:10:55 -08001507}
1508
Qi Wangb693c782017-03-17 12:42:33 -07001509static int
1510background_thread_ctl(tsd_t *tsd, const size_t *mib, size_t miblen,
1511 void *oldp, size_t *oldlenp, void *newp, size_t newlen) {
1512 int ret;
1513 bool oldval;
1514
1515 if (!have_background_thread) {
1516 return ENOENT;
1517 }
Qi Wang340071f2017-06-01 12:52:09 -07001518 background_thread_ctl_init(tsd_tsdn(tsd));
Qi Wangb693c782017-03-17 12:42:33 -07001519
Qi Wang73713fb2017-06-07 15:49:09 -07001520 malloc_mutex_lock(tsd_tsdn(tsd), &ctl_mtx);
Qi Wangb693c782017-03-17 12:42:33 -07001521 malloc_mutex_lock(tsd_tsdn(tsd), &background_thread_lock);
1522 if (newp == NULL) {
1523 oldval = background_thread_enabled();
1524 READ(oldval, bool);
1525 } else {
1526 if (newlen != sizeof(bool)) {
1527 ret = EINVAL;
1528 goto label_return;
1529 }
1530 oldval = background_thread_enabled();
1531 READ(oldval, bool);
1532
1533 bool newval = *(bool *)newp;
1534 if (newval == oldval) {
1535 ret = 0;
1536 goto label_return;
1537 }
1538
1539 background_thread_enabled_set(tsd_tsdn(tsd), newval);
1540 if (newval) {
Qi Wanga4d6fe72017-06-14 12:12:23 -07001541 if (!can_enable_background_thread) {
1542 malloc_printf("<jemalloc>: Error in dlsym("
1543 "RTLD_NEXT, \"pthread_create\"). Cannot "
1544 "enable background_thread\n");
1545 ret = EFAULT;
1546 goto label_return;
1547 }
Qi Wangb693c782017-03-17 12:42:33 -07001548 if (background_threads_enable(tsd)) {
1549 ret = EFAULT;
1550 goto label_return;
1551 }
1552 } else {
1553 if (background_threads_disable(tsd)) {
1554 ret = EFAULT;
1555 goto label_return;
1556 }
1557 }
1558 }
1559 ret = 0;
1560label_return:
1561 malloc_mutex_unlock(tsd_tsdn(tsd), &background_thread_lock);
Qi Wang73713fb2017-06-07 15:49:09 -07001562 malloc_mutex_unlock(tsd_tsdn(tsd), &ctl_mtx);
1563
Qi Wangb693c782017-03-17 12:42:33 -07001564 return ret;
1565}
1566
Jason Evansd8a39002013-12-19 21:40:41 -08001567/******************************************************************************/
Jason Evansd4be8b72012-03-26 18:54:44 -07001568
Jason Evansf8290092016-02-07 14:23:22 -08001569CTL_RO_CONFIG_GEN(config_cache_oblivious, bool)
1570CTL_RO_CONFIG_GEN(config_debug, bool)
1571CTL_RO_CONFIG_GEN(config_fill, bool)
1572CTL_RO_CONFIG_GEN(config_lazy_lock, bool)
1573CTL_RO_CONFIG_GEN(config_malloc_conf, const char *)
Jason Evansf8290092016-02-07 14:23:22 -08001574CTL_RO_CONFIG_GEN(config_prof, bool)
1575CTL_RO_CONFIG_GEN(config_prof_libgcc, bool)
1576CTL_RO_CONFIG_GEN(config_prof_libunwind, bool)
1577CTL_RO_CONFIG_GEN(config_stats, bool)
Jason Evansf8290092016-02-07 14:23:22 -08001578CTL_RO_CONFIG_GEN(config_utrace, bool)
Jason Evansf8290092016-02-07 14:23:22 -08001579CTL_RO_CONFIG_GEN(config_xmalloc, bool)
Jason Evansd4be8b72012-03-26 18:54:44 -07001580
Jason Evansd8a39002013-12-19 21:40:41 -08001581/******************************************************************************/
Jason Evansd4be8b72012-03-26 18:54:44 -07001582
Jason Evansd8a39002013-12-19 21:40:41 -08001583CTL_RO_NL_GEN(opt_abort, opt_abort, bool)
Qi Wangb86d2712017-05-25 15:30:11 -07001584CTL_RO_NL_GEN(opt_abort_conf, opt_abort_conf, bool)
Qi Wang47b20bb2017-08-24 14:29:28 -07001585CTL_RO_NL_GEN(opt_metadata_thp, metadata_thp_mode_names[opt_metadata_thp],
1586 const char *)
Jason Evansb9ab04a2017-04-26 16:26:12 -07001587CTL_RO_NL_GEN(opt_retain, opt_retain, bool)
Jason Evansd8a39002013-12-19 21:40:41 -08001588CTL_RO_NL_GEN(opt_dss, opt_dss, const char *)
Jason Evans8f683b92016-02-24 11:03:40 -08001589CTL_RO_NL_GEN(opt_narenas, opt_narenas, unsigned)
Jason Evansb5112322017-05-31 16:45:14 -07001590CTL_RO_NL_GEN(opt_percpu_arena, percpu_arena_mode_names[opt_percpu_arena],
1591 const char *)
Qi Wangb693c782017-03-17 12:42:33 -07001592CTL_RO_NL_GEN(opt_background_thread, opt_background_thread, bool)
Jason Evans6e62c622017-05-17 10:47:00 -07001593CTL_RO_NL_GEN(opt_dirty_decay_ms, opt_dirty_decay_ms, ssize_t)
1594CTL_RO_NL_GEN(opt_muzzy_decay_ms, opt_muzzy_decay_ms, ssize_t)
Jason Evansd8a39002013-12-19 21:40:41 -08001595CTL_RO_NL_GEN(opt_stats_print, opt_stats_print, bool)
Qi Wangd5ef5ae2017-05-27 15:35:36 -07001596CTL_RO_NL_GEN(opt_stats_print_opts, opt_stats_print_opts, const char *)
Guilherme Goncalves2c5cb612014-12-08 19:12:41 -02001597CTL_RO_NL_CGEN(config_fill, opt_junk, opt_junk, const char *)
Jason Evansd8a39002013-12-19 21:40:41 -08001598CTL_RO_NL_CGEN(config_fill, opt_zero, opt_zero, bool)
1599CTL_RO_NL_CGEN(config_utrace, opt_utrace, opt_utrace, bool)
Jason Evansd8a39002013-12-19 21:40:41 -08001600CTL_RO_NL_CGEN(config_xmalloc, opt_xmalloc, opt_xmalloc, bool)
Jason Evans4403c9a2017-04-20 17:21:37 -07001601CTL_RO_NL_GEN(opt_tcache, opt_tcache, bool)
Qi Wange4f090e2018-02-16 14:19:19 -08001602CTL_RO_NL_GEN(opt_thp, thp_mode_names[opt_thp], const char *)
Qi Wangfac70682017-11-09 13:51:39 -08001603CTL_RO_NL_GEN(opt_lg_extent_max_active_fit, opt_lg_extent_max_active_fit,
1604 size_t)
Jason Evans4403c9a2017-04-20 17:21:37 -07001605CTL_RO_NL_GEN(opt_lg_tcache_max, opt_lg_tcache_max, ssize_t)
Jason Evansd8a39002013-12-19 21:40:41 -08001606CTL_RO_NL_CGEN(config_prof, opt_prof, opt_prof, bool)
1607CTL_RO_NL_CGEN(config_prof, opt_prof_prefix, opt_prof_prefix, const char *)
Jason Evansfc12c0b2014-10-03 23:25:30 -07001608CTL_RO_NL_CGEN(config_prof, opt_prof_active, opt_prof_active, bool)
1609CTL_RO_NL_CGEN(config_prof, opt_prof_thread_active_init,
1610 opt_prof_thread_active_init, bool)
Jason Evansd8a39002013-12-19 21:40:41 -08001611CTL_RO_NL_CGEN(config_prof, opt_lg_prof_sample, opt_lg_prof_sample, size_t)
1612CTL_RO_NL_CGEN(config_prof, opt_prof_accum, opt_prof_accum, bool)
1613CTL_RO_NL_CGEN(config_prof, opt_lg_prof_interval, opt_lg_prof_interval, ssize_t)
1614CTL_RO_NL_CGEN(config_prof, opt_prof_gdump, opt_prof_gdump, bool)
1615CTL_RO_NL_CGEN(config_prof, opt_prof_final, opt_prof_final, bool)
1616CTL_RO_NL_CGEN(config_prof, opt_prof_leak, opt_prof_leak, bool)
Jason Evansd4be8b72012-03-26 18:54:44 -07001617
Jason Evansd8a39002013-12-19 21:40:41 -08001618/******************************************************************************/
Jason Evans3c234352010-01-27 13:10:55 -08001619
Jason Evansb267d0f2010-08-13 15:42:29 -07001620static int
Jason Evansb2c0d632016-04-13 23:36:15 -07001621thread_arena_ctl(tsd_t *tsd, const size_t *mib, size_t miblen, void *oldp,
Jason Evansc4c25922017-01-15 16:56:30 -08001622 size_t *oldlenp, void *newp, size_t newlen) {
Jason Evansb267d0f2010-08-13 15:42:29 -07001623 int ret;
Jason Evans1cb181e2015-01-29 15:30:47 -08001624 arena_t *oldarena;
Jason Evansb267d0f2010-08-13 15:42:29 -07001625 unsigned newind, oldind;
1626
Jason Evans90827a32016-05-03 15:00:42 -07001627 oldarena = arena_choose(tsd, NULL);
Jason Evansc4c25922017-01-15 16:56:30 -08001628 if (oldarena == NULL) {
Jason Evansf4086432017-01-19 18:15:45 -08001629 return EAGAIN;
Jason Evansc4c25922017-01-15 16:56:30 -08001630 }
Jason Evansa0dd3a42016-12-22 16:39:10 -06001631 newind = oldind = arena_ind_get(oldarena);
Jason Evansa7153a02011-03-14 11:39:49 -07001632 WRITE(newind, unsigned);
1633 READ(oldind, unsigned);
Qi Wangec532e22017-02-02 17:02:05 -08001634
Jason Evansb267d0f2010-08-13 15:42:29 -07001635 if (newind != oldind) {
Jason Evans1cb181e2015-01-29 15:30:47 -08001636 arena_t *newarena;
1637
Jason Evansb6c08672016-10-03 10:37:12 -07001638 if (newind >= narenas_total_get()) {
Jason Evansb267d0f2010-08-13 15:42:29 -07001639 /* New arena index is out of range. */
1640 ret = EFAULT;
Jason Evansa1ee7832012-04-10 15:07:44 -07001641 goto label_return;
Jason Evansb267d0f2010-08-13 15:42:29 -07001642 }
1643
Qi Wangec532e22017-02-02 17:02:05 -08001644 if (have_percpu_arena &&
Jason Evansb5112322017-05-31 16:45:14 -07001645 PERCPU_ARENA_ENABLED(opt_percpu_arena)) {
1646 if (newind < percpu_arena_ind_limit(opt_percpu_arena)) {
Qi Wangec532e22017-02-02 17:02:05 -08001647 /*
1648 * If perCPU arena is enabled, thread_arena
1649 * control is not allowed for the auto arena
1650 * range.
1651 */
1652 ret = EPERM;
1653 goto label_return;
1654 }
1655 }
1656
Jason Evansb267d0f2010-08-13 15:42:29 -07001657 /* Initialize arena if necessary. */
Jason Evansc1e00ef2016-05-10 22:21:10 -07001658 newarena = arena_get(tsd_tsdn(tsd), newind, true);
Jason Evans1cb181e2015-01-29 15:30:47 -08001659 if (newarena == NULL) {
Jason Evansb267d0f2010-08-13 15:42:29 -07001660 ret = EAGAIN;
Jason Evansa1ee7832012-04-10 15:07:44 -07001661 goto label_return;
Jason Evansb267d0f2010-08-13 15:42:29 -07001662 }
Jason Evans8bb31982014-10-07 23:14:57 -07001663 /* Set new arena/tcache associations. */
1664 arena_migrate(tsd, oldind, newind);
Jason Evans4403c9a2017-04-20 17:21:37 -07001665 if (tcache_available(tsd)) {
1666 tcache_arena_reassociate(tsd_tsdn(tsd),
1667 tsd_tcachep_get(tsd), newarena);
Jason Evans624f2f32010-12-29 12:21:05 -08001668 }
Jason Evansb267d0f2010-08-13 15:42:29 -07001669 }
1670
1671 ret = 0;
Jason Evansa1ee7832012-04-10 15:07:44 -07001672label_return:
Jason Evansf4086432017-01-19 18:15:45 -08001673 return ret;
Jason Evansb267d0f2010-08-13 15:42:29 -07001674}
Jason Evansb267d0f2010-08-13 15:42:29 -07001675
Jason Evans5460aa62014-09-22 21:09:23 -07001676CTL_TSD_RO_NL_CGEN(config_stats, thread_allocated, tsd_thread_allocated_get,
1677 uint64_t)
1678CTL_TSD_RO_NL_CGEN(config_stats, thread_allocatedp, tsd_thread_allocatedp_get,
1679 uint64_t *)
1680CTL_TSD_RO_NL_CGEN(config_stats, thread_deallocated, tsd_thread_deallocated_get,
1681 uint64_t)
1682CTL_TSD_RO_NL_CGEN(config_stats, thread_deallocatedp,
1683 tsd_thread_deallocatedp_get, uint64_t *)
Jason Evans93443682010-10-20 17:39:18 -07001684
Jason Evansd8a39002013-12-19 21:40:41 -08001685static int
Jason Evansb2c0d632016-04-13 23:36:15 -07001686thread_tcache_enabled_ctl(tsd_t *tsd, const size_t *mib, size_t miblen,
Jason Evansc4c25922017-01-15 16:56:30 -08001687 void *oldp, size_t *oldlenp, void *newp, size_t newlen) {
Jason Evansd8a39002013-12-19 21:40:41 -08001688 int ret;
1689 bool oldval;
Jason Evans3c234352010-01-27 13:10:55 -08001690
Qi Wangfde3e202017-03-27 21:50:38 -07001691 oldval = tcache_enabled_get(tsd);
Jason Evansd8a39002013-12-19 21:40:41 -08001692 if (newp != NULL) {
1693 if (newlen != sizeof(bool)) {
1694 ret = EINVAL;
1695 goto label_return;
1696 }
Qi Wangfde3e202017-03-27 21:50:38 -07001697 tcache_enabled_set(tsd, *(bool *)newp);
Jason Evansd8a39002013-12-19 21:40:41 -08001698 }
1699 READ(oldval, bool);
Jason Evans3c234352010-01-27 13:10:55 -08001700
Jason Evansd8a39002013-12-19 21:40:41 -08001701 ret = 0;
1702label_return:
Jason Evansf4086432017-01-19 18:15:45 -08001703 return ret;
Jason Evansd8a39002013-12-19 21:40:41 -08001704}
1705
1706static int
Jason Evansb2c0d632016-04-13 23:36:15 -07001707thread_tcache_flush_ctl(tsd_t *tsd, const size_t *mib, size_t miblen,
Jason Evansc4c25922017-01-15 16:56:30 -08001708 void *oldp, size_t *oldlenp, void *newp, size_t newlen) {
Jason Evansd8a39002013-12-19 21:40:41 -08001709 int ret;
1710
Jason Evans4403c9a2017-04-20 17:21:37 -07001711 if (!tcache_available(tsd)) {
1712 ret = EFAULT;
1713 goto label_return;
Jason Evansc4c25922017-01-15 16:56:30 -08001714 }
Jason Evansd8a39002013-12-19 21:40:41 -08001715
1716 READONLY();
1717 WRITEONLY();
1718
Qi Wangae93fb02017-06-15 15:16:18 -07001719 tcache_flush(tsd);
Jason Evansd8a39002013-12-19 21:40:41 -08001720
1721 ret = 0;
1722label_return:
Jason Evansf4086432017-01-19 18:15:45 -08001723 return ret;
Jason Evansd8a39002013-12-19 21:40:41 -08001724}
Jason Evans3c234352010-01-27 13:10:55 -08001725
Jason Evans602c8e02014-08-18 16:22:13 -07001726static int
Jason Evansb2c0d632016-04-13 23:36:15 -07001727thread_prof_name_ctl(tsd_t *tsd, const size_t *mib, size_t miblen, void *oldp,
Jason Evansc4c25922017-01-15 16:56:30 -08001728 size_t *oldlenp, void *newp, size_t newlen) {
Jason Evans602c8e02014-08-18 16:22:13 -07001729 int ret;
Jason Evans602c8e02014-08-18 16:22:13 -07001730
Jason Evansc4c25922017-01-15 16:56:30 -08001731 if (!config_prof) {
Jason Evansf4086432017-01-19 18:15:45 -08001732 return ENOENT;
Jason Evansc4c25922017-01-15 16:56:30 -08001733 }
Jason Evans602c8e02014-08-18 16:22:13 -07001734
Jason Evansfc12c0b2014-10-03 23:25:30 -07001735 READ_XOR_WRITE();
1736
Jason Evans602c8e02014-08-18 16:22:13 -07001737 if (newp != NULL) {
1738 if (newlen != sizeof(const char *)) {
1739 ret = EINVAL;
1740 goto label_return;
1741 }
Jason Evans5460aa62014-09-22 21:09:23 -07001742
Jason Evansfc12c0b2014-10-03 23:25:30 -07001743 if ((ret = prof_thread_name_set(tsd, *(const char **)newp)) !=
Jason Evansc4c25922017-01-15 16:56:30 -08001744 0) {
Jason Evans602c8e02014-08-18 16:22:13 -07001745 goto label_return;
Jason Evansc4c25922017-01-15 16:56:30 -08001746 }
Jason Evansfc12c0b2014-10-03 23:25:30 -07001747 } else {
Jason Evansb2c0d632016-04-13 23:36:15 -07001748 const char *oldname = prof_thread_name_get(tsd);
Jason Evansfc12c0b2014-10-03 23:25:30 -07001749 READ(oldname, const char *);
Jason Evans602c8e02014-08-18 16:22:13 -07001750 }
Jason Evans602c8e02014-08-18 16:22:13 -07001751
1752 ret = 0;
1753label_return:
Jason Evansf4086432017-01-19 18:15:45 -08001754 return ret;
Jason Evans602c8e02014-08-18 16:22:13 -07001755}
1756
1757static int
Jason Evansb2c0d632016-04-13 23:36:15 -07001758thread_prof_active_ctl(tsd_t *tsd, const size_t *mib, size_t miblen, void *oldp,
Jason Evansc4c25922017-01-15 16:56:30 -08001759 size_t *oldlenp, void *newp, size_t newlen) {
Jason Evans602c8e02014-08-18 16:22:13 -07001760 int ret;
1761 bool oldval;
1762
Jason Evansc4c25922017-01-15 16:56:30 -08001763 if (!config_prof) {
Jason Evansf4086432017-01-19 18:15:45 -08001764 return ENOENT;
Jason Evansc4c25922017-01-15 16:56:30 -08001765 }
Jason Evans602c8e02014-08-18 16:22:13 -07001766
Jason Evansb2c0d632016-04-13 23:36:15 -07001767 oldval = prof_thread_active_get(tsd);
Jason Evans602c8e02014-08-18 16:22:13 -07001768 if (newp != NULL) {
1769 if (newlen != sizeof(bool)) {
1770 ret = EINVAL;
1771 goto label_return;
1772 }
Jason Evansb2c0d632016-04-13 23:36:15 -07001773 if (prof_thread_active_set(tsd, *(bool *)newp)) {
Jason Evans602c8e02014-08-18 16:22:13 -07001774 ret = EAGAIN;
1775 goto label_return;
1776 }
1777 }
1778 READ(oldval, bool);
1779
1780 ret = 0;
1781label_return:
Jason Evansf4086432017-01-19 18:15:45 -08001782 return ret;
Jason Evans602c8e02014-08-18 16:22:13 -07001783}
1784
Jason Evans3c234352010-01-27 13:10:55 -08001785/******************************************************************************/
1786
Jason Evans1cb181e2015-01-29 15:30:47 -08001787static int
Jason Evansb2c0d632016-04-13 23:36:15 -07001788tcache_create_ctl(tsd_t *tsd, const size_t *mib, size_t miblen, void *oldp,
Jason Evansc4c25922017-01-15 16:56:30 -08001789 size_t *oldlenp, void *newp, size_t newlen) {
Jason Evans1cb181e2015-01-29 15:30:47 -08001790 int ret;
Jason Evans1cb181e2015-01-29 15:30:47 -08001791 unsigned tcache_ind;
1792
Jason Evans1cb181e2015-01-29 15:30:47 -08001793 READONLY();
Jason Evansb54d1602016-10-20 23:59:12 -07001794 if (tcaches_create(tsd, &tcache_ind)) {
Jason Evans1cb181e2015-01-29 15:30:47 -08001795 ret = EFAULT;
1796 goto label_return;
1797 }
1798 READ(tcache_ind, unsigned);
1799
1800 ret = 0;
1801label_return:
Jason Evansf4086432017-01-19 18:15:45 -08001802 return ret;
Jason Evans1cb181e2015-01-29 15:30:47 -08001803}
1804
1805static int
Jason Evansb2c0d632016-04-13 23:36:15 -07001806tcache_flush_ctl(tsd_t *tsd, const size_t *mib, size_t miblen, void *oldp,
Jason Evansc4c25922017-01-15 16:56:30 -08001807 size_t *oldlenp, void *newp, size_t newlen) {
Jason Evans1cb181e2015-01-29 15:30:47 -08001808 int ret;
Jason Evans1cb181e2015-01-29 15:30:47 -08001809 unsigned tcache_ind;
1810
Jason Evans1cb181e2015-01-29 15:30:47 -08001811 WRITEONLY();
1812 tcache_ind = UINT_MAX;
1813 WRITE(tcache_ind, unsigned);
1814 if (tcache_ind == UINT_MAX) {
1815 ret = EFAULT;
1816 goto label_return;
1817 }
1818 tcaches_flush(tsd, tcache_ind);
1819
1820 ret = 0;
1821label_return:
Jason Evansf4086432017-01-19 18:15:45 -08001822 return ret;
Jason Evans1cb181e2015-01-29 15:30:47 -08001823}
1824
1825static int
Jason Evansb2c0d632016-04-13 23:36:15 -07001826tcache_destroy_ctl(tsd_t *tsd, const size_t *mib, size_t miblen, void *oldp,
Jason Evansc4c25922017-01-15 16:56:30 -08001827 size_t *oldlenp, void *newp, size_t newlen) {
Jason Evans1cb181e2015-01-29 15:30:47 -08001828 int ret;
Jason Evans1cb181e2015-01-29 15:30:47 -08001829 unsigned tcache_ind;
1830
Jason Evans1cb181e2015-01-29 15:30:47 -08001831 WRITEONLY();
1832 tcache_ind = UINT_MAX;
1833 WRITE(tcache_ind, unsigned);
1834 if (tcache_ind == UINT_MAX) {
1835 ret = EFAULT;
1836 goto label_return;
1837 }
1838 tcaches_destroy(tsd, tcache_ind);
1839
1840 ret = 0;
1841label_return:
Jason Evansf4086432017-01-19 18:15:45 -08001842 return ret;
Jason Evans1cb181e2015-01-29 15:30:47 -08001843}
1844
1845/******************************************************************************/
1846
Jason Evansdc2125c2017-01-04 10:21:53 -08001847static int
1848arena_i_initialized_ctl(tsd_t *tsd, const size_t *mib, size_t miblen,
Jason Evansc4c25922017-01-15 16:56:30 -08001849 void *oldp, size_t *oldlenp, void *newp, size_t newlen) {
Jason Evansdc2125c2017-01-04 10:21:53 -08001850 int ret;
1851 tsdn_t *tsdn = tsd_tsdn(tsd);
1852 unsigned arena_ind;
1853 bool initialized;
1854
1855 READONLY();
1856 MIB_UNSIGNED(arena_ind, 1);
1857
1858 malloc_mutex_lock(tsdn, &ctl_mtx);
Jason Evans9eb1b1c2017-01-18 23:03:37 -08001859 initialized = arenas_i(arena_ind)->initialized;
Jason Evansdc2125c2017-01-04 10:21:53 -08001860 malloc_mutex_unlock(tsdn, &ctl_mtx);
1861
1862 READ(initialized, bool);
1863
1864 ret = 0;
1865label_return:
Jason Evansf4086432017-01-19 18:15:45 -08001866 return ret;
Jason Evansdc2125c2017-01-04 10:21:53 -08001867}
1868
Jason Evans34457f52012-11-03 21:18:28 -07001869static void
Jason Evans64e458f2017-03-08 22:42:57 -08001870arena_i_decay(tsdn_t *tsdn, unsigned arena_ind, bool all) {
Jason Evansc1e00ef2016-05-10 22:21:10 -07001871 malloc_mutex_lock(tsdn, &ctl_mtx);
Jason Evans243f7a02016-02-19 20:09:31 -08001872 {
Jason Evans9eb1b1c2017-01-18 23:03:37 -08001873 unsigned narenas = ctl_arenas->narenas;
Jason Evans609ae592012-10-11 13:53:15 -07001874
Jason Evans3dc4e832017-01-03 07:27:42 -08001875 /*
1876 * Access via index narenas is deprecated, and scheduled for
1877 * removal in 6.0.0.
1878 */
1879 if (arena_ind == MALLCTL_ARENAS_ALL || arena_ind == narenas) {
Jason Evans243f7a02016-02-19 20:09:31 -08001880 unsigned i;
Jason Evans243f7a02016-02-19 20:09:31 -08001881 VARIABLE_ARRAY(arena_t *, tarenas, narenas);
1882
Jason Evansc4c25922017-01-15 16:56:30 -08001883 for (i = 0; i < narenas; i++) {
Jason Evansc1e00ef2016-05-10 22:21:10 -07001884 tarenas[i] = arena_get(tsdn, i, false);
Jason Evansc4c25922017-01-15 16:56:30 -08001885 }
Jason Evans243f7a02016-02-19 20:09:31 -08001886
1887 /*
1888 * No further need to hold ctl_mtx, since narenas and
1889 * tarenas contain everything needed below.
1890 */
Jason Evansc1e00ef2016-05-10 22:21:10 -07001891 malloc_mutex_unlock(tsdn, &ctl_mtx);
Jason Evans243f7a02016-02-19 20:09:31 -08001892
1893 for (i = 0; i < narenas; i++) {
Jason Evansc4c25922017-01-15 16:56:30 -08001894 if (tarenas[i] != NULL) {
Qi Wangb693c782017-03-17 12:42:33 -07001895 arena_decay(tsdn, tarenas[i], false,
1896 all);
Jason Evansc4c25922017-01-15 16:56:30 -08001897 }
Jason Evans243f7a02016-02-19 20:09:31 -08001898 }
1899 } else {
1900 arena_t *tarena;
1901
1902 assert(arena_ind < narenas);
1903
Jason Evansc1e00ef2016-05-10 22:21:10 -07001904 tarena = arena_get(tsdn, arena_ind, false);
Jason Evans243f7a02016-02-19 20:09:31 -08001905
1906 /* No further need to hold ctl_mtx. */
Jason Evansc1e00ef2016-05-10 22:21:10 -07001907 malloc_mutex_unlock(tsdn, &ctl_mtx);
Jason Evans243f7a02016-02-19 20:09:31 -08001908
Jason Evansc4c25922017-01-15 16:56:30 -08001909 if (tarena != NULL) {
Qi Wangb693c782017-03-17 12:42:33 -07001910 arena_decay(tsdn, tarena, false, all);
Jason Evansc4c25922017-01-15 16:56:30 -08001911 }
Jason Evans609ae592012-10-11 13:53:15 -07001912 }
1913 }
Jason Evans609ae592012-10-11 13:53:15 -07001914}
1915
1916static int
Jason Evansb2c0d632016-04-13 23:36:15 -07001917arena_i_decay_ctl(tsd_t *tsd, const size_t *mib, size_t miblen, void *oldp,
Jason Evansc4c25922017-01-15 16:56:30 -08001918 size_t *oldlenp, void *newp, size_t newlen) {
Jason Evans243f7a02016-02-19 20:09:31 -08001919 int ret;
Jason Evans6edbedd2017-01-04 07:51:49 -08001920 unsigned arena_ind;
Jason Evans243f7a02016-02-19 20:09:31 -08001921
1922 READONLY();
1923 WRITEONLY();
Jason Evans6edbedd2017-01-04 07:51:49 -08001924 MIB_UNSIGNED(arena_ind, 1);
Jason Evans64e458f2017-03-08 22:42:57 -08001925 arena_i_decay(tsd_tsdn(tsd), arena_ind, false);
1926
1927 ret = 0;
1928label_return:
1929 return ret;
1930}
1931
1932static int
1933arena_i_purge_ctl(tsd_t *tsd, const size_t *mib, size_t miblen, void *oldp,
1934 size_t *oldlenp, void *newp, size_t newlen) {
1935 int ret;
1936 unsigned arena_ind;
1937
1938 READONLY();
1939 WRITEONLY();
1940 MIB_UNSIGNED(arena_ind, 1);
1941 arena_i_decay(tsd_tsdn(tsd), arena_ind, true);
Jason Evans609ae592012-10-11 13:53:15 -07001942
Jason Evans34457f52012-11-03 21:18:28 -07001943 ret = 0;
Jason Evans609ae592012-10-11 13:53:15 -07001944label_return:
Jason Evansf4086432017-01-19 18:15:45 -08001945 return ret;
Jason Evans609ae592012-10-11 13:53:15 -07001946}
1947
1948static int
Jason Evansedf1baf2017-01-03 17:21:59 -08001949arena_i_reset_destroy_helper(tsd_t *tsd, const size_t *mib, size_t miblen,
1950 void *oldp, size_t *oldlenp, void *newp, size_t newlen, unsigned *arena_ind,
Jason Evansc4c25922017-01-15 16:56:30 -08001951 arena_t **arena) {
Jason Evansedf1baf2017-01-03 17:21:59 -08001952 int ret;
1953
1954 READONLY();
1955 WRITEONLY();
1956 MIB_UNSIGNED(*arena_ind, 1);
1957
Jason Evansedf1baf2017-01-03 17:21:59 -08001958 *arena = arena_get(tsd_tsdn(tsd), *arena_ind, false);
Qi Wang5aa46f02017-04-20 15:19:02 -07001959 if (*arena == NULL || arena_is_auto(*arena)) {
Jason Evansedf1baf2017-01-03 17:21:59 -08001960 ret = EFAULT;
1961 goto label_return;
1962 }
1963
1964 ret = 0;
1965label_return:
Jason Evansf4086432017-01-19 18:15:45 -08001966 return ret;
Jason Evansedf1baf2017-01-03 17:21:59 -08001967}
1968
Qi Wangb693c782017-03-17 12:42:33 -07001969static void
1970arena_reset_prepare_background_thread(tsd_t *tsd, unsigned arena_ind) {
1971 /* Temporarily disable the background thread during arena reset. */
1972 if (have_background_thread) {
1973 malloc_mutex_lock(tsd_tsdn(tsd), &background_thread_lock);
1974 if (background_thread_enabled()) {
1975 unsigned ind = arena_ind % ncpus;
1976 background_thread_info_t *info =
1977 &background_thread_info[ind];
Qi Wang394df952017-06-09 15:45:25 -07001978 assert(info->state == background_thread_started);
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_paused;
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 }
1984}
1985
1986static void
1987arena_reset_finish_background_thread(tsd_t *tsd, unsigned arena_ind) {
1988 if (have_background_thread) {
1989 if (background_thread_enabled()) {
1990 unsigned ind = arena_ind % ncpus;
1991 background_thread_info_t *info =
1992 &background_thread_info[ind];
Jason Evansd49ac4c2017-06-23 10:40:02 -07001993 assert(info->state == background_thread_paused);
Qi Wang464cb602017-06-08 22:46:31 -07001994 malloc_mutex_lock(tsd_tsdn(tsd), &info->mtx);
Qi Wang394df952017-06-09 15:45:25 -07001995 info->state = background_thread_started;
Qi Wang464cb602017-06-08 22:46:31 -07001996 malloc_mutex_unlock(tsd_tsdn(tsd), &info->mtx);
Qi Wangb693c782017-03-17 12:42:33 -07001997 }
1998 malloc_mutex_unlock(tsd_tsdn(tsd), &background_thread_lock);
1999 }
2000}
2001
Jason Evansedf1baf2017-01-03 17:21:59 -08002002static int
Jason Evans19ff2ce2016-04-22 14:37:17 -07002003arena_i_reset_ctl(tsd_t *tsd, const size_t *mib, size_t miblen, void *oldp,
Jason Evansc4c25922017-01-15 16:56:30 -08002004 size_t *oldlenp, void *newp, size_t newlen) {
Jason Evans19ff2ce2016-04-22 14:37:17 -07002005 int ret;
2006 unsigned arena_ind;
2007 arena_t *arena;
2008
Jason Evansedf1baf2017-01-03 17:21:59 -08002009 ret = arena_i_reset_destroy_helper(tsd, mib, miblen, oldp, oldlenp,
2010 newp, newlen, &arena_ind, &arena);
Jason Evansc4c25922017-01-15 16:56:30 -08002011 if (ret != 0) {
Jason Evansf4086432017-01-19 18:15:45 -08002012 return ret;
Jason Evansc4c25922017-01-15 16:56:30 -08002013 }
Jason Evans19ff2ce2016-04-22 14:37:17 -07002014
Qi Wangb693c782017-03-17 12:42:33 -07002015 arena_reset_prepare_background_thread(tsd, arena_ind);
Jason Evansedf1baf2017-01-03 17:21:59 -08002016 arena_reset(tsd, arena);
Qi Wangb693c782017-03-17 12:42:33 -07002017 arena_reset_finish_background_thread(tsd, arena_ind);
Jason Evans19ff2ce2016-04-22 14:37:17 -07002018
Jason Evansf4086432017-01-19 18:15:45 -08002019 return ret;
Jason Evansedf1baf2017-01-03 17:21:59 -08002020}
2021
2022static int
2023arena_i_destroy_ctl(tsd_t *tsd, const size_t *mib, size_t miblen, void *oldp,
Jason Evansc4c25922017-01-15 16:56:30 -08002024 size_t *oldlenp, void *newp, size_t newlen) {
Jason Evansedf1baf2017-01-03 17:21:59 -08002025 int ret;
2026 unsigned arena_ind;
2027 arena_t *arena;
Jason Evans9eb1b1c2017-01-18 23:03:37 -08002028 ctl_arena_t *ctl_darena, *ctl_arena;
Jason Evansedf1baf2017-01-03 17:21:59 -08002029
2030 ret = arena_i_reset_destroy_helper(tsd, mib, miblen, oldp, oldlenp,
2031 newp, newlen, &arena_ind, &arena);
Jason Evansc4c25922017-01-15 16:56:30 -08002032 if (ret != 0) {
Jason Evansedf1baf2017-01-03 17:21:59 -08002033 goto label_return;
Jason Evansc4c25922017-01-15 16:56:30 -08002034 }
Jason Evansedf1baf2017-01-03 17:21:59 -08002035
2036 if (arena_nthreads_get(arena, false) != 0 || arena_nthreads_get(arena,
2037 true) != 0) {
Jason Evans3dc4e832017-01-03 07:27:42 -08002038 ret = EFAULT;
2039 goto label_return;
2040 }
Jason Evans19ff2ce2016-04-22 14:37:17 -07002041
Qi Wangb693c782017-03-17 12:42:33 -07002042 arena_reset_prepare_background_thread(tsd, arena_ind);
Jason Evansedf1baf2017-01-03 17:21:59 -08002043 /* Merge stats after resetting and purging arena. */
Jason Evans19ff2ce2016-04-22 14:37:17 -07002044 arena_reset(tsd, arena);
Qi Wangb693c782017-03-17 12:42:33 -07002045 arena_decay(tsd_tsdn(tsd), arena, false, true);
Jason Evans9eb1b1c2017-01-18 23:03:37 -08002046 ctl_darena = arenas_i(MALLCTL_ARENAS_DESTROYED);
2047 ctl_darena->initialized = true;
2048 ctl_arena_refresh(tsd_tsdn(tsd), arena, ctl_darena, arena_ind, true);
Jason Evansedf1baf2017-01-03 17:21:59 -08002049 /* Destroy arena. */
2050 arena_destroy(tsd, arena);
Jason Evans9eb1b1c2017-01-18 23:03:37 -08002051 ctl_arena = arenas_i(arena_ind);
2052 ctl_arena->initialized = false;
Jason Evansedf1baf2017-01-03 17:21:59 -08002053 /* Record arena index for later recycling via arenas.create. */
Jason Evans9eb1b1c2017-01-18 23:03:37 -08002054 ql_elm_new(ctl_arena, destroyed_link);
2055 ql_tail_insert(&ctl_arenas->destroyed, ctl_arena, destroyed_link);
Qi Wangb693c782017-03-17 12:42:33 -07002056 arena_reset_finish_background_thread(tsd, arena_ind);
Jason Evans19ff2ce2016-04-22 14:37:17 -07002057
Jason Evansedf1baf2017-01-03 17:21:59 -08002058 assert(ret == 0);
Jason Evans19ff2ce2016-04-22 14:37:17 -07002059label_return:
Jason Evansf4086432017-01-19 18:15:45 -08002060 return ret;
Jason Evans19ff2ce2016-04-22 14:37:17 -07002061}
2062
2063static int
Jason Evansb2c0d632016-04-13 23:36:15 -07002064arena_i_dss_ctl(tsd_t *tsd, const size_t *mib, size_t miblen, void *oldp,
Jason Evansc4c25922017-01-15 16:56:30 -08002065 size_t *oldlenp, void *newp, size_t newlen) {
Jason Evans586c8ed2014-08-15 12:20:20 -07002066 int ret;
2067 const char *dss = NULL;
Jason Evans6edbedd2017-01-04 07:51:49 -08002068 unsigned arena_ind;
Jason Evans609ae592012-10-11 13:53:15 -07002069 dss_prec_t dss_prec_old = dss_prec_limit;
2070 dss_prec_t dss_prec = dss_prec_limit;
2071
Jason Evansc1e00ef2016-05-10 22:21:10 -07002072 malloc_mutex_lock(tsd_tsdn(tsd), &ctl_mtx);
Jason Evans609ae592012-10-11 13:53:15 -07002073 WRITE(dss, const char *);
Jason Evans6edbedd2017-01-04 07:51:49 -08002074 MIB_UNSIGNED(arena_ind, 1);
Jason Evans586c8ed2014-08-15 12:20:20 -07002075 if (dss != NULL) {
2076 int i;
2077 bool match = false;
2078
2079 for (i = 0; i < dss_prec_limit; i++) {
2080 if (strcmp(dss_prec_names[i], dss) == 0) {
2081 dss_prec = i;
2082 match = true;
2083 break;
2084 }
Jason Evans609ae592012-10-11 13:53:15 -07002085 }
Jason Evans586c8ed2014-08-15 12:20:20 -07002086
Jason Evans551ebc42014-10-03 10:16:09 -07002087 if (!match) {
Jason Evans586c8ed2014-08-15 12:20:20 -07002088 ret = EINVAL;
2089 goto label_return;
2090 }
Jason Evans609ae592012-10-11 13:53:15 -07002091 }
2092
Jason Evans3dc4e832017-01-03 07:27:42 -08002093 /*
2094 * Access via index narenas is deprecated, and scheduled for removal in
2095 * 6.0.0.
2096 */
Jason Evansd778dd22017-01-03 12:40:54 -08002097 if (arena_ind == MALLCTL_ARENAS_ALL || arena_ind ==
Jason Evans9eb1b1c2017-01-18 23:03:37 -08002098 ctl_arenas->narenas) {
Jason Evans3dc4e832017-01-03 07:27:42 -08002099 if (dss_prec != dss_prec_limit &&
2100 extent_dss_prec_set(dss_prec)) {
2101 ret = EFAULT;
2102 goto label_return;
2103 }
2104 dss_prec_old = extent_dss_prec_get();
2105 } else {
Jason Evansc1e00ef2016-05-10 22:21:10 -07002106 arena_t *arena = arena_get(tsd_tsdn(tsd), arena_ind, false);
Jason Evans586c8ed2014-08-15 12:20:20 -07002107 if (arena == NULL || (dss_prec != dss_prec_limit &&
Jason Evansb7795222017-02-12 16:34:36 -08002108 arena_dss_prec_set(arena, dss_prec))) {
Jason Evans586c8ed2014-08-15 12:20:20 -07002109 ret = EFAULT;
2110 goto label_return;
2111 }
Jason Evansb7795222017-02-12 16:34:36 -08002112 dss_prec_old = arena_dss_prec_get(arena);
Jason Evans609ae592012-10-11 13:53:15 -07002113 }
Jason Evans586c8ed2014-08-15 12:20:20 -07002114
Jason Evans609ae592012-10-11 13:53:15 -07002115 dss = dss_prec_names[dss_prec_old];
2116 READ(dss, const char *);
Jason Evans609ae592012-10-11 13:53:15 -07002117
2118 ret = 0;
2119label_return:
Jason Evansc1e00ef2016-05-10 22:21:10 -07002120 malloc_mutex_unlock(tsd_tsdn(tsd), &ctl_mtx);
Jason Evansf4086432017-01-19 18:15:45 -08002121 return ret;
Jason Evans609ae592012-10-11 13:53:15 -07002122}
2123
aravindfb7fe502014-05-05 15:16:56 -07002124static int
Jason Evans6e62c622017-05-17 10:47:00 -07002125arena_i_decay_ms_ctl_impl(tsd_t *tsd, const size_t *mib, size_t miblen,
Jason Evans64e458f2017-03-08 22:42:57 -08002126 void *oldp, size_t *oldlenp, void *newp, size_t newlen, bool dirty) {
Jason Evans243f7a02016-02-19 20:09:31 -08002127 int ret;
Jason Evans6edbedd2017-01-04 07:51:49 -08002128 unsigned arena_ind;
Jason Evans243f7a02016-02-19 20:09:31 -08002129 arena_t *arena;
2130
Jason Evans6edbedd2017-01-04 07:51:49 -08002131 MIB_UNSIGNED(arena_ind, 1);
Jason Evansc1e00ef2016-05-10 22:21:10 -07002132 arena = arena_get(tsd_tsdn(tsd), arena_ind, false);
Jason Evans243f7a02016-02-19 20:09:31 -08002133 if (arena == NULL) {
2134 ret = EFAULT;
2135 goto label_return;
2136 }
2137
2138 if (oldp != NULL && oldlenp != NULL) {
Jason Evans6e62c622017-05-17 10:47:00 -07002139 size_t oldval = dirty ? arena_dirty_decay_ms_get(arena) :
2140 arena_muzzy_decay_ms_get(arena);
Jason Evans243f7a02016-02-19 20:09:31 -08002141 READ(oldval, ssize_t);
2142 }
2143 if (newp != NULL) {
2144 if (newlen != sizeof(ssize_t)) {
2145 ret = EINVAL;
2146 goto label_return;
2147 }
Jason Evans6e62c622017-05-17 10:47:00 -07002148 if (dirty ? arena_dirty_decay_ms_set(tsd_tsdn(tsd), arena,
2149 *(ssize_t *)newp) : arena_muzzy_decay_ms_set(tsd_tsdn(tsd),
2150 arena, *(ssize_t *)newp)) {
Jason Evans243f7a02016-02-19 20:09:31 -08002151 ret = EFAULT;
2152 goto label_return;
2153 }
2154 }
2155
2156 ret = 0;
2157label_return:
Jason Evansf4086432017-01-19 18:15:45 -08002158 return ret;
Jason Evans243f7a02016-02-19 20:09:31 -08002159}
2160
2161static int
Jason Evans6e62c622017-05-17 10:47:00 -07002162arena_i_dirty_decay_ms_ctl(tsd_t *tsd, const size_t *mib, size_t miblen,
Jason Evans64e458f2017-03-08 22:42:57 -08002163 void *oldp, size_t *oldlenp, void *newp, size_t newlen) {
Jason Evans6e62c622017-05-17 10:47:00 -07002164 return arena_i_decay_ms_ctl_impl(tsd, mib, miblen, oldp, oldlenp, newp,
2165 newlen, true);
Jason Evans64e458f2017-03-08 22:42:57 -08002166}
2167
2168static int
Jason Evans6e62c622017-05-17 10:47:00 -07002169arena_i_muzzy_decay_ms_ctl(tsd_t *tsd, const size_t *mib, size_t miblen,
Jason Evans64e458f2017-03-08 22:42:57 -08002170 void *oldp, size_t *oldlenp, void *newp, size_t newlen) {
Jason Evans6e62c622017-05-17 10:47:00 -07002171 return arena_i_decay_ms_ctl_impl(tsd, mib, miblen, oldp, oldlenp, newp,
2172 newlen, false);
Jason Evans64e458f2017-03-08 22:42:57 -08002173}
2174
2175static int
Jason Evans9c305c92016-05-31 15:03:51 -07002176arena_i_extent_hooks_ctl(tsd_t *tsd, const size_t *mib, size_t miblen,
Jason Evansc4c25922017-01-15 16:56:30 -08002177 void *oldp, size_t *oldlenp, void *newp, size_t newlen) {
Jason Evansb49a3342015-07-28 11:28:19 -04002178 int ret;
Jason Evans6edbedd2017-01-04 07:51:49 -08002179 unsigned arena_ind;
Jason Evansb49a3342015-07-28 11:28:19 -04002180 arena_t *arena;
2181
Jason Evansc1e00ef2016-05-10 22:21:10 -07002182 malloc_mutex_lock(tsd_tsdn(tsd), &ctl_mtx);
Jason Evans6edbedd2017-01-04 07:51:49 -08002183 MIB_UNSIGNED(arena_ind, 1);
Jason Evansb49a3342015-07-28 11:28:19 -04002184 if (arena_ind < narenas_total_get() && (arena =
Jason Evansc1e00ef2016-05-10 22:21:10 -07002185 arena_get(tsd_tsdn(tsd), arena_ind, false)) != NULL) {
Jason Evansb49a3342015-07-28 11:28:19 -04002186 if (newp != NULL) {
Jason Evansf02fec82016-06-03 19:39:14 -07002187 extent_hooks_t *old_extent_hooks;
2188 extent_hooks_t *new_extent_hooks
2189 JEMALLOC_CC_SILENCE_INIT(NULL);
Jason Evansf8f05422016-06-03 12:05:53 -07002190 WRITE(new_extent_hooks, extent_hooks_t *);
Qi Wang3a813942017-06-02 16:27:05 -07002191 old_extent_hooks = extent_hooks_set(tsd, arena,
Jason Evansf8f05422016-06-03 12:05:53 -07002192 new_extent_hooks);
2193 READ(old_extent_hooks, extent_hooks_t *);
Jason Evansb49a3342015-07-28 11:28:19 -04002194 } else {
Jason Evansf8f05422016-06-03 12:05:53 -07002195 extent_hooks_t *old_extent_hooks =
2196 extent_hooks_get(arena);
2197 READ(old_extent_hooks, extent_hooks_t *);
Jason Evansb49a3342015-07-28 11:28:19 -04002198 }
2199 } else {
2200 ret = EFAULT;
2201 goto label_return;
2202 }
2203 ret = 0;
2204label_return:
Jason Evansc1e00ef2016-05-10 22:21:10 -07002205 malloc_mutex_unlock(tsd_tsdn(tsd), &ctl_mtx);
Jason Evansf4086432017-01-19 18:15:45 -08002206 return ret;
aravindfb7fe502014-05-05 15:16:56 -07002207}
2208
Qi Wange422fa82017-11-02 17:48:39 -07002209static int
2210arena_i_retain_grow_limit_ctl(tsd_t *tsd, const size_t *mib, size_t miblen,
2211 void *oldp, size_t *oldlenp, void *newp, size_t newlen) {
2212 int ret;
2213 unsigned arena_ind;
2214 arena_t *arena;
2215
2216 if (!opt_retain) {
2217 /* Only relevant when retain is enabled. */
2218 return ENOENT;
2219 }
2220
2221 malloc_mutex_lock(tsd_tsdn(tsd), &ctl_mtx);
2222 MIB_UNSIGNED(arena_ind, 1);
2223 if (arena_ind < narenas_total_get() && (arena =
2224 arena_get(tsd_tsdn(tsd), arena_ind, false)) != NULL) {
2225 size_t old_limit, new_limit;
2226 if (newp != NULL) {
2227 WRITE(new_limit, size_t);
2228 }
2229 bool err = arena_retain_grow_limit_get_set(tsd, arena,
2230 &old_limit, newp != NULL ? &new_limit : NULL);
2231 if (!err) {
2232 READ(old_limit, size_t);
2233 ret = 0;
2234 } else {
2235 ret = EFAULT;
2236 }
2237 } else {
2238 ret = EFAULT;
2239 }
2240label_return:
2241 malloc_mutex_unlock(tsd_tsdn(tsd), &ctl_mtx);
2242 return ret;
2243}
2244
Jason Evans609ae592012-10-11 13:53:15 -07002245static const ctl_named_node_t *
Jason Evansc4c25922017-01-15 16:56:30 -08002246arena_i_index(tsdn_t *tsdn, const size_t *mib, size_t miblen, size_t i) {
Jason Evansb2c0d632016-04-13 23:36:15 -07002247 const ctl_named_node_t *ret;
Jason Evans609ae592012-10-11 13:53:15 -07002248
Jason Evansc1e00ef2016-05-10 22:21:10 -07002249 malloc_mutex_lock(tsdn, &ctl_mtx);
Jason Evansedf1baf2017-01-03 17:21:59 -08002250 switch (i) {
2251 case MALLCTL_ARENAS_ALL:
2252 case MALLCTL_ARENAS_DESTROYED:
2253 break;
2254 default:
Jason Evans9eb1b1c2017-01-18 23:03:37 -08002255 if (i > ctl_arenas->narenas) {
Jason Evansedf1baf2017-01-03 17:21:59 -08002256 ret = NULL;
2257 goto label_return;
2258 }
2259 break;
Jason Evans609ae592012-10-11 13:53:15 -07002260 }
2261
2262 ret = super_arena_i_node;
2263label_return:
Jason Evansc1e00ef2016-05-10 22:21:10 -07002264 malloc_mutex_unlock(tsdn, &ctl_mtx);
Jason Evansf4086432017-01-19 18:15:45 -08002265 return ret;
Jason Evans609ae592012-10-11 13:53:15 -07002266}
2267
Jason Evans609ae592012-10-11 13:53:15 -07002268/******************************************************************************/
2269
Jason Evans609ae592012-10-11 13:53:15 -07002270static int
Jason Evansb2c0d632016-04-13 23:36:15 -07002271arenas_narenas_ctl(tsd_t *tsd, const size_t *mib, size_t miblen, void *oldp,
Jason Evansc4c25922017-01-15 16:56:30 -08002272 size_t *oldlenp, void *newp, size_t newlen) {
Jason Evans609ae592012-10-11 13:53:15 -07002273 int ret;
2274 unsigned narenas;
2275
Jason Evansc1e00ef2016-05-10 22:21:10 -07002276 malloc_mutex_lock(tsd_tsdn(tsd), &ctl_mtx);
Jason Evans609ae592012-10-11 13:53:15 -07002277 READONLY();
2278 if (*oldlenp != sizeof(unsigned)) {
2279 ret = EINVAL;
2280 goto label_return;
2281 }
Jason Evans9eb1b1c2017-01-18 23:03:37 -08002282 narenas = ctl_arenas->narenas;
Jason Evans609ae592012-10-11 13:53:15 -07002283 READ(narenas, unsigned);
2284
2285 ret = 0;
2286label_return:
Jason Evansc1e00ef2016-05-10 22:21:10 -07002287 malloc_mutex_unlock(tsd_tsdn(tsd), &ctl_mtx);
Jason Evansf4086432017-01-19 18:15:45 -08002288 return ret;
Jason Evans609ae592012-10-11 13:53:15 -07002289}
Jason Evans3c234352010-01-27 13:10:55 -08002290
2291static int
Jason Evans6e62c622017-05-17 10:47:00 -07002292arenas_decay_ms_ctl_impl(tsd_t *tsd, const size_t *mib, size_t miblen,
Jason Evans64e458f2017-03-08 22:42:57 -08002293 void *oldp, size_t *oldlenp, void *newp, size_t newlen, bool dirty) {
Jason Evans243f7a02016-02-19 20:09:31 -08002294 int ret;
2295
2296 if (oldp != NULL && oldlenp != NULL) {
Jason Evans6e62c622017-05-17 10:47:00 -07002297 size_t oldval = (dirty ? arena_dirty_decay_ms_default_get() :
2298 arena_muzzy_decay_ms_default_get());
Jason Evans243f7a02016-02-19 20:09:31 -08002299 READ(oldval, ssize_t);
2300 }
2301 if (newp != NULL) {
2302 if (newlen != sizeof(ssize_t)) {
2303 ret = EINVAL;
2304 goto label_return;
2305 }
Qi Wange422fa82017-11-02 17:48:39 -07002306 if (dirty ? arena_dirty_decay_ms_default_set(*(ssize_t *)newp)
Jason Evans6e62c622017-05-17 10:47:00 -07002307 : arena_muzzy_decay_ms_default_set(*(ssize_t *)newp)) {
Jason Evans243f7a02016-02-19 20:09:31 -08002308 ret = EFAULT;
2309 goto label_return;
2310 }
2311 }
2312
2313 ret = 0;
2314label_return:
Jason Evansf4086432017-01-19 18:15:45 -08002315 return ret;
Jason Evans243f7a02016-02-19 20:09:31 -08002316}
2317
Jason Evans64e458f2017-03-08 22:42:57 -08002318static int
Jason Evans6e62c622017-05-17 10:47:00 -07002319arenas_dirty_decay_ms_ctl(tsd_t *tsd, const size_t *mib, size_t miblen,
Jason Evans64e458f2017-03-08 22:42:57 -08002320 void *oldp, size_t *oldlenp, void *newp, size_t newlen) {
Jason Evans6e62c622017-05-17 10:47:00 -07002321 return arenas_decay_ms_ctl_impl(tsd, mib, miblen, oldp, oldlenp, newp,
Jason Evans64e458f2017-03-08 22:42:57 -08002322 newlen, true);
2323}
2324
2325static int
Jason Evans6e62c622017-05-17 10:47:00 -07002326arenas_muzzy_decay_ms_ctl(tsd_t *tsd, const size_t *mib, size_t miblen,
Jason Evans64e458f2017-03-08 22:42:57 -08002327 void *oldp, size_t *oldlenp, void *newp, size_t newlen) {
Jason Evans6e62c622017-05-17 10:47:00 -07002328 return arenas_decay_ms_ctl_impl(tsd, mib, miblen, oldp, oldlenp, newp,
Jason Evans64e458f2017-03-08 22:42:57 -08002329 newlen, false);
2330}
2331
Jason Evansfc4dcfa2010-11-24 15:44:21 -08002332CTL_RO_NL_GEN(arenas_quantum, QUANTUM, size_t)
Jason Evansae4c7b42012-04-02 07:04:34 -07002333CTL_RO_NL_GEN(arenas_page, PAGE, size_t)
Jason Evans4403c9a2017-04-20 17:21:37 -07002334CTL_RO_NL_GEN(arenas_tcache_max, tcache_maxclass, size_t)
Jason Evansb1726102012-02-28 16:50:47 -08002335CTL_RO_NL_GEN(arenas_nbins, NBINS, unsigned)
Jason Evans4403c9a2017-04-20 17:21:37 -07002336CTL_RO_NL_GEN(arenas_nhbins, nhbins, unsigned)
David T. Goldblatt4bf4a1c2017-10-01 17:22:06 -07002337CTL_RO_NL_GEN(arenas_bin_i_size, bin_infos[mib[2]].reg_size, size_t)
2338CTL_RO_NL_GEN(arenas_bin_i_nregs, bin_infos[mib[2]].nregs, uint32_t)
2339CTL_RO_NL_GEN(arenas_bin_i_slab_size, bin_infos[mib[2]].slab_size, size_t)
Jason Evansd8a39002013-12-19 21:40:41 -08002340static const ctl_named_node_t *
Jason Evansc4c25922017-01-15 16:56:30 -08002341arenas_bin_i_index(tsdn_t *tsdn, const size_t *mib, size_t miblen, size_t i) {
2342 if (i > NBINS) {
Jason Evansf4086432017-01-19 18:15:45 -08002343 return NULL;
Jason Evansc4c25922017-01-15 16:56:30 -08002344 }
Jason Evansf4086432017-01-19 18:15:45 -08002345 return super_arenas_bin_i_node;
Jason Evansd8a39002013-12-19 21:40:41 -08002346}
2347
Jason Evans7d63fed2016-05-31 14:50:21 -07002348CTL_RO_NL_GEN(arenas_nlextents, NSIZES - NBINS, unsigned)
David Goldblatt8261e582017-05-30 10:45:37 -07002349CTL_RO_NL_GEN(arenas_lextent_i_size, sz_index2size(NBINS+(szind_t)mib[2]),
2350 size_t)
Jason Evans3c4d92e2014-10-12 22:53:59 -07002351static const ctl_named_node_t *
Jason Evansc4c25922017-01-15 16:56:30 -08002352arenas_lextent_i_index(tsdn_t *tsdn, const size_t *mib, size_t miblen,
2353 size_t i) {
2354 if (i > NSIZES - NBINS) {
Jason Evansf4086432017-01-19 18:15:45 -08002355 return NULL;
Jason Evansc4c25922017-01-15 16:56:30 -08002356 }
Jason Evansf4086432017-01-19 18:15:45 -08002357 return super_arenas_lextent_i_node;
Jason Evans3c4d92e2014-10-12 22:53:59 -07002358}
2359
Jason Evans6005f072010-09-30 16:55:08 -07002360static int
Jason Evans0f04bb12017-01-03 08:21:29 -08002361arenas_create_ctl(tsd_t *tsd, const size_t *mib, size_t miblen, void *oldp,
Jason Evansc4c25922017-01-15 16:56:30 -08002362 size_t *oldlenp, void *newp, size_t newlen) {
Jason Evans609ae592012-10-11 13:53:15 -07002363 int ret;
Jason Evansa0dd3a42016-12-22 16:39:10 -06002364 extent_hooks_t *extent_hooks;
Jason Evansedf1baf2017-01-03 17:21:59 -08002365 unsigned arena_ind;
Jason Evans609ae592012-10-11 13:53:15 -07002366
Jason Evansc1e00ef2016-05-10 22:21:10 -07002367 malloc_mutex_lock(tsd_tsdn(tsd), &ctl_mtx);
Jason Evansa0dd3a42016-12-22 16:39:10 -06002368
2369 extent_hooks = (extent_hooks_t *)&extent_hooks_default;
2370 WRITE(extent_hooks, extent_hooks_t *);
Qi Wang57beeb22017-06-22 18:58:40 -07002371 if ((arena_ind = ctl_arena_init(tsd, extent_hooks)) == UINT_MAX) {
Jason Evans609ae592012-10-11 13:53:15 -07002372 ret = EAGAIN;
2373 goto label_return;
2374 }
Jason Evansedf1baf2017-01-03 17:21:59 -08002375 READ(arena_ind, unsigned);
Jason Evans609ae592012-10-11 13:53:15 -07002376
Jason Evans6005f072010-09-30 16:55:08 -07002377 ret = 0;
Jason Evansa1ee7832012-04-10 15:07:44 -07002378label_return:
Jason Evansc1e00ef2016-05-10 22:21:10 -07002379 malloc_mutex_unlock(tsd_tsdn(tsd), &ctl_mtx);
Jason Evansf4086432017-01-19 18:15:45 -08002380 return ret;
Jason Evans6005f072010-09-30 16:55:08 -07002381}
2382
Jason Evans3c234352010-01-27 13:10:55 -08002383/******************************************************************************/
2384
Jason Evansd34f9e72010-02-11 13:19:21 -08002385static int
Jason Evansb2c0d632016-04-13 23:36:15 -07002386prof_thread_active_init_ctl(tsd_t *tsd, const size_t *mib, size_t miblen,
Jason Evansc4c25922017-01-15 16:56:30 -08002387 void *oldp, size_t *oldlenp, void *newp, size_t newlen) {
Jason Evansb2c0d632016-04-13 23:36:15 -07002388 int ret;
2389 bool oldval;
2390
Jason Evansc4c25922017-01-15 16:56:30 -08002391 if (!config_prof) {
Jason Evansf4086432017-01-19 18:15:45 -08002392 return ENOENT;
Jason Evansc4c25922017-01-15 16:56:30 -08002393 }
Jason Evansb2c0d632016-04-13 23:36:15 -07002394
2395 if (newp != NULL) {
2396 if (newlen != sizeof(bool)) {
2397 ret = EINVAL;
2398 goto label_return;
2399 }
Jason Evansc1e00ef2016-05-10 22:21:10 -07002400 oldval = prof_thread_active_init_set(tsd_tsdn(tsd),
2401 *(bool *)newp);
Jason Evansc4c25922017-01-15 16:56:30 -08002402 } else {
Jason Evansc1e00ef2016-05-10 22:21:10 -07002403 oldval = prof_thread_active_init_get(tsd_tsdn(tsd));
Jason Evansc4c25922017-01-15 16:56:30 -08002404 }
Jason Evansb2c0d632016-04-13 23:36:15 -07002405 READ(oldval, bool);
2406
2407 ret = 0;
2408label_return:
Jason Evansf4086432017-01-19 18:15:45 -08002409 return ret;
Jason Evansb2c0d632016-04-13 23:36:15 -07002410}
2411
2412static int
2413prof_active_ctl(tsd_t *tsd, const size_t *mib, size_t miblen, void *oldp,
Jason Evansc4c25922017-01-15 16:56:30 -08002414 size_t *oldlenp, void *newp, size_t newlen) {
Jason Evansfc12c0b2014-10-03 23:25:30 -07002415 int ret;
2416 bool oldval;
2417
Jason Evansc4c25922017-01-15 16:56:30 -08002418 if (!config_prof) {
Jason Evansf4086432017-01-19 18:15:45 -08002419 return ENOENT;
Jason Evansc4c25922017-01-15 16:56:30 -08002420 }
Jason Evansfc12c0b2014-10-03 23:25:30 -07002421
2422 if (newp != NULL) {
2423 if (newlen != sizeof(bool)) {
2424 ret = EINVAL;
2425 goto label_return;
2426 }
Jason Evansc1e00ef2016-05-10 22:21:10 -07002427 oldval = prof_active_set(tsd_tsdn(tsd), *(bool *)newp);
Jason Evansc4c25922017-01-15 16:56:30 -08002428 } else {
Jason Evansc1e00ef2016-05-10 22:21:10 -07002429 oldval = prof_active_get(tsd_tsdn(tsd));
Jason Evansc4c25922017-01-15 16:56:30 -08002430 }
Jason Evansfc12c0b2014-10-03 23:25:30 -07002431 READ(oldval, bool);
2432
2433 ret = 0;
2434label_return:
Jason Evansf4086432017-01-19 18:15:45 -08002435 return ret;
Jason Evansfc12c0b2014-10-03 23:25:30 -07002436}
2437
2438static int
Jason Evansb2c0d632016-04-13 23:36:15 -07002439prof_dump_ctl(tsd_t *tsd, const size_t *mib, size_t miblen, void *oldp,
Jason Evansc4c25922017-01-15 16:56:30 -08002440 size_t *oldlenp, void *newp, size_t newlen) {
Jason Evansd34f9e72010-02-11 13:19:21 -08002441 int ret;
Jason Evans22ca8552010-03-02 11:57:30 -08002442 const char *filename = NULL;
Jason Evansd34f9e72010-02-11 13:19:21 -08002443
Jason Evansc4c25922017-01-15 16:56:30 -08002444 if (!config_prof) {
Jason Evansf4086432017-01-19 18:15:45 -08002445 return ENOENT;
Jason Evansc4c25922017-01-15 16:56:30 -08002446 }
Jason Evans7372b152012-02-10 20:22:09 -08002447
Jason Evans22ca8552010-03-02 11:57:30 -08002448 WRITEONLY();
2449 WRITE(filename, const char *);
Jason Evansd34f9e72010-02-11 13:19:21 -08002450
Jason Evansb2c0d632016-04-13 23:36:15 -07002451 if (prof_mdump(tsd, filename)) {
Jason Evans22ca8552010-03-02 11:57:30 -08002452 ret = EFAULT;
Jason Evansa1ee7832012-04-10 15:07:44 -07002453 goto label_return;
Jason Evans22ca8552010-03-02 11:57:30 -08002454 }
Jason Evansd34f9e72010-02-11 13:19:21 -08002455
2456 ret = 0;
Jason Evansa1ee7832012-04-10 15:07:44 -07002457label_return:
Jason Evansf4086432017-01-19 18:15:45 -08002458 return ret;
Jason Evansd34f9e72010-02-11 13:19:21 -08002459}
2460
Jason Evans602c8e02014-08-18 16:22:13 -07002461static int
Jason Evansb2c0d632016-04-13 23:36:15 -07002462prof_gdump_ctl(tsd_t *tsd, const size_t *mib, size_t miblen, void *oldp,
Jason Evansc4c25922017-01-15 16:56:30 -08002463 size_t *oldlenp, void *newp, size_t newlen) {
Jason Evans5b8ed5b2015-01-25 21:16:57 -08002464 int ret;
2465 bool oldval;
2466
Jason Evansc4c25922017-01-15 16:56:30 -08002467 if (!config_prof) {
Jason Evansf4086432017-01-19 18:15:45 -08002468 return ENOENT;
Jason Evansc4c25922017-01-15 16:56:30 -08002469 }
Jason Evans5b8ed5b2015-01-25 21:16:57 -08002470
2471 if (newp != NULL) {
2472 if (newlen != sizeof(bool)) {
2473 ret = EINVAL;
2474 goto label_return;
2475 }
Jason Evansc1e00ef2016-05-10 22:21:10 -07002476 oldval = prof_gdump_set(tsd_tsdn(tsd), *(bool *)newp);
Jason Evansc4c25922017-01-15 16:56:30 -08002477 } else {
Jason Evansc1e00ef2016-05-10 22:21:10 -07002478 oldval = prof_gdump_get(tsd_tsdn(tsd));
Jason Evansc4c25922017-01-15 16:56:30 -08002479 }
Jason Evans5b8ed5b2015-01-25 21:16:57 -08002480 READ(oldval, bool);
2481
2482 ret = 0;
2483label_return:
Jason Evansf4086432017-01-19 18:15:45 -08002484 return ret;
Jason Evans5b8ed5b2015-01-25 21:16:57 -08002485}
2486
2487static int
Jason Evansb2c0d632016-04-13 23:36:15 -07002488prof_reset_ctl(tsd_t *tsd, const size_t *mib, size_t miblen, void *oldp,
Jason Evansc4c25922017-01-15 16:56:30 -08002489 size_t *oldlenp, void *newp, size_t newlen) {
Jason Evans602c8e02014-08-18 16:22:13 -07002490 int ret;
2491 size_t lg_sample = lg_prof_sample;
2492
Jason Evansc4c25922017-01-15 16:56:30 -08002493 if (!config_prof) {
Jason Evansf4086432017-01-19 18:15:45 -08002494 return ENOENT;
Jason Evansc4c25922017-01-15 16:56:30 -08002495 }
Jason Evans602c8e02014-08-18 16:22:13 -07002496
2497 WRITEONLY();
2498 WRITE(lg_sample, size_t);
Jason Evansc4c25922017-01-15 16:56:30 -08002499 if (lg_sample >= (sizeof(uint64_t) << 3)) {
Jason Evans602c8e02014-08-18 16:22:13 -07002500 lg_sample = (sizeof(uint64_t) << 3) - 1;
Jason Evansc4c25922017-01-15 16:56:30 -08002501 }
Jason Evans602c8e02014-08-18 16:22:13 -07002502
Jason Evansb54d1602016-10-20 23:59:12 -07002503 prof_reset(tsd, lg_sample);
Jason Evans602c8e02014-08-18 16:22:13 -07002504
2505 ret = 0;
2506label_return:
Jason Evansf4086432017-01-19 18:15:45 -08002507 return ret;
Jason Evans602c8e02014-08-18 16:22:13 -07002508}
2509
Jason Evans7372b152012-02-10 20:22:09 -08002510CTL_RO_NL_CGEN(config_prof, prof_interval, prof_interval, uint64_t)
Jason Evans602c8e02014-08-18 16:22:13 -07002511CTL_RO_NL_CGEN(config_prof, lg_prof_sample, lg_prof_sample, size_t)
Jason Evansd34f9e72010-02-11 13:19:21 -08002512
2513/******************************************************************************/
2514
Jason Evansd778dd22017-01-03 12:40:54 -08002515CTL_RO_CGEN(config_stats, stats_allocated, ctl_stats->allocated, size_t)
2516CTL_RO_CGEN(config_stats, stats_active, ctl_stats->active, size_t)
2517CTL_RO_CGEN(config_stats, stats_metadata, ctl_stats->metadata, size_t)
Qi Wange55c3ca2017-08-25 13:24:49 -07002518CTL_RO_CGEN(config_stats, stats_metadata_thp, ctl_stats->metadata_thp, size_t)
Jason Evansd778dd22017-01-03 12:40:54 -08002519CTL_RO_CGEN(config_stats, stats_resident, ctl_stats->resident, size_t)
2520CTL_RO_CGEN(config_stats, stats_mapped, ctl_stats->mapped, size_t)
2521CTL_RO_CGEN(config_stats, stats_retained, ctl_stats->retained, size_t)
Jason Evansd8a39002013-12-19 21:40:41 -08002522
Qi Wang2bee0c62017-05-12 12:30:33 -07002523CTL_RO_CGEN(config_stats, stats_background_thread_num_threads,
2524 ctl_stats->background_thread.num_threads, size_t)
2525CTL_RO_CGEN(config_stats, stats_background_thread_num_runs,
2526 ctl_stats->background_thread.num_runs, uint64_t)
2527CTL_RO_CGEN(config_stats, stats_background_thread_run_interval,
2528 nstime_ns(&ctl_stats->background_thread.run_interval), uint64_t)
2529
Jason Evans9eb1b1c2017-01-18 23:03:37 -08002530CTL_RO_GEN(stats_arenas_i_dss, arenas_i(mib[2])->dss, const char *)
Jason Evans6e62c622017-05-17 10:47:00 -07002531CTL_RO_GEN(stats_arenas_i_dirty_decay_ms, arenas_i(mib[2])->dirty_decay_ms,
Jason Evans64e458f2017-03-08 22:42:57 -08002532 ssize_t)
Jason Evans6e62c622017-05-17 10:47:00 -07002533CTL_RO_GEN(stats_arenas_i_muzzy_decay_ms, arenas_i(mib[2])->muzzy_decay_ms,
Jason Evans243f7a02016-02-19 20:09:31 -08002534 ssize_t)
Jason Evans9eb1b1c2017-01-18 23:03:37 -08002535CTL_RO_GEN(stats_arenas_i_nthreads, arenas_i(mib[2])->nthreads, unsigned)
Qi Wangbaf3e292017-05-16 13:56:00 -07002536CTL_RO_GEN(stats_arenas_i_uptime,
2537 nstime_ns(&arenas_i(mib[2])->astats->astats.uptime), uint64_t)
Jason Evans9eb1b1c2017-01-18 23:03:37 -08002538CTL_RO_GEN(stats_arenas_i_pactive, arenas_i(mib[2])->pactive, size_t)
2539CTL_RO_GEN(stats_arenas_i_pdirty, arenas_i(mib[2])->pdirty, size_t)
Jason Evans64e458f2017-03-08 22:42:57 -08002540CTL_RO_GEN(stats_arenas_i_pmuzzy, arenas_i(mib[2])->pmuzzy, size_t)
Jason Evansd8a39002013-12-19 21:40:41 -08002541CTL_RO_CGEN(config_stats, stats_arenas_i_mapped,
David Goldblattee202ef2017-03-13 16:18:40 -07002542 atomic_load_zu(&arenas_i(mib[2])->astats->astats.mapped, ATOMIC_RELAXED),
2543 size_t)
Jason Evans04c3c0f2016-05-03 22:11:35 -07002544CTL_RO_CGEN(config_stats, stats_arenas_i_retained,
David Goldblattee202ef2017-03-13 16:18:40 -07002545 atomic_load_zu(&arenas_i(mib[2])->astats->astats.retained, ATOMIC_RELAXED),
2546 size_t)
Jason Evans64e458f2017-03-08 22:42:57 -08002547
2548CTL_RO_CGEN(config_stats, stats_arenas_i_dirty_npurge,
David T. Goldblatt7f1b02e2017-11-04 12:50:19 -07002549 ctl_arena_stats_read_u64(
2550 &arenas_i(mib[2])->astats->astats.decay_dirty.npurge), uint64_t)
Jason Evans64e458f2017-03-08 22:42:57 -08002551CTL_RO_CGEN(config_stats, stats_arenas_i_dirty_nmadvise,
David T. Goldblatt7f1b02e2017-11-04 12:50:19 -07002552 ctl_arena_stats_read_u64(
Jason Evans64e458f2017-03-08 22:42:57 -08002553 &arenas_i(mib[2])->astats->astats.decay_dirty.nmadvise), uint64_t)
2554CTL_RO_CGEN(config_stats, stats_arenas_i_dirty_purged,
David T. Goldblatt7f1b02e2017-11-04 12:50:19 -07002555 ctl_arena_stats_read_u64(
2556 &arenas_i(mib[2])->astats->astats.decay_dirty.purged), uint64_t)
Jason Evans64e458f2017-03-08 22:42:57 -08002557
2558CTL_RO_CGEN(config_stats, stats_arenas_i_muzzy_npurge,
David T. Goldblatt7f1b02e2017-11-04 12:50:19 -07002559 ctl_arena_stats_read_u64(
2560 &arenas_i(mib[2])->astats->astats.decay_muzzy.npurge), uint64_t)
Jason Evans64e458f2017-03-08 22:42:57 -08002561CTL_RO_CGEN(config_stats, stats_arenas_i_muzzy_nmadvise,
David T. Goldblatt7f1b02e2017-11-04 12:50:19 -07002562 ctl_arena_stats_read_u64(
Jason Evans64e458f2017-03-08 22:42:57 -08002563 &arenas_i(mib[2])->astats->astats.decay_muzzy.nmadvise), uint64_t)
2564CTL_RO_CGEN(config_stats, stats_arenas_i_muzzy_purged,
David T. Goldblatt7f1b02e2017-11-04 12:50:19 -07002565 ctl_arena_stats_read_u64(
2566 &arenas_i(mib[2])->astats->astats.decay_muzzy.purged), uint64_t)
Jason Evans64e458f2017-03-08 22:42:57 -08002567
Jason Evansa0dd3a42016-12-22 16:39:10 -06002568CTL_RO_CGEN(config_stats, stats_arenas_i_base,
David Goldblattee202ef2017-03-13 16:18:40 -07002569 atomic_load_zu(&arenas_i(mib[2])->astats->astats.base, ATOMIC_RELAXED),
2570 size_t)
Jason Evansa0dd3a42016-12-22 16:39:10 -06002571CTL_RO_CGEN(config_stats, stats_arenas_i_internal,
David Goldblattee202ef2017-03-13 16:18:40 -07002572 atomic_load_zu(&arenas_i(mib[2])->astats->astats.internal, ATOMIC_RELAXED),
2573 size_t)
Qi Wange55c3ca2017-08-25 13:24:49 -07002574CTL_RO_CGEN(config_stats, stats_arenas_i_metadata_thp,
2575 atomic_load_zu(&arenas_i(mib[2])->astats->astats.metadata_thp,
2576 ATOMIC_RELAXED), size_t)
Jason Evans4403c9a2017-04-20 17:21:37 -07002577CTL_RO_CGEN(config_stats, stats_arenas_i_tcache_bytes,
David Goldblattee202ef2017-03-13 16:18:40 -07002578 atomic_load_zu(&arenas_i(mib[2])->astats->astats.tcache_bytes,
2579 ATOMIC_RELAXED), size_t)
Jason Evansa0dd3a42016-12-22 16:39:10 -06002580CTL_RO_CGEN(config_stats, stats_arenas_i_resident,
David Goldblattee202ef2017-03-13 16:18:40 -07002581 atomic_load_zu(&arenas_i(mib[2])->astats->astats.resident, ATOMIC_RELAXED),
2582 size_t)
Jason Evansd8a39002013-12-19 21:40:41 -08002583
Jason Evans7372b152012-02-10 20:22:09 -08002584CTL_RO_CGEN(config_stats, stats_arenas_i_small_allocated,
Jason Evans9eb1b1c2017-01-18 23:03:37 -08002585 arenas_i(mib[2])->astats->allocated_small, size_t)
Jason Evans7372b152012-02-10 20:22:09 -08002586CTL_RO_CGEN(config_stats, stats_arenas_i_small_nmalloc,
Jason Evans9eb1b1c2017-01-18 23:03:37 -08002587 arenas_i(mib[2])->astats->nmalloc_small, uint64_t)
Jason Evans7372b152012-02-10 20:22:09 -08002588CTL_RO_CGEN(config_stats, stats_arenas_i_small_ndalloc,
Jason Evans9eb1b1c2017-01-18 23:03:37 -08002589 arenas_i(mib[2])->astats->ndalloc_small, uint64_t)
Jason Evans7372b152012-02-10 20:22:09 -08002590CTL_RO_CGEN(config_stats, stats_arenas_i_small_nrequests,
Jason Evans9eb1b1c2017-01-18 23:03:37 -08002591 arenas_i(mib[2])->astats->nrequests_small, uint64_t)
Jason Evans7d63fed2016-05-31 14:50:21 -07002592CTL_RO_CGEN(config_stats, stats_arenas_i_large_allocated,
David Goldblattee202ef2017-03-13 16:18:40 -07002593 atomic_load_zu(&arenas_i(mib[2])->astats->astats.allocated_large,
2594 ATOMIC_RELAXED), size_t)
Jason Evans7d63fed2016-05-31 14:50:21 -07002595CTL_RO_CGEN(config_stats, stats_arenas_i_large_nmalloc,
David T. Goldblatt7f1b02e2017-11-04 12:50:19 -07002596 ctl_arena_stats_read_u64(
2597 &arenas_i(mib[2])->astats->astats.nmalloc_large), uint64_t)
Jason Evans7d63fed2016-05-31 14:50:21 -07002598CTL_RO_CGEN(config_stats, stats_arenas_i_large_ndalloc,
David T. Goldblatt7f1b02e2017-11-04 12:50:19 -07002599 ctl_arena_stats_read_u64(
2600 &arenas_i(mib[2])->astats->astats.ndalloc_large), uint64_t)
2601/*
2602 * Note: "nmalloc" here instead of "nrequests" in the read. This is intentional.
2603 */
Jason Evans7d63fed2016-05-31 14:50:21 -07002604CTL_RO_CGEN(config_stats, stats_arenas_i_large_nrequests,
David T. Goldblatt7f1b02e2017-11-04 12:50:19 -07002605 ctl_arena_stats_read_u64(
2606 &arenas_i(mib[2])->astats->astats.nmalloc_large), uint64_t) /* Intentional. */
Jason Evans3c234352010-01-27 13:10:55 -08002607
Qi Wang0fb5c0e2017-03-10 12:14:05 -08002608/* Lock profiling related APIs below. */
Qi Wang64c5f5c2017-03-13 17:29:03 -07002609#define RO_MUTEX_CTL_GEN(n, l) \
Qi Wangca9074d2017-03-11 20:28:31 -08002610CTL_RO_CGEN(config_stats, stats_##n##_num_ops, \
2611 l.n_lock_ops, uint64_t) \
2612CTL_RO_CGEN(config_stats, stats_##n##_num_wait, \
2613 l.n_wait_times, uint64_t) \
2614CTL_RO_CGEN(config_stats, stats_##n##_num_spin_acq, \
2615 l.n_spin_acquired, uint64_t) \
2616CTL_RO_CGEN(config_stats, stats_##n##_num_owner_switch, \
2617 l.n_owner_switches, uint64_t) \
2618CTL_RO_CGEN(config_stats, stats_##n##_total_wait_time, \
Qi Wangf6698ec2017-03-17 17:42:10 -07002619 nstime_ns(&l.tot_wait_time), uint64_t) \
Qi Wangca9074d2017-03-11 20:28:31 -08002620CTL_RO_CGEN(config_stats, stats_##n##_max_wait_time, \
Qi Wangf6698ec2017-03-17 17:42:10 -07002621 nstime_ns(&l.max_wait_time), uint64_t) \
Qi Wangca9074d2017-03-11 20:28:31 -08002622CTL_RO_CGEN(config_stats, stats_##n##_max_num_thds, \
Qi Wangd3fde1c2017-03-21 11:56:38 -07002623 l.max_n_thds, uint32_t)
Qi Wang0fb5c0e2017-03-10 12:14:05 -08002624
Qi Wang64c5f5c2017-03-13 17:29:03 -07002625/* Global mutexes. */
Qi Wangd3fde1c2017-03-21 11:56:38 -07002626#define OP(mtx) \
2627 RO_MUTEX_CTL_GEN(mutexes_##mtx, \
2628 ctl_stats->mutex_prof_data[global_prof_mutex_##mtx])
David Goldblatt89e2d3c2017-04-24 17:09:56 -07002629MUTEX_PROF_GLOBAL_MUTEXES
Qi Wangd3fde1c2017-03-21 11:56:38 -07002630#undef OP
2631
2632/* Per arena mutexes */
2633#define OP(mtx) RO_MUTEX_CTL_GEN(arenas_i_mutexes_##mtx, \
2634 arenas_i(mib[2])->astats->astats.mutex_prof_data[arena_prof_mutex_##mtx])
David Goldblatt89e2d3c2017-04-24 17:09:56 -07002635MUTEX_PROF_ARENA_MUTEXES
Qi Wangd3fde1c2017-03-21 11:56:38 -07002636#undef OP
Qi Wangca9074d2017-03-11 20:28:31 -08002637
Qi Wang20b8c702017-03-15 14:00:57 -07002638/* tcache bin mutex */
Qi Wang64c5f5c2017-03-13 17:29:03 -07002639RO_MUTEX_CTL_GEN(arenas_i_bins_j_mutex,
2640 arenas_i(mib[2])->astats->bstats[mib[4]].mutex_data)
Qi Wang64c5f5c2017-03-13 17:29:03 -07002641#undef RO_MUTEX_CTL_GEN
2642
2643/* Resets all mutex stats, including global, arena and bin mutexes. */
2644static int
2645stats_mutexes_reset_ctl(tsd_t *tsd, const size_t *mib, size_t miblen,
2646 void *oldp, size_t *oldlenp, void *newp, size_t newlen) {
2647 if (!config_stats) {
2648 return ENOENT;
2649 }
2650
2651 tsdn_t *tsdn = tsd_tsdn(tsd);
2652
2653#define MUTEX_PROF_RESET(mtx) \
2654 malloc_mutex_lock(tsdn, &mtx); \
2655 malloc_mutex_prof_data_reset(tsdn, &mtx); \
2656 malloc_mutex_unlock(tsdn, &mtx);
2657
Qi Wang362e3562017-03-22 01:49:56 -07002658 /* Global mutexes: ctl and prof. */
2659 MUTEX_PROF_RESET(ctl_mtx);
Qi Wang5f5ed212017-05-12 16:26:59 -07002660 if (have_background_thread) {
2661 MUTEX_PROF_RESET(background_thread_lock);
2662 }
Qi Wang64c5f5c2017-03-13 17:29:03 -07002663 if (config_prof && opt_prof) {
2664 MUTEX_PROF_RESET(bt2gctx_mtx);
2665 }
Qi Wang362e3562017-03-22 01:49:56 -07002666
Qi Wang64c5f5c2017-03-13 17:29:03 -07002667
2668 /* Per arena mutexes. */
2669 unsigned n = narenas_total_get();
2670
2671 for (unsigned i = 0; i < n; i++) {
2672 arena_t *arena = arena_get(tsdn, i, false);
2673 if (!arena) {
2674 continue;
2675 }
2676 MUTEX_PROF_RESET(arena->large_mtx);
Jason Evans881fbf72017-04-16 22:31:16 -07002677 MUTEX_PROF_RESET(arena->extent_avail_mtx);
Qi Wang20b8c702017-03-15 14:00:57 -07002678 MUTEX_PROF_RESET(arena->extents_dirty.mtx);
2679 MUTEX_PROF_RESET(arena->extents_muzzy.mtx);
Qi Wang64c5f5c2017-03-13 17:29:03 -07002680 MUTEX_PROF_RESET(arena->extents_retained.mtx);
Qi Wang20b8c702017-03-15 14:00:57 -07002681 MUTEX_PROF_RESET(arena->decay_dirty.mtx);
2682 MUTEX_PROF_RESET(arena->decay_muzzy.mtx);
Jason Evans4403c9a2017-04-20 17:21:37 -07002683 MUTEX_PROF_RESET(arena->tcache_ql_mtx);
Qi Wang362e3562017-03-22 01:49:56 -07002684 MUTEX_PROF_RESET(arena->base->mtx);
Qi Wang64c5f5c2017-03-13 17:29:03 -07002685
2686 for (szind_t i = 0; i < NBINS; i++) {
David T. Goldblatt4bf4a1c2017-10-01 17:22:06 -07002687 bin_t *bin = &arena->bins[i];
Qi Wang64c5f5c2017-03-13 17:29:03 -07002688 MUTEX_PROF_RESET(bin->lock);
2689 }
2690 }
2691#undef MUTEX_PROF_RESET
2692 return 0;
2693}
Qi Wang0fb5c0e2017-03-10 12:14:05 -08002694
Jason Evans7372b152012-02-10 20:22:09 -08002695CTL_RO_CGEN(config_stats, stats_arenas_i_bins_j_nmalloc,
Jason Evans9eb1b1c2017-01-18 23:03:37 -08002696 arenas_i(mib[2])->astats->bstats[mib[4]].nmalloc, uint64_t)
Jason Evans7372b152012-02-10 20:22:09 -08002697CTL_RO_CGEN(config_stats, stats_arenas_i_bins_j_ndalloc,
Jason Evans9eb1b1c2017-01-18 23:03:37 -08002698 arenas_i(mib[2])->astats->bstats[mib[4]].ndalloc, uint64_t)
Jason Evans7372b152012-02-10 20:22:09 -08002699CTL_RO_CGEN(config_stats, stats_arenas_i_bins_j_nrequests,
Jason Evans9eb1b1c2017-01-18 23:03:37 -08002700 arenas_i(mib[2])->astats->bstats[mib[4]].nrequests, uint64_t)
Jason Evans3c4d92e2014-10-12 22:53:59 -07002701CTL_RO_CGEN(config_stats, stats_arenas_i_bins_j_curregs,
Jason Evans9eb1b1c2017-01-18 23:03:37 -08002702 arenas_i(mib[2])->astats->bstats[mib[4]].curregs, size_t)
Jason Evans4403c9a2017-04-20 17:21:37 -07002703CTL_RO_CGEN(config_stats, stats_arenas_i_bins_j_nfills,
Jason Evans9eb1b1c2017-01-18 23:03:37 -08002704 arenas_i(mib[2])->astats->bstats[mib[4]].nfills, uint64_t)
Jason Evans4403c9a2017-04-20 17:21:37 -07002705CTL_RO_CGEN(config_stats, stats_arenas_i_bins_j_nflushes,
Jason Evans9eb1b1c2017-01-18 23:03:37 -08002706 arenas_i(mib[2])->astats->bstats[mib[4]].nflushes, uint64_t)
Jason Evans498856f2016-05-29 18:34:50 -07002707CTL_RO_CGEN(config_stats, stats_arenas_i_bins_j_nslabs,
Jason Evans9eb1b1c2017-01-18 23:03:37 -08002708 arenas_i(mib[2])->astats->bstats[mib[4]].nslabs, uint64_t)
Jason Evans498856f2016-05-29 18:34:50 -07002709CTL_RO_CGEN(config_stats, stats_arenas_i_bins_j_nreslabs,
Jason Evans9eb1b1c2017-01-18 23:03:37 -08002710 arenas_i(mib[2])->astats->bstats[mib[4]].reslabs, uint64_t)
Jason Evans498856f2016-05-29 18:34:50 -07002711CTL_RO_CGEN(config_stats, stats_arenas_i_bins_j_curslabs,
Jason Evans9eb1b1c2017-01-18 23:03:37 -08002712 arenas_i(mib[2])->astats->bstats[mib[4]].curslabs, size_t)
Jason Evans3c234352010-01-27 13:10:55 -08002713
Jason Evans609ae592012-10-11 13:53:15 -07002714static const ctl_named_node_t *
Jason Evansc1e00ef2016-05-10 22:21:10 -07002715stats_arenas_i_bins_j_index(tsdn_t *tsdn, const size_t *mib, size_t miblen,
Jason Evansc4c25922017-01-15 16:56:30 -08002716 size_t j) {
2717 if (j > NBINS) {
Jason Evansf4086432017-01-19 18:15:45 -08002718 return NULL;
Jason Evansc4c25922017-01-15 16:56:30 -08002719 }
Jason Evansf4086432017-01-19 18:15:45 -08002720 return super_stats_arenas_i_bins_j_node;
Jason Evans3c234352010-01-27 13:10:55 -08002721}
2722
Jason Evans7d63fed2016-05-31 14:50:21 -07002723CTL_RO_CGEN(config_stats, stats_arenas_i_lextents_j_nmalloc,
David T. Goldblatt7f1b02e2017-11-04 12:50:19 -07002724 ctl_arena_stats_read_u64(
2725 &arenas_i(mib[2])->astats->lstats[mib[4]].nmalloc), uint64_t)
Jason Evans7d63fed2016-05-31 14:50:21 -07002726CTL_RO_CGEN(config_stats, stats_arenas_i_lextents_j_ndalloc,
David T. Goldblatt7f1b02e2017-11-04 12:50:19 -07002727 ctl_arena_stats_read_u64(
2728 &arenas_i(mib[2])->astats->lstats[mib[4]].ndalloc), uint64_t)
Jason Evans7d63fed2016-05-31 14:50:21 -07002729CTL_RO_CGEN(config_stats, stats_arenas_i_lextents_j_nrequests,
David T. Goldblatt7f1b02e2017-11-04 12:50:19 -07002730 ctl_arena_stats_read_u64(
2731 &arenas_i(mib[2])->astats->lstats[mib[4]].nrequests), uint64_t)
Jason Evans7d63fed2016-05-31 14:50:21 -07002732CTL_RO_CGEN(config_stats, stats_arenas_i_lextents_j_curlextents,
Jason Evans9eb1b1c2017-01-18 23:03:37 -08002733 arenas_i(mib[2])->astats->lstats[mib[4]].curlextents, size_t)
Jason Evans3c4d92e2014-10-12 22:53:59 -07002734
2735static const ctl_named_node_t *
Jason Evans7d63fed2016-05-31 14:50:21 -07002736stats_arenas_i_lextents_j_index(tsdn_t *tsdn, const size_t *mib, size_t miblen,
Jason Evansc4c25922017-01-15 16:56:30 -08002737 size_t j) {
2738 if (j > NSIZES - NBINS) {
Jason Evansf4086432017-01-19 18:15:45 -08002739 return NULL;
Jason Evansc4c25922017-01-15 16:56:30 -08002740 }
Jason Evansf4086432017-01-19 18:15:45 -08002741 return super_stats_arenas_i_lextents_j_node;
Jason Evans3c4d92e2014-10-12 22:53:59 -07002742}
2743
Jason Evans609ae592012-10-11 13:53:15 -07002744static const ctl_named_node_t *
Jason Evansc4c25922017-01-15 16:56:30 -08002745stats_arenas_i_index(tsdn_t *tsdn, const size_t *mib, size_t miblen, size_t i) {
Jason Evans3dc4e832017-01-03 07:27:42 -08002746 const ctl_named_node_t *ret;
2747 size_t a;
Jason Evans3c234352010-01-27 13:10:55 -08002748
Jason Evansc1e00ef2016-05-10 22:21:10 -07002749 malloc_mutex_lock(tsdn, &ctl_mtx);
Jason Evans9eb1b1c2017-01-18 23:03:37 -08002750 a = arenas_i2a_impl(i, true, true);
2751 if (a == UINT_MAX || !ctl_arenas->arenas[a]->initialized) {
Jason Evansfc4dcfa2010-11-24 15:44:21 -08002752 ret = NULL;
Jason Evansa1ee7832012-04-10 15:07:44 -07002753 goto label_return;
Jason Evansfc4dcfa2010-11-24 15:44:21 -08002754 }
2755
2756 ret = super_stats_arenas_i_node;
Jason Evansa1ee7832012-04-10 15:07:44 -07002757label_return:
Jason Evansc1e00ef2016-05-10 22:21:10 -07002758 malloc_mutex_unlock(tsdn, &ctl_mtx);
Jason Evansf4086432017-01-19 18:15:45 -08002759 return ret;
Jason Evans3c234352010-01-27 13:10:55 -08002760}