blob: 86c2837a0ef4b0728d391576ae0ab0e6f02a4e12 [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)
Dave Watson8b14f3a2018-03-29 12:58:13 -070060CTL_PROTO(max_background_threads)
Jason Evansd4be8b72012-03-26 18:54:44 -070061CTL_PROTO(thread_tcache_enabled)
Jason Evanse7b8fa12012-03-16 17:09:32 -070062CTL_PROTO(thread_tcache_flush)
Jason Evans602c8e02014-08-18 16:22:13 -070063CTL_PROTO(thread_prof_name)
64CTL_PROTO(thread_prof_active)
Jason Evansb267d0f2010-08-13 15:42:29 -070065CTL_PROTO(thread_arena)
Jason Evans93443682010-10-20 17:39:18 -070066CTL_PROTO(thread_allocated)
Jason Evansecf229a2010-12-03 15:55:47 -080067CTL_PROTO(thread_allocatedp)
Jason Evans93443682010-10-20 17:39:18 -070068CTL_PROTO(thread_deallocated)
Jason Evansecf229a2010-12-03 15:55:47 -080069CTL_PROTO(thread_deallocatedp)
Jason Evansf2bc8522015-07-17 16:38:25 -070070CTL_PROTO(config_cache_oblivious)
Jason Evans3c234352010-01-27 13:10:55 -080071CTL_PROTO(config_debug)
Jason Evans3c234352010-01-27 13:10:55 -080072CTL_PROTO(config_fill)
73CTL_PROTO(config_lazy_lock)
Jason Evansf8290092016-02-07 14:23:22 -080074CTL_PROTO(config_malloc_conf)
Jason Evansd34f9e72010-02-11 13:19:21 -080075CTL_PROTO(config_prof)
76CTL_PROTO(config_prof_libgcc)
77CTL_PROTO(config_prof_libunwind)
Jason Evans3c234352010-01-27 13:10:55 -080078CTL_PROTO(config_stats)
Jason Evansb1476112012-04-05 13:36:17 -070079CTL_PROTO(config_utrace)
Jason Evans3c234352010-01-27 13:10:55 -080080CTL_PROTO(config_xmalloc)
81CTL_PROTO(opt_abort)
Qi Wangb86d2712017-05-25 15:30:11 -070082CTL_PROTO(opt_abort_conf)
Qi Wang8fdd9a52017-08-10 13:14:26 -070083CTL_PROTO(opt_metadata_thp)
Jason Evansb9ab04a2017-04-26 16:26:12 -070084CTL_PROTO(opt_retain)
Jason Evans609ae592012-10-11 13:53:15 -070085CTL_PROTO(opt_dss)
Jason Evanse7339702010-10-23 18:37:06 -070086CTL_PROTO(opt_narenas)
Qi Wangec532e22017-02-02 17:02:05 -080087CTL_PROTO(opt_percpu_arena)
Qi Wangb693c782017-03-17 12:42:33 -070088CTL_PROTO(opt_background_thread)
Dave Watson8b14f3a2018-03-29 12:58:13 -070089CTL_PROTO(opt_max_background_threads)
Jason Evans6e62c622017-05-17 10:47:00 -070090CTL_PROTO(opt_dirty_decay_ms)
91CTL_PROTO(opt_muzzy_decay_ms)
Jason Evanse7339702010-10-23 18:37:06 -070092CTL_PROTO(opt_stats_print)
Qi Wangd5ef5ae2017-05-27 15:35:36 -070093CTL_PROTO(opt_stats_print_opts)
Jason Evans3c234352010-01-27 13:10:55 -080094CTL_PROTO(opt_junk)
Jason Evanse7339702010-10-23 18:37:06 -070095CTL_PROTO(opt_zero)
Jason Evansb1476112012-04-05 13:36:17 -070096CTL_PROTO(opt_utrace)
Jason Evans3c234352010-01-27 13:10:55 -080097CTL_PROTO(opt_xmalloc)
Jason Evans3fa9a2f2010-03-07 15:34:14 -080098CTL_PROTO(opt_tcache)
Qi Wange4f090e2018-02-16 14:19:19 -080099CTL_PROTO(opt_thp)
Qi Wangfac70682017-11-09 13:51:39 -0800100CTL_PROTO(opt_lg_extent_max_active_fit)
Jason Evansf3ca7c82012-04-04 16:16:09 -0700101CTL_PROTO(opt_lg_tcache_max)
Jason Evansd34f9e72010-02-11 13:19:21 -0800102CTL_PROTO(opt_prof)
Jason Evanse7339702010-10-23 18:37:06 -0700103CTL_PROTO(opt_prof_prefix)
Jason Evansf18c9822010-03-31 18:43:24 -0700104CTL_PROTO(opt_prof_active)
Jason Evansfc12c0b2014-10-03 23:25:30 -0700105CTL_PROTO(opt_prof_thread_active_init)
Jason Evansb9477e72010-03-01 20:15:26 -0800106CTL_PROTO(opt_lg_prof_sample)
Jason Evansd34f9e72010-02-11 13:19:21 -0800107CTL_PROTO(opt_lg_prof_interval)
Jason Evanse7339702010-10-23 18:37:06 -0700108CTL_PROTO(opt_prof_gdump)
Jason Evans0b25fe72012-04-17 16:39:33 -0700109CTL_PROTO(opt_prof_final)
Jason Evansd34f9e72010-02-11 13:19:21 -0800110CTL_PROTO(opt_prof_leak)
Jason Evansa881cd22010-10-02 15:18:50 -0700111CTL_PROTO(opt_prof_accum)
Jason Evans1cb181e2015-01-29 15:30:47 -0800112CTL_PROTO(tcache_create)
113CTL_PROTO(tcache_flush)
114CTL_PROTO(tcache_destroy)
Jason Evansdc2125c2017-01-04 10:21:53 -0800115CTL_PROTO(arena_i_initialized)
Jason Evans243f7a02016-02-19 20:09:31 -0800116CTL_PROTO(arena_i_decay)
Jason Evans64e458f2017-03-08 22:42:57 -0800117CTL_PROTO(arena_i_purge)
Jason Evans19ff2ce2016-04-22 14:37:17 -0700118CTL_PROTO(arena_i_reset)
Jason Evansedf1baf2017-01-03 17:21:59 -0800119CTL_PROTO(arena_i_destroy)
Jason Evans609ae592012-10-11 13:53:15 -0700120CTL_PROTO(arena_i_dss)
Jason Evans6e62c622017-05-17 10:47:00 -0700121CTL_PROTO(arena_i_dirty_decay_ms)
122CTL_PROTO(arena_i_muzzy_decay_ms)
Jason Evans9c305c92016-05-31 15:03:51 -0700123CTL_PROTO(arena_i_extent_hooks)
Qi Wange422fa82017-11-02 17:48:39 -0700124CTL_PROTO(arena_i_retain_grow_limit)
Jason Evans609ae592012-10-11 13:53:15 -0700125INDEX_PROTO(arena_i)
Jason Evans3c234352010-01-27 13:10:55 -0800126CTL_PROTO(arenas_bin_i_size)
127CTL_PROTO(arenas_bin_i_nregs)
Jason Evans498856f2016-05-29 18:34:50 -0700128CTL_PROTO(arenas_bin_i_slab_size)
Jason Evans3c234352010-01-27 13:10:55 -0800129INDEX_PROTO(arenas_bin_i)
Jason Evans7d63fed2016-05-31 14:50:21 -0700130CTL_PROTO(arenas_lextent_i_size)
131INDEX_PROTO(arenas_lextent_i)
Jason Evans3c234352010-01-27 13:10:55 -0800132CTL_PROTO(arenas_narenas)
Jason Evans6e62c622017-05-17 10:47:00 -0700133CTL_PROTO(arenas_dirty_decay_ms)
134CTL_PROTO(arenas_muzzy_decay_ms)
Jason Evans3c234352010-01-27 13:10:55 -0800135CTL_PROTO(arenas_quantum)
Jason Evansae4c7b42012-04-02 07:04:34 -0700136CTL_PROTO(arenas_page)
Jason Evansdafde142010-03-17 16:27:39 -0700137CTL_PROTO(arenas_tcache_max)
Jason Evans3c234352010-01-27 13:10:55 -0800138CTL_PROTO(arenas_nbins)
Jason Evansdafde142010-03-17 16:27:39 -0700139CTL_PROTO(arenas_nhbins)
Jason Evans7d63fed2016-05-31 14:50:21 -0700140CTL_PROTO(arenas_nlextents)
Jason Evans0f04bb12017-01-03 08:21:29 -0800141CTL_PROTO(arenas_create)
Jason Evansfc12c0b2014-10-03 23:25:30 -0700142CTL_PROTO(prof_thread_active_init)
Jason Evansf18c9822010-03-31 18:43:24 -0700143CTL_PROTO(prof_active)
Jason Evansd34f9e72010-02-11 13:19:21 -0800144CTL_PROTO(prof_dump)
Jason Evans5b8ed5b2015-01-25 21:16:57 -0800145CTL_PROTO(prof_gdump)
Jason Evans602c8e02014-08-18 16:22:13 -0700146CTL_PROTO(prof_reset)
Jason Evansd34f9e72010-02-11 13:19:21 -0800147CTL_PROTO(prof_interval)
Jason Evans602c8e02014-08-18 16:22:13 -0700148CTL_PROTO(lg_prof_sample)
Jason Evans3c234352010-01-27 13:10:55 -0800149CTL_PROTO(stats_arenas_i_small_allocated)
150CTL_PROTO(stats_arenas_i_small_nmalloc)
151CTL_PROTO(stats_arenas_i_small_ndalloc)
Jason Evans86815df2010-03-13 20:32:56 -0800152CTL_PROTO(stats_arenas_i_small_nrequests)
Jason Evans7d63fed2016-05-31 14:50:21 -0700153CTL_PROTO(stats_arenas_i_large_allocated)
154CTL_PROTO(stats_arenas_i_large_nmalloc)
155CTL_PROTO(stats_arenas_i_large_ndalloc)
156CTL_PROTO(stats_arenas_i_large_nrequests)
Jason Evans86815df2010-03-13 20:32:56 -0800157CTL_PROTO(stats_arenas_i_bins_j_nmalloc)
158CTL_PROTO(stats_arenas_i_bins_j_ndalloc)
Jason Evans3c234352010-01-27 13:10:55 -0800159CTL_PROTO(stats_arenas_i_bins_j_nrequests)
Jason Evans3c4d92e2014-10-12 22:53:59 -0700160CTL_PROTO(stats_arenas_i_bins_j_curregs)
Jason Evans3c234352010-01-27 13:10:55 -0800161CTL_PROTO(stats_arenas_i_bins_j_nfills)
162CTL_PROTO(stats_arenas_i_bins_j_nflushes)
Jason Evans498856f2016-05-29 18:34:50 -0700163CTL_PROTO(stats_arenas_i_bins_j_nslabs)
164CTL_PROTO(stats_arenas_i_bins_j_nreslabs)
165CTL_PROTO(stats_arenas_i_bins_j_curslabs)
Jason Evans3c234352010-01-27 13:10:55 -0800166INDEX_PROTO(stats_arenas_i_bins_j)
Jason Evans7d63fed2016-05-31 14:50:21 -0700167CTL_PROTO(stats_arenas_i_lextents_j_nmalloc)
168CTL_PROTO(stats_arenas_i_lextents_j_ndalloc)
169CTL_PROTO(stats_arenas_i_lextents_j_nrequests)
170CTL_PROTO(stats_arenas_i_lextents_j_curlextents)
171INDEX_PROTO(stats_arenas_i_lextents_j)
Jason Evans597632b2011-03-18 13:41:33 -0700172CTL_PROTO(stats_arenas_i_nthreads)
Qi Wangbaf3e292017-05-16 13:56:00 -0700173CTL_PROTO(stats_arenas_i_uptime)
Jason Evans609ae592012-10-11 13:53:15 -0700174CTL_PROTO(stats_arenas_i_dss)
Jason Evans6e62c622017-05-17 10:47:00 -0700175CTL_PROTO(stats_arenas_i_dirty_decay_ms)
176CTL_PROTO(stats_arenas_i_muzzy_decay_ms)
Jason Evans3c234352010-01-27 13:10:55 -0800177CTL_PROTO(stats_arenas_i_pactive)
178CTL_PROTO(stats_arenas_i_pdirty)
Jason Evans64e458f2017-03-08 22:42:57 -0800179CTL_PROTO(stats_arenas_i_pmuzzy)
Jason Evans3c234352010-01-27 13:10:55 -0800180CTL_PROTO(stats_arenas_i_mapped)
Jason Evans04c3c0f2016-05-03 22:11:35 -0700181CTL_PROTO(stats_arenas_i_retained)
Jason Evans64e458f2017-03-08 22:42:57 -0800182CTL_PROTO(stats_arenas_i_dirty_npurge)
183CTL_PROTO(stats_arenas_i_dirty_nmadvise)
184CTL_PROTO(stats_arenas_i_dirty_purged)
185CTL_PROTO(stats_arenas_i_muzzy_npurge)
186CTL_PROTO(stats_arenas_i_muzzy_nmadvise)
187CTL_PROTO(stats_arenas_i_muzzy_purged)
Jason Evansa0dd3a42016-12-22 16:39:10 -0600188CTL_PROTO(stats_arenas_i_base)
189CTL_PROTO(stats_arenas_i_internal)
Qi Wange55c3ca2017-08-25 13:24:49 -0700190CTL_PROTO(stats_arenas_i_metadata_thp)
Qi Wang58424e62016-04-22 18:37:44 -0700191CTL_PROTO(stats_arenas_i_tcache_bytes)
Jason Evansa0dd3a42016-12-22 16:39:10 -0600192CTL_PROTO(stats_arenas_i_resident)
Jason Evans3c234352010-01-27 13:10:55 -0800193INDEX_PROTO(stats_arenas_i)
Jason Evans3c234352010-01-27 13:10:55 -0800194CTL_PROTO(stats_allocated)
195CTL_PROTO(stats_active)
Qi Wang2bee0c62017-05-12 12:30:33 -0700196CTL_PROTO(stats_background_thread_num_threads)
197CTL_PROTO(stats_background_thread_num_runs)
198CTL_PROTO(stats_background_thread_run_interval)
Jason Evans4581b972014-11-27 17:22:36 -0200199CTL_PROTO(stats_metadata)
Qi Wange55c3ca2017-08-25 13:24:49 -0700200CTL_PROTO(stats_metadata_thp)
Jason Evans4acd75a2015-03-23 17:25:57 -0700201CTL_PROTO(stats_resident)
Jason Evans3c234352010-01-27 13:10:55 -0800202CTL_PROTO(stats_mapped)
Jason Evans04c3c0f2016-05-03 22:11:35 -0700203CTL_PROTO(stats_retained)
Jason Evans3c234352010-01-27 13:10:55 -0800204
Qi Wang64c5f5c2017-03-13 17:29:03 -0700205#define MUTEX_STATS_CTL_PROTO_GEN(n) \
Qi Wangca9074d2017-03-11 20:28:31 -0800206CTL_PROTO(stats_##n##_num_ops) \
207CTL_PROTO(stats_##n##_num_wait) \
208CTL_PROTO(stats_##n##_num_spin_acq) \
209CTL_PROTO(stats_##n##_num_owner_switch) \
210CTL_PROTO(stats_##n##_total_wait_time) \
211CTL_PROTO(stats_##n##_max_wait_time) \
212CTL_PROTO(stats_##n##_max_num_thds)
Qi Wang0fb5c0e2017-03-10 12:14:05 -0800213
Qi Wang64c5f5c2017-03-13 17:29:03 -0700214/* Global mutexes. */
Qi Wangd3fde1c2017-03-21 11:56:38 -0700215#define OP(mtx) MUTEX_STATS_CTL_PROTO_GEN(mutexes_##mtx)
David Goldblatt89e2d3c2017-04-24 17:09:56 -0700216MUTEX_PROF_GLOBAL_MUTEXES
Qi Wangd3fde1c2017-03-21 11:56:38 -0700217#undef OP
218
219/* Per arena mutexes. */
220#define OP(mtx) MUTEX_STATS_CTL_PROTO_GEN(arenas_i_mutexes_##mtx)
David Goldblatt89e2d3c2017-04-24 17:09:56 -0700221MUTEX_PROF_ARENA_MUTEXES
Qi Wangd3fde1c2017-03-21 11:56:38 -0700222#undef OP
Qi Wangca9074d2017-03-11 20:28:31 -0800223
Qi Wang64c5f5c2017-03-13 17:29:03 -0700224/* Arena bin mutexes. */
225MUTEX_STATS_CTL_PROTO_GEN(arenas_i_bins_j_mutex)
Qi Wang64c5f5c2017-03-13 17:29:03 -0700226#undef MUTEX_STATS_CTL_PROTO_GEN
227
228CTL_PROTO(stats_mutexes_reset)
Qi Wang0fb5c0e2017-03-10 12:14:05 -0800229
Jason Evans3c234352010-01-27 13:10:55 -0800230/******************************************************************************/
231/* mallctl tree. */
232
Jason Evansc0cc5db2017-01-19 21:41:41 -0800233#define NAME(n) {true}, n
234#define CHILD(t, c) \
Jason Evans65f343a2012-04-23 19:31:45 -0700235 sizeof(c##_node) / sizeof(ctl_##t##_node_t), \
236 (ctl_node_t *)c##_node, \
237 NULL
Jason Evansc0cc5db2017-01-19 21:41:41 -0800238#define CTL(c) 0, NULL, c##_ctl
Jason Evans3c234352010-01-27 13:10:55 -0800239
240/*
241 * Only handles internal indexed nodes, since there are currently no external
242 * ones.
243 */
Jason Evansc0cc5db2017-01-19 21:41:41 -0800244#define INDEX(i) {false}, i##_index
Jason Evans3c234352010-01-27 13:10:55 -0800245
Jason Evans602c8e02014-08-18 16:22:13 -0700246static const ctl_named_node_t thread_tcache_node[] = {
Jason Evansd4be8b72012-03-26 18:54:44 -0700247 {NAME("enabled"), CTL(thread_tcache_enabled)},
Jason Evanse7b8fa12012-03-16 17:09:32 -0700248 {NAME("flush"), CTL(thread_tcache_flush)}
Jason Evans3c234352010-01-27 13:10:55 -0800249};
Jason Evans3c234352010-01-27 13:10:55 -0800250
Jason Evans602c8e02014-08-18 16:22:13 -0700251static const ctl_named_node_t thread_prof_node[] = {
252 {NAME("name"), CTL(thread_prof_name)},
253 {NAME("active"), CTL(thread_prof_active)}
254};
255
Mike Hommey461ad5c2012-04-20 08:38:42 +0200256static const ctl_named_node_t thread_node[] = {
Jason Evans7372b152012-02-10 20:22:09 -0800257 {NAME("arena"), CTL(thread_arena)},
Jason Evans93443682010-10-20 17:39:18 -0700258 {NAME("allocated"), CTL(thread_allocated)},
Jason Evansecf229a2010-12-03 15:55:47 -0800259 {NAME("allocatedp"), CTL(thread_allocatedp)},
260 {NAME("deallocated"), CTL(thread_deallocated)},
Jason Evanse7b8fa12012-03-16 17:09:32 -0700261 {NAME("deallocatedp"), CTL(thread_deallocatedp)},
Jason Evans602c8e02014-08-18 16:22:13 -0700262 {NAME("tcache"), CHILD(named, thread_tcache)},
263 {NAME("prof"), CHILD(named, thread_prof)}
Jason Evansb267d0f2010-08-13 15:42:29 -0700264};
Jason Evansb267d0f2010-08-13 15:42:29 -0700265
Mike Hommey461ad5c2012-04-20 08:38:42 +0200266static const ctl_named_node_t config_node[] = {
Jason Evansf2bc8522015-07-17 16:38:25 -0700267 {NAME("cache_oblivious"), CTL(config_cache_oblivious)},
Jason Evans3c4d92e2014-10-12 22:53:59 -0700268 {NAME("debug"), CTL(config_debug)},
269 {NAME("fill"), CTL(config_fill)},
270 {NAME("lazy_lock"), CTL(config_lazy_lock)},
Jason Evansf8290092016-02-07 14:23:22 -0800271 {NAME("malloc_conf"), CTL(config_malloc_conf)},
Jason Evans3c4d92e2014-10-12 22:53:59 -0700272 {NAME("prof"), CTL(config_prof)},
273 {NAME("prof_libgcc"), CTL(config_prof_libgcc)},
274 {NAME("prof_libunwind"), CTL(config_prof_libunwind)},
275 {NAME("stats"), CTL(config_stats)},
Jason Evans3c4d92e2014-10-12 22:53:59 -0700276 {NAME("utrace"), CTL(config_utrace)},
Jason Evans3c4d92e2014-10-12 22:53:59 -0700277 {NAME("xmalloc"), CTL(config_xmalloc)}
Jason Evans3c234352010-01-27 13:10:55 -0800278};
279
Mike Hommey461ad5c2012-04-20 08:38:42 +0200280static const ctl_named_node_t opt_node[] = {
Jason Evans3c4d92e2014-10-12 22:53:59 -0700281 {NAME("abort"), CTL(opt_abort)},
Qi Wangb86d2712017-05-25 15:30:11 -0700282 {NAME("abort_conf"), CTL(opt_abort_conf)},
Qi Wang8fdd9a52017-08-10 13:14:26 -0700283 {NAME("metadata_thp"), CTL(opt_metadata_thp)},
Jason Evansb9ab04a2017-04-26 16:26:12 -0700284 {NAME("retain"), CTL(opt_retain)},
Jason Evans3c4d92e2014-10-12 22:53:59 -0700285 {NAME("dss"), CTL(opt_dss)},
Jason Evans3c4d92e2014-10-12 22:53:59 -0700286 {NAME("narenas"), CTL(opt_narenas)},
Qi Wangec532e22017-02-02 17:02:05 -0800287 {NAME("percpu_arena"), CTL(opt_percpu_arena)},
Qi Wangb693c782017-03-17 12:42:33 -0700288 {NAME("background_thread"), CTL(opt_background_thread)},
Dave Watson8b14f3a2018-03-29 12:58:13 -0700289 {NAME("max_background_threads"), CTL(opt_max_background_threads)},
Jason Evans6e62c622017-05-17 10:47:00 -0700290 {NAME("dirty_decay_ms"), CTL(opt_dirty_decay_ms)},
291 {NAME("muzzy_decay_ms"), CTL(opt_muzzy_decay_ms)},
Jason Evans3c4d92e2014-10-12 22:53:59 -0700292 {NAME("stats_print"), CTL(opt_stats_print)},
Qi Wangd5ef5ae2017-05-27 15:35:36 -0700293 {NAME("stats_print_opts"), CTL(opt_stats_print_opts)},
Jason Evans3c4d92e2014-10-12 22:53:59 -0700294 {NAME("junk"), CTL(opt_junk)},
295 {NAME("zero"), CTL(opt_zero)},
Jason Evans3c4d92e2014-10-12 22:53:59 -0700296 {NAME("utrace"), CTL(opt_utrace)},
297 {NAME("xmalloc"), CTL(opt_xmalloc)},
298 {NAME("tcache"), CTL(opt_tcache)},
Qi Wange4f090e2018-02-16 14:19:19 -0800299 {NAME("thp"), CTL(opt_thp)},
Qi Wangfac70682017-11-09 13:51:39 -0800300 {NAME("lg_extent_max_active_fit"), CTL(opt_lg_extent_max_active_fit)},
Jason Evans3c4d92e2014-10-12 22:53:59 -0700301 {NAME("lg_tcache_max"), CTL(opt_lg_tcache_max)},
302 {NAME("prof"), CTL(opt_prof)},
303 {NAME("prof_prefix"), CTL(opt_prof_prefix)},
304 {NAME("prof_active"), CTL(opt_prof_active)},
Jason Evansfc12c0b2014-10-03 23:25:30 -0700305 {NAME("prof_thread_active_init"), CTL(opt_prof_thread_active_init)},
Jason Evans3c4d92e2014-10-12 22:53:59 -0700306 {NAME("lg_prof_sample"), CTL(opt_lg_prof_sample)},
307 {NAME("lg_prof_interval"), CTL(opt_lg_prof_interval)},
308 {NAME("prof_gdump"), CTL(opt_prof_gdump)},
309 {NAME("prof_final"), CTL(opt_prof_final)},
310 {NAME("prof_leak"), CTL(opt_prof_leak)},
311 {NAME("prof_accum"), CTL(opt_prof_accum)}
Jason Evans3c234352010-01-27 13:10:55 -0800312};
313
Jason Evans1cb181e2015-01-29 15:30:47 -0800314static const ctl_named_node_t tcache_node[] = {
315 {NAME("create"), CTL(tcache_create)},
316 {NAME("flush"), CTL(tcache_flush)},
317 {NAME("destroy"), CTL(tcache_destroy)}
318};
319
Jason Evans609ae592012-10-11 13:53:15 -0700320static const ctl_named_node_t arena_i_node[] = {
Jason Evansdc2125c2017-01-04 10:21:53 -0800321 {NAME("initialized"), CTL(arena_i_initialized)},
Jason Evans243f7a02016-02-19 20:09:31 -0800322 {NAME("decay"), CTL(arena_i_decay)},
Jason Evans64e458f2017-03-08 22:42:57 -0800323 {NAME("purge"), CTL(arena_i_purge)},
Jason Evans19ff2ce2016-04-22 14:37:17 -0700324 {NAME("reset"), CTL(arena_i_reset)},
Jason Evansedf1baf2017-01-03 17:21:59 -0800325 {NAME("destroy"), CTL(arena_i_destroy)},
Jason Evans3c4d92e2014-10-12 22:53:59 -0700326 {NAME("dss"), CTL(arena_i_dss)},
Jason Evans6e62c622017-05-17 10:47:00 -0700327 {NAME("dirty_decay_ms"), CTL(arena_i_dirty_decay_ms)},
328 {NAME("muzzy_decay_ms"), CTL(arena_i_muzzy_decay_ms)},
Qi Wange422fa82017-11-02 17:48:39 -0700329 {NAME("extent_hooks"), CTL(arena_i_extent_hooks)},
330 {NAME("retain_grow_limit"), CTL(arena_i_retain_grow_limit)}
Jason Evans609ae592012-10-11 13:53:15 -0700331};
332static const ctl_named_node_t super_arena_i_node[] = {
Jason Evans3c4d92e2014-10-12 22:53:59 -0700333 {NAME(""), CHILD(named, arena_i)}
Jason Evans609ae592012-10-11 13:53:15 -0700334};
335
336static const ctl_indexed_node_t arena_node[] = {
337 {INDEX(arena_i)}
338};
339
Mike Hommey461ad5c2012-04-20 08:38:42 +0200340static const ctl_named_node_t arenas_bin_i_node[] = {
Jason Evans3c4d92e2014-10-12 22:53:59 -0700341 {NAME("size"), CTL(arenas_bin_i_size)},
342 {NAME("nregs"), CTL(arenas_bin_i_nregs)},
Jason Evans498856f2016-05-29 18:34:50 -0700343 {NAME("slab_size"), CTL(arenas_bin_i_slab_size)}
Jason Evans3c234352010-01-27 13:10:55 -0800344};
Mike Hommey461ad5c2012-04-20 08:38:42 +0200345static const ctl_named_node_t super_arenas_bin_i_node[] = {
Jason Evans3c4d92e2014-10-12 22:53:59 -0700346 {NAME(""), CHILD(named, arenas_bin_i)}
Jason Evans3c234352010-01-27 13:10:55 -0800347};
348
Mike Hommey461ad5c2012-04-20 08:38:42 +0200349static const ctl_indexed_node_t arenas_bin_node[] = {
Jason Evans3c234352010-01-27 13:10:55 -0800350 {INDEX(arenas_bin_i)}
351};
352
Jason Evans7d63fed2016-05-31 14:50:21 -0700353static const ctl_named_node_t arenas_lextent_i_node[] = {
354 {NAME("size"), CTL(arenas_lextent_i_size)}
Jason Evans3c4d92e2014-10-12 22:53:59 -0700355};
Jason Evans7d63fed2016-05-31 14:50:21 -0700356static const ctl_named_node_t super_arenas_lextent_i_node[] = {
357 {NAME(""), CHILD(named, arenas_lextent_i)}
Jason Evans3c4d92e2014-10-12 22:53:59 -0700358};
359
Jason Evans7d63fed2016-05-31 14:50:21 -0700360static const ctl_indexed_node_t arenas_lextent_node[] = {
361 {INDEX(arenas_lextent_i)}
Jason Evans3c4d92e2014-10-12 22:53:59 -0700362};
363
Mike Hommey461ad5c2012-04-20 08:38:42 +0200364static const ctl_named_node_t arenas_node[] = {
Jason Evans3c4d92e2014-10-12 22:53:59 -0700365 {NAME("narenas"), CTL(arenas_narenas)},
Jason Evans6e62c622017-05-17 10:47:00 -0700366 {NAME("dirty_decay_ms"), CTL(arenas_dirty_decay_ms)},
367 {NAME("muzzy_decay_ms"), CTL(arenas_muzzy_decay_ms)},
Jason Evans3c4d92e2014-10-12 22:53:59 -0700368 {NAME("quantum"), CTL(arenas_quantum)},
369 {NAME("page"), CTL(arenas_page)},
370 {NAME("tcache_max"), CTL(arenas_tcache_max)},
371 {NAME("nbins"), CTL(arenas_nbins)},
372 {NAME("nhbins"), CTL(arenas_nhbins)},
373 {NAME("bin"), CHILD(indexed, arenas_bin)},
Jason Evans7d63fed2016-05-31 14:50:21 -0700374 {NAME("nlextents"), CTL(arenas_nlextents)},
375 {NAME("lextent"), CHILD(indexed, arenas_lextent)},
Jason Evans0f04bb12017-01-03 08:21:29 -0800376 {NAME("create"), CTL(arenas_create)}
Jason Evans3c234352010-01-27 13:10:55 -0800377};
378
Mike Hommey461ad5c2012-04-20 08:38:42 +0200379static const ctl_named_node_t prof_node[] = {
Jason Evansfc12c0b2014-10-03 23:25:30 -0700380 {NAME("thread_active_init"), CTL(prof_thread_active_init)},
Jason Evansf18c9822010-03-31 18:43:24 -0700381 {NAME("active"), CTL(prof_active)},
Jason Evansd34f9e72010-02-11 13:19:21 -0800382 {NAME("dump"), CTL(prof_dump)},
Jason Evans5b8ed5b2015-01-25 21:16:57 -0800383 {NAME("gdump"), CTL(prof_gdump)},
Jason Evans602c8e02014-08-18 16:22:13 -0700384 {NAME("reset"), CTL(prof_reset)},
385 {NAME("interval"), CTL(prof_interval)},
386 {NAME("lg_sample"), CTL(lg_prof_sample)}
Jason Evansd34f9e72010-02-11 13:19:21 -0800387};
Jason Evansd34f9e72010-02-11 13:19:21 -0800388
Mike Hommey461ad5c2012-04-20 08:38:42 +0200389static const ctl_named_node_t stats_arenas_i_small_node[] = {
Jason Evans3c4d92e2014-10-12 22:53:59 -0700390 {NAME("allocated"), CTL(stats_arenas_i_small_allocated)},
391 {NAME("nmalloc"), CTL(stats_arenas_i_small_nmalloc)},
392 {NAME("ndalloc"), CTL(stats_arenas_i_small_ndalloc)},
393 {NAME("nrequests"), CTL(stats_arenas_i_small_nrequests)}
Jason Evans3c234352010-01-27 13:10:55 -0800394};
395
Jason Evans7d63fed2016-05-31 14:50:21 -0700396static const ctl_named_node_t stats_arenas_i_large_node[] = {
397 {NAME("allocated"), CTL(stats_arenas_i_large_allocated)},
398 {NAME("nmalloc"), CTL(stats_arenas_i_large_nmalloc)},
399 {NAME("ndalloc"), CTL(stats_arenas_i_large_ndalloc)},
400 {NAME("nrequests"), CTL(stats_arenas_i_large_nrequests)}
Jason Evanse2deab72014-05-15 22:22:27 -0700401};
402
Qi Wang64c5f5c2017-03-13 17:29:03 -0700403#define MUTEX_PROF_DATA_NODE(prefix) \
Qi Wangca9074d2017-03-11 20:28:31 -0800404static const ctl_named_node_t stats_##prefix##_node[] = { \
Qi Wang0fb5c0e2017-03-10 12:14:05 -0800405 {NAME("num_ops"), \
Qi Wangca9074d2017-03-11 20:28:31 -0800406 CTL(stats_##prefix##_num_ops)}, \
Qi Wang0fb5c0e2017-03-10 12:14:05 -0800407 {NAME("num_wait"), \
Qi Wangca9074d2017-03-11 20:28:31 -0800408 CTL(stats_##prefix##_num_wait)}, \
Qi Wang0fb5c0e2017-03-10 12:14:05 -0800409 {NAME("num_spin_acq"), \
Qi Wangca9074d2017-03-11 20:28:31 -0800410 CTL(stats_##prefix##_num_spin_acq)}, \
Qi Wang0fb5c0e2017-03-10 12:14:05 -0800411 {NAME("num_owner_switch"), \
Qi Wangca9074d2017-03-11 20:28:31 -0800412 CTL(stats_##prefix##_num_owner_switch)}, \
Qi Wang0fb5c0e2017-03-10 12:14:05 -0800413 {NAME("total_wait_time"), \
Qi Wangca9074d2017-03-11 20:28:31 -0800414 CTL(stats_##prefix##_total_wait_time)}, \
Qi Wang0fb5c0e2017-03-10 12:14:05 -0800415 {NAME("max_wait_time"), \
Qi Wangca9074d2017-03-11 20:28:31 -0800416 CTL(stats_##prefix##_max_wait_time)}, \
Qi Wang0fb5c0e2017-03-10 12:14:05 -0800417 {NAME("max_num_thds"), \
Qi Wangca9074d2017-03-11 20:28:31 -0800418 CTL(stats_##prefix##_max_num_thds)} \
Qi Wang0fb5c0e2017-03-10 12:14:05 -0800419 /* Note that # of current waiting thread not provided. */ \
420};
421
Qi Wang64c5f5c2017-03-13 17:29:03 -0700422MUTEX_PROF_DATA_NODE(arenas_i_bins_j_mutex)
Qi Wangca9074d2017-03-11 20:28:31 -0800423
Mike Hommey461ad5c2012-04-20 08:38:42 +0200424static const ctl_named_node_t stats_arenas_i_bins_j_node[] = {
Jason Evans3c4d92e2014-10-12 22:53:59 -0700425 {NAME("nmalloc"), CTL(stats_arenas_i_bins_j_nmalloc)},
426 {NAME("ndalloc"), CTL(stats_arenas_i_bins_j_ndalloc)},
427 {NAME("nrequests"), CTL(stats_arenas_i_bins_j_nrequests)},
428 {NAME("curregs"), CTL(stats_arenas_i_bins_j_curregs)},
429 {NAME("nfills"), CTL(stats_arenas_i_bins_j_nfills)},
430 {NAME("nflushes"), CTL(stats_arenas_i_bins_j_nflushes)},
Jason Evans498856f2016-05-29 18:34:50 -0700431 {NAME("nslabs"), CTL(stats_arenas_i_bins_j_nslabs)},
432 {NAME("nreslabs"), CTL(stats_arenas_i_bins_j_nreslabs)},
Qi Wanga4f176a2017-03-03 19:58:43 -0800433 {NAME("curslabs"), CTL(stats_arenas_i_bins_j_curslabs)},
Qi Wang64c5f5c2017-03-13 17:29:03 -0700434 {NAME("mutex"), CHILD(named, stats_arenas_i_bins_j_mutex)}
Jason Evans3c234352010-01-27 13:10:55 -0800435};
Qi Wang0fb5c0e2017-03-10 12:14:05 -0800436
Mike Hommey461ad5c2012-04-20 08:38:42 +0200437static const ctl_named_node_t super_stats_arenas_i_bins_j_node[] = {
Jason Evans3c4d92e2014-10-12 22:53:59 -0700438 {NAME(""), CHILD(named, stats_arenas_i_bins_j)}
Jason Evans3c234352010-01-27 13:10:55 -0800439};
440
Mike Hommey461ad5c2012-04-20 08:38:42 +0200441static const ctl_indexed_node_t stats_arenas_i_bins_node[] = {
Jason Evans3c234352010-01-27 13:10:55 -0800442 {INDEX(stats_arenas_i_bins_j)}
443};
444
Jason Evans7d63fed2016-05-31 14:50:21 -0700445static const ctl_named_node_t stats_arenas_i_lextents_j_node[] = {
446 {NAME("nmalloc"), CTL(stats_arenas_i_lextents_j_nmalloc)},
447 {NAME("ndalloc"), CTL(stats_arenas_i_lextents_j_ndalloc)},
448 {NAME("nrequests"), CTL(stats_arenas_i_lextents_j_nrequests)},
449 {NAME("curlextents"), CTL(stats_arenas_i_lextents_j_curlextents)}
Jason Evans3c4d92e2014-10-12 22:53:59 -0700450};
Jason Evans7d63fed2016-05-31 14:50:21 -0700451static const ctl_named_node_t super_stats_arenas_i_lextents_j_node[] = {
452 {NAME(""), CHILD(named, stats_arenas_i_lextents_j)}
Jason Evans3c4d92e2014-10-12 22:53:59 -0700453};
454
Jason Evans7d63fed2016-05-31 14:50:21 -0700455static const ctl_indexed_node_t stats_arenas_i_lextents_node[] = {
456 {INDEX(stats_arenas_i_lextents_j)}
Jason Evans3c4d92e2014-10-12 22:53:59 -0700457};
458
Qi Wangd3fde1c2017-03-21 11:56:38 -0700459#define OP(mtx) MUTEX_PROF_DATA_NODE(arenas_i_mutexes_##mtx)
David Goldblatt89e2d3c2017-04-24 17:09:56 -0700460MUTEX_PROF_ARENA_MUTEXES
Qi Wangd3fde1c2017-03-21 11:56:38 -0700461#undef OP
Qi Wang0fb5c0e2017-03-10 12:14:05 -0800462
Qi Wang64c5f5c2017-03-13 17:29:03 -0700463static const ctl_named_node_t stats_arenas_i_mutexes_node[] = {
Qi Wangd3fde1c2017-03-21 11:56:38 -0700464#define OP(mtx) {NAME(#mtx), CHILD(named, stats_arenas_i_mutexes_##mtx)},
David Goldblatt89e2d3c2017-04-24 17:09:56 -0700465MUTEX_PROF_ARENA_MUTEXES
Qi Wangd3fde1c2017-03-21 11:56:38 -0700466#undef OP
Qi Wang0fb5c0e2017-03-10 12:14:05 -0800467};
Qi Wang0fb5c0e2017-03-10 12:14:05 -0800468
Mike Hommey461ad5c2012-04-20 08:38:42 +0200469static const ctl_named_node_t stats_arenas_i_node[] = {
Jason Evans3c4d92e2014-10-12 22:53:59 -0700470 {NAME("nthreads"), CTL(stats_arenas_i_nthreads)},
Qi Wangbaf3e292017-05-16 13:56:00 -0700471 {NAME("uptime"), CTL(stats_arenas_i_uptime)},
Jason Evans3c4d92e2014-10-12 22:53:59 -0700472 {NAME("dss"), CTL(stats_arenas_i_dss)},
Jason Evans6e62c622017-05-17 10:47:00 -0700473 {NAME("dirty_decay_ms"), CTL(stats_arenas_i_dirty_decay_ms)},
474 {NAME("muzzy_decay_ms"), CTL(stats_arenas_i_muzzy_decay_ms)},
Jason Evans3c4d92e2014-10-12 22:53:59 -0700475 {NAME("pactive"), CTL(stats_arenas_i_pactive)},
476 {NAME("pdirty"), CTL(stats_arenas_i_pdirty)},
Jason Evans64e458f2017-03-08 22:42:57 -0800477 {NAME("pmuzzy"), CTL(stats_arenas_i_pmuzzy)},
Jason Evans3c4d92e2014-10-12 22:53:59 -0700478 {NAME("mapped"), CTL(stats_arenas_i_mapped)},
Jason Evans04c3c0f2016-05-03 22:11:35 -0700479 {NAME("retained"), CTL(stats_arenas_i_retained)},
Jason Evans64e458f2017-03-08 22:42:57 -0800480 {NAME("dirty_npurge"), CTL(stats_arenas_i_dirty_npurge)},
481 {NAME("dirty_nmadvise"), CTL(stats_arenas_i_dirty_nmadvise)},
482 {NAME("dirty_purged"), CTL(stats_arenas_i_dirty_purged)},
483 {NAME("muzzy_npurge"), CTL(stats_arenas_i_muzzy_npurge)},
484 {NAME("muzzy_nmadvise"), CTL(stats_arenas_i_muzzy_nmadvise)},
485 {NAME("muzzy_purged"), CTL(stats_arenas_i_muzzy_purged)},
Jason Evansa0dd3a42016-12-22 16:39:10 -0600486 {NAME("base"), CTL(stats_arenas_i_base)},
487 {NAME("internal"), CTL(stats_arenas_i_internal)},
Qi Wange55c3ca2017-08-25 13:24:49 -0700488 {NAME("metadata_thp"), CTL(stats_arenas_i_metadata_thp)},
Qi Wang58424e62016-04-22 18:37:44 -0700489 {NAME("tcache_bytes"), CTL(stats_arenas_i_tcache_bytes)},
Jason Evansa0dd3a42016-12-22 16:39:10 -0600490 {NAME("resident"), CTL(stats_arenas_i_resident)},
Jason Evans3c4d92e2014-10-12 22:53:59 -0700491 {NAME("small"), CHILD(named, stats_arenas_i_small)},
Jason Evans7d63fed2016-05-31 14:50:21 -0700492 {NAME("large"), CHILD(named, stats_arenas_i_large)},
Jason Evans3c4d92e2014-10-12 22:53:59 -0700493 {NAME("bins"), CHILD(indexed, stats_arenas_i_bins)},
Qi Wang0fb5c0e2017-03-10 12:14:05 -0800494 {NAME("lextents"), CHILD(indexed, stats_arenas_i_lextents)},
Qi Wang64c5f5c2017-03-13 17:29:03 -0700495 {NAME("mutexes"), CHILD(named, stats_arenas_i_mutexes)}
Jason Evans3c234352010-01-27 13:10:55 -0800496};
Mike Hommey461ad5c2012-04-20 08:38:42 +0200497static const ctl_named_node_t super_stats_arenas_i_node[] = {
Jason Evans3c4d92e2014-10-12 22:53:59 -0700498 {NAME(""), CHILD(named, stats_arenas_i)}
Jason Evans3c234352010-01-27 13:10:55 -0800499};
500
Mike Hommey461ad5c2012-04-20 08:38:42 +0200501static const ctl_indexed_node_t stats_arenas_node[] = {
Jason Evans3c234352010-01-27 13:10:55 -0800502 {INDEX(stats_arenas_i)}
503};
504
Qi Wang2bee0c62017-05-12 12:30:33 -0700505static const ctl_named_node_t stats_background_thread_node[] = {
506 {NAME("num_threads"), CTL(stats_background_thread_num_threads)},
507 {NAME("num_runs"), CTL(stats_background_thread_num_runs)},
508 {NAME("run_interval"), CTL(stats_background_thread_run_interval)}
509};
510
Qi Wangd3fde1c2017-03-21 11:56:38 -0700511#define OP(mtx) MUTEX_PROF_DATA_NODE(mutexes_##mtx)
David Goldblatt89e2d3c2017-04-24 17:09:56 -0700512MUTEX_PROF_GLOBAL_MUTEXES
Qi Wangd3fde1c2017-03-21 11:56:38 -0700513#undef OP
514
Qi Wang64c5f5c2017-03-13 17:29:03 -0700515static const ctl_named_node_t stats_mutexes_node[] = {
Qi Wangd3fde1c2017-03-21 11:56:38 -0700516#define OP(mtx) {NAME(#mtx), CHILD(named, stats_mutexes_##mtx)},
David Goldblatt89e2d3c2017-04-24 17:09:56 -0700517MUTEX_PROF_GLOBAL_MUTEXES
Qi Wangd3fde1c2017-03-21 11:56:38 -0700518#undef OP
Qi Wang64c5f5c2017-03-13 17:29:03 -0700519 {NAME("reset"), CTL(stats_mutexes_reset)}
Qi Wangca9074d2017-03-11 20:28:31 -0800520};
Qi Wangd3fde1c2017-03-21 11:56:38 -0700521#undef MUTEX_PROF_DATA_NODE
Qi Wangca9074d2017-03-11 20:28:31 -0800522
Mike Hommey461ad5c2012-04-20 08:38:42 +0200523static const ctl_named_node_t stats_node[] = {
Jason Evans3c4d92e2014-10-12 22:53:59 -0700524 {NAME("allocated"), CTL(stats_allocated)},
525 {NAME("active"), CTL(stats_active)},
Jason Evans4581b972014-11-27 17:22:36 -0200526 {NAME("metadata"), CTL(stats_metadata)},
Qi Wange55c3ca2017-08-25 13:24:49 -0700527 {NAME("metadata_thp"), CTL(stats_metadata_thp)},
Jason Evans4acd75a2015-03-23 17:25:57 -0700528 {NAME("resident"), CTL(stats_resident)},
Jason Evans3c4d92e2014-10-12 22:53:59 -0700529 {NAME("mapped"), CTL(stats_mapped)},
Jason Evans04c3c0f2016-05-03 22:11:35 -0700530 {NAME("retained"), CTL(stats_retained)},
Qi Wang2bee0c62017-05-12 12:30:33 -0700531 {NAME("background_thread"),
532 CHILD(named, stats_background_thread)},
Qi Wang64c5f5c2017-03-13 17:29:03 -0700533 {NAME("mutexes"), CHILD(named, stats_mutexes)},
Jason Evans3c4d92e2014-10-12 22:53:59 -0700534 {NAME("arenas"), CHILD(indexed, stats_arenas)}
Jason Evans3c234352010-01-27 13:10:55 -0800535};
536
Mike Hommey461ad5c2012-04-20 08:38:42 +0200537static const ctl_named_node_t root_node[] = {
Jason Evansa40bc7a2010-03-02 13:01:16 -0800538 {NAME("version"), CTL(version)},
Jason Evans3c234352010-01-27 13:10:55 -0800539 {NAME("epoch"), CTL(epoch)},
Qi Wangb693c782017-03-17 12:42:33 -0700540 {NAME("background_thread"), CTL(background_thread)},
Dave Watson8b14f3a2018-03-29 12:58:13 -0700541 {NAME("max_background_threads"), CTL(max_background_threads)},
Jason Evans65f343a2012-04-23 19:31:45 -0700542 {NAME("thread"), CHILD(named, thread)},
543 {NAME("config"), CHILD(named, config)},
544 {NAME("opt"), CHILD(named, opt)},
Jason Evans1cb181e2015-01-29 15:30:47 -0800545 {NAME("tcache"), CHILD(named, tcache)},
Jason Evans609ae592012-10-11 13:53:15 -0700546 {NAME("arena"), CHILD(indexed, arena)},
Jason Evans65f343a2012-04-23 19:31:45 -0700547 {NAME("arenas"), CHILD(named, arenas)},
548 {NAME("prof"), CHILD(named, prof)},
549 {NAME("stats"), CHILD(named, stats)}
Jason Evans3c234352010-01-27 13:10:55 -0800550};
Mike Hommey461ad5c2012-04-20 08:38:42 +0200551static const ctl_named_node_t super_root_node[] = {
Jason Evans65f343a2012-04-23 19:31:45 -0700552 {NAME(""), CHILD(named, root)}
Jason Evans3c234352010-01-27 13:10:55 -0800553};
554
555#undef NAME
556#undef CHILD
557#undef CTL
558#undef INDEX
559
560/******************************************************************************/
561
David Goldblatt4fc2acf2017-03-08 15:56:31 -0800562/*
563 * Sets *dst + *src non-atomically. This is safe, since everything is
564 * synchronized by the ctl mutex.
565 */
566static void
David T. Goldblatt7f1b02e2017-11-04 12:50:19 -0700567ctl_accum_arena_stats_u64(arena_stats_u64_t *dst, arena_stats_u64_t *src) {
David Goldblatt4fc2acf2017-03-08 15:56:31 -0800568#ifdef JEMALLOC_ATOMIC_U64
569 uint64_t cur_dst = atomic_load_u64(dst, ATOMIC_RELAXED);
570 uint64_t cur_src = atomic_load_u64(src, ATOMIC_RELAXED);
571 atomic_store_u64(dst, cur_dst + cur_src, ATOMIC_RELAXED);
572#else
573 *dst += *src;
574#endif
575}
576
577/* Likewise: with ctl mutex synchronization, reading is simple. */
578static uint64_t
David T. Goldblatt7f1b02e2017-11-04 12:50:19 -0700579ctl_arena_stats_read_u64(arena_stats_u64_t *p) {
David Goldblatt4fc2acf2017-03-08 15:56:31 -0800580#ifdef JEMALLOC_ATOMIC_U64
581 return atomic_load_u64(p, ATOMIC_RELAXED);
582#else
583 return *p;
584#endif
585}
586
David T. Goldblatt7f1b02e2017-11-04 12:50:19 -0700587static void
588accum_atomic_zu(atomic_zu_t *dst, atomic_zu_t *src) {
David Goldblattee202ef2017-03-13 16:18:40 -0700589 size_t cur_dst = atomic_load_zu(dst, ATOMIC_RELAXED);
590 size_t cur_src = atomic_load_zu(src, ATOMIC_RELAXED);
591 atomic_store_zu(dst, cur_dst + cur_src, ATOMIC_RELAXED);
592}
593
David Goldblatt4fc2acf2017-03-08 15:56:31 -0800594/******************************************************************************/
595
Jason Evans3dc4e832017-01-03 07:27:42 -0800596static unsigned
Jason Evansc4c25922017-01-15 16:56:30 -0800597arenas_i2a_impl(size_t i, bool compat, bool validate) {
Jason Evans3dc4e832017-01-03 07:27:42 -0800598 unsigned a;
599
Jason Evans3dc4e832017-01-03 07:27:42 -0800600 switch (i) {
601 case MALLCTL_ARENAS_ALL:
602 a = 0;
603 break;
Jason Evansedf1baf2017-01-03 17:21:59 -0800604 case MALLCTL_ARENAS_DESTROYED:
605 a = 1;
606 break;
Jason Evans3dc4e832017-01-03 07:27:42 -0800607 default:
Jason Evans9eb1b1c2017-01-18 23:03:37 -0800608 if (compat && i == ctl_arenas->narenas) {
Jason Evans3dc4e832017-01-03 07:27:42 -0800609 /*
610 * Provide deprecated backward compatibility for
611 * accessing the merged stats at index narenas rather
612 * than via MALLCTL_ARENAS_ALL. This is scheduled for
613 * removal in 6.0.0.
614 */
615 a = 0;
Jason Evansc4c25922017-01-15 16:56:30 -0800616 } else if (validate && i >= ctl_arenas->narenas) {
Jason Evans3dc4e832017-01-03 07:27:42 -0800617 a = UINT_MAX;
Jason Evansc4c25922017-01-15 16:56:30 -0800618 } else {
Jason Evans3dc4e832017-01-03 07:27:42 -0800619 /*
620 * This function should never be called for an index
621 * more than one past the range of indices that have
Jason Evans9eb1b1c2017-01-18 23:03:37 -0800622 * initialized ctl data.
Jason Evans3dc4e832017-01-03 07:27:42 -0800623 */
Jason Evans9eb1b1c2017-01-18 23:03:37 -0800624 assert(i < ctl_arenas->narenas || (!validate && i ==
625 ctl_arenas->narenas));
Jason Evansedf1baf2017-01-03 17:21:59 -0800626 a = (unsigned)i + 2;
Jason Evans3dc4e832017-01-03 07:27:42 -0800627 }
628 break;
629 }
630
Jason Evansf4086432017-01-19 18:15:45 -0800631 return a;
Jason Evans3dc4e832017-01-03 07:27:42 -0800632}
633
Jason Evansedf1baf2017-01-03 17:21:59 -0800634static unsigned
Jason Evansc4c25922017-01-15 16:56:30 -0800635arenas_i2a(size_t i) {
Jason Evansf4086432017-01-19 18:15:45 -0800636 return arenas_i2a_impl(i, true, false);
Jason Evansedf1baf2017-01-03 17:21:59 -0800637}
638
Jason Evans9eb1b1c2017-01-18 23:03:37 -0800639static ctl_arena_t *
Qi Wang57beeb22017-06-22 18:58:40 -0700640arenas_i_impl(tsd_t *tsd, size_t i, bool compat, bool init) {
Jason Evans9eb1b1c2017-01-18 23:03:37 -0800641 ctl_arena_t *ret;
Jason Evansd778dd22017-01-03 12:40:54 -0800642
643 assert(!compat || !init);
644
Jason Evans9eb1b1c2017-01-18 23:03:37 -0800645 ret = ctl_arenas->arenas[arenas_i2a_impl(i, compat, false)];
Jason Evansd778dd22017-01-03 12:40:54 -0800646 if (init && ret == NULL) {
Jason Evans9eb1b1c2017-01-18 23:03:37 -0800647 if (config_stats) {
648 struct container_s {
649 ctl_arena_t ctl_arena;
650 ctl_arena_stats_t astats;
651 };
652 struct container_s *cont =
Qi Wang57beeb22017-06-22 18:58:40 -0700653 (struct container_s *)base_alloc(tsd_tsdn(tsd),
654 b0get(), sizeof(struct container_s), QUANTUM);
Jason Evans9eb1b1c2017-01-18 23:03:37 -0800655 if (cont == NULL) {
656 return NULL;
657 }
658 ret = &cont->ctl_arena;
659 ret->astats = &cont->astats;
660 } else {
Qi Wang57beeb22017-06-22 18:58:40 -0700661 ret = (ctl_arena_t *)base_alloc(tsd_tsdn(tsd), b0get(),
Jason Evans9eb1b1c2017-01-18 23:03:37 -0800662 sizeof(ctl_arena_t), QUANTUM);
663 if (ret == NULL) {
664 return NULL;
665 }
666 }
Jason Evansedf1baf2017-01-03 17:21:59 -0800667 ret->arena_ind = (unsigned)i;
Jason Evans9eb1b1c2017-01-18 23:03:37 -0800668 ctl_arenas->arenas[arenas_i2a_impl(i, compat, false)] = ret;
Jason Evansd778dd22017-01-03 12:40:54 -0800669 }
670
Jason Evans9eb1b1c2017-01-18 23:03:37 -0800671 assert(ret == NULL || arenas_i2a(ret->arena_ind) == arenas_i2a(i));
Jason Evansf4086432017-01-19 18:15:45 -0800672 return ret;
Jason Evansd778dd22017-01-03 12:40:54 -0800673}
674
Jason Evans9eb1b1c2017-01-18 23:03:37 -0800675static ctl_arena_t *
Jason Evansc4c25922017-01-15 16:56:30 -0800676arenas_i(size_t i) {
Qi Wang57beeb22017-06-22 18:58:40 -0700677 ctl_arena_t *ret = arenas_i_impl(tsd_fetch(), i, true, false);
Jason Evansd778dd22017-01-03 12:40:54 -0800678 assert(ret != NULL);
Jason Evansf4086432017-01-19 18:15:45 -0800679 return ret;
Jason Evans3dc4e832017-01-03 07:27:42 -0800680}
681
Jason Evans3c234352010-01-27 13:10:55 -0800682static void
Jason Evansc4c25922017-01-15 16:56:30 -0800683ctl_arena_clear(ctl_arena_t *ctl_arena) {
Jason Evans9eb1b1c2017-01-18 23:03:37 -0800684 ctl_arena->nthreads = 0;
685 ctl_arena->dss = dss_prec_names[dss_prec_limit];
Jason Evans6e62c622017-05-17 10:47:00 -0700686 ctl_arena->dirty_decay_ms = -1;
687 ctl_arena->muzzy_decay_ms = -1;
Jason Evans9eb1b1c2017-01-18 23:03:37 -0800688 ctl_arena->pactive = 0;
689 ctl_arena->pdirty = 0;
Jason Evans64e458f2017-03-08 22:42:57 -0800690 ctl_arena->pmuzzy = 0;
Jason Evans7372b152012-02-10 20:22:09 -0800691 if (config_stats) {
Jason Evans9eb1b1c2017-01-18 23:03:37 -0800692 memset(&ctl_arena->astats->astats, 0, sizeof(arena_stats_t));
693 ctl_arena->astats->allocated_small = 0;
694 ctl_arena->astats->nmalloc_small = 0;
695 ctl_arena->astats->ndalloc_small = 0;
696 ctl_arena->astats->nrequests_small = 0;
697 memset(ctl_arena->astats->bstats, 0, NBINS *
David T. Goldblatt7f1b02e2017-11-04 12:50:19 -0700698 sizeof(bin_stats_t));
Jason Evans9eb1b1c2017-01-18 23:03:37 -0800699 memset(ctl_arena->astats->lstats, 0, (NSIZES - NBINS) *
David T. Goldblatt7f1b02e2017-11-04 12:50:19 -0700700 sizeof(arena_stats_large_t));
Jason Evans7372b152012-02-10 20:22:09 -0800701 }
Jason Evans3c234352010-01-27 13:10:55 -0800702}
703
Jason Evans86815df2010-03-13 20:32:56 -0800704static void
Jason Evansc4c25922017-01-15 16:56:30 -0800705ctl_arena_stats_amerge(tsdn_t *tsdn, ctl_arena_t *ctl_arena, arena_t *arena) {
Jason Evans86815df2010-03-13 20:32:56 -0800706 unsigned i;
707
Jason Evans3c07f802016-02-27 20:40:13 -0800708 if (config_stats) {
Jason Evans9eb1b1c2017-01-18 23:03:37 -0800709 arena_stats_merge(tsdn, arena, &ctl_arena->nthreads,
Jason Evans6e62c622017-05-17 10:47:00 -0700710 &ctl_arena->dss, &ctl_arena->dirty_decay_ms,
711 &ctl_arena->muzzy_decay_ms, &ctl_arena->pactive,
Jason Evans64e458f2017-03-08 22:42:57 -0800712 &ctl_arena->pdirty, &ctl_arena->pmuzzy,
Jason Evans9eb1b1c2017-01-18 23:03:37 -0800713 &ctl_arena->astats->astats, ctl_arena->astats->bstats,
714 ctl_arena->astats->lstats);
Jason Evans86815df2010-03-13 20:32:56 -0800715
Jason Evans3c07f802016-02-27 20:40:13 -0800716 for (i = 0; i < NBINS; i++) {
Jason Evans9eb1b1c2017-01-18 23:03:37 -0800717 ctl_arena->astats->allocated_small +=
718 ctl_arena->astats->bstats[i].curregs *
David Goldblatt8261e582017-05-30 10:45:37 -0700719 sz_index2size(i);
Jason Evans9eb1b1c2017-01-18 23:03:37 -0800720 ctl_arena->astats->nmalloc_small +=
721 ctl_arena->astats->bstats[i].nmalloc;
722 ctl_arena->astats->ndalloc_small +=
723 ctl_arena->astats->bstats[i].ndalloc;
724 ctl_arena->astats->nrequests_small +=
725 ctl_arena->astats->bstats[i].nrequests;
Jason Evans3c07f802016-02-27 20:40:13 -0800726 }
727 } else {
Jason Evans9eb1b1c2017-01-18 23:03:37 -0800728 arena_basic_stats_merge(tsdn, arena, &ctl_arena->nthreads,
Jason Evans6e62c622017-05-17 10:47:00 -0700729 &ctl_arena->dss, &ctl_arena->dirty_decay_ms,
730 &ctl_arena->muzzy_decay_ms, &ctl_arena->pactive,
Jason Evans64e458f2017-03-08 22:42:57 -0800731 &ctl_arena->pdirty, &ctl_arena->pmuzzy);
Jason Evans86815df2010-03-13 20:32:56 -0800732 }
Jason Evans86815df2010-03-13 20:32:56 -0800733}
734
735static void
Jason Evans9eb1b1c2017-01-18 23:03:37 -0800736ctl_arena_stats_sdmerge(ctl_arena_t *ctl_sdarena, ctl_arena_t *ctl_arena,
Jason Evansc4c25922017-01-15 16:56:30 -0800737 bool destroyed) {
Jason Evans86815df2010-03-13 20:32:56 -0800738 unsigned i;
739
Jason Evansedf1baf2017-01-03 17:21:59 -0800740 if (!destroyed) {
Jason Evans9eb1b1c2017-01-18 23:03:37 -0800741 ctl_sdarena->nthreads += ctl_arena->nthreads;
742 ctl_sdarena->pactive += ctl_arena->pactive;
743 ctl_sdarena->pdirty += ctl_arena->pdirty;
Jason Evans64e458f2017-03-08 22:42:57 -0800744 ctl_sdarena->pmuzzy += ctl_arena->pmuzzy;
Jason Evansedf1baf2017-01-03 17:21:59 -0800745 } else {
Jason Evans9eb1b1c2017-01-18 23:03:37 -0800746 assert(ctl_arena->nthreads == 0);
747 assert(ctl_arena->pactive == 0);
748 assert(ctl_arena->pdirty == 0);
Jason Evans64e458f2017-03-08 22:42:57 -0800749 assert(ctl_arena->pmuzzy == 0);
Jason Evansedf1baf2017-01-03 17:21:59 -0800750 }
Jason Evans86815df2010-03-13 20:32:56 -0800751
Jason Evans3c07f802016-02-27 20:40:13 -0800752 if (config_stats) {
Jason Evans9eb1b1c2017-01-18 23:03:37 -0800753 ctl_arena_stats_t *sdstats = ctl_sdarena->astats;
754 ctl_arena_stats_t *astats = ctl_arena->astats;
755
Jason Evansedf1baf2017-01-03 17:21:59 -0800756 if (!destroyed) {
David Goldblattee202ef2017-03-13 16:18:40 -0700757 accum_atomic_zu(&sdstats->astats.mapped,
758 &astats->astats.mapped);
759 accum_atomic_zu(&sdstats->astats.retained,
760 &astats->astats.retained);
Jason Evansedf1baf2017-01-03 17:21:59 -0800761 }
Jason Evans64e458f2017-03-08 22:42:57 -0800762
David T. Goldblatt7f1b02e2017-11-04 12:50:19 -0700763 ctl_accum_arena_stats_u64(&sdstats->astats.decay_dirty.npurge,
Jason Evans64e458f2017-03-08 22:42:57 -0800764 &astats->astats.decay_dirty.npurge);
David T. Goldblatt7f1b02e2017-11-04 12:50:19 -0700765 ctl_accum_arena_stats_u64(&sdstats->astats.decay_dirty.nmadvise,
Jason Evans64e458f2017-03-08 22:42:57 -0800766 &astats->astats.decay_dirty.nmadvise);
David T. Goldblatt7f1b02e2017-11-04 12:50:19 -0700767 ctl_accum_arena_stats_u64(&sdstats->astats.decay_dirty.purged,
Jason Evans64e458f2017-03-08 22:42:57 -0800768 &astats->astats.decay_dirty.purged);
769
David T. Goldblatt7f1b02e2017-11-04 12:50:19 -0700770 ctl_accum_arena_stats_u64(&sdstats->astats.decay_muzzy.npurge,
Jason Evans64e458f2017-03-08 22:42:57 -0800771 &astats->astats.decay_muzzy.npurge);
David T. Goldblatt7f1b02e2017-11-04 12:50:19 -0700772 ctl_accum_arena_stats_u64(&sdstats->astats.decay_muzzy.nmadvise,
Jason Evans64e458f2017-03-08 22:42:57 -0800773 &astats->astats.decay_muzzy.nmadvise);
David T. Goldblatt7f1b02e2017-11-04 12:50:19 -0700774 ctl_accum_arena_stats_u64(&sdstats->astats.decay_muzzy.purged,
Jason Evans64e458f2017-03-08 22:42:57 -0800775 &astats->astats.decay_muzzy.purged);
Jason Evans86815df2010-03-13 20:32:56 -0800776
Qi Wangd3fde1c2017-03-21 11:56:38 -0700777#define OP(mtx) malloc_mutex_prof_merge( \
778 &(sdstats->astats.mutex_prof_data[ \
779 arena_prof_mutex_##mtx]), \
780 &(astats->astats.mutex_prof_data[ \
781 arena_prof_mutex_##mtx]));
David Goldblatt89e2d3c2017-04-24 17:09:56 -0700782MUTEX_PROF_ARENA_MUTEXES
Qi Wangd3fde1c2017-03-21 11:56:38 -0700783#undef OP
Jason Evansedf1baf2017-01-03 17:21:59 -0800784 if (!destroyed) {
David Goldblattee202ef2017-03-13 16:18:40 -0700785 accum_atomic_zu(&sdstats->astats.base,
786 &astats->astats.base);
787 accum_atomic_zu(&sdstats->astats.internal,
788 &astats->astats.internal);
789 accum_atomic_zu(&sdstats->astats.resident,
790 &astats->astats.resident);
Qi Wange55c3ca2017-08-25 13:24:49 -0700791 accum_atomic_zu(&sdstats->astats.metadata_thp,
792 &astats->astats.metadata_thp);
Jason Evansc4c25922017-01-15 16:56:30 -0800793 } else {
David Goldblattee202ef2017-03-13 16:18:40 -0700794 assert(atomic_load_zu(
795 &astats->astats.internal, ATOMIC_RELAXED) == 0);
Jason Evansc4c25922017-01-15 16:56:30 -0800796 }
Jason Evans4581b972014-11-27 17:22:36 -0200797
Jason Evansc4c25922017-01-15 16:56:30 -0800798 if (!destroyed) {
Jason Evansedf1baf2017-01-03 17:21:59 -0800799 sdstats->allocated_small += astats->allocated_small;
Jason Evansc4c25922017-01-15 16:56:30 -0800800 } else {
Jason Evansedf1baf2017-01-03 17:21:59 -0800801 assert(astats->allocated_small == 0);
Jason Evansc4c25922017-01-15 16:56:30 -0800802 }
Jason Evansedf1baf2017-01-03 17:21:59 -0800803 sdstats->nmalloc_small += astats->nmalloc_small;
804 sdstats->ndalloc_small += astats->ndalloc_small;
805 sdstats->nrequests_small += astats->nrequests_small;
Jason Evans86815df2010-03-13 20:32:56 -0800806
Jason Evansedf1baf2017-01-03 17:21:59 -0800807 if (!destroyed) {
David Goldblattee202ef2017-03-13 16:18:40 -0700808 accum_atomic_zu(&sdstats->astats.allocated_large,
809 &astats->astats.allocated_large);
Jason Evansc4c25922017-01-15 16:56:30 -0800810 } else {
David Goldblattee202ef2017-03-13 16:18:40 -0700811 assert(atomic_load_zu(&astats->astats.allocated_large,
812 ATOMIC_RELAXED) == 0);
Jason Evansc4c25922017-01-15 16:56:30 -0800813 }
David T. Goldblatt7f1b02e2017-11-04 12:50:19 -0700814 ctl_accum_arena_stats_u64(&sdstats->astats.nmalloc_large,
David Goldblatt4fc2acf2017-03-08 15:56:31 -0800815 &astats->astats.nmalloc_large);
David T. Goldblatt7f1b02e2017-11-04 12:50:19 -0700816 ctl_accum_arena_stats_u64(&sdstats->astats.ndalloc_large,
David Goldblatt4fc2acf2017-03-08 15:56:31 -0800817 &astats->astats.ndalloc_large);
David T. Goldblatt7f1b02e2017-11-04 12:50:19 -0700818 ctl_accum_arena_stats_u64(&sdstats->astats.nrequests_large,
David Goldblatt4fc2acf2017-03-08 15:56:31 -0800819 &astats->astats.nrequests_large);
Jason Evans86815df2010-03-13 20:32:56 -0800820
Jason Evans4403c9a2017-04-20 17:21:37 -0700821 accum_atomic_zu(&sdstats->astats.tcache_bytes,
822 &astats->astats.tcache_bytes);
Qi Wang58424e62016-04-22 18:37:44 -0700823
Qi Wangbaf3e292017-05-16 13:56:00 -0700824 if (ctl_arena->arena_ind == 0) {
825 sdstats->astats.uptime = astats->astats.uptime;
826 }
827
Jason Evans3c07f802016-02-27 20:40:13 -0800828 for (i = 0; i < NBINS; i++) {
Jason Evansedf1baf2017-01-03 17:21:59 -0800829 sdstats->bstats[i].nmalloc += astats->bstats[i].nmalloc;
830 sdstats->bstats[i].ndalloc += astats->bstats[i].ndalloc;
831 sdstats->bstats[i].nrequests +=
Jason Evans3c07f802016-02-27 20:40:13 -0800832 astats->bstats[i].nrequests;
Jason Evansedf1baf2017-01-03 17:21:59 -0800833 if (!destroyed) {
834 sdstats->bstats[i].curregs +=
835 astats->bstats[i].curregs;
Jason Evansc4c25922017-01-15 16:56:30 -0800836 } else {
Jason Evansedf1baf2017-01-03 17:21:59 -0800837 assert(astats->bstats[i].curregs == 0);
Jason Evansc4c25922017-01-15 16:56:30 -0800838 }
Jason Evans4403c9a2017-04-20 17:21:37 -0700839 sdstats->bstats[i].nfills += astats->bstats[i].nfills;
840 sdstats->bstats[i].nflushes +=
841 astats->bstats[i].nflushes;
Jason Evansedf1baf2017-01-03 17:21:59 -0800842 sdstats->bstats[i].nslabs += astats->bstats[i].nslabs;
843 sdstats->bstats[i].reslabs += astats->bstats[i].reslabs;
844 if (!destroyed) {
845 sdstats->bstats[i].curslabs +=
846 astats->bstats[i].curslabs;
Jason Evansc4c25922017-01-15 16:56:30 -0800847 } else {
Jason Evansedf1baf2017-01-03 17:21:59 -0800848 assert(astats->bstats[i].curslabs == 0);
Jason Evansc4c25922017-01-15 16:56:30 -0800849 }
Qi Wang64c5f5c2017-03-13 17:29:03 -0700850 malloc_mutex_prof_merge(&sdstats->bstats[i].mutex_data,
851 &astats->bstats[i].mutex_data);
Jason Evans7372b152012-02-10 20:22:09 -0800852 }
Jason Evans3c4d92e2014-10-12 22:53:59 -0700853
Jason Evansed2c2422016-05-28 00:17:28 -0700854 for (i = 0; i < NSIZES - NBINS; i++) {
David T. Goldblatt7f1b02e2017-11-04 12:50:19 -0700855 ctl_accum_arena_stats_u64(&sdstats->lstats[i].nmalloc,
David Goldblatt4fc2acf2017-03-08 15:56:31 -0800856 &astats->lstats[i].nmalloc);
David T. Goldblatt7f1b02e2017-11-04 12:50:19 -0700857 ctl_accum_arena_stats_u64(&sdstats->lstats[i].ndalloc,
David Goldblatt4fc2acf2017-03-08 15:56:31 -0800858 &astats->lstats[i].ndalloc);
David T. Goldblatt7f1b02e2017-11-04 12:50:19 -0700859 ctl_accum_arena_stats_u64(&sdstats->lstats[i].nrequests,
David Goldblatt4fc2acf2017-03-08 15:56:31 -0800860 &astats->lstats[i].nrequests);
Jason Evansedf1baf2017-01-03 17:21:59 -0800861 if (!destroyed) {
862 sdstats->lstats[i].curlextents +=
863 astats->lstats[i].curlextents;
Jason Evansc4c25922017-01-15 16:56:30 -0800864 } else {
Jason Evansedf1baf2017-01-03 17:21:59 -0800865 assert(astats->lstats[i].curlextents == 0);
Jason Evansc4c25922017-01-15 16:56:30 -0800866 }
Jason Evans3c07f802016-02-27 20:40:13 -0800867 }
Jason Evans3c4d92e2014-10-12 22:53:59 -0700868 }
Jason Evans86815df2010-03-13 20:32:56 -0800869}
Jason Evans86815df2010-03-13 20:32:56 -0800870
Jason Evans3c234352010-01-27 13:10:55 -0800871static void
Jason Evans9eb1b1c2017-01-18 23:03:37 -0800872ctl_arena_refresh(tsdn_t *tsdn, arena_t *arena, ctl_arena_t *ctl_sdarena,
Jason Evansc4c25922017-01-15 16:56:30 -0800873 unsigned i, bool destroyed) {
Jason Evans9eb1b1c2017-01-18 23:03:37 -0800874 ctl_arena_t *ctl_arena = arenas_i(i);
Jason Evans3c234352010-01-27 13:10:55 -0800875
Jason Evans9eb1b1c2017-01-18 23:03:37 -0800876 ctl_arena_clear(ctl_arena);
877 ctl_arena_stats_amerge(tsdn, ctl_arena, arena);
Jason Evans3c07f802016-02-27 20:40:13 -0800878 /* Merge into sum stats as well. */
Jason Evans9eb1b1c2017-01-18 23:03:37 -0800879 ctl_arena_stats_sdmerge(ctl_sdarena, ctl_arena, destroyed);
Jason Evans3c234352010-01-27 13:10:55 -0800880}
881
Jason Evansedf1baf2017-01-03 17:21:59 -0800882static unsigned
Qi Wang57beeb22017-06-22 18:58:40 -0700883ctl_arena_init(tsd_t *tsd, extent_hooks_t *extent_hooks) {
Jason Evansedf1baf2017-01-03 17:21:59 -0800884 unsigned arena_ind;
Jason Evans9eb1b1c2017-01-18 23:03:37 -0800885 ctl_arena_t *ctl_arena;
Jason Evansedf1baf2017-01-03 17:21:59 -0800886
Jason Evans9eb1b1c2017-01-18 23:03:37 -0800887 if ((ctl_arena = ql_last(&ctl_arenas->destroyed, destroyed_link)) !=
888 NULL) {
889 ql_remove(&ctl_arenas->destroyed, ctl_arena, destroyed_link);
890 arena_ind = ctl_arena->arena_ind;
Jason Evansc4c25922017-01-15 16:56:30 -0800891 } else {
Jason Evans9eb1b1c2017-01-18 23:03:37 -0800892 arena_ind = ctl_arenas->narenas;
Jason Evansc4c25922017-01-15 16:56:30 -0800893 }
Jason Evansd778dd22017-01-03 12:40:54 -0800894
895 /* Trigger stats allocation. */
Qi Wang57beeb22017-06-22 18:58:40 -0700896 if (arenas_i_impl(tsd, arena_ind, false, true) == NULL) {
Jason Evansf4086432017-01-19 18:15:45 -0800897 return UINT_MAX;
Jason Evansc4c25922017-01-15 16:56:30 -0800898 }
Jason Evans609ae592012-10-11 13:53:15 -0700899
Jason Evans8bb31982014-10-07 23:14:57 -0700900 /* Initialize new arena. */
Qi Wang57beeb22017-06-22 18:58:40 -0700901 if (arena_init(tsd_tsdn(tsd), arena_ind, extent_hooks) == NULL) {
Jason Evansf4086432017-01-19 18:15:45 -0800902 return UINT_MAX;
Jason Evansc4c25922017-01-15 16:56:30 -0800903 }
Jason Evans609ae592012-10-11 13:53:15 -0700904
Jason Evansc4c25922017-01-15 16:56:30 -0800905 if (arena_ind == ctl_arenas->narenas) {
Jason Evans9eb1b1c2017-01-18 23:03:37 -0800906 ctl_arenas->narenas++;
Jason Evansc4c25922017-01-15 16:56:30 -0800907 }
Jason Evansedf1baf2017-01-03 17:21:59 -0800908
Jason Evansf4086432017-01-19 18:15:45 -0800909 return arena_ind;
Jason Evans609ae592012-10-11 13:53:15 -0700910}
911
Jason Evans3c234352010-01-27 13:10:55 -0800912static void
Qi Wang2bee0c62017-05-12 12:30:33 -0700913ctl_background_thread_stats_read(tsdn_t *tsdn) {
914 background_thread_stats_t *stats = &ctl_stats->background_thread;
915 if (!have_background_thread ||
916 background_thread_stats_read(tsdn, stats)) {
917 memset(stats, 0, sizeof(background_thread_stats_t));
918 nstime_init(&stats->run_interval, 0);
919 }
920}
921
922static void
Jason Evansc4c25922017-01-15 16:56:30 -0800923ctl_refresh(tsdn_t *tsdn) {
Jason Evans3c234352010-01-27 13:10:55 -0800924 unsigned i;
Jason Evans9eb1b1c2017-01-18 23:03:37 -0800925 ctl_arena_t *ctl_sarena = arenas_i(MALLCTL_ARENAS_ALL);
926 VARIABLE_ARRAY(arena_t *, tarenas, ctl_arenas->narenas);
Jason Evans3c234352010-01-27 13:10:55 -0800927
Jason Evans3c234352010-01-27 13:10:55 -0800928 /*
Jason Evans13668262010-01-31 03:57:29 -0800929 * Clear sum stats, since they will be merged into by
Jason Evans3c234352010-01-27 13:10:55 -0800930 * ctl_arena_refresh().
931 */
Jason Evans9eb1b1c2017-01-18 23:03:37 -0800932 ctl_arena_clear(ctl_sarena);
Jason Evans3c234352010-01-27 13:10:55 -0800933
Jason Evans9eb1b1c2017-01-18 23:03:37 -0800934 for (i = 0; i < ctl_arenas->narenas; i++) {
Jason Evansc1e00ef2016-05-10 22:21:10 -0700935 tarenas[i] = arena_get(tsdn, i, false);
Jason Evans9eb1b1c2017-01-18 23:03:37 -0800936 }
Jason Evans8bb31982014-10-07 23:14:57 -0700937
Jason Evans9eb1b1c2017-01-18 23:03:37 -0800938 for (i = 0; i < ctl_arenas->narenas; i++) {
939 ctl_arena_t *ctl_arena = arenas_i(i);
Jason Evans3c234352010-01-27 13:10:55 -0800940 bool initialized = (tarenas[i] != NULL);
941
Jason Evans9eb1b1c2017-01-18 23:03:37 -0800942 ctl_arena->initialized = initialized;
943 if (initialized) {
944 ctl_arena_refresh(tsdn, tarenas[i], ctl_sarena, i,
945 false);
946 }
Jason Evans3c234352010-01-27 13:10:55 -0800947 }
948
Jason Evans7372b152012-02-10 20:22:09 -0800949 if (config_stats) {
Jason Evans9eb1b1c2017-01-18 23:03:37 -0800950 ctl_stats->allocated = ctl_sarena->astats->allocated_small +
David Goldblattee202ef2017-03-13 16:18:40 -0700951 atomic_load_zu(&ctl_sarena->astats->astats.allocated_large,
952 ATOMIC_RELAXED);
Jason Evans9eb1b1c2017-01-18 23:03:37 -0800953 ctl_stats->active = (ctl_sarena->pactive << LG_PAGE);
David Goldblattee202ef2017-03-13 16:18:40 -0700954 ctl_stats->metadata = atomic_load_zu(
955 &ctl_sarena->astats->astats.base, ATOMIC_RELAXED) +
956 atomic_load_zu(&ctl_sarena->astats->astats.internal,
957 ATOMIC_RELAXED);
Qi Wange55c3ca2017-08-25 13:24:49 -0700958 ctl_stats->metadata_thp = atomic_load_zu(
959 &ctl_sarena->astats->astats.metadata_thp, ATOMIC_RELAXED);
David Goldblattee202ef2017-03-13 16:18:40 -0700960 ctl_stats->resident = atomic_load_zu(
961 &ctl_sarena->astats->astats.resident, ATOMIC_RELAXED);
962 ctl_stats->mapped = atomic_load_zu(
963 &ctl_sarena->astats->astats.mapped, ATOMIC_RELAXED);
964 ctl_stats->retained = atomic_load_zu(
965 &ctl_sarena->astats->astats.retained, ATOMIC_RELAXED);
Qi Wangca9074d2017-03-11 20:28:31 -0800966
Qi Wang2bee0c62017-05-12 12:30:33 -0700967 ctl_background_thread_stats_read(tsdn);
968
Qi Wangd3fde1c2017-03-21 11:56:38 -0700969#define READ_GLOBAL_MUTEX_PROF_DATA(i, mtx) \
Qi Wangca9074d2017-03-11 20:28:31 -0800970 malloc_mutex_lock(tsdn, &mtx); \
Qi Wangd3fde1c2017-03-21 11:56:38 -0700971 malloc_mutex_prof_read(tsdn, &ctl_stats->mutex_prof_data[i], &mtx); \
Qi Wangca9074d2017-03-11 20:28:31 -0800972 malloc_mutex_unlock(tsdn, &mtx);
973
Qi Wangbd2006a2017-03-12 01:28:52 -0800974 if (config_prof && opt_prof) {
Qi Wangd3fde1c2017-03-21 11:56:38 -0700975 READ_GLOBAL_MUTEX_PROF_DATA(global_prof_mutex_prof,
976 bt2gctx_mtx);
Qi Wangbd2006a2017-03-12 01:28:52 -0800977 }
Qi Wang5f5ed212017-05-12 16:26:59 -0700978 if (have_background_thread) {
979 READ_GLOBAL_MUTEX_PROF_DATA(
980 global_prof_mutex_background_thread,
981 background_thread_lock);
982 } else {
983 memset(&ctl_stats->mutex_prof_data[
984 global_prof_mutex_background_thread], 0,
985 sizeof(mutex_prof_data_t));
986 }
Qi Wangca9074d2017-03-11 20:28:31 -0800987 /* We own ctl mutex already. */
Qi Wangd3fde1c2017-03-21 11:56:38 -0700988 malloc_mutex_prof_read(tsdn,
989 &ctl_stats->mutex_prof_data[global_prof_mutex_ctl],
990 &ctl_mtx);
Qi Wangca9074d2017-03-11 20:28:31 -0800991#undef READ_GLOBAL_MUTEX_PROF_DATA
Jason Evans7372b152012-02-10 20:22:09 -0800992 }
Jason Evans9eb1b1c2017-01-18 23:03:37 -0800993 ctl_arenas->epoch++;
Jason Evans3c234352010-01-27 13:10:55 -0800994}
995
996static bool
Qi Wang57beeb22017-06-22 18:58:40 -0700997ctl_init(tsd_t *tsd) {
Jason Evansfc4dcfa2010-11-24 15:44:21 -0800998 bool ret;
Qi Wang57beeb22017-06-22 18:58:40 -0700999 tsdn_t *tsdn = tsd_tsdn(tsd);
Jason Evans3c234352010-01-27 13:10:55 -08001000
Jason Evansc1e00ef2016-05-10 22:21:10 -07001001 malloc_mutex_lock(tsdn, &ctl_mtx);
Jason Evans551ebc42014-10-03 10:16:09 -07001002 if (!ctl_initialized) {
Jason Evans9eb1b1c2017-01-18 23:03:37 -08001003 ctl_arena_t *ctl_sarena, *ctl_darena;
Jason Evansd778dd22017-01-03 12:40:54 -08001004 unsigned i;
1005
Jason Evans3c234352010-01-27 13:10:55 -08001006 /*
Jason Evans9eb1b1c2017-01-18 23:03:37 -08001007 * Allocate demand-zeroed space for pointers to the full
1008 * range of supported arena indices.
Jason Evans3c234352010-01-27 13:10:55 -08001009 */
Jason Evans9eb1b1c2017-01-18 23:03:37 -08001010 if (ctl_arenas == NULL) {
1011 ctl_arenas = (ctl_arenas_t *)base_alloc(tsdn,
1012 b0get(), sizeof(ctl_arenas_t), QUANTUM);
1013 if (ctl_arenas == NULL) {
1014 ret = true;
1015 goto label_return;
1016 }
1017 }
1018
1019 if (config_stats && ctl_stats == NULL) {
Jason Evansd778dd22017-01-03 12:40:54 -08001020 ctl_stats = (ctl_stats_t *)base_alloc(tsdn, b0get(),
1021 sizeof(ctl_stats_t), QUANTUM);
1022 if (ctl_stats == NULL) {
1023 ret = true;
1024 goto label_return;
1025 }
1026 }
1027
1028 /*
Jason Evans9eb1b1c2017-01-18 23:03:37 -08001029 * Allocate space for the current full range of arenas
1030 * here rather than doing it lazily elsewhere, in order
1031 * to limit when OOM-caused errors can occur.
Jason Evansd778dd22017-01-03 12:40:54 -08001032 */
Qi Wang57beeb22017-06-22 18:58:40 -07001033 if ((ctl_sarena = arenas_i_impl(tsd, MALLCTL_ARENAS_ALL, false,
Jason Evans9eb1b1c2017-01-18 23:03:37 -08001034 true)) == NULL) {
1035 ret = true;
1036 goto label_return;
1037 }
1038 ctl_sarena->initialized = true;
1039
Qi Wang57beeb22017-06-22 18:58:40 -07001040 if ((ctl_darena = arenas_i_impl(tsd, MALLCTL_ARENAS_DESTROYED,
Jason Evansd778dd22017-01-03 12:40:54 -08001041 false, true)) == NULL) {
Jason Evansfc4dcfa2010-11-24 15:44:21 -08001042 ret = true;
Jason Evansa1ee7832012-04-10 15:07:44 -07001043 goto label_return;
Jason Evansfc4dcfa2010-11-24 15:44:21 -08001044 }
Jason Evans9eb1b1c2017-01-18 23:03:37 -08001045 ctl_arena_clear(ctl_darena);
Jason Evansedf1baf2017-01-03 17:21:59 -08001046 /*
Jason Evans9eb1b1c2017-01-18 23:03:37 -08001047 * Don't toggle ctl_darena to initialized until an arena is
1048 * actually destroyed, so that arena.<i>.initialized can be used
1049 * to query whether the stats are relevant.
Jason Evansedf1baf2017-01-03 17:21:59 -08001050 */
1051
Jason Evans9eb1b1c2017-01-18 23:03:37 -08001052 ctl_arenas->narenas = narenas_total_get();
1053 for (i = 0; i < ctl_arenas->narenas; i++) {
Qi Wang57beeb22017-06-22 18:58:40 -07001054 if (arenas_i_impl(tsd, i, false, true) == NULL) {
Jason Evansd778dd22017-01-03 12:40:54 -08001055 ret = true;
1056 goto label_return;
1057 }
1058 }
Jason Evans3c234352010-01-27 13:10:55 -08001059
Jason Evans9eb1b1c2017-01-18 23:03:37 -08001060 ql_new(&ctl_arenas->destroyed);
Jason Evansc1e00ef2016-05-10 22:21:10 -07001061 ctl_refresh(tsdn);
Jason Evans9eb1b1c2017-01-18 23:03:37 -08001062
Jason Evans3c234352010-01-27 13:10:55 -08001063 ctl_initialized = true;
1064 }
1065
Jason Evansfc4dcfa2010-11-24 15:44:21 -08001066 ret = false;
Jason Evansa1ee7832012-04-10 15:07:44 -07001067label_return:
Jason Evansc1e00ef2016-05-10 22:21:10 -07001068 malloc_mutex_unlock(tsdn, &ctl_mtx);
Jason Evansf4086432017-01-19 18:15:45 -08001069 return ret;
Jason Evans3c234352010-01-27 13:10:55 -08001070}
1071
1072static int
Jason Evansc1e00ef2016-05-10 22:21:10 -07001073ctl_lookup(tsdn_t *tsdn, const char *name, ctl_node_t const **nodesp,
Jason Evansc4c25922017-01-15 16:56:30 -08001074 size_t *mibp, size_t *depthp) {
Jason Evans3c234352010-01-27 13:10:55 -08001075 int ret;
1076 const char *elm, *tdot, *dot;
1077 size_t elen, i, j;
Mike Hommey461ad5c2012-04-20 08:38:42 +02001078 const ctl_named_node_t *node;
Jason Evans3c234352010-01-27 13:10:55 -08001079
1080 elm = name;
1081 /* Equivalent to strchrnul(). */
1082 dot = ((tdot = strchr(elm, '.')) != NULL) ? tdot : strchr(elm, '\0');
1083 elen = (size_t)((uintptr_t)dot - (uintptr_t)elm);
1084 if (elen == 0) {
1085 ret = ENOENT;
Jason Evansa1ee7832012-04-10 15:07:44 -07001086 goto label_return;
Jason Evans3c234352010-01-27 13:10:55 -08001087 }
1088 node = super_root_node;
1089 for (i = 0; i < *depthp; i++) {
Mike Hommey461ad5c2012-04-20 08:38:42 +02001090 assert(node);
1091 assert(node->nchildren > 0);
1092 if (ctl_named_node(node->children) != NULL) {
1093 const ctl_named_node_t *pnode = node;
Jason Evans3c234352010-01-27 13:10:55 -08001094
1095 /* Children are named. */
Mike Hommey461ad5c2012-04-20 08:38:42 +02001096 for (j = 0; j < node->nchildren; j++) {
1097 const ctl_named_node_t *child =
1098 ctl_named_children(node, j);
1099 if (strlen(child->name) == elen &&
1100 strncmp(elm, child->name, elen) == 0) {
Jason Evans3c234352010-01-27 13:10:55 -08001101 node = child;
Jason Evansc4c25922017-01-15 16:56:30 -08001102 if (nodesp != NULL) {
Mike Hommey461ad5c2012-04-20 08:38:42 +02001103 nodesp[i] =
1104 (const ctl_node_t *)node;
Jason Evansc4c25922017-01-15 16:56:30 -08001105 }
Jason Evans3c234352010-01-27 13:10:55 -08001106 mibp[i] = j;
1107 break;
1108 }
1109 }
1110 if (node == pnode) {
1111 ret = ENOENT;
Jason Evansa1ee7832012-04-10 15:07:44 -07001112 goto label_return;
Jason Evans3c234352010-01-27 13:10:55 -08001113 }
1114 } else {
Jason Evans41b6afb2012-02-02 22:04:57 -08001115 uintmax_t index;
Mike Hommey461ad5c2012-04-20 08:38:42 +02001116 const ctl_indexed_node_t *inode;
Jason Evans3c234352010-01-27 13:10:55 -08001117
1118 /* Children are indexed. */
Jason Evans41b6afb2012-02-02 22:04:57 -08001119 index = malloc_strtoumax(elm, NULL, 10);
1120 if (index == UINTMAX_MAX || index > SIZE_T_MAX) {
Jason Evans3c234352010-01-27 13:10:55 -08001121 ret = ENOENT;
Jason Evansa1ee7832012-04-10 15:07:44 -07001122 goto label_return;
Jason Evans3c234352010-01-27 13:10:55 -08001123 }
1124
Mike Hommey461ad5c2012-04-20 08:38:42 +02001125 inode = ctl_indexed_node(node->children);
Jason Evansc1e00ef2016-05-10 22:21:10 -07001126 node = inode->index(tsdn, mibp, *depthp, (size_t)index);
Jason Evans3c234352010-01-27 13:10:55 -08001127 if (node == NULL) {
1128 ret = ENOENT;
Jason Evansa1ee7832012-04-10 15:07:44 -07001129 goto label_return;
Jason Evans3c234352010-01-27 13:10:55 -08001130 }
1131
Jason Evansc4c25922017-01-15 16:56:30 -08001132 if (nodesp != NULL) {
Mike Hommey461ad5c2012-04-20 08:38:42 +02001133 nodesp[i] = (const ctl_node_t *)node;
Jason Evansc4c25922017-01-15 16:56:30 -08001134 }
Jason Evans3c234352010-01-27 13:10:55 -08001135 mibp[i] = (size_t)index;
1136 }
1137
1138 if (node->ctl != NULL) {
1139 /* Terminal node. */
1140 if (*dot != '\0') {
1141 /*
1142 * The name contains more elements than are
1143 * in this path through the tree.
1144 */
1145 ret = ENOENT;
Jason Evansa1ee7832012-04-10 15:07:44 -07001146 goto label_return;
Jason Evans3c234352010-01-27 13:10:55 -08001147 }
1148 /* Complete lookup successful. */
1149 *depthp = i + 1;
1150 break;
1151 }
1152
1153 /* Update elm. */
1154 if (*dot == '\0') {
1155 /* No more elements. */
1156 ret = ENOENT;
Jason Evansa1ee7832012-04-10 15:07:44 -07001157 goto label_return;
Jason Evans3c234352010-01-27 13:10:55 -08001158 }
1159 elm = &dot[1];
1160 dot = ((tdot = strchr(elm, '.')) != NULL) ? tdot :
1161 strchr(elm, '\0');
1162 elen = (size_t)((uintptr_t)dot - (uintptr_t)elm);
1163 }
1164
1165 ret = 0;
Jason Evansa1ee7832012-04-10 15:07:44 -07001166label_return:
Jason Evansf4086432017-01-19 18:15:45 -08001167 return ret;
Jason Evans3c234352010-01-27 13:10:55 -08001168}
1169
1170int
Jason Evansb2c0d632016-04-13 23:36:15 -07001171ctl_byname(tsd_t *tsd, const char *name, void *oldp, size_t *oldlenp,
Jason Evansc4c25922017-01-15 16:56:30 -08001172 void *newp, size_t newlen) {
Jason Evans3c234352010-01-27 13:10:55 -08001173 int ret;
1174 size_t depth;
1175 ctl_node_t const *nodes[CTL_MAX_DEPTH];
1176 size_t mib[CTL_MAX_DEPTH];
Mike Hommey461ad5c2012-04-20 08:38:42 +02001177 const ctl_named_node_t *node;
Jason Evans3c234352010-01-27 13:10:55 -08001178
Qi Wang57beeb22017-06-22 18:58:40 -07001179 if (!ctl_initialized && ctl_init(tsd)) {
Jason Evans3c234352010-01-27 13:10:55 -08001180 ret = EAGAIN;
Jason Evansa1ee7832012-04-10 15:07:44 -07001181 goto label_return;
Jason Evans3c234352010-01-27 13:10:55 -08001182 }
1183
1184 depth = CTL_MAX_DEPTH;
Jason Evansc1e00ef2016-05-10 22:21:10 -07001185 ret = ctl_lookup(tsd_tsdn(tsd), name, nodes, mib, &depth);
Jason Evansc4c25922017-01-15 16:56:30 -08001186 if (ret != 0) {
Jason Evansa1ee7832012-04-10 15:07:44 -07001187 goto label_return;
Jason Evansc4c25922017-01-15 16:56:30 -08001188 }
Jason Evans3c234352010-01-27 13:10:55 -08001189
Mike Hommey461ad5c2012-04-20 08:38:42 +02001190 node = ctl_named_node(nodes[depth-1]);
Jason Evansc4c25922017-01-15 16:56:30 -08001191 if (node != NULL && node->ctl) {
Jason Evansb2c0d632016-04-13 23:36:15 -07001192 ret = node->ctl(tsd, mib, depth, oldp, oldlenp, newp, newlen);
Qi Wangaa1de062017-03-01 14:43:35 -08001193 } else {
Jason Evans3c234352010-01-27 13:10:55 -08001194 /* The name refers to a partial path through the ctl tree. */
1195 ret = ENOENT;
Jason Evans3c234352010-01-27 13:10:55 -08001196 }
Jason Evans3c234352010-01-27 13:10:55 -08001197
Jason Evansa1ee7832012-04-10 15:07:44 -07001198label_return:
Jason Evans3c234352010-01-27 13:10:55 -08001199 return(ret);
1200}
1201
1202int
Qi Wang57beeb22017-06-22 18:58:40 -07001203ctl_nametomib(tsd_t *tsd, const char *name, size_t *mibp, size_t *miblenp) {
Jason Evans3c234352010-01-27 13:10:55 -08001204 int ret;
1205
Qi Wang57beeb22017-06-22 18:58:40 -07001206 if (!ctl_initialized && ctl_init(tsd)) {
Jason Evans3c234352010-01-27 13:10:55 -08001207 ret = EAGAIN;
Jason Evansa1ee7832012-04-10 15:07:44 -07001208 goto label_return;
Jason Evans3c234352010-01-27 13:10:55 -08001209 }
1210
Qi Wang57beeb22017-06-22 18:58:40 -07001211 ret = ctl_lookup(tsd_tsdn(tsd), name, NULL, mibp, miblenp);
Jason Evansa1ee7832012-04-10 15:07:44 -07001212label_return:
Jason Evans3c234352010-01-27 13:10:55 -08001213 return(ret);
1214}
1215
1216int
Jason Evansb2c0d632016-04-13 23:36:15 -07001217ctl_bymib(tsd_t *tsd, const size_t *mib, size_t miblen, void *oldp,
Jason Evansc4c25922017-01-15 16:56:30 -08001218 size_t *oldlenp, void *newp, size_t newlen) {
Jason Evans3c234352010-01-27 13:10:55 -08001219 int ret;
Mike Hommey461ad5c2012-04-20 08:38:42 +02001220 const ctl_named_node_t *node;
Jason Evans3c234352010-01-27 13:10:55 -08001221 size_t i;
1222
Qi Wang57beeb22017-06-22 18:58:40 -07001223 if (!ctl_initialized && ctl_init(tsd)) {
Jason Evans3c234352010-01-27 13:10:55 -08001224 ret = EAGAIN;
Jason Evansa1ee7832012-04-10 15:07:44 -07001225 goto label_return;
Jason Evans3c234352010-01-27 13:10:55 -08001226 }
1227
1228 /* Iterate down the tree. */
1229 node = super_root_node;
1230 for (i = 0; i < miblen; i++) {
Mike Hommey461ad5c2012-04-20 08:38:42 +02001231 assert(node);
1232 assert(node->nchildren > 0);
1233 if (ctl_named_node(node->children) != NULL) {
Jason Evans3c234352010-01-27 13:10:55 -08001234 /* Children are named. */
Jason Evans6edbedd2017-01-04 07:51:49 -08001235 if (node->nchildren <= mib[i]) {
Jason Evans3c234352010-01-27 13:10:55 -08001236 ret = ENOENT;
Jason Evansa1ee7832012-04-10 15:07:44 -07001237 goto label_return;
Jason Evans3c234352010-01-27 13:10:55 -08001238 }
Mike Hommey461ad5c2012-04-20 08:38:42 +02001239 node = ctl_named_children(node, mib[i]);
Jason Evans3c234352010-01-27 13:10:55 -08001240 } else {
Mike Hommey461ad5c2012-04-20 08:38:42 +02001241 const ctl_indexed_node_t *inode;
Jason Evans3c234352010-01-27 13:10:55 -08001242
1243 /* Indexed element. */
Mike Hommey461ad5c2012-04-20 08:38:42 +02001244 inode = ctl_indexed_node(node->children);
Jason Evansc1e00ef2016-05-10 22:21:10 -07001245 node = inode->index(tsd_tsdn(tsd), mib, miblen, mib[i]);
Jason Evans3c234352010-01-27 13:10:55 -08001246 if (node == NULL) {
1247 ret = ENOENT;
Jason Evansa1ee7832012-04-10 15:07:44 -07001248 goto label_return;
Jason Evans3c234352010-01-27 13:10:55 -08001249 }
1250 }
1251 }
1252
1253 /* Call the ctl function. */
Jason Evansc4c25922017-01-15 16:56:30 -08001254 if (node && node->ctl) {
Jason Evansb2c0d632016-04-13 23:36:15 -07001255 ret = node->ctl(tsd, mib, miblen, oldp, oldlenp, newp, newlen);
Jason Evansc4c25922017-01-15 16:56:30 -08001256 } else {
Jason Evans3c234352010-01-27 13:10:55 -08001257 /* Partial MIB. */
1258 ret = ENOENT;
Jason Evans3c234352010-01-27 13:10:55 -08001259 }
Jason Evans3c234352010-01-27 13:10:55 -08001260
Jason Evansa1ee7832012-04-10 15:07:44 -07001261label_return:
Jason Evans3c234352010-01-27 13:10:55 -08001262 return(ret);
1263}
1264
1265bool
Jason Evansc4c25922017-01-15 16:56:30 -08001266ctl_boot(void) {
David Goldblatt26c792e2017-05-15 15:38:15 -07001267 if (malloc_mutex_init(&ctl_mtx, "ctl", WITNESS_RANK_CTL,
1268 malloc_mutex_rank_exclusive)) {
Jason Evansf4086432017-01-19 18:15:45 -08001269 return true;
Jason Evansc4c25922017-01-15 16:56:30 -08001270 }
Jason Evans3c234352010-01-27 13:10:55 -08001271
1272 ctl_initialized = false;
1273
Jason Evansf4086432017-01-19 18:15:45 -08001274 return false;
Jason Evans3c234352010-01-27 13:10:55 -08001275}
1276
Jason Evans20f1fc92012-10-09 14:46:22 -07001277void
Jason Evansc4c25922017-01-15 16:56:30 -08001278ctl_prefork(tsdn_t *tsdn) {
Jason Evansc1e00ef2016-05-10 22:21:10 -07001279 malloc_mutex_prefork(tsdn, &ctl_mtx);
Jason Evans20f1fc92012-10-09 14:46:22 -07001280}
1281
1282void
Jason Evansc4c25922017-01-15 16:56:30 -08001283ctl_postfork_parent(tsdn_t *tsdn) {
Jason Evansc1e00ef2016-05-10 22:21:10 -07001284 malloc_mutex_postfork_parent(tsdn, &ctl_mtx);
Jason Evans20f1fc92012-10-09 14:46:22 -07001285}
1286
1287void
Jason Evansc4c25922017-01-15 16:56:30 -08001288ctl_postfork_child(tsdn_t *tsdn) {
Jason Evansc1e00ef2016-05-10 22:21:10 -07001289 malloc_mutex_postfork_child(tsdn, &ctl_mtx);
Jason Evans20f1fc92012-10-09 14:46:22 -07001290}
1291
Jason Evans3c234352010-01-27 13:10:55 -08001292/******************************************************************************/
1293/* *_ctl() functions. */
1294
Jason Evansc0cc5db2017-01-19 21:41:41 -08001295#define READONLY() do { \
Jason Evans3c234352010-01-27 13:10:55 -08001296 if (newp != NULL || newlen != 0) { \
1297 ret = EPERM; \
Jason Evans6b9ed672012-04-25 13:12:46 -07001298 goto label_return; \
Jason Evans3c234352010-01-27 13:10:55 -08001299 } \
1300} while (0)
1301
Jason Evansc0cc5db2017-01-19 21:41:41 -08001302#define WRITEONLY() do { \
Jason Evans3c234352010-01-27 13:10:55 -08001303 if (oldp != NULL || oldlenp != NULL) { \
1304 ret = EPERM; \
Jason Evans6b9ed672012-04-25 13:12:46 -07001305 goto label_return; \
Jason Evans3c234352010-01-27 13:10:55 -08001306 } \
1307} while (0)
1308
Jason Evansc0cc5db2017-01-19 21:41:41 -08001309#define READ_XOR_WRITE() do { \
Jason Evansfc12c0b2014-10-03 23:25:30 -07001310 if ((oldp != NULL && oldlenp != NULL) && (newp != NULL || \
1311 newlen != 0)) { \
1312 ret = EPERM; \
1313 goto label_return; \
1314 } \
1315} while (0)
1316
Jason Evansc0cc5db2017-01-19 21:41:41 -08001317#define READ(v, t) do { \
Jason Evans3c234352010-01-27 13:10:55 -08001318 if (oldp != NULL && oldlenp != NULL) { \
1319 if (*oldlenp != sizeof(t)) { \
1320 size_t copylen = (sizeof(t) <= *oldlenp) \
1321 ? sizeof(t) : *oldlenp; \
Jason Evans6eb84fb2012-11-29 22:13:04 -08001322 memcpy(oldp, (void *)&(v), copylen); \
Jason Evans3c234352010-01-27 13:10:55 -08001323 ret = EINVAL; \
Jason Evans6b9ed672012-04-25 13:12:46 -07001324 goto label_return; \
Jason Evansb49a3342015-07-28 11:28:19 -04001325 } \
1326 *(t *)oldp = (v); \
Jason Evans3c234352010-01-27 13:10:55 -08001327 } \
1328} while (0)
1329
Jason Evansc0cc5db2017-01-19 21:41:41 -08001330#define WRITE(v, t) do { \
Jason Evans3c234352010-01-27 13:10:55 -08001331 if (newp != NULL) { \
1332 if (newlen != sizeof(t)) { \
1333 ret = EINVAL; \
Jason Evans6b9ed672012-04-25 13:12:46 -07001334 goto label_return; \
Jason Evans3c234352010-01-27 13:10:55 -08001335 } \
Jason Evans6eb84fb2012-11-29 22:13:04 -08001336 (v) = *(t *)newp; \
Jason Evans3c234352010-01-27 13:10:55 -08001337 } \
1338} while (0)
1339
Jason Evansc0cc5db2017-01-19 21:41:41 -08001340#define MIB_UNSIGNED(v, i) do { \
Jason Evans6edbedd2017-01-04 07:51:49 -08001341 if (mib[i] > UINT_MAX) { \
1342 ret = EFAULT; \
1343 goto label_return; \
1344 } \
1345 v = (unsigned)mib[i]; \
1346} while (0)
1347
Jason Evans7372b152012-02-10 20:22:09 -08001348/*
1349 * There's a lot of code duplication in the following macros due to limitations
1350 * in how nested cpp macros are expanded.
1351 */
Jason Evansc0cc5db2017-01-19 21:41:41 -08001352#define CTL_RO_CLGEN(c, l, n, v, t) \
Jason Evans7372b152012-02-10 20:22:09 -08001353static int \
Jason Evansb2c0d632016-04-13 23:36:15 -07001354n##_ctl(tsd_t *tsd, const size_t *mib, size_t miblen, void *oldp, \
Jason Evansc4c25922017-01-15 16:56:30 -08001355 size_t *oldlenp, void *newp, size_t newlen) { \
Jason Evans7372b152012-02-10 20:22:09 -08001356 int ret; \
1357 t oldval; \
1358 \
Jason Evansc4c25922017-01-15 16:56:30 -08001359 if (!(c)) { \
Jason Evansf4086432017-01-19 18:15:45 -08001360 return ENOENT; \
Jason Evansc4c25922017-01-15 16:56:30 -08001361 } \
1362 if (l) { \
Jason Evansc1e00ef2016-05-10 22:21:10 -07001363 malloc_mutex_lock(tsd_tsdn(tsd), &ctl_mtx); \
Jason Evansc4c25922017-01-15 16:56:30 -08001364 } \
Jason Evans7372b152012-02-10 20:22:09 -08001365 READONLY(); \
Jason Evans6eb84fb2012-11-29 22:13:04 -08001366 oldval = (v); \
Jason Evans7372b152012-02-10 20:22:09 -08001367 READ(oldval, t); \
1368 \
1369 ret = 0; \
Jason Evans6b9ed672012-04-25 13:12:46 -07001370label_return: \
Jason Evansc4c25922017-01-15 16:56:30 -08001371 if (l) { \
Jason Evansc1e00ef2016-05-10 22:21:10 -07001372 malloc_mutex_unlock(tsd_tsdn(tsd), &ctl_mtx); \
Jason Evansc4c25922017-01-15 16:56:30 -08001373 } \
Jason Evansf4086432017-01-19 18:15:45 -08001374 return ret; \
Jason Evans7372b152012-02-10 20:22:09 -08001375}
1376
Jason Evansc0cc5db2017-01-19 21:41:41 -08001377#define CTL_RO_CGEN(c, n, v, t) \
Jason Evans7372b152012-02-10 20:22:09 -08001378static int \
Jason Evansb2c0d632016-04-13 23:36:15 -07001379n##_ctl(tsd_t *tsd, const size_t *mib, size_t miblen, void *oldp, \
Jason Evansc4c25922017-01-15 16:56:30 -08001380 size_t *oldlenp, void *newp, size_t newlen) { \
Jason Evans7372b152012-02-10 20:22:09 -08001381 int ret; \
1382 t oldval; \
1383 \
Jason Evansc4c25922017-01-15 16:56:30 -08001384 if (!(c)) { \
Jason Evansf4086432017-01-19 18:15:45 -08001385 return ENOENT; \
Jason Evansc4c25922017-01-15 16:56:30 -08001386 } \
Jason Evansc1e00ef2016-05-10 22:21:10 -07001387 malloc_mutex_lock(tsd_tsdn(tsd), &ctl_mtx); \
Jason Evans7372b152012-02-10 20:22:09 -08001388 READONLY(); \
Jason Evans6eb84fb2012-11-29 22:13:04 -08001389 oldval = (v); \
Jason Evans7372b152012-02-10 20:22:09 -08001390 READ(oldval, t); \
1391 \
1392 ret = 0; \
Jason Evans6b9ed672012-04-25 13:12:46 -07001393label_return: \
Jason Evansc1e00ef2016-05-10 22:21:10 -07001394 malloc_mutex_unlock(tsd_tsdn(tsd), &ctl_mtx); \
Jason Evansf4086432017-01-19 18:15:45 -08001395 return ret; \
Jason Evans7372b152012-02-10 20:22:09 -08001396}
1397
Jason Evansc0cc5db2017-01-19 21:41:41 -08001398#define CTL_RO_GEN(n, v, t) \
Jason Evans3c234352010-01-27 13:10:55 -08001399static int \
Jason Evansb2c0d632016-04-13 23:36:15 -07001400n##_ctl(tsd_t *tsd, const size_t *mib, size_t miblen, void *oldp, \
Jason Evansc4c25922017-01-15 16:56:30 -08001401 size_t *oldlenp, void *newp, size_t newlen) { \
Jason Evans3c234352010-01-27 13:10:55 -08001402 int ret; \
1403 t oldval; \
1404 \
Jason Evansc1e00ef2016-05-10 22:21:10 -07001405 malloc_mutex_lock(tsd_tsdn(tsd), &ctl_mtx); \
Jason Evansfc4dcfa2010-11-24 15:44:21 -08001406 READONLY(); \
Jason Evans6eb84fb2012-11-29 22:13:04 -08001407 oldval = (v); \
Jason Evansfc4dcfa2010-11-24 15:44:21 -08001408 READ(oldval, t); \
1409 \
1410 ret = 0; \
Jason Evans6b9ed672012-04-25 13:12:46 -07001411label_return: \
Jason Evansc1e00ef2016-05-10 22:21:10 -07001412 malloc_mutex_unlock(tsd_tsdn(tsd), &ctl_mtx); \
Jason Evansf4086432017-01-19 18:15:45 -08001413 return ret; \
Jason Evansfc4dcfa2010-11-24 15:44:21 -08001414}
1415
1416/*
1417 * ctl_mtx is not acquired, under the assumption that no pertinent data will
1418 * mutate during the call.
1419 */
Jason Evansc0cc5db2017-01-19 21:41:41 -08001420#define CTL_RO_NL_CGEN(c, n, v, t) \
Jason Evans7372b152012-02-10 20:22:09 -08001421static int \
Jason Evansb2c0d632016-04-13 23:36:15 -07001422n##_ctl(tsd_t *tsd, const size_t *mib, size_t miblen, void *oldp, \
Jason Evansc4c25922017-01-15 16:56:30 -08001423 size_t *oldlenp, void *newp, size_t newlen) { \
Jason Evans7372b152012-02-10 20:22:09 -08001424 int ret; \
1425 t oldval; \
1426 \
Jason Evansc4c25922017-01-15 16:56:30 -08001427 if (!(c)) { \
Jason Evansf4086432017-01-19 18:15:45 -08001428 return ENOENT; \
Jason Evansc4c25922017-01-15 16:56:30 -08001429 } \
Jason Evans7372b152012-02-10 20:22:09 -08001430 READONLY(); \
Jason Evans6eb84fb2012-11-29 22:13:04 -08001431 oldval = (v); \
Jason Evans7372b152012-02-10 20:22:09 -08001432 READ(oldval, t); \
1433 \
1434 ret = 0; \
Jason Evans6b9ed672012-04-25 13:12:46 -07001435label_return: \
Jason Evansf4086432017-01-19 18:15:45 -08001436 return ret; \
Jason Evans7372b152012-02-10 20:22:09 -08001437}
1438
Jason Evansc0cc5db2017-01-19 21:41:41 -08001439#define CTL_RO_NL_GEN(n, v, t) \
Jason Evansfc4dcfa2010-11-24 15:44:21 -08001440static int \
Jason Evansb2c0d632016-04-13 23:36:15 -07001441n##_ctl(tsd_t *tsd, const size_t *mib, size_t miblen, void *oldp, \
Jason Evansc4c25922017-01-15 16:56:30 -08001442 size_t *oldlenp, void *newp, size_t newlen) { \
Jason Evansfc4dcfa2010-11-24 15:44:21 -08001443 int ret; \
1444 t oldval; \
1445 \
Jason Evans3c234352010-01-27 13:10:55 -08001446 READONLY(); \
Jason Evans6eb84fb2012-11-29 22:13:04 -08001447 oldval = (v); \
Jason Evans3c234352010-01-27 13:10:55 -08001448 READ(oldval, t); \
1449 \
1450 ret = 0; \
Jason Evans6b9ed672012-04-25 13:12:46 -07001451label_return: \
Jason Evansf4086432017-01-19 18:15:45 -08001452 return ret; \
Jason Evans3c234352010-01-27 13:10:55 -08001453}
1454
Jason Evansc0cc5db2017-01-19 21:41:41 -08001455#define CTL_TSD_RO_NL_CGEN(c, n, m, t) \
Jason Evans5460aa62014-09-22 21:09:23 -07001456static int \
Jason Evansb2c0d632016-04-13 23:36:15 -07001457n##_ctl(tsd_t *tsd, const size_t *mib, size_t miblen, void *oldp, \
Jason Evansc4c25922017-01-15 16:56:30 -08001458 size_t *oldlenp, void *newp, size_t newlen) { \
Jason Evans5460aa62014-09-22 21:09:23 -07001459 int ret; \
1460 t oldval; \
Jason Evans5460aa62014-09-22 21:09:23 -07001461 \
Jason Evansc4c25922017-01-15 16:56:30 -08001462 if (!(c)) { \
Jason Evansf4086432017-01-19 18:15:45 -08001463 return ENOENT; \
Jason Evansc4c25922017-01-15 16:56:30 -08001464 } \
Jason Evans5460aa62014-09-22 21:09:23 -07001465 READONLY(); \
Jason Evans5460aa62014-09-22 21:09:23 -07001466 oldval = (m(tsd)); \
1467 READ(oldval, t); \
1468 \
1469 ret = 0; \
1470label_return: \
Jason Evansf4086432017-01-19 18:15:45 -08001471 return ret; \
Jason Evans5460aa62014-09-22 21:09:23 -07001472}
1473
Jason Evansc0cc5db2017-01-19 21:41:41 -08001474#define CTL_RO_CONFIG_GEN(n, t) \
Jason Evans3c234352010-01-27 13:10:55 -08001475static int \
Jason Evansb2c0d632016-04-13 23:36:15 -07001476n##_ctl(tsd_t *tsd, const size_t *mib, size_t miblen, void *oldp, \
Jason Evansc4c25922017-01-15 16:56:30 -08001477 size_t *oldlenp, void *newp, size_t newlen) { \
Jason Evans3c234352010-01-27 13:10:55 -08001478 int ret; \
Jason Evansf8290092016-02-07 14:23:22 -08001479 t oldval; \
Jason Evans3c234352010-01-27 13:10:55 -08001480 \
1481 READONLY(); \
Jason Evans7372b152012-02-10 20:22:09 -08001482 oldval = n; \
Jason Evansf8290092016-02-07 14:23:22 -08001483 READ(oldval, t); \
Jason Evans3c234352010-01-27 13:10:55 -08001484 \
1485 ret = 0; \
Jason Evans6b9ed672012-04-25 13:12:46 -07001486label_return: \
Jason Evansf4086432017-01-19 18:15:45 -08001487 return ret; \
Jason Evans3c234352010-01-27 13:10:55 -08001488}
1489
Jason Evansd8a39002013-12-19 21:40:41 -08001490/******************************************************************************/
1491
Jason Evansfc4dcfa2010-11-24 15:44:21 -08001492CTL_RO_NL_GEN(version, JEMALLOC_VERSION, const char *)
Jason Evansa40bc7a2010-03-02 13:01:16 -08001493
Jason Evans3c234352010-01-27 13:10:55 -08001494static int
Jason Evansb2c0d632016-04-13 23:36:15 -07001495epoch_ctl(tsd_t *tsd, const size_t *mib, size_t miblen, void *oldp,
Jason Evansc4c25922017-01-15 16:56:30 -08001496 size_t *oldlenp, void *newp, size_t newlen) {
Jason Evans3c234352010-01-27 13:10:55 -08001497 int ret;
Jason Evans3ab682d2013-10-19 17:19:49 -07001498 UNUSED uint64_t newval;
Jason Evans3c234352010-01-27 13:10:55 -08001499
Jason Evansc1e00ef2016-05-10 22:21:10 -07001500 malloc_mutex_lock(tsd_tsdn(tsd), &ctl_mtx);
Jason Evans3c234352010-01-27 13:10:55 -08001501 WRITE(newval, uint64_t);
Jason Evansc4c25922017-01-15 16:56:30 -08001502 if (newp != NULL) {
Jason Evansc1e00ef2016-05-10 22:21:10 -07001503 ctl_refresh(tsd_tsdn(tsd));
Jason Evansc4c25922017-01-15 16:56:30 -08001504 }
Jason Evans9eb1b1c2017-01-18 23:03:37 -08001505 READ(ctl_arenas->epoch, uint64_t);
Jason Evans3c234352010-01-27 13:10:55 -08001506
1507 ret = 0;
Jason Evansa1ee7832012-04-10 15:07:44 -07001508label_return:
Jason Evansc1e00ef2016-05-10 22:21:10 -07001509 malloc_mutex_unlock(tsd_tsdn(tsd), &ctl_mtx);
Jason Evansf4086432017-01-19 18:15:45 -08001510 return ret;
Jason Evans3c234352010-01-27 13:10:55 -08001511}
1512
Qi Wangb693c782017-03-17 12:42:33 -07001513static int
1514background_thread_ctl(tsd_t *tsd, const size_t *mib, size_t miblen,
1515 void *oldp, size_t *oldlenp, void *newp, size_t newlen) {
1516 int ret;
1517 bool oldval;
1518
1519 if (!have_background_thread) {
1520 return ENOENT;
1521 }
Qi Wang340071f2017-06-01 12:52:09 -07001522 background_thread_ctl_init(tsd_tsdn(tsd));
Qi Wangb693c782017-03-17 12:42:33 -07001523
Qi Wang73713fb2017-06-07 15:49:09 -07001524 malloc_mutex_lock(tsd_tsdn(tsd), &ctl_mtx);
Qi Wangb693c782017-03-17 12:42:33 -07001525 malloc_mutex_lock(tsd_tsdn(tsd), &background_thread_lock);
1526 if (newp == NULL) {
1527 oldval = background_thread_enabled();
1528 READ(oldval, bool);
1529 } else {
1530 if (newlen != sizeof(bool)) {
1531 ret = EINVAL;
1532 goto label_return;
1533 }
1534 oldval = background_thread_enabled();
1535 READ(oldval, bool);
1536
1537 bool newval = *(bool *)newp;
1538 if (newval == oldval) {
1539 ret = 0;
1540 goto label_return;
1541 }
1542
1543 background_thread_enabled_set(tsd_tsdn(tsd), newval);
1544 if (newval) {
Qi Wanga4d6fe72017-06-14 12:12:23 -07001545 if (!can_enable_background_thread) {
1546 malloc_printf("<jemalloc>: Error in dlsym("
1547 "RTLD_NEXT, \"pthread_create\"). Cannot "
1548 "enable background_thread\n");
1549 ret = EFAULT;
1550 goto label_return;
1551 }
Qi Wangb693c782017-03-17 12:42:33 -07001552 if (background_threads_enable(tsd)) {
1553 ret = EFAULT;
1554 goto label_return;
1555 }
1556 } else {
1557 if (background_threads_disable(tsd)) {
1558 ret = EFAULT;
1559 goto label_return;
1560 }
1561 }
1562 }
1563 ret = 0;
1564label_return:
1565 malloc_mutex_unlock(tsd_tsdn(tsd), &background_thread_lock);
Qi Wang73713fb2017-06-07 15:49:09 -07001566 malloc_mutex_unlock(tsd_tsdn(tsd), &ctl_mtx);
1567
Qi Wangb693c782017-03-17 12:42:33 -07001568 return ret;
1569}
1570
Dave Watson8b14f3a2018-03-29 12:58:13 -07001571static int
1572max_background_threads_ctl(tsd_t *tsd, const size_t *mib, size_t miblen,
1573 void *oldp, size_t *oldlenp, void *newp, size_t newlen) {
1574 int ret;
1575 size_t oldval;
1576
1577 if (!have_background_thread) {
1578 return ENOENT;
1579 }
1580 background_thread_ctl_init(tsd_tsdn(tsd));
1581
1582 malloc_mutex_lock(tsd_tsdn(tsd), &ctl_mtx);
1583 malloc_mutex_lock(tsd_tsdn(tsd), &background_thread_lock);
1584 if (newp == NULL) {
1585 oldval = max_background_threads;
1586 READ(oldval, size_t);
1587 } else {
1588 if (newlen != sizeof(size_t)) {
1589 ret = EINVAL;
1590 goto label_return;
1591 }
1592 oldval = max_background_threads;
1593 READ(oldval, size_t);
1594
1595 size_t newval = *(size_t *)newp;
1596 if (newval == oldval) {
1597 ret = 0;
1598 goto label_return;
1599 }
1600 if (newval > opt_max_background_threads) {
1601 ret = EINVAL;
1602 goto label_return;
1603 }
1604
1605 if (background_thread_enabled()) {
1606 if (!can_enable_background_thread) {
1607 malloc_printf("<jemalloc>: Error in dlsym("
1608 "RTLD_NEXT, \"pthread_create\"). Cannot "
1609 "enable background_thread\n");
1610 ret = EFAULT;
1611 goto label_return;
1612 }
1613 background_thread_enabled_set(tsd_tsdn(tsd), false);
1614 if (background_threads_disable(tsd)) {
1615 ret = EFAULT;
1616 goto label_return;
1617 }
1618 max_background_threads = newval;
1619 background_thread_enabled_set(tsd_tsdn(tsd), true);
1620 if (background_threads_enable(tsd)) {
1621 ret = EFAULT;
1622 goto label_return;
1623 }
1624 } else {
1625 max_background_threads = newval;
1626 }
1627 }
1628 ret = 0;
1629label_return:
1630 malloc_mutex_unlock(tsd_tsdn(tsd), &background_thread_lock);
1631 malloc_mutex_unlock(tsd_tsdn(tsd), &ctl_mtx);
1632
1633 return ret;
1634}
1635
Jason Evansd8a39002013-12-19 21:40:41 -08001636/******************************************************************************/
Jason Evansd4be8b72012-03-26 18:54:44 -07001637
Jason Evansf8290092016-02-07 14:23:22 -08001638CTL_RO_CONFIG_GEN(config_cache_oblivious, bool)
1639CTL_RO_CONFIG_GEN(config_debug, bool)
1640CTL_RO_CONFIG_GEN(config_fill, bool)
1641CTL_RO_CONFIG_GEN(config_lazy_lock, bool)
1642CTL_RO_CONFIG_GEN(config_malloc_conf, const char *)
Jason Evansf8290092016-02-07 14:23:22 -08001643CTL_RO_CONFIG_GEN(config_prof, bool)
1644CTL_RO_CONFIG_GEN(config_prof_libgcc, bool)
1645CTL_RO_CONFIG_GEN(config_prof_libunwind, bool)
1646CTL_RO_CONFIG_GEN(config_stats, bool)
Jason Evansf8290092016-02-07 14:23:22 -08001647CTL_RO_CONFIG_GEN(config_utrace, bool)
Jason Evansf8290092016-02-07 14:23:22 -08001648CTL_RO_CONFIG_GEN(config_xmalloc, bool)
Jason Evansd4be8b72012-03-26 18:54:44 -07001649
Jason Evansd8a39002013-12-19 21:40:41 -08001650/******************************************************************************/
Jason Evansd4be8b72012-03-26 18:54:44 -07001651
Jason Evansd8a39002013-12-19 21:40:41 -08001652CTL_RO_NL_GEN(opt_abort, opt_abort, bool)
Qi Wangb86d2712017-05-25 15:30:11 -07001653CTL_RO_NL_GEN(opt_abort_conf, opt_abort_conf, bool)
Qi Wang47b20bb2017-08-24 14:29:28 -07001654CTL_RO_NL_GEN(opt_metadata_thp, metadata_thp_mode_names[opt_metadata_thp],
1655 const char *)
Jason Evansb9ab04a2017-04-26 16:26:12 -07001656CTL_RO_NL_GEN(opt_retain, opt_retain, bool)
Jason Evansd8a39002013-12-19 21:40:41 -08001657CTL_RO_NL_GEN(opt_dss, opt_dss, const char *)
Jason Evans8f683b92016-02-24 11:03:40 -08001658CTL_RO_NL_GEN(opt_narenas, opt_narenas, unsigned)
Jason Evansb5112322017-05-31 16:45:14 -07001659CTL_RO_NL_GEN(opt_percpu_arena, percpu_arena_mode_names[opt_percpu_arena],
1660 const char *)
Qi Wangb693c782017-03-17 12:42:33 -07001661CTL_RO_NL_GEN(opt_background_thread, opt_background_thread, bool)
Dave Watson8b14f3a2018-03-29 12:58:13 -07001662CTL_RO_NL_GEN(opt_max_background_threads, opt_max_background_threads, size_t)
Jason Evans6e62c622017-05-17 10:47:00 -07001663CTL_RO_NL_GEN(opt_dirty_decay_ms, opt_dirty_decay_ms, ssize_t)
1664CTL_RO_NL_GEN(opt_muzzy_decay_ms, opt_muzzy_decay_ms, ssize_t)
Jason Evansd8a39002013-12-19 21:40:41 -08001665CTL_RO_NL_GEN(opt_stats_print, opt_stats_print, bool)
Qi Wangd5ef5ae2017-05-27 15:35:36 -07001666CTL_RO_NL_GEN(opt_stats_print_opts, opt_stats_print_opts, const char *)
Guilherme Goncalves2c5cb612014-12-08 19:12:41 -02001667CTL_RO_NL_CGEN(config_fill, opt_junk, opt_junk, const char *)
Jason Evansd8a39002013-12-19 21:40:41 -08001668CTL_RO_NL_CGEN(config_fill, opt_zero, opt_zero, bool)
1669CTL_RO_NL_CGEN(config_utrace, opt_utrace, opt_utrace, bool)
Jason Evansd8a39002013-12-19 21:40:41 -08001670CTL_RO_NL_CGEN(config_xmalloc, opt_xmalloc, opt_xmalloc, bool)
Jason Evans4403c9a2017-04-20 17:21:37 -07001671CTL_RO_NL_GEN(opt_tcache, opt_tcache, bool)
Qi Wange4f090e2018-02-16 14:19:19 -08001672CTL_RO_NL_GEN(opt_thp, thp_mode_names[opt_thp], const char *)
Qi Wangfac70682017-11-09 13:51:39 -08001673CTL_RO_NL_GEN(opt_lg_extent_max_active_fit, opt_lg_extent_max_active_fit,
1674 size_t)
Jason Evans4403c9a2017-04-20 17:21:37 -07001675CTL_RO_NL_GEN(opt_lg_tcache_max, opt_lg_tcache_max, ssize_t)
Jason Evansd8a39002013-12-19 21:40:41 -08001676CTL_RO_NL_CGEN(config_prof, opt_prof, opt_prof, bool)
1677CTL_RO_NL_CGEN(config_prof, opt_prof_prefix, opt_prof_prefix, const char *)
Jason Evansfc12c0b2014-10-03 23:25:30 -07001678CTL_RO_NL_CGEN(config_prof, opt_prof_active, opt_prof_active, bool)
1679CTL_RO_NL_CGEN(config_prof, opt_prof_thread_active_init,
1680 opt_prof_thread_active_init, bool)
Jason Evansd8a39002013-12-19 21:40:41 -08001681CTL_RO_NL_CGEN(config_prof, opt_lg_prof_sample, opt_lg_prof_sample, size_t)
1682CTL_RO_NL_CGEN(config_prof, opt_prof_accum, opt_prof_accum, bool)
1683CTL_RO_NL_CGEN(config_prof, opt_lg_prof_interval, opt_lg_prof_interval, ssize_t)
1684CTL_RO_NL_CGEN(config_prof, opt_prof_gdump, opt_prof_gdump, bool)
1685CTL_RO_NL_CGEN(config_prof, opt_prof_final, opt_prof_final, bool)
1686CTL_RO_NL_CGEN(config_prof, opt_prof_leak, opt_prof_leak, bool)
Jason Evansd4be8b72012-03-26 18:54:44 -07001687
Jason Evansd8a39002013-12-19 21:40:41 -08001688/******************************************************************************/
Jason Evans3c234352010-01-27 13:10:55 -08001689
Jason Evansb267d0f2010-08-13 15:42:29 -07001690static int
Jason Evansb2c0d632016-04-13 23:36:15 -07001691thread_arena_ctl(tsd_t *tsd, const size_t *mib, size_t miblen, void *oldp,
Jason Evansc4c25922017-01-15 16:56:30 -08001692 size_t *oldlenp, void *newp, size_t newlen) {
Jason Evansb267d0f2010-08-13 15:42:29 -07001693 int ret;
Jason Evans1cb181e2015-01-29 15:30:47 -08001694 arena_t *oldarena;
Jason Evansb267d0f2010-08-13 15:42:29 -07001695 unsigned newind, oldind;
1696
Jason Evans90827a32016-05-03 15:00:42 -07001697 oldarena = arena_choose(tsd, NULL);
Jason Evansc4c25922017-01-15 16:56:30 -08001698 if (oldarena == NULL) {
Jason Evansf4086432017-01-19 18:15:45 -08001699 return EAGAIN;
Jason Evansc4c25922017-01-15 16:56:30 -08001700 }
Jason Evansa0dd3a42016-12-22 16:39:10 -06001701 newind = oldind = arena_ind_get(oldarena);
Jason Evansa7153a02011-03-14 11:39:49 -07001702 WRITE(newind, unsigned);
1703 READ(oldind, unsigned);
Qi Wangec532e22017-02-02 17:02:05 -08001704
Jason Evansb267d0f2010-08-13 15:42:29 -07001705 if (newind != oldind) {
Jason Evans1cb181e2015-01-29 15:30:47 -08001706 arena_t *newarena;
1707
Jason Evansb6c08672016-10-03 10:37:12 -07001708 if (newind >= narenas_total_get()) {
Jason Evansb267d0f2010-08-13 15:42:29 -07001709 /* New arena index is out of range. */
1710 ret = EFAULT;
Jason Evansa1ee7832012-04-10 15:07:44 -07001711 goto label_return;
Jason Evansb267d0f2010-08-13 15:42:29 -07001712 }
1713
Qi Wangec532e22017-02-02 17:02:05 -08001714 if (have_percpu_arena &&
Jason Evansb5112322017-05-31 16:45:14 -07001715 PERCPU_ARENA_ENABLED(opt_percpu_arena)) {
1716 if (newind < percpu_arena_ind_limit(opt_percpu_arena)) {
Qi Wangec532e22017-02-02 17:02:05 -08001717 /*
1718 * If perCPU arena is enabled, thread_arena
1719 * control is not allowed for the auto arena
1720 * range.
1721 */
1722 ret = EPERM;
1723 goto label_return;
1724 }
1725 }
1726
Jason Evansb267d0f2010-08-13 15:42:29 -07001727 /* Initialize arena if necessary. */
Jason Evansc1e00ef2016-05-10 22:21:10 -07001728 newarena = arena_get(tsd_tsdn(tsd), newind, true);
Jason Evans1cb181e2015-01-29 15:30:47 -08001729 if (newarena == NULL) {
Jason Evansb267d0f2010-08-13 15:42:29 -07001730 ret = EAGAIN;
Jason Evansa1ee7832012-04-10 15:07:44 -07001731 goto label_return;
Jason Evansb267d0f2010-08-13 15:42:29 -07001732 }
Jason Evans8bb31982014-10-07 23:14:57 -07001733 /* Set new arena/tcache associations. */
1734 arena_migrate(tsd, oldind, newind);
Jason Evans4403c9a2017-04-20 17:21:37 -07001735 if (tcache_available(tsd)) {
1736 tcache_arena_reassociate(tsd_tsdn(tsd),
1737 tsd_tcachep_get(tsd), newarena);
Jason Evans624f2f32010-12-29 12:21:05 -08001738 }
Jason Evansb267d0f2010-08-13 15:42:29 -07001739 }
1740
1741 ret = 0;
Jason Evansa1ee7832012-04-10 15:07:44 -07001742label_return:
Jason Evansf4086432017-01-19 18:15:45 -08001743 return ret;
Jason Evansb267d0f2010-08-13 15:42:29 -07001744}
Jason Evansb267d0f2010-08-13 15:42:29 -07001745
Jason Evans5460aa62014-09-22 21:09:23 -07001746CTL_TSD_RO_NL_CGEN(config_stats, thread_allocated, tsd_thread_allocated_get,
1747 uint64_t)
1748CTL_TSD_RO_NL_CGEN(config_stats, thread_allocatedp, tsd_thread_allocatedp_get,
1749 uint64_t *)
1750CTL_TSD_RO_NL_CGEN(config_stats, thread_deallocated, tsd_thread_deallocated_get,
1751 uint64_t)
1752CTL_TSD_RO_NL_CGEN(config_stats, thread_deallocatedp,
1753 tsd_thread_deallocatedp_get, uint64_t *)
Jason Evans93443682010-10-20 17:39:18 -07001754
Jason Evansd8a39002013-12-19 21:40:41 -08001755static int
Jason Evansb2c0d632016-04-13 23:36:15 -07001756thread_tcache_enabled_ctl(tsd_t *tsd, const size_t *mib, size_t miblen,
Jason Evansc4c25922017-01-15 16:56:30 -08001757 void *oldp, size_t *oldlenp, void *newp, size_t newlen) {
Jason Evansd8a39002013-12-19 21:40:41 -08001758 int ret;
1759 bool oldval;
Jason Evans3c234352010-01-27 13:10:55 -08001760
Qi Wangfde3e202017-03-27 21:50:38 -07001761 oldval = tcache_enabled_get(tsd);
Jason Evansd8a39002013-12-19 21:40:41 -08001762 if (newp != NULL) {
1763 if (newlen != sizeof(bool)) {
1764 ret = EINVAL;
1765 goto label_return;
1766 }
Qi Wangfde3e202017-03-27 21:50:38 -07001767 tcache_enabled_set(tsd, *(bool *)newp);
Jason Evansd8a39002013-12-19 21:40:41 -08001768 }
1769 READ(oldval, bool);
Jason Evans3c234352010-01-27 13:10:55 -08001770
Jason Evansd8a39002013-12-19 21:40:41 -08001771 ret = 0;
1772label_return:
Jason Evansf4086432017-01-19 18:15:45 -08001773 return ret;
Jason Evansd8a39002013-12-19 21:40:41 -08001774}
1775
1776static int
Jason Evansb2c0d632016-04-13 23:36:15 -07001777thread_tcache_flush_ctl(tsd_t *tsd, const size_t *mib, size_t miblen,
Jason Evansc4c25922017-01-15 16:56:30 -08001778 void *oldp, size_t *oldlenp, void *newp, size_t newlen) {
Jason Evansd8a39002013-12-19 21:40:41 -08001779 int ret;
1780
Jason Evans4403c9a2017-04-20 17:21:37 -07001781 if (!tcache_available(tsd)) {
1782 ret = EFAULT;
1783 goto label_return;
Jason Evansc4c25922017-01-15 16:56:30 -08001784 }
Jason Evansd8a39002013-12-19 21:40:41 -08001785
1786 READONLY();
1787 WRITEONLY();
1788
Qi Wangae93fb02017-06-15 15:16:18 -07001789 tcache_flush(tsd);
Jason Evansd8a39002013-12-19 21:40:41 -08001790
1791 ret = 0;
1792label_return:
Jason Evansf4086432017-01-19 18:15:45 -08001793 return ret;
Jason Evansd8a39002013-12-19 21:40:41 -08001794}
Jason Evans3c234352010-01-27 13:10:55 -08001795
Jason Evans602c8e02014-08-18 16:22:13 -07001796static int
Jason Evansb2c0d632016-04-13 23:36:15 -07001797thread_prof_name_ctl(tsd_t *tsd, const size_t *mib, size_t miblen, void *oldp,
Jason Evansc4c25922017-01-15 16:56:30 -08001798 size_t *oldlenp, void *newp, size_t newlen) {
Jason Evans602c8e02014-08-18 16:22:13 -07001799 int ret;
Jason Evans602c8e02014-08-18 16:22:13 -07001800
Jason Evansc4c25922017-01-15 16:56:30 -08001801 if (!config_prof) {
Jason Evansf4086432017-01-19 18:15:45 -08001802 return ENOENT;
Jason Evansc4c25922017-01-15 16:56:30 -08001803 }
Jason Evans602c8e02014-08-18 16:22:13 -07001804
Jason Evansfc12c0b2014-10-03 23:25:30 -07001805 READ_XOR_WRITE();
1806
Jason Evans602c8e02014-08-18 16:22:13 -07001807 if (newp != NULL) {
1808 if (newlen != sizeof(const char *)) {
1809 ret = EINVAL;
1810 goto label_return;
1811 }
Jason Evans5460aa62014-09-22 21:09:23 -07001812
Jason Evansfc12c0b2014-10-03 23:25:30 -07001813 if ((ret = prof_thread_name_set(tsd, *(const char **)newp)) !=
Jason Evansc4c25922017-01-15 16:56:30 -08001814 0) {
Jason Evans602c8e02014-08-18 16:22:13 -07001815 goto label_return;
Jason Evansc4c25922017-01-15 16:56:30 -08001816 }
Jason Evansfc12c0b2014-10-03 23:25:30 -07001817 } else {
Jason Evansb2c0d632016-04-13 23:36:15 -07001818 const char *oldname = prof_thread_name_get(tsd);
Jason Evansfc12c0b2014-10-03 23:25:30 -07001819 READ(oldname, const char *);
Jason Evans602c8e02014-08-18 16:22:13 -07001820 }
Jason Evans602c8e02014-08-18 16:22:13 -07001821
1822 ret = 0;
1823label_return:
Jason Evansf4086432017-01-19 18:15:45 -08001824 return ret;
Jason Evans602c8e02014-08-18 16:22:13 -07001825}
1826
1827static int
Jason Evansb2c0d632016-04-13 23:36:15 -07001828thread_prof_active_ctl(tsd_t *tsd, const size_t *mib, size_t miblen, void *oldp,
Jason Evansc4c25922017-01-15 16:56:30 -08001829 size_t *oldlenp, void *newp, size_t newlen) {
Jason Evans602c8e02014-08-18 16:22:13 -07001830 int ret;
1831 bool oldval;
1832
Jason Evansc4c25922017-01-15 16:56:30 -08001833 if (!config_prof) {
Jason Evansf4086432017-01-19 18:15:45 -08001834 return ENOENT;
Jason Evansc4c25922017-01-15 16:56:30 -08001835 }
Jason Evans602c8e02014-08-18 16:22:13 -07001836
Jason Evansb2c0d632016-04-13 23:36:15 -07001837 oldval = prof_thread_active_get(tsd);
Jason Evans602c8e02014-08-18 16:22:13 -07001838 if (newp != NULL) {
1839 if (newlen != sizeof(bool)) {
1840 ret = EINVAL;
1841 goto label_return;
1842 }
Jason Evansb2c0d632016-04-13 23:36:15 -07001843 if (prof_thread_active_set(tsd, *(bool *)newp)) {
Jason Evans602c8e02014-08-18 16:22:13 -07001844 ret = EAGAIN;
1845 goto label_return;
1846 }
1847 }
1848 READ(oldval, bool);
1849
1850 ret = 0;
1851label_return:
Jason Evansf4086432017-01-19 18:15:45 -08001852 return ret;
Jason Evans602c8e02014-08-18 16:22:13 -07001853}
1854
Jason Evans3c234352010-01-27 13:10:55 -08001855/******************************************************************************/
1856
Jason Evans1cb181e2015-01-29 15:30:47 -08001857static int
Jason Evansb2c0d632016-04-13 23:36:15 -07001858tcache_create_ctl(tsd_t *tsd, const size_t *mib, size_t miblen, void *oldp,
Jason Evansc4c25922017-01-15 16:56:30 -08001859 size_t *oldlenp, void *newp, size_t newlen) {
Jason Evans1cb181e2015-01-29 15:30:47 -08001860 int ret;
Jason Evans1cb181e2015-01-29 15:30:47 -08001861 unsigned tcache_ind;
1862
Jason Evans1cb181e2015-01-29 15:30:47 -08001863 READONLY();
Jason Evansb54d1602016-10-20 23:59:12 -07001864 if (tcaches_create(tsd, &tcache_ind)) {
Jason Evans1cb181e2015-01-29 15:30:47 -08001865 ret = EFAULT;
1866 goto label_return;
1867 }
1868 READ(tcache_ind, unsigned);
1869
1870 ret = 0;
1871label_return:
Jason Evansf4086432017-01-19 18:15:45 -08001872 return ret;
Jason Evans1cb181e2015-01-29 15:30:47 -08001873}
1874
1875static int
Jason Evansb2c0d632016-04-13 23:36:15 -07001876tcache_flush_ctl(tsd_t *tsd, const size_t *mib, size_t miblen, void *oldp,
Jason Evansc4c25922017-01-15 16:56:30 -08001877 size_t *oldlenp, void *newp, size_t newlen) {
Jason Evans1cb181e2015-01-29 15:30:47 -08001878 int ret;
Jason Evans1cb181e2015-01-29 15:30:47 -08001879 unsigned tcache_ind;
1880
Jason Evans1cb181e2015-01-29 15:30:47 -08001881 WRITEONLY();
1882 tcache_ind = UINT_MAX;
1883 WRITE(tcache_ind, unsigned);
1884 if (tcache_ind == UINT_MAX) {
1885 ret = EFAULT;
1886 goto label_return;
1887 }
1888 tcaches_flush(tsd, tcache_ind);
1889
1890 ret = 0;
1891label_return:
Jason Evansf4086432017-01-19 18:15:45 -08001892 return ret;
Jason Evans1cb181e2015-01-29 15:30:47 -08001893}
1894
1895static int
Jason Evansb2c0d632016-04-13 23:36:15 -07001896tcache_destroy_ctl(tsd_t *tsd, const size_t *mib, size_t miblen, void *oldp,
Jason Evansc4c25922017-01-15 16:56:30 -08001897 size_t *oldlenp, void *newp, size_t newlen) {
Jason Evans1cb181e2015-01-29 15:30:47 -08001898 int ret;
Jason Evans1cb181e2015-01-29 15:30:47 -08001899 unsigned tcache_ind;
1900
Jason Evans1cb181e2015-01-29 15:30:47 -08001901 WRITEONLY();
1902 tcache_ind = UINT_MAX;
1903 WRITE(tcache_ind, unsigned);
1904 if (tcache_ind == UINT_MAX) {
1905 ret = EFAULT;
1906 goto label_return;
1907 }
1908 tcaches_destroy(tsd, tcache_ind);
1909
1910 ret = 0;
1911label_return:
Jason Evansf4086432017-01-19 18:15:45 -08001912 return ret;
Jason Evans1cb181e2015-01-29 15:30:47 -08001913}
1914
1915/******************************************************************************/
1916
Jason Evansdc2125c2017-01-04 10:21:53 -08001917static int
1918arena_i_initialized_ctl(tsd_t *tsd, const size_t *mib, size_t miblen,
Jason Evansc4c25922017-01-15 16:56:30 -08001919 void *oldp, size_t *oldlenp, void *newp, size_t newlen) {
Jason Evansdc2125c2017-01-04 10:21:53 -08001920 int ret;
1921 tsdn_t *tsdn = tsd_tsdn(tsd);
1922 unsigned arena_ind;
1923 bool initialized;
1924
1925 READONLY();
1926 MIB_UNSIGNED(arena_ind, 1);
1927
1928 malloc_mutex_lock(tsdn, &ctl_mtx);
Jason Evans9eb1b1c2017-01-18 23:03:37 -08001929 initialized = arenas_i(arena_ind)->initialized;
Jason Evansdc2125c2017-01-04 10:21:53 -08001930 malloc_mutex_unlock(tsdn, &ctl_mtx);
1931
1932 READ(initialized, bool);
1933
1934 ret = 0;
1935label_return:
Jason Evansf4086432017-01-19 18:15:45 -08001936 return ret;
Jason Evansdc2125c2017-01-04 10:21:53 -08001937}
1938
Jason Evans34457f52012-11-03 21:18:28 -07001939static void
Jason Evans64e458f2017-03-08 22:42:57 -08001940arena_i_decay(tsdn_t *tsdn, unsigned arena_ind, bool all) {
Jason Evansc1e00ef2016-05-10 22:21:10 -07001941 malloc_mutex_lock(tsdn, &ctl_mtx);
Jason Evans243f7a02016-02-19 20:09:31 -08001942 {
Jason Evans9eb1b1c2017-01-18 23:03:37 -08001943 unsigned narenas = ctl_arenas->narenas;
Jason Evans609ae592012-10-11 13:53:15 -07001944
Jason Evans3dc4e832017-01-03 07:27:42 -08001945 /*
1946 * Access via index narenas is deprecated, and scheduled for
1947 * removal in 6.0.0.
1948 */
1949 if (arena_ind == MALLCTL_ARENAS_ALL || arena_ind == narenas) {
Jason Evans243f7a02016-02-19 20:09:31 -08001950 unsigned i;
Jason Evans243f7a02016-02-19 20:09:31 -08001951 VARIABLE_ARRAY(arena_t *, tarenas, narenas);
1952
Jason Evansc4c25922017-01-15 16:56:30 -08001953 for (i = 0; i < narenas; i++) {
Jason Evansc1e00ef2016-05-10 22:21:10 -07001954 tarenas[i] = arena_get(tsdn, i, false);
Jason Evansc4c25922017-01-15 16:56:30 -08001955 }
Jason Evans243f7a02016-02-19 20:09:31 -08001956
1957 /*
1958 * No further need to hold ctl_mtx, since narenas and
1959 * tarenas contain everything needed below.
1960 */
Jason Evansc1e00ef2016-05-10 22:21:10 -07001961 malloc_mutex_unlock(tsdn, &ctl_mtx);
Jason Evans243f7a02016-02-19 20:09:31 -08001962
1963 for (i = 0; i < narenas; i++) {
Jason Evansc4c25922017-01-15 16:56:30 -08001964 if (tarenas[i] != NULL) {
Qi Wangb693c782017-03-17 12:42:33 -07001965 arena_decay(tsdn, tarenas[i], false,
1966 all);
Jason Evansc4c25922017-01-15 16:56:30 -08001967 }
Jason Evans243f7a02016-02-19 20:09:31 -08001968 }
1969 } else {
1970 arena_t *tarena;
1971
1972 assert(arena_ind < narenas);
1973
Jason Evansc1e00ef2016-05-10 22:21:10 -07001974 tarena = arena_get(tsdn, arena_ind, false);
Jason Evans243f7a02016-02-19 20:09:31 -08001975
1976 /* No further need to hold ctl_mtx. */
Jason Evansc1e00ef2016-05-10 22:21:10 -07001977 malloc_mutex_unlock(tsdn, &ctl_mtx);
Jason Evans243f7a02016-02-19 20:09:31 -08001978
Jason Evansc4c25922017-01-15 16:56:30 -08001979 if (tarena != NULL) {
Qi Wangb693c782017-03-17 12:42:33 -07001980 arena_decay(tsdn, tarena, false, all);
Jason Evansc4c25922017-01-15 16:56:30 -08001981 }
Jason Evans609ae592012-10-11 13:53:15 -07001982 }
1983 }
Jason Evans609ae592012-10-11 13:53:15 -07001984}
1985
1986static int
Jason Evansb2c0d632016-04-13 23:36:15 -07001987arena_i_decay_ctl(tsd_t *tsd, const size_t *mib, size_t miblen, void *oldp,
Jason Evansc4c25922017-01-15 16:56:30 -08001988 size_t *oldlenp, void *newp, size_t newlen) {
Jason Evans243f7a02016-02-19 20:09:31 -08001989 int ret;
Jason Evans6edbedd2017-01-04 07:51:49 -08001990 unsigned arena_ind;
Jason Evans243f7a02016-02-19 20:09:31 -08001991
1992 READONLY();
1993 WRITEONLY();
Jason Evans6edbedd2017-01-04 07:51:49 -08001994 MIB_UNSIGNED(arena_ind, 1);
Jason Evans64e458f2017-03-08 22:42:57 -08001995 arena_i_decay(tsd_tsdn(tsd), arena_ind, false);
1996
1997 ret = 0;
1998label_return:
1999 return ret;
2000}
2001
2002static int
2003arena_i_purge_ctl(tsd_t *tsd, const size_t *mib, size_t miblen, void *oldp,
2004 size_t *oldlenp, void *newp, size_t newlen) {
2005 int ret;
2006 unsigned arena_ind;
2007
2008 READONLY();
2009 WRITEONLY();
2010 MIB_UNSIGNED(arena_ind, 1);
2011 arena_i_decay(tsd_tsdn(tsd), arena_ind, true);
Jason Evans609ae592012-10-11 13:53:15 -07002012
Jason Evans34457f52012-11-03 21:18:28 -07002013 ret = 0;
Jason Evans609ae592012-10-11 13:53:15 -07002014label_return:
Jason Evansf4086432017-01-19 18:15:45 -08002015 return ret;
Jason Evans609ae592012-10-11 13:53:15 -07002016}
2017
2018static int
Jason Evansedf1baf2017-01-03 17:21:59 -08002019arena_i_reset_destroy_helper(tsd_t *tsd, const size_t *mib, size_t miblen,
2020 void *oldp, size_t *oldlenp, void *newp, size_t newlen, unsigned *arena_ind,
Jason Evansc4c25922017-01-15 16:56:30 -08002021 arena_t **arena) {
Jason Evansedf1baf2017-01-03 17:21:59 -08002022 int ret;
2023
2024 READONLY();
2025 WRITEONLY();
2026 MIB_UNSIGNED(*arena_ind, 1);
2027
Jason Evansedf1baf2017-01-03 17:21:59 -08002028 *arena = arena_get(tsd_tsdn(tsd), *arena_ind, false);
Qi Wang5aa46f02017-04-20 15:19:02 -07002029 if (*arena == NULL || arena_is_auto(*arena)) {
Jason Evansedf1baf2017-01-03 17:21:59 -08002030 ret = EFAULT;
2031 goto label_return;
2032 }
2033
2034 ret = 0;
2035label_return:
Jason Evansf4086432017-01-19 18:15:45 -08002036 return ret;
Jason Evansedf1baf2017-01-03 17:21:59 -08002037}
2038
Qi Wangb693c782017-03-17 12:42:33 -07002039static void
2040arena_reset_prepare_background_thread(tsd_t *tsd, unsigned arena_ind) {
2041 /* Temporarily disable the background thread during arena reset. */
2042 if (have_background_thread) {
2043 malloc_mutex_lock(tsd_tsdn(tsd), &background_thread_lock);
2044 if (background_thread_enabled()) {
2045 unsigned ind = arena_ind % ncpus;
2046 background_thread_info_t *info =
2047 &background_thread_info[ind];
Qi Wang394df952017-06-09 15:45:25 -07002048 assert(info->state == background_thread_started);
Qi Wang464cb602017-06-08 22:46:31 -07002049 malloc_mutex_lock(tsd_tsdn(tsd), &info->mtx);
Qi Wang394df952017-06-09 15:45:25 -07002050 info->state = background_thread_paused;
Qi Wang464cb602017-06-08 22:46:31 -07002051 malloc_mutex_unlock(tsd_tsdn(tsd), &info->mtx);
Qi Wangb693c782017-03-17 12:42:33 -07002052 }
2053 }
2054}
2055
2056static void
2057arena_reset_finish_background_thread(tsd_t *tsd, unsigned arena_ind) {
2058 if (have_background_thread) {
2059 if (background_thread_enabled()) {
2060 unsigned ind = arena_ind % ncpus;
2061 background_thread_info_t *info =
2062 &background_thread_info[ind];
Jason Evansd49ac4c2017-06-23 10:40:02 -07002063 assert(info->state == background_thread_paused);
Qi Wang464cb602017-06-08 22:46:31 -07002064 malloc_mutex_lock(tsd_tsdn(tsd), &info->mtx);
Qi Wang394df952017-06-09 15:45:25 -07002065 info->state = background_thread_started;
Qi Wang464cb602017-06-08 22:46:31 -07002066 malloc_mutex_unlock(tsd_tsdn(tsd), &info->mtx);
Qi Wangb693c782017-03-17 12:42:33 -07002067 }
2068 malloc_mutex_unlock(tsd_tsdn(tsd), &background_thread_lock);
2069 }
2070}
2071
Jason Evansedf1baf2017-01-03 17:21:59 -08002072static int
Jason Evans19ff2ce2016-04-22 14:37:17 -07002073arena_i_reset_ctl(tsd_t *tsd, const size_t *mib, size_t miblen, void *oldp,
Jason Evansc4c25922017-01-15 16:56:30 -08002074 size_t *oldlenp, void *newp, size_t newlen) {
Jason Evans19ff2ce2016-04-22 14:37:17 -07002075 int ret;
2076 unsigned arena_ind;
2077 arena_t *arena;
2078
Jason Evansedf1baf2017-01-03 17:21:59 -08002079 ret = arena_i_reset_destroy_helper(tsd, mib, miblen, oldp, oldlenp,
2080 newp, newlen, &arena_ind, &arena);
Jason Evansc4c25922017-01-15 16:56:30 -08002081 if (ret != 0) {
Jason Evansf4086432017-01-19 18:15:45 -08002082 return ret;
Jason Evansc4c25922017-01-15 16:56:30 -08002083 }
Jason Evans19ff2ce2016-04-22 14:37:17 -07002084
Qi Wangb693c782017-03-17 12:42:33 -07002085 arena_reset_prepare_background_thread(tsd, arena_ind);
Jason Evansedf1baf2017-01-03 17:21:59 -08002086 arena_reset(tsd, arena);
Qi Wangb693c782017-03-17 12:42:33 -07002087 arena_reset_finish_background_thread(tsd, arena_ind);
Jason Evans19ff2ce2016-04-22 14:37:17 -07002088
Jason Evansf4086432017-01-19 18:15:45 -08002089 return ret;
Jason Evansedf1baf2017-01-03 17:21:59 -08002090}
2091
2092static int
2093arena_i_destroy_ctl(tsd_t *tsd, const size_t *mib, size_t miblen, void *oldp,
Jason Evansc4c25922017-01-15 16:56:30 -08002094 size_t *oldlenp, void *newp, size_t newlen) {
Jason Evansedf1baf2017-01-03 17:21:59 -08002095 int ret;
2096 unsigned arena_ind;
2097 arena_t *arena;
Jason Evans9eb1b1c2017-01-18 23:03:37 -08002098 ctl_arena_t *ctl_darena, *ctl_arena;
Jason Evansedf1baf2017-01-03 17:21:59 -08002099
2100 ret = arena_i_reset_destroy_helper(tsd, mib, miblen, oldp, oldlenp,
2101 newp, newlen, &arena_ind, &arena);
Jason Evansc4c25922017-01-15 16:56:30 -08002102 if (ret != 0) {
Jason Evansedf1baf2017-01-03 17:21:59 -08002103 goto label_return;
Jason Evansc4c25922017-01-15 16:56:30 -08002104 }
Jason Evansedf1baf2017-01-03 17:21:59 -08002105
2106 if (arena_nthreads_get(arena, false) != 0 || arena_nthreads_get(arena,
2107 true) != 0) {
Jason Evans3dc4e832017-01-03 07:27:42 -08002108 ret = EFAULT;
2109 goto label_return;
2110 }
Jason Evans19ff2ce2016-04-22 14:37:17 -07002111
Qi Wangb693c782017-03-17 12:42:33 -07002112 arena_reset_prepare_background_thread(tsd, arena_ind);
Jason Evansedf1baf2017-01-03 17:21:59 -08002113 /* Merge stats after resetting and purging arena. */
Jason Evans19ff2ce2016-04-22 14:37:17 -07002114 arena_reset(tsd, arena);
Qi Wangb693c782017-03-17 12:42:33 -07002115 arena_decay(tsd_tsdn(tsd), arena, false, true);
Jason Evans9eb1b1c2017-01-18 23:03:37 -08002116 ctl_darena = arenas_i(MALLCTL_ARENAS_DESTROYED);
2117 ctl_darena->initialized = true;
2118 ctl_arena_refresh(tsd_tsdn(tsd), arena, ctl_darena, arena_ind, true);
Jason Evansedf1baf2017-01-03 17:21:59 -08002119 /* Destroy arena. */
2120 arena_destroy(tsd, arena);
Jason Evans9eb1b1c2017-01-18 23:03:37 -08002121 ctl_arena = arenas_i(arena_ind);
2122 ctl_arena->initialized = false;
Jason Evansedf1baf2017-01-03 17:21:59 -08002123 /* Record arena index for later recycling via arenas.create. */
Jason Evans9eb1b1c2017-01-18 23:03:37 -08002124 ql_elm_new(ctl_arena, destroyed_link);
2125 ql_tail_insert(&ctl_arenas->destroyed, ctl_arena, destroyed_link);
Qi Wangb693c782017-03-17 12:42:33 -07002126 arena_reset_finish_background_thread(tsd, arena_ind);
Jason Evans19ff2ce2016-04-22 14:37:17 -07002127
Jason Evansedf1baf2017-01-03 17:21:59 -08002128 assert(ret == 0);
Jason Evans19ff2ce2016-04-22 14:37:17 -07002129label_return:
Jason Evansf4086432017-01-19 18:15:45 -08002130 return ret;
Jason Evans19ff2ce2016-04-22 14:37:17 -07002131}
2132
2133static int
Jason Evansb2c0d632016-04-13 23:36:15 -07002134arena_i_dss_ctl(tsd_t *tsd, const size_t *mib, size_t miblen, void *oldp,
Jason Evansc4c25922017-01-15 16:56:30 -08002135 size_t *oldlenp, void *newp, size_t newlen) {
Jason Evans586c8ed2014-08-15 12:20:20 -07002136 int ret;
2137 const char *dss = NULL;
Jason Evans6edbedd2017-01-04 07:51:49 -08002138 unsigned arena_ind;
Jason Evans609ae592012-10-11 13:53:15 -07002139 dss_prec_t dss_prec_old = dss_prec_limit;
2140 dss_prec_t dss_prec = dss_prec_limit;
2141
Jason Evansc1e00ef2016-05-10 22:21:10 -07002142 malloc_mutex_lock(tsd_tsdn(tsd), &ctl_mtx);
Jason Evans609ae592012-10-11 13:53:15 -07002143 WRITE(dss, const char *);
Jason Evans6edbedd2017-01-04 07:51:49 -08002144 MIB_UNSIGNED(arena_ind, 1);
Jason Evans586c8ed2014-08-15 12:20:20 -07002145 if (dss != NULL) {
2146 int i;
2147 bool match = false;
2148
2149 for (i = 0; i < dss_prec_limit; i++) {
2150 if (strcmp(dss_prec_names[i], dss) == 0) {
2151 dss_prec = i;
2152 match = true;
2153 break;
2154 }
Jason Evans609ae592012-10-11 13:53:15 -07002155 }
Jason Evans586c8ed2014-08-15 12:20:20 -07002156
Jason Evans551ebc42014-10-03 10:16:09 -07002157 if (!match) {
Jason Evans586c8ed2014-08-15 12:20:20 -07002158 ret = EINVAL;
2159 goto label_return;
2160 }
Jason Evans609ae592012-10-11 13:53:15 -07002161 }
2162
Jason Evans3dc4e832017-01-03 07:27:42 -08002163 /*
2164 * Access via index narenas is deprecated, and scheduled for removal in
2165 * 6.0.0.
2166 */
Jason Evansd778dd22017-01-03 12:40:54 -08002167 if (arena_ind == MALLCTL_ARENAS_ALL || arena_ind ==
Jason Evans9eb1b1c2017-01-18 23:03:37 -08002168 ctl_arenas->narenas) {
Jason Evans3dc4e832017-01-03 07:27:42 -08002169 if (dss_prec != dss_prec_limit &&
2170 extent_dss_prec_set(dss_prec)) {
2171 ret = EFAULT;
2172 goto label_return;
2173 }
2174 dss_prec_old = extent_dss_prec_get();
2175 } else {
Jason Evansc1e00ef2016-05-10 22:21:10 -07002176 arena_t *arena = arena_get(tsd_tsdn(tsd), arena_ind, false);
Jason Evans586c8ed2014-08-15 12:20:20 -07002177 if (arena == NULL || (dss_prec != dss_prec_limit &&
Jason Evansb7795222017-02-12 16:34:36 -08002178 arena_dss_prec_set(arena, dss_prec))) {
Jason Evans586c8ed2014-08-15 12:20:20 -07002179 ret = EFAULT;
2180 goto label_return;
2181 }
Jason Evansb7795222017-02-12 16:34:36 -08002182 dss_prec_old = arena_dss_prec_get(arena);
Jason Evans609ae592012-10-11 13:53:15 -07002183 }
Jason Evans586c8ed2014-08-15 12:20:20 -07002184
Jason Evans609ae592012-10-11 13:53:15 -07002185 dss = dss_prec_names[dss_prec_old];
2186 READ(dss, const char *);
Jason Evans609ae592012-10-11 13:53:15 -07002187
2188 ret = 0;
2189label_return:
Jason Evansc1e00ef2016-05-10 22:21:10 -07002190 malloc_mutex_unlock(tsd_tsdn(tsd), &ctl_mtx);
Jason Evansf4086432017-01-19 18:15:45 -08002191 return ret;
Jason Evans609ae592012-10-11 13:53:15 -07002192}
2193
aravindfb7fe502014-05-05 15:16:56 -07002194static int
Jason Evans6e62c622017-05-17 10:47:00 -07002195arena_i_decay_ms_ctl_impl(tsd_t *tsd, const size_t *mib, size_t miblen,
Jason Evans64e458f2017-03-08 22:42:57 -08002196 void *oldp, size_t *oldlenp, void *newp, size_t newlen, bool dirty) {
Jason Evans243f7a02016-02-19 20:09:31 -08002197 int ret;
Jason Evans6edbedd2017-01-04 07:51:49 -08002198 unsigned arena_ind;
Jason Evans243f7a02016-02-19 20:09:31 -08002199 arena_t *arena;
2200
Jason Evans6edbedd2017-01-04 07:51:49 -08002201 MIB_UNSIGNED(arena_ind, 1);
Jason Evansc1e00ef2016-05-10 22:21:10 -07002202 arena = arena_get(tsd_tsdn(tsd), arena_ind, false);
Jason Evans243f7a02016-02-19 20:09:31 -08002203 if (arena == NULL) {
2204 ret = EFAULT;
2205 goto label_return;
2206 }
2207
2208 if (oldp != NULL && oldlenp != NULL) {
Jason Evans6e62c622017-05-17 10:47:00 -07002209 size_t oldval = dirty ? arena_dirty_decay_ms_get(arena) :
2210 arena_muzzy_decay_ms_get(arena);
Jason Evans243f7a02016-02-19 20:09:31 -08002211 READ(oldval, ssize_t);
2212 }
2213 if (newp != NULL) {
2214 if (newlen != sizeof(ssize_t)) {
2215 ret = EINVAL;
2216 goto label_return;
2217 }
Jason Evans6e62c622017-05-17 10:47:00 -07002218 if (dirty ? arena_dirty_decay_ms_set(tsd_tsdn(tsd), arena,
2219 *(ssize_t *)newp) : arena_muzzy_decay_ms_set(tsd_tsdn(tsd),
2220 arena, *(ssize_t *)newp)) {
Jason Evans243f7a02016-02-19 20:09:31 -08002221 ret = EFAULT;
2222 goto label_return;
2223 }
2224 }
2225
2226 ret = 0;
2227label_return:
Jason Evansf4086432017-01-19 18:15:45 -08002228 return ret;
Jason Evans243f7a02016-02-19 20:09:31 -08002229}
2230
2231static int
Jason Evans6e62c622017-05-17 10:47:00 -07002232arena_i_dirty_decay_ms_ctl(tsd_t *tsd, const size_t *mib, size_t miblen,
Jason Evans64e458f2017-03-08 22:42:57 -08002233 void *oldp, size_t *oldlenp, void *newp, size_t newlen) {
Jason Evans6e62c622017-05-17 10:47:00 -07002234 return arena_i_decay_ms_ctl_impl(tsd, mib, miblen, oldp, oldlenp, newp,
2235 newlen, true);
Jason Evans64e458f2017-03-08 22:42:57 -08002236}
2237
2238static int
Jason Evans6e62c622017-05-17 10:47:00 -07002239arena_i_muzzy_decay_ms_ctl(tsd_t *tsd, const size_t *mib, size_t miblen,
Jason Evans64e458f2017-03-08 22:42:57 -08002240 void *oldp, size_t *oldlenp, void *newp, size_t newlen) {
Jason Evans6e62c622017-05-17 10:47:00 -07002241 return arena_i_decay_ms_ctl_impl(tsd, mib, miblen, oldp, oldlenp, newp,
2242 newlen, false);
Jason Evans64e458f2017-03-08 22:42:57 -08002243}
2244
2245static int
Jason Evans9c305c92016-05-31 15:03:51 -07002246arena_i_extent_hooks_ctl(tsd_t *tsd, const size_t *mib, size_t miblen,
Jason Evansc4c25922017-01-15 16:56:30 -08002247 void *oldp, size_t *oldlenp, void *newp, size_t newlen) {
Jason Evansb49a3342015-07-28 11:28:19 -04002248 int ret;
Jason Evans6edbedd2017-01-04 07:51:49 -08002249 unsigned arena_ind;
Jason Evansb49a3342015-07-28 11:28:19 -04002250 arena_t *arena;
2251
Jason Evansc1e00ef2016-05-10 22:21:10 -07002252 malloc_mutex_lock(tsd_tsdn(tsd), &ctl_mtx);
Jason Evans6edbedd2017-01-04 07:51:49 -08002253 MIB_UNSIGNED(arena_ind, 1);
Qi Wang3f0dc642018-04-11 15:15:26 -07002254 if (arena_ind < narenas_total_get()) {
2255 extent_hooks_t *old_extent_hooks;
2256 arena = arena_get(tsd_tsdn(tsd), arena_ind, false);
2257 if (arena == NULL) {
2258 if (arena_ind >= narenas_auto) {
2259 ret = EFAULT;
2260 goto label_return;
2261 }
2262 old_extent_hooks =
2263 (extent_hooks_t *)&extent_hooks_default;
Jason Evansf8f05422016-06-03 12:05:53 -07002264 READ(old_extent_hooks, extent_hooks_t *);
Qi Wang3f0dc642018-04-11 15:15:26 -07002265 if (newp != NULL) {
2266 /* Initialize a new arena as a side effect. */
2267 extent_hooks_t *new_extent_hooks
2268 JEMALLOC_CC_SILENCE_INIT(NULL);
2269 WRITE(new_extent_hooks, extent_hooks_t *);
2270 arena = arena_init(tsd_tsdn(tsd), arena_ind,
2271 new_extent_hooks);
2272 if (arena == NULL) {
2273 ret = EFAULT;
2274 goto label_return;
2275 }
2276 }
Jason Evansb49a3342015-07-28 11:28:19 -04002277 } else {
Qi Wang3f0dc642018-04-11 15:15:26 -07002278 if (newp != NULL) {
2279 extent_hooks_t *new_extent_hooks
2280 JEMALLOC_CC_SILENCE_INIT(NULL);
2281 WRITE(new_extent_hooks, extent_hooks_t *);
2282 old_extent_hooks = extent_hooks_set(tsd, arena,
2283 new_extent_hooks);
2284 READ(old_extent_hooks, extent_hooks_t *);
2285 } else {
2286 old_extent_hooks = extent_hooks_get(arena);
2287 READ(old_extent_hooks, extent_hooks_t *);
2288 }
Jason Evansb49a3342015-07-28 11:28:19 -04002289 }
2290 } else {
2291 ret = EFAULT;
2292 goto label_return;
2293 }
2294 ret = 0;
2295label_return:
Jason Evansc1e00ef2016-05-10 22:21:10 -07002296 malloc_mutex_unlock(tsd_tsdn(tsd), &ctl_mtx);
Jason Evansf4086432017-01-19 18:15:45 -08002297 return ret;
aravindfb7fe502014-05-05 15:16:56 -07002298}
2299
Qi Wange422fa82017-11-02 17:48:39 -07002300static int
2301arena_i_retain_grow_limit_ctl(tsd_t *tsd, const size_t *mib, size_t miblen,
2302 void *oldp, size_t *oldlenp, void *newp, size_t newlen) {
2303 int ret;
2304 unsigned arena_ind;
2305 arena_t *arena;
2306
2307 if (!opt_retain) {
2308 /* Only relevant when retain is enabled. */
2309 return ENOENT;
2310 }
2311
2312 malloc_mutex_lock(tsd_tsdn(tsd), &ctl_mtx);
2313 MIB_UNSIGNED(arena_ind, 1);
2314 if (arena_ind < narenas_total_get() && (arena =
2315 arena_get(tsd_tsdn(tsd), arena_ind, false)) != NULL) {
2316 size_t old_limit, new_limit;
2317 if (newp != NULL) {
2318 WRITE(new_limit, size_t);
2319 }
2320 bool err = arena_retain_grow_limit_get_set(tsd, arena,
2321 &old_limit, newp != NULL ? &new_limit : NULL);
2322 if (!err) {
2323 READ(old_limit, size_t);
2324 ret = 0;
2325 } else {
2326 ret = EFAULT;
2327 }
2328 } else {
2329 ret = EFAULT;
2330 }
2331label_return:
2332 malloc_mutex_unlock(tsd_tsdn(tsd), &ctl_mtx);
2333 return ret;
2334}
2335
Jason Evans609ae592012-10-11 13:53:15 -07002336static const ctl_named_node_t *
Jason Evansc4c25922017-01-15 16:56:30 -08002337arena_i_index(tsdn_t *tsdn, const size_t *mib, size_t miblen, size_t i) {
Jason Evansb2c0d632016-04-13 23:36:15 -07002338 const ctl_named_node_t *ret;
Jason Evans609ae592012-10-11 13:53:15 -07002339
Jason Evansc1e00ef2016-05-10 22:21:10 -07002340 malloc_mutex_lock(tsdn, &ctl_mtx);
Jason Evansedf1baf2017-01-03 17:21:59 -08002341 switch (i) {
2342 case MALLCTL_ARENAS_ALL:
2343 case MALLCTL_ARENAS_DESTROYED:
2344 break;
2345 default:
Jason Evans9eb1b1c2017-01-18 23:03:37 -08002346 if (i > ctl_arenas->narenas) {
Jason Evansedf1baf2017-01-03 17:21:59 -08002347 ret = NULL;
2348 goto label_return;
2349 }
2350 break;
Jason Evans609ae592012-10-11 13:53:15 -07002351 }
2352
2353 ret = super_arena_i_node;
2354label_return:
Jason Evansc1e00ef2016-05-10 22:21:10 -07002355 malloc_mutex_unlock(tsdn, &ctl_mtx);
Jason Evansf4086432017-01-19 18:15:45 -08002356 return ret;
Jason Evans609ae592012-10-11 13:53:15 -07002357}
2358
Jason Evans609ae592012-10-11 13:53:15 -07002359/******************************************************************************/
2360
Jason Evans609ae592012-10-11 13:53:15 -07002361static int
Jason Evansb2c0d632016-04-13 23:36:15 -07002362arenas_narenas_ctl(tsd_t *tsd, const size_t *mib, size_t miblen, void *oldp,
Jason Evansc4c25922017-01-15 16:56:30 -08002363 size_t *oldlenp, void *newp, size_t newlen) {
Jason Evans609ae592012-10-11 13:53:15 -07002364 int ret;
2365 unsigned narenas;
2366
Jason Evansc1e00ef2016-05-10 22:21:10 -07002367 malloc_mutex_lock(tsd_tsdn(tsd), &ctl_mtx);
Jason Evans609ae592012-10-11 13:53:15 -07002368 READONLY();
2369 if (*oldlenp != sizeof(unsigned)) {
2370 ret = EINVAL;
2371 goto label_return;
2372 }
Jason Evans9eb1b1c2017-01-18 23:03:37 -08002373 narenas = ctl_arenas->narenas;
Jason Evans609ae592012-10-11 13:53:15 -07002374 READ(narenas, unsigned);
2375
2376 ret = 0;
2377label_return:
Jason Evansc1e00ef2016-05-10 22:21:10 -07002378 malloc_mutex_unlock(tsd_tsdn(tsd), &ctl_mtx);
Jason Evansf4086432017-01-19 18:15:45 -08002379 return ret;
Jason Evans609ae592012-10-11 13:53:15 -07002380}
Jason Evans3c234352010-01-27 13:10:55 -08002381
2382static int
Jason Evans6e62c622017-05-17 10:47:00 -07002383arenas_decay_ms_ctl_impl(tsd_t *tsd, const size_t *mib, size_t miblen,
Jason Evans64e458f2017-03-08 22:42:57 -08002384 void *oldp, size_t *oldlenp, void *newp, size_t newlen, bool dirty) {
Jason Evans243f7a02016-02-19 20:09:31 -08002385 int ret;
2386
2387 if (oldp != NULL && oldlenp != NULL) {
Jason Evans6e62c622017-05-17 10:47:00 -07002388 size_t oldval = (dirty ? arena_dirty_decay_ms_default_get() :
2389 arena_muzzy_decay_ms_default_get());
Jason Evans243f7a02016-02-19 20:09:31 -08002390 READ(oldval, ssize_t);
2391 }
2392 if (newp != NULL) {
2393 if (newlen != sizeof(ssize_t)) {
2394 ret = EINVAL;
2395 goto label_return;
2396 }
Qi Wange422fa82017-11-02 17:48:39 -07002397 if (dirty ? arena_dirty_decay_ms_default_set(*(ssize_t *)newp)
Jason Evans6e62c622017-05-17 10:47:00 -07002398 : arena_muzzy_decay_ms_default_set(*(ssize_t *)newp)) {
Jason Evans243f7a02016-02-19 20:09:31 -08002399 ret = EFAULT;
2400 goto label_return;
2401 }
2402 }
2403
2404 ret = 0;
2405label_return:
Jason Evansf4086432017-01-19 18:15:45 -08002406 return ret;
Jason Evans243f7a02016-02-19 20:09:31 -08002407}
2408
Jason Evans64e458f2017-03-08 22:42:57 -08002409static int
Jason Evans6e62c622017-05-17 10:47:00 -07002410arenas_dirty_decay_ms_ctl(tsd_t *tsd, const size_t *mib, size_t miblen,
Jason Evans64e458f2017-03-08 22:42:57 -08002411 void *oldp, size_t *oldlenp, void *newp, size_t newlen) {
Jason Evans6e62c622017-05-17 10:47:00 -07002412 return arenas_decay_ms_ctl_impl(tsd, mib, miblen, oldp, oldlenp, newp,
Jason Evans64e458f2017-03-08 22:42:57 -08002413 newlen, true);
2414}
2415
2416static int
Jason Evans6e62c622017-05-17 10:47:00 -07002417arenas_muzzy_decay_ms_ctl(tsd_t *tsd, const size_t *mib, size_t miblen,
Jason Evans64e458f2017-03-08 22:42:57 -08002418 void *oldp, size_t *oldlenp, void *newp, size_t newlen) {
Jason Evans6e62c622017-05-17 10:47:00 -07002419 return arenas_decay_ms_ctl_impl(tsd, mib, miblen, oldp, oldlenp, newp,
Jason Evans64e458f2017-03-08 22:42:57 -08002420 newlen, false);
2421}
2422
Jason Evansfc4dcfa2010-11-24 15:44:21 -08002423CTL_RO_NL_GEN(arenas_quantum, QUANTUM, size_t)
Jason Evansae4c7b42012-04-02 07:04:34 -07002424CTL_RO_NL_GEN(arenas_page, PAGE, size_t)
Jason Evans4403c9a2017-04-20 17:21:37 -07002425CTL_RO_NL_GEN(arenas_tcache_max, tcache_maxclass, size_t)
Jason Evansb1726102012-02-28 16:50:47 -08002426CTL_RO_NL_GEN(arenas_nbins, NBINS, unsigned)
Jason Evans4403c9a2017-04-20 17:21:37 -07002427CTL_RO_NL_GEN(arenas_nhbins, nhbins, unsigned)
David T. Goldblatt4bf4a1c2017-10-01 17:22:06 -07002428CTL_RO_NL_GEN(arenas_bin_i_size, bin_infos[mib[2]].reg_size, size_t)
2429CTL_RO_NL_GEN(arenas_bin_i_nregs, bin_infos[mib[2]].nregs, uint32_t)
2430CTL_RO_NL_GEN(arenas_bin_i_slab_size, bin_infos[mib[2]].slab_size, size_t)
Jason Evansd8a39002013-12-19 21:40:41 -08002431static const ctl_named_node_t *
Jason Evansc4c25922017-01-15 16:56:30 -08002432arenas_bin_i_index(tsdn_t *tsdn, const size_t *mib, size_t miblen, size_t i) {
2433 if (i > NBINS) {
Jason Evansf4086432017-01-19 18:15:45 -08002434 return NULL;
Jason Evansc4c25922017-01-15 16:56:30 -08002435 }
Jason Evansf4086432017-01-19 18:15:45 -08002436 return super_arenas_bin_i_node;
Jason Evansd8a39002013-12-19 21:40:41 -08002437}
2438
Jason Evans7d63fed2016-05-31 14:50:21 -07002439CTL_RO_NL_GEN(arenas_nlextents, NSIZES - NBINS, unsigned)
David Goldblatt8261e582017-05-30 10:45:37 -07002440CTL_RO_NL_GEN(arenas_lextent_i_size, sz_index2size(NBINS+(szind_t)mib[2]),
2441 size_t)
Jason Evans3c4d92e2014-10-12 22:53:59 -07002442static const ctl_named_node_t *
Jason Evansc4c25922017-01-15 16:56:30 -08002443arenas_lextent_i_index(tsdn_t *tsdn, const size_t *mib, size_t miblen,
2444 size_t i) {
2445 if (i > NSIZES - NBINS) {
Jason Evansf4086432017-01-19 18:15:45 -08002446 return NULL;
Jason Evansc4c25922017-01-15 16:56:30 -08002447 }
Jason Evansf4086432017-01-19 18:15:45 -08002448 return super_arenas_lextent_i_node;
Jason Evans3c4d92e2014-10-12 22:53:59 -07002449}
2450
Jason Evans6005f072010-09-30 16:55:08 -07002451static int
Jason Evans0f04bb12017-01-03 08:21:29 -08002452arenas_create_ctl(tsd_t *tsd, const size_t *mib, size_t miblen, void *oldp,
Jason Evansc4c25922017-01-15 16:56:30 -08002453 size_t *oldlenp, void *newp, size_t newlen) {
Jason Evans609ae592012-10-11 13:53:15 -07002454 int ret;
Jason Evansa0dd3a42016-12-22 16:39:10 -06002455 extent_hooks_t *extent_hooks;
Jason Evansedf1baf2017-01-03 17:21:59 -08002456 unsigned arena_ind;
Jason Evans609ae592012-10-11 13:53:15 -07002457
Jason Evansc1e00ef2016-05-10 22:21:10 -07002458 malloc_mutex_lock(tsd_tsdn(tsd), &ctl_mtx);
Jason Evansa0dd3a42016-12-22 16:39:10 -06002459
2460 extent_hooks = (extent_hooks_t *)&extent_hooks_default;
2461 WRITE(extent_hooks, extent_hooks_t *);
Qi Wang57beeb22017-06-22 18:58:40 -07002462 if ((arena_ind = ctl_arena_init(tsd, extent_hooks)) == UINT_MAX) {
Jason Evans609ae592012-10-11 13:53:15 -07002463 ret = EAGAIN;
2464 goto label_return;
2465 }
Jason Evansedf1baf2017-01-03 17:21:59 -08002466 READ(arena_ind, unsigned);
Jason Evans609ae592012-10-11 13:53:15 -07002467
Jason Evans6005f072010-09-30 16:55:08 -07002468 ret = 0;
Jason Evansa1ee7832012-04-10 15:07:44 -07002469label_return:
Jason Evansc1e00ef2016-05-10 22:21:10 -07002470 malloc_mutex_unlock(tsd_tsdn(tsd), &ctl_mtx);
Jason Evansf4086432017-01-19 18:15:45 -08002471 return ret;
Jason Evans6005f072010-09-30 16:55:08 -07002472}
2473
Jason Evans3c234352010-01-27 13:10:55 -08002474/******************************************************************************/
2475
Jason Evansd34f9e72010-02-11 13:19:21 -08002476static int
Jason Evansb2c0d632016-04-13 23:36:15 -07002477prof_thread_active_init_ctl(tsd_t *tsd, const size_t *mib, size_t miblen,
Jason Evansc4c25922017-01-15 16:56:30 -08002478 void *oldp, size_t *oldlenp, void *newp, size_t newlen) {
Jason Evansb2c0d632016-04-13 23:36:15 -07002479 int ret;
2480 bool oldval;
2481
Jason Evansc4c25922017-01-15 16:56:30 -08002482 if (!config_prof) {
Jason Evansf4086432017-01-19 18:15:45 -08002483 return ENOENT;
Jason Evansc4c25922017-01-15 16:56:30 -08002484 }
Jason Evansb2c0d632016-04-13 23:36:15 -07002485
2486 if (newp != NULL) {
2487 if (newlen != sizeof(bool)) {
2488 ret = EINVAL;
2489 goto label_return;
2490 }
Jason Evansc1e00ef2016-05-10 22:21:10 -07002491 oldval = prof_thread_active_init_set(tsd_tsdn(tsd),
2492 *(bool *)newp);
Jason Evansc4c25922017-01-15 16:56:30 -08002493 } else {
Jason Evansc1e00ef2016-05-10 22:21:10 -07002494 oldval = prof_thread_active_init_get(tsd_tsdn(tsd));
Jason Evansc4c25922017-01-15 16:56:30 -08002495 }
Jason Evansb2c0d632016-04-13 23:36:15 -07002496 READ(oldval, bool);
2497
2498 ret = 0;
2499label_return:
Jason Evansf4086432017-01-19 18:15:45 -08002500 return ret;
Jason Evansb2c0d632016-04-13 23:36:15 -07002501}
2502
2503static int
2504prof_active_ctl(tsd_t *tsd, const size_t *mib, size_t miblen, void *oldp,
Jason Evansc4c25922017-01-15 16:56:30 -08002505 size_t *oldlenp, void *newp, size_t newlen) {
Jason Evansfc12c0b2014-10-03 23:25:30 -07002506 int ret;
2507 bool oldval;
2508
Jason Evansc4c25922017-01-15 16:56:30 -08002509 if (!config_prof) {
Jason Evansf4086432017-01-19 18:15:45 -08002510 return ENOENT;
Jason Evansc4c25922017-01-15 16:56:30 -08002511 }
Jason Evansfc12c0b2014-10-03 23:25:30 -07002512
2513 if (newp != NULL) {
2514 if (newlen != sizeof(bool)) {
2515 ret = EINVAL;
2516 goto label_return;
2517 }
Jason Evansc1e00ef2016-05-10 22:21:10 -07002518 oldval = prof_active_set(tsd_tsdn(tsd), *(bool *)newp);
Jason Evansc4c25922017-01-15 16:56:30 -08002519 } else {
Jason Evansc1e00ef2016-05-10 22:21:10 -07002520 oldval = prof_active_get(tsd_tsdn(tsd));
Jason Evansc4c25922017-01-15 16:56:30 -08002521 }
Jason Evansfc12c0b2014-10-03 23:25:30 -07002522 READ(oldval, bool);
2523
2524 ret = 0;
2525label_return:
Jason Evansf4086432017-01-19 18:15:45 -08002526 return ret;
Jason Evansfc12c0b2014-10-03 23:25:30 -07002527}
2528
2529static int
Jason Evansb2c0d632016-04-13 23:36:15 -07002530prof_dump_ctl(tsd_t *tsd, const size_t *mib, size_t miblen, void *oldp,
Jason Evansc4c25922017-01-15 16:56:30 -08002531 size_t *oldlenp, void *newp, size_t newlen) {
Jason Evansd34f9e72010-02-11 13:19:21 -08002532 int ret;
Jason Evans22ca8552010-03-02 11:57:30 -08002533 const char *filename = NULL;
Jason Evansd34f9e72010-02-11 13:19:21 -08002534
Jason Evansc4c25922017-01-15 16:56:30 -08002535 if (!config_prof) {
Jason Evansf4086432017-01-19 18:15:45 -08002536 return ENOENT;
Jason Evansc4c25922017-01-15 16:56:30 -08002537 }
Jason Evans7372b152012-02-10 20:22:09 -08002538
Jason Evans22ca8552010-03-02 11:57:30 -08002539 WRITEONLY();
2540 WRITE(filename, const char *);
Jason Evansd34f9e72010-02-11 13:19:21 -08002541
Jason Evansb2c0d632016-04-13 23:36:15 -07002542 if (prof_mdump(tsd, filename)) {
Jason Evans22ca8552010-03-02 11:57:30 -08002543 ret = EFAULT;
Jason Evansa1ee7832012-04-10 15:07:44 -07002544 goto label_return;
Jason Evans22ca8552010-03-02 11:57:30 -08002545 }
Jason Evansd34f9e72010-02-11 13:19:21 -08002546
2547 ret = 0;
Jason Evansa1ee7832012-04-10 15:07:44 -07002548label_return:
Jason Evansf4086432017-01-19 18:15:45 -08002549 return ret;
Jason Evansd34f9e72010-02-11 13:19:21 -08002550}
2551
Jason Evans602c8e02014-08-18 16:22:13 -07002552static int
Jason Evansb2c0d632016-04-13 23:36:15 -07002553prof_gdump_ctl(tsd_t *tsd, const size_t *mib, size_t miblen, void *oldp,
Jason Evansc4c25922017-01-15 16:56:30 -08002554 size_t *oldlenp, void *newp, size_t newlen) {
Jason Evans5b8ed5b2015-01-25 21:16:57 -08002555 int ret;
2556 bool oldval;
2557
Jason Evansc4c25922017-01-15 16:56:30 -08002558 if (!config_prof) {
Jason Evansf4086432017-01-19 18:15:45 -08002559 return ENOENT;
Jason Evansc4c25922017-01-15 16:56:30 -08002560 }
Jason Evans5b8ed5b2015-01-25 21:16:57 -08002561
2562 if (newp != NULL) {
2563 if (newlen != sizeof(bool)) {
2564 ret = EINVAL;
2565 goto label_return;
2566 }
Jason Evansc1e00ef2016-05-10 22:21:10 -07002567 oldval = prof_gdump_set(tsd_tsdn(tsd), *(bool *)newp);
Jason Evansc4c25922017-01-15 16:56:30 -08002568 } else {
Jason Evansc1e00ef2016-05-10 22:21:10 -07002569 oldval = prof_gdump_get(tsd_tsdn(tsd));
Jason Evansc4c25922017-01-15 16:56:30 -08002570 }
Jason Evans5b8ed5b2015-01-25 21:16:57 -08002571 READ(oldval, bool);
2572
2573 ret = 0;
2574label_return:
Jason Evansf4086432017-01-19 18:15:45 -08002575 return ret;
Jason Evans5b8ed5b2015-01-25 21:16:57 -08002576}
2577
2578static int
Jason Evansb2c0d632016-04-13 23:36:15 -07002579prof_reset_ctl(tsd_t *tsd, const size_t *mib, size_t miblen, void *oldp,
Jason Evansc4c25922017-01-15 16:56:30 -08002580 size_t *oldlenp, void *newp, size_t newlen) {
Jason Evans602c8e02014-08-18 16:22:13 -07002581 int ret;
2582 size_t lg_sample = lg_prof_sample;
2583
Jason Evansc4c25922017-01-15 16:56:30 -08002584 if (!config_prof) {
Jason Evansf4086432017-01-19 18:15:45 -08002585 return ENOENT;
Jason Evansc4c25922017-01-15 16:56:30 -08002586 }
Jason Evans602c8e02014-08-18 16:22:13 -07002587
2588 WRITEONLY();
2589 WRITE(lg_sample, size_t);
Jason Evansc4c25922017-01-15 16:56:30 -08002590 if (lg_sample >= (sizeof(uint64_t) << 3)) {
Jason Evans602c8e02014-08-18 16:22:13 -07002591 lg_sample = (sizeof(uint64_t) << 3) - 1;
Jason Evansc4c25922017-01-15 16:56:30 -08002592 }
Jason Evans602c8e02014-08-18 16:22:13 -07002593
Jason Evansb54d1602016-10-20 23:59:12 -07002594 prof_reset(tsd, lg_sample);
Jason Evans602c8e02014-08-18 16:22:13 -07002595
2596 ret = 0;
2597label_return:
Jason Evansf4086432017-01-19 18:15:45 -08002598 return ret;
Jason Evans602c8e02014-08-18 16:22:13 -07002599}
2600
Jason Evans7372b152012-02-10 20:22:09 -08002601CTL_RO_NL_CGEN(config_prof, prof_interval, prof_interval, uint64_t)
Jason Evans602c8e02014-08-18 16:22:13 -07002602CTL_RO_NL_CGEN(config_prof, lg_prof_sample, lg_prof_sample, size_t)
Jason Evansd34f9e72010-02-11 13:19:21 -08002603
2604/******************************************************************************/
2605
Jason Evansd778dd22017-01-03 12:40:54 -08002606CTL_RO_CGEN(config_stats, stats_allocated, ctl_stats->allocated, size_t)
2607CTL_RO_CGEN(config_stats, stats_active, ctl_stats->active, size_t)
2608CTL_RO_CGEN(config_stats, stats_metadata, ctl_stats->metadata, size_t)
Qi Wange55c3ca2017-08-25 13:24:49 -07002609CTL_RO_CGEN(config_stats, stats_metadata_thp, ctl_stats->metadata_thp, size_t)
Jason Evansd778dd22017-01-03 12:40:54 -08002610CTL_RO_CGEN(config_stats, stats_resident, ctl_stats->resident, size_t)
2611CTL_RO_CGEN(config_stats, stats_mapped, ctl_stats->mapped, size_t)
2612CTL_RO_CGEN(config_stats, stats_retained, ctl_stats->retained, size_t)
Jason Evansd8a39002013-12-19 21:40:41 -08002613
Qi Wang2bee0c62017-05-12 12:30:33 -07002614CTL_RO_CGEN(config_stats, stats_background_thread_num_threads,
2615 ctl_stats->background_thread.num_threads, size_t)
2616CTL_RO_CGEN(config_stats, stats_background_thread_num_runs,
2617 ctl_stats->background_thread.num_runs, uint64_t)
2618CTL_RO_CGEN(config_stats, stats_background_thread_run_interval,
2619 nstime_ns(&ctl_stats->background_thread.run_interval), uint64_t)
2620
Jason Evans9eb1b1c2017-01-18 23:03:37 -08002621CTL_RO_GEN(stats_arenas_i_dss, arenas_i(mib[2])->dss, const char *)
Jason Evans6e62c622017-05-17 10:47:00 -07002622CTL_RO_GEN(stats_arenas_i_dirty_decay_ms, arenas_i(mib[2])->dirty_decay_ms,
Jason Evans64e458f2017-03-08 22:42:57 -08002623 ssize_t)
Jason Evans6e62c622017-05-17 10:47:00 -07002624CTL_RO_GEN(stats_arenas_i_muzzy_decay_ms, arenas_i(mib[2])->muzzy_decay_ms,
Jason Evans243f7a02016-02-19 20:09:31 -08002625 ssize_t)
Jason Evans9eb1b1c2017-01-18 23:03:37 -08002626CTL_RO_GEN(stats_arenas_i_nthreads, arenas_i(mib[2])->nthreads, unsigned)
Qi Wangbaf3e292017-05-16 13:56:00 -07002627CTL_RO_GEN(stats_arenas_i_uptime,
2628 nstime_ns(&arenas_i(mib[2])->astats->astats.uptime), uint64_t)
Jason Evans9eb1b1c2017-01-18 23:03:37 -08002629CTL_RO_GEN(stats_arenas_i_pactive, arenas_i(mib[2])->pactive, size_t)
2630CTL_RO_GEN(stats_arenas_i_pdirty, arenas_i(mib[2])->pdirty, size_t)
Jason Evans64e458f2017-03-08 22:42:57 -08002631CTL_RO_GEN(stats_arenas_i_pmuzzy, arenas_i(mib[2])->pmuzzy, size_t)
Jason Evansd8a39002013-12-19 21:40:41 -08002632CTL_RO_CGEN(config_stats, stats_arenas_i_mapped,
David Goldblattee202ef2017-03-13 16:18:40 -07002633 atomic_load_zu(&arenas_i(mib[2])->astats->astats.mapped, ATOMIC_RELAXED),
2634 size_t)
Jason Evans04c3c0f2016-05-03 22:11:35 -07002635CTL_RO_CGEN(config_stats, stats_arenas_i_retained,
David Goldblattee202ef2017-03-13 16:18:40 -07002636 atomic_load_zu(&arenas_i(mib[2])->astats->astats.retained, ATOMIC_RELAXED),
2637 size_t)
Jason Evans64e458f2017-03-08 22:42:57 -08002638
2639CTL_RO_CGEN(config_stats, stats_arenas_i_dirty_npurge,
David T. Goldblatt7f1b02e2017-11-04 12:50:19 -07002640 ctl_arena_stats_read_u64(
2641 &arenas_i(mib[2])->astats->astats.decay_dirty.npurge), uint64_t)
Jason Evans64e458f2017-03-08 22:42:57 -08002642CTL_RO_CGEN(config_stats, stats_arenas_i_dirty_nmadvise,
David T. Goldblatt7f1b02e2017-11-04 12:50:19 -07002643 ctl_arena_stats_read_u64(
Jason Evans64e458f2017-03-08 22:42:57 -08002644 &arenas_i(mib[2])->astats->astats.decay_dirty.nmadvise), uint64_t)
2645CTL_RO_CGEN(config_stats, stats_arenas_i_dirty_purged,
David T. Goldblatt7f1b02e2017-11-04 12:50:19 -07002646 ctl_arena_stats_read_u64(
2647 &arenas_i(mib[2])->astats->astats.decay_dirty.purged), uint64_t)
Jason Evans64e458f2017-03-08 22:42:57 -08002648
2649CTL_RO_CGEN(config_stats, stats_arenas_i_muzzy_npurge,
David T. Goldblatt7f1b02e2017-11-04 12:50:19 -07002650 ctl_arena_stats_read_u64(
2651 &arenas_i(mib[2])->astats->astats.decay_muzzy.npurge), uint64_t)
Jason Evans64e458f2017-03-08 22:42:57 -08002652CTL_RO_CGEN(config_stats, stats_arenas_i_muzzy_nmadvise,
David T. Goldblatt7f1b02e2017-11-04 12:50:19 -07002653 ctl_arena_stats_read_u64(
Jason Evans64e458f2017-03-08 22:42:57 -08002654 &arenas_i(mib[2])->astats->astats.decay_muzzy.nmadvise), uint64_t)
2655CTL_RO_CGEN(config_stats, stats_arenas_i_muzzy_purged,
David T. Goldblatt7f1b02e2017-11-04 12:50:19 -07002656 ctl_arena_stats_read_u64(
2657 &arenas_i(mib[2])->astats->astats.decay_muzzy.purged), uint64_t)
Jason Evans64e458f2017-03-08 22:42:57 -08002658
Jason Evansa0dd3a42016-12-22 16:39:10 -06002659CTL_RO_CGEN(config_stats, stats_arenas_i_base,
David Goldblattee202ef2017-03-13 16:18:40 -07002660 atomic_load_zu(&arenas_i(mib[2])->astats->astats.base, ATOMIC_RELAXED),
2661 size_t)
Jason Evansa0dd3a42016-12-22 16:39:10 -06002662CTL_RO_CGEN(config_stats, stats_arenas_i_internal,
David Goldblattee202ef2017-03-13 16:18:40 -07002663 atomic_load_zu(&arenas_i(mib[2])->astats->astats.internal, ATOMIC_RELAXED),
2664 size_t)
Qi Wange55c3ca2017-08-25 13:24:49 -07002665CTL_RO_CGEN(config_stats, stats_arenas_i_metadata_thp,
2666 atomic_load_zu(&arenas_i(mib[2])->astats->astats.metadata_thp,
2667 ATOMIC_RELAXED), size_t)
Jason Evans4403c9a2017-04-20 17:21:37 -07002668CTL_RO_CGEN(config_stats, stats_arenas_i_tcache_bytes,
David Goldblattee202ef2017-03-13 16:18:40 -07002669 atomic_load_zu(&arenas_i(mib[2])->astats->astats.tcache_bytes,
2670 ATOMIC_RELAXED), size_t)
Jason Evansa0dd3a42016-12-22 16:39:10 -06002671CTL_RO_CGEN(config_stats, stats_arenas_i_resident,
David Goldblattee202ef2017-03-13 16:18:40 -07002672 atomic_load_zu(&arenas_i(mib[2])->astats->astats.resident, ATOMIC_RELAXED),
2673 size_t)
Jason Evansd8a39002013-12-19 21:40:41 -08002674
Jason Evans7372b152012-02-10 20:22:09 -08002675CTL_RO_CGEN(config_stats, stats_arenas_i_small_allocated,
Jason Evans9eb1b1c2017-01-18 23:03:37 -08002676 arenas_i(mib[2])->astats->allocated_small, size_t)
Jason Evans7372b152012-02-10 20:22:09 -08002677CTL_RO_CGEN(config_stats, stats_arenas_i_small_nmalloc,
Jason Evans9eb1b1c2017-01-18 23:03:37 -08002678 arenas_i(mib[2])->astats->nmalloc_small, uint64_t)
Jason Evans7372b152012-02-10 20:22:09 -08002679CTL_RO_CGEN(config_stats, stats_arenas_i_small_ndalloc,
Jason Evans9eb1b1c2017-01-18 23:03:37 -08002680 arenas_i(mib[2])->astats->ndalloc_small, uint64_t)
Jason Evans7372b152012-02-10 20:22:09 -08002681CTL_RO_CGEN(config_stats, stats_arenas_i_small_nrequests,
Jason Evans9eb1b1c2017-01-18 23:03:37 -08002682 arenas_i(mib[2])->astats->nrequests_small, uint64_t)
Jason Evans7d63fed2016-05-31 14:50:21 -07002683CTL_RO_CGEN(config_stats, stats_arenas_i_large_allocated,
David Goldblattee202ef2017-03-13 16:18:40 -07002684 atomic_load_zu(&arenas_i(mib[2])->astats->astats.allocated_large,
2685 ATOMIC_RELAXED), size_t)
Jason Evans7d63fed2016-05-31 14:50:21 -07002686CTL_RO_CGEN(config_stats, stats_arenas_i_large_nmalloc,
David T. Goldblatt7f1b02e2017-11-04 12:50:19 -07002687 ctl_arena_stats_read_u64(
2688 &arenas_i(mib[2])->astats->astats.nmalloc_large), uint64_t)
Jason Evans7d63fed2016-05-31 14:50:21 -07002689CTL_RO_CGEN(config_stats, stats_arenas_i_large_ndalloc,
David T. Goldblatt7f1b02e2017-11-04 12:50:19 -07002690 ctl_arena_stats_read_u64(
2691 &arenas_i(mib[2])->astats->astats.ndalloc_large), uint64_t)
2692/*
2693 * Note: "nmalloc" here instead of "nrequests" in the read. This is intentional.
2694 */
Jason Evans7d63fed2016-05-31 14:50:21 -07002695CTL_RO_CGEN(config_stats, stats_arenas_i_large_nrequests,
David T. Goldblatt7f1b02e2017-11-04 12:50:19 -07002696 ctl_arena_stats_read_u64(
2697 &arenas_i(mib[2])->astats->astats.nmalloc_large), uint64_t) /* Intentional. */
Jason Evans3c234352010-01-27 13:10:55 -08002698
Qi Wang0fb5c0e2017-03-10 12:14:05 -08002699/* Lock profiling related APIs below. */
Qi Wang64c5f5c2017-03-13 17:29:03 -07002700#define RO_MUTEX_CTL_GEN(n, l) \
Qi Wangca9074d2017-03-11 20:28:31 -08002701CTL_RO_CGEN(config_stats, stats_##n##_num_ops, \
2702 l.n_lock_ops, uint64_t) \
2703CTL_RO_CGEN(config_stats, stats_##n##_num_wait, \
2704 l.n_wait_times, uint64_t) \
2705CTL_RO_CGEN(config_stats, stats_##n##_num_spin_acq, \
2706 l.n_spin_acquired, uint64_t) \
2707CTL_RO_CGEN(config_stats, stats_##n##_num_owner_switch, \
2708 l.n_owner_switches, uint64_t) \
2709CTL_RO_CGEN(config_stats, stats_##n##_total_wait_time, \
Qi Wangf6698ec2017-03-17 17:42:10 -07002710 nstime_ns(&l.tot_wait_time), uint64_t) \
Qi Wangca9074d2017-03-11 20:28:31 -08002711CTL_RO_CGEN(config_stats, stats_##n##_max_wait_time, \
Qi Wangf6698ec2017-03-17 17:42:10 -07002712 nstime_ns(&l.max_wait_time), uint64_t) \
Qi Wangca9074d2017-03-11 20:28:31 -08002713CTL_RO_CGEN(config_stats, stats_##n##_max_num_thds, \
Qi Wangd3fde1c2017-03-21 11:56:38 -07002714 l.max_n_thds, uint32_t)
Qi Wang0fb5c0e2017-03-10 12:14:05 -08002715
Qi Wang64c5f5c2017-03-13 17:29:03 -07002716/* Global mutexes. */
Qi Wangd3fde1c2017-03-21 11:56:38 -07002717#define OP(mtx) \
2718 RO_MUTEX_CTL_GEN(mutexes_##mtx, \
2719 ctl_stats->mutex_prof_data[global_prof_mutex_##mtx])
David Goldblatt89e2d3c2017-04-24 17:09:56 -07002720MUTEX_PROF_GLOBAL_MUTEXES
Qi Wangd3fde1c2017-03-21 11:56:38 -07002721#undef OP
2722
2723/* Per arena mutexes */
2724#define OP(mtx) RO_MUTEX_CTL_GEN(arenas_i_mutexes_##mtx, \
2725 arenas_i(mib[2])->astats->astats.mutex_prof_data[arena_prof_mutex_##mtx])
David Goldblatt89e2d3c2017-04-24 17:09:56 -07002726MUTEX_PROF_ARENA_MUTEXES
Qi Wangd3fde1c2017-03-21 11:56:38 -07002727#undef OP
Qi Wangca9074d2017-03-11 20:28:31 -08002728
Qi Wang20b8c702017-03-15 14:00:57 -07002729/* tcache bin mutex */
Qi Wang64c5f5c2017-03-13 17:29:03 -07002730RO_MUTEX_CTL_GEN(arenas_i_bins_j_mutex,
2731 arenas_i(mib[2])->astats->bstats[mib[4]].mutex_data)
Qi Wang64c5f5c2017-03-13 17:29:03 -07002732#undef RO_MUTEX_CTL_GEN
2733
2734/* Resets all mutex stats, including global, arena and bin mutexes. */
2735static int
2736stats_mutexes_reset_ctl(tsd_t *tsd, const size_t *mib, size_t miblen,
2737 void *oldp, size_t *oldlenp, void *newp, size_t newlen) {
2738 if (!config_stats) {
2739 return ENOENT;
2740 }
2741
2742 tsdn_t *tsdn = tsd_tsdn(tsd);
2743
2744#define MUTEX_PROF_RESET(mtx) \
2745 malloc_mutex_lock(tsdn, &mtx); \
2746 malloc_mutex_prof_data_reset(tsdn, &mtx); \
2747 malloc_mutex_unlock(tsdn, &mtx);
2748
Qi Wang362e3562017-03-22 01:49:56 -07002749 /* Global mutexes: ctl and prof. */
2750 MUTEX_PROF_RESET(ctl_mtx);
Qi Wang5f5ed212017-05-12 16:26:59 -07002751 if (have_background_thread) {
2752 MUTEX_PROF_RESET(background_thread_lock);
2753 }
Qi Wang64c5f5c2017-03-13 17:29:03 -07002754 if (config_prof && opt_prof) {
2755 MUTEX_PROF_RESET(bt2gctx_mtx);
2756 }
Qi Wang362e3562017-03-22 01:49:56 -07002757
Qi Wang64c5f5c2017-03-13 17:29:03 -07002758
2759 /* Per arena mutexes. */
2760 unsigned n = narenas_total_get();
2761
2762 for (unsigned i = 0; i < n; i++) {
2763 arena_t *arena = arena_get(tsdn, i, false);
2764 if (!arena) {
2765 continue;
2766 }
2767 MUTEX_PROF_RESET(arena->large_mtx);
Jason Evans881fbf72017-04-16 22:31:16 -07002768 MUTEX_PROF_RESET(arena->extent_avail_mtx);
Qi Wang20b8c702017-03-15 14:00:57 -07002769 MUTEX_PROF_RESET(arena->extents_dirty.mtx);
2770 MUTEX_PROF_RESET(arena->extents_muzzy.mtx);
Qi Wang64c5f5c2017-03-13 17:29:03 -07002771 MUTEX_PROF_RESET(arena->extents_retained.mtx);
Qi Wang20b8c702017-03-15 14:00:57 -07002772 MUTEX_PROF_RESET(arena->decay_dirty.mtx);
2773 MUTEX_PROF_RESET(arena->decay_muzzy.mtx);
Jason Evans4403c9a2017-04-20 17:21:37 -07002774 MUTEX_PROF_RESET(arena->tcache_ql_mtx);
Qi Wang362e3562017-03-22 01:49:56 -07002775 MUTEX_PROF_RESET(arena->base->mtx);
Qi Wang64c5f5c2017-03-13 17:29:03 -07002776
2777 for (szind_t i = 0; i < NBINS; i++) {
David T. Goldblatt4bf4a1c2017-10-01 17:22:06 -07002778 bin_t *bin = &arena->bins[i];
Qi Wang64c5f5c2017-03-13 17:29:03 -07002779 MUTEX_PROF_RESET(bin->lock);
2780 }
2781 }
2782#undef MUTEX_PROF_RESET
2783 return 0;
2784}
Qi Wang0fb5c0e2017-03-10 12:14:05 -08002785
Jason Evans7372b152012-02-10 20:22:09 -08002786CTL_RO_CGEN(config_stats, stats_arenas_i_bins_j_nmalloc,
Jason Evans9eb1b1c2017-01-18 23:03:37 -08002787 arenas_i(mib[2])->astats->bstats[mib[4]].nmalloc, uint64_t)
Jason Evans7372b152012-02-10 20:22:09 -08002788CTL_RO_CGEN(config_stats, stats_arenas_i_bins_j_ndalloc,
Jason Evans9eb1b1c2017-01-18 23:03:37 -08002789 arenas_i(mib[2])->astats->bstats[mib[4]].ndalloc, uint64_t)
Jason Evans7372b152012-02-10 20:22:09 -08002790CTL_RO_CGEN(config_stats, stats_arenas_i_bins_j_nrequests,
Jason Evans9eb1b1c2017-01-18 23:03:37 -08002791 arenas_i(mib[2])->astats->bstats[mib[4]].nrequests, uint64_t)
Jason Evans3c4d92e2014-10-12 22:53:59 -07002792CTL_RO_CGEN(config_stats, stats_arenas_i_bins_j_curregs,
Jason Evans9eb1b1c2017-01-18 23:03:37 -08002793 arenas_i(mib[2])->astats->bstats[mib[4]].curregs, size_t)
Jason Evans4403c9a2017-04-20 17:21:37 -07002794CTL_RO_CGEN(config_stats, stats_arenas_i_bins_j_nfills,
Jason Evans9eb1b1c2017-01-18 23:03:37 -08002795 arenas_i(mib[2])->astats->bstats[mib[4]].nfills, uint64_t)
Jason Evans4403c9a2017-04-20 17:21:37 -07002796CTL_RO_CGEN(config_stats, stats_arenas_i_bins_j_nflushes,
Jason Evans9eb1b1c2017-01-18 23:03:37 -08002797 arenas_i(mib[2])->astats->bstats[mib[4]].nflushes, uint64_t)
Jason Evans498856f2016-05-29 18:34:50 -07002798CTL_RO_CGEN(config_stats, stats_arenas_i_bins_j_nslabs,
Jason Evans9eb1b1c2017-01-18 23:03:37 -08002799 arenas_i(mib[2])->astats->bstats[mib[4]].nslabs, uint64_t)
Jason Evans498856f2016-05-29 18:34:50 -07002800CTL_RO_CGEN(config_stats, stats_arenas_i_bins_j_nreslabs,
Jason Evans9eb1b1c2017-01-18 23:03:37 -08002801 arenas_i(mib[2])->astats->bstats[mib[4]].reslabs, uint64_t)
Jason Evans498856f2016-05-29 18:34:50 -07002802CTL_RO_CGEN(config_stats, stats_arenas_i_bins_j_curslabs,
Jason Evans9eb1b1c2017-01-18 23:03:37 -08002803 arenas_i(mib[2])->astats->bstats[mib[4]].curslabs, size_t)
Jason Evans3c234352010-01-27 13:10:55 -08002804
Jason Evans609ae592012-10-11 13:53:15 -07002805static const ctl_named_node_t *
Jason Evansc1e00ef2016-05-10 22:21:10 -07002806stats_arenas_i_bins_j_index(tsdn_t *tsdn, const size_t *mib, size_t miblen,
Jason Evansc4c25922017-01-15 16:56:30 -08002807 size_t j) {
2808 if (j > NBINS) {
Jason Evansf4086432017-01-19 18:15:45 -08002809 return NULL;
Jason Evansc4c25922017-01-15 16:56:30 -08002810 }
Jason Evansf4086432017-01-19 18:15:45 -08002811 return super_stats_arenas_i_bins_j_node;
Jason Evans3c234352010-01-27 13:10:55 -08002812}
2813
Jason Evans7d63fed2016-05-31 14:50:21 -07002814CTL_RO_CGEN(config_stats, stats_arenas_i_lextents_j_nmalloc,
David T. Goldblatt7f1b02e2017-11-04 12:50:19 -07002815 ctl_arena_stats_read_u64(
2816 &arenas_i(mib[2])->astats->lstats[mib[4]].nmalloc), uint64_t)
Jason Evans7d63fed2016-05-31 14:50:21 -07002817CTL_RO_CGEN(config_stats, stats_arenas_i_lextents_j_ndalloc,
David T. Goldblatt7f1b02e2017-11-04 12:50:19 -07002818 ctl_arena_stats_read_u64(
2819 &arenas_i(mib[2])->astats->lstats[mib[4]].ndalloc), uint64_t)
Jason Evans7d63fed2016-05-31 14:50:21 -07002820CTL_RO_CGEN(config_stats, stats_arenas_i_lextents_j_nrequests,
David T. Goldblatt7f1b02e2017-11-04 12:50:19 -07002821 ctl_arena_stats_read_u64(
2822 &arenas_i(mib[2])->astats->lstats[mib[4]].nrequests), uint64_t)
Jason Evans7d63fed2016-05-31 14:50:21 -07002823CTL_RO_CGEN(config_stats, stats_arenas_i_lextents_j_curlextents,
Jason Evans9eb1b1c2017-01-18 23:03:37 -08002824 arenas_i(mib[2])->astats->lstats[mib[4]].curlextents, size_t)
Jason Evans3c4d92e2014-10-12 22:53:59 -07002825
2826static const ctl_named_node_t *
Jason Evans7d63fed2016-05-31 14:50:21 -07002827stats_arenas_i_lextents_j_index(tsdn_t *tsdn, const size_t *mib, size_t miblen,
Jason Evansc4c25922017-01-15 16:56:30 -08002828 size_t j) {
2829 if (j > NSIZES - NBINS) {
Jason Evansf4086432017-01-19 18:15:45 -08002830 return NULL;
Jason Evansc4c25922017-01-15 16:56:30 -08002831 }
Jason Evansf4086432017-01-19 18:15:45 -08002832 return super_stats_arenas_i_lextents_j_node;
Jason Evans3c4d92e2014-10-12 22:53:59 -07002833}
2834
Jason Evans609ae592012-10-11 13:53:15 -07002835static const ctl_named_node_t *
Jason Evansc4c25922017-01-15 16:56:30 -08002836stats_arenas_i_index(tsdn_t *tsdn, const size_t *mib, size_t miblen, size_t i) {
Jason Evans3dc4e832017-01-03 07:27:42 -08002837 const ctl_named_node_t *ret;
2838 size_t a;
Jason Evans3c234352010-01-27 13:10:55 -08002839
Jason Evansc1e00ef2016-05-10 22:21:10 -07002840 malloc_mutex_lock(tsdn, &ctl_mtx);
Jason Evans9eb1b1c2017-01-18 23:03:37 -08002841 a = arenas_i2a_impl(i, true, true);
2842 if (a == UINT_MAX || !ctl_arenas->arenas[a]->initialized) {
Jason Evansfc4dcfa2010-11-24 15:44:21 -08002843 ret = NULL;
Jason Evansa1ee7832012-04-10 15:07:44 -07002844 goto label_return;
Jason Evansfc4dcfa2010-11-24 15:44:21 -08002845 }
2846
2847 ret = super_stats_arenas_i_node;
Jason Evansa1ee7832012-04-10 15:07:44 -07002848label_return:
Jason Evansc1e00ef2016-05-10 22:21:10 -07002849 malloc_mutex_unlock(tsdn, &ctl_mtx);
Jason Evansf4086432017-01-19 18:15:45 -08002850 return ret;
Jason Evans3c234352010-01-27 13:10:55 -08002851}