blob: b2b9e7d96f6e90981014aee9f2396de790179ba5 [file] [log] [blame]
Jason Evansc0cc5db2017-01-19 21:41:41 -08001#define JEMALLOC_CTL_C_
Jason Evans376b1522010-02-11 14:45:59 -08002#include "jemalloc/internal/jemalloc_internal.h"
Jason Evans3c234352010-01-27 13:10:55 -08003
4/******************************************************************************/
5/* Data. */
6
Jason Evansfc4dcfa2010-11-24 15:44:21 -08007/*
8 * ctl_mtx protects the following:
Jason Evansd778dd22017-01-03 12:40:54 -08009 * - ctl_stats->*
Jason Evansfc4dcfa2010-11-24 15:44:21 -080010 */
Jason Evans3c234352010-01-27 13:10:55 -080011static malloc_mutex_t ctl_mtx;
12static bool ctl_initialized;
Jason Evansd778dd22017-01-03 12:40:54 -080013static ctl_stats_t *ctl_stats;
Jason Evans9eb1b1c2017-01-18 23:03:37 -080014static ctl_arenas_t *ctl_arenas;
Jason Evans3c234352010-01-27 13:10:55 -080015
Qi Wang64c5f5c2017-03-13 17:29:03 -070016const char *global_mutex_names[NUM_GLOBAL_PROF_MUTEXES] = {
Qi Wangca9074d2017-03-11 20:28:31 -080017 "base",
18 "prof",
19 "ctl"
20};
21
Qi Wang64c5f5c2017-03-13 17:29:03 -070022const char *arena_mutex_names[NUM_ARENA_PROF_MUTEXES] = {
Qi Wang0fb5c0e2017-03-10 12:14:05 -080023 "large",
24 "extent_freelist",
25 "extents_cached",
26 "extents_retained",
27 "decay",
28 "tcache"
29};
Qi Wangca9074d2017-03-11 20:28:31 -080030
Qi Wang64c5f5c2017-03-13 17:29:03 -070031const char *mutex_counter_names[NUM_MUTEX_PROF_COUNTERS] = {
Qi Wang0fb5c0e2017-03-10 12:14:05 -080032 "num_ops",
33 "num_wait",
34 "num_spin_acq",
35 "num_owner_switch",
36 "total_wait_time",
37 "max_wait_time",
38 "max_num_thds"
39};
40
Jason Evans3c234352010-01-27 13:10:55 -080041/******************************************************************************/
Mike Hommey461ad5c2012-04-20 08:38:42 +020042/* Helpers for named and indexed nodes. */
43
Jason Evansaf1f5922014-10-30 16:38:08 -070044JEMALLOC_INLINE_C const ctl_named_node_t *
Jason Evansc4c25922017-01-15 16:56:30 -080045ctl_named_node(const ctl_node_t *node) {
Mike Hommey461ad5c2012-04-20 08:38:42 +020046 return ((node->named) ? (const ctl_named_node_t *)node : NULL);
47}
48
Jason Evansaf1f5922014-10-30 16:38:08 -070049JEMALLOC_INLINE_C const ctl_named_node_t *
Jason Evansc4c25922017-01-15 16:56:30 -080050ctl_named_children(const ctl_named_node_t *node, size_t index) {
Mike Hommey461ad5c2012-04-20 08:38:42 +020051 const ctl_named_node_t *children = ctl_named_node(node->children);
52
53 return (children ? &children[index] : NULL);
54}
55
Jason Evansaf1f5922014-10-30 16:38:08 -070056JEMALLOC_INLINE_C const ctl_indexed_node_t *
Jason Evansc4c25922017-01-15 16:56:30 -080057ctl_indexed_node(const ctl_node_t *node) {
Jason Evans551ebc42014-10-03 10:16:09 -070058 return (!node->named ? (const ctl_indexed_node_t *)node : NULL);
Mike Hommey461ad5c2012-04-20 08:38:42 +020059}
60
61/******************************************************************************/
Jason Evans3c234352010-01-27 13:10:55 -080062/* Function prototypes for non-inline static functions. */
63
Jason Evansc0cc5db2017-01-19 21:41:41 -080064#define CTL_PROTO(n) \
Jason Evansb2c0d632016-04-13 23:36:15 -070065static int n##_ctl(tsd_t *tsd, const size_t *mib, size_t miblen, \
66 void *oldp, size_t *oldlenp, void *newp, size_t newlen);
Jason Evans3c234352010-01-27 13:10:55 -080067
Jason Evansc0cc5db2017-01-19 21:41:41 -080068#define INDEX_PROTO(n) \
Jason Evansc1e00ef2016-05-10 22:21:10 -070069static const ctl_named_node_t *n##_index(tsdn_t *tsdn, \
Jason Evansb2c0d632016-04-13 23:36:15 -070070 const size_t *mib, size_t miblen, size_t i);
Jason Evans3c234352010-01-27 13:10:55 -080071
Jason Evansa40bc7a2010-03-02 13:01:16 -080072CTL_PROTO(version)
Jason Evans3c234352010-01-27 13:10:55 -080073CTL_PROTO(epoch)
Jason Evansd4be8b72012-03-26 18:54:44 -070074CTL_PROTO(thread_tcache_enabled)
Jason Evanse7b8fa12012-03-16 17:09:32 -070075CTL_PROTO(thread_tcache_flush)
Jason Evans602c8e02014-08-18 16:22:13 -070076CTL_PROTO(thread_prof_name)
77CTL_PROTO(thread_prof_active)
Jason Evansb267d0f2010-08-13 15:42:29 -070078CTL_PROTO(thread_arena)
Jason Evans93443682010-10-20 17:39:18 -070079CTL_PROTO(thread_allocated)
Jason Evansecf229a2010-12-03 15:55:47 -080080CTL_PROTO(thread_allocatedp)
Jason Evans93443682010-10-20 17:39:18 -070081CTL_PROTO(thread_deallocated)
Jason Evansecf229a2010-12-03 15:55:47 -080082CTL_PROTO(thread_deallocatedp)
Jason Evansf2bc8522015-07-17 16:38:25 -070083CTL_PROTO(config_cache_oblivious)
Jason Evans3c234352010-01-27 13:10:55 -080084CTL_PROTO(config_debug)
Jason Evans3c234352010-01-27 13:10:55 -080085CTL_PROTO(config_fill)
86CTL_PROTO(config_lazy_lock)
Jason Evansf8290092016-02-07 14:23:22 -080087CTL_PROTO(config_malloc_conf)
Jason Evans59ae2762012-04-16 17:52:27 -070088CTL_PROTO(config_munmap)
Jason Evansd34f9e72010-02-11 13:19:21 -080089CTL_PROTO(config_prof)
90CTL_PROTO(config_prof_libgcc)
91CTL_PROTO(config_prof_libunwind)
Jason Evans3c234352010-01-27 13:10:55 -080092CTL_PROTO(config_stats)
Jason Evans3c234352010-01-27 13:10:55 -080093CTL_PROTO(config_tcache)
Jason Evans3c234352010-01-27 13:10:55 -080094CTL_PROTO(config_tls)
Jason Evansb1476112012-04-05 13:36:17 -070095CTL_PROTO(config_utrace)
Jason Evans3c234352010-01-27 13:10:55 -080096CTL_PROTO(config_xmalloc)
97CTL_PROTO(opt_abort)
Jason Evans609ae592012-10-11 13:53:15 -070098CTL_PROTO(opt_dss)
Jason Evanse7339702010-10-23 18:37:06 -070099CTL_PROTO(opt_narenas)
Qi Wangec532e22017-02-02 17:02:05 -0800100CTL_PROTO(opt_percpu_arena)
Jason Evans64e458f2017-03-08 22:42:57 -0800101CTL_PROTO(opt_dirty_decay_time)
102CTL_PROTO(opt_muzzy_decay_time)
Jason Evanse7339702010-10-23 18:37:06 -0700103CTL_PROTO(opt_stats_print)
Jason Evans3c234352010-01-27 13:10:55 -0800104CTL_PROTO(opt_junk)
Jason Evanse7339702010-10-23 18:37:06 -0700105CTL_PROTO(opt_zero)
Jason Evansb1476112012-04-05 13:36:17 -0700106CTL_PROTO(opt_utrace)
Jason Evans3c234352010-01-27 13:10:55 -0800107CTL_PROTO(opt_xmalloc)
Jason Evans3fa9a2f2010-03-07 15:34:14 -0800108CTL_PROTO(opt_tcache)
Jason Evansf3ca7c82012-04-04 16:16:09 -0700109CTL_PROTO(opt_lg_tcache_max)
Jason Evansd34f9e72010-02-11 13:19:21 -0800110CTL_PROTO(opt_prof)
Jason Evanse7339702010-10-23 18:37:06 -0700111CTL_PROTO(opt_prof_prefix)
Jason Evansf18c9822010-03-31 18:43:24 -0700112CTL_PROTO(opt_prof_active)
Jason Evansfc12c0b2014-10-03 23:25:30 -0700113CTL_PROTO(opt_prof_thread_active_init)
Jason Evansb9477e72010-03-01 20:15:26 -0800114CTL_PROTO(opt_lg_prof_sample)
Jason Evansd34f9e72010-02-11 13:19:21 -0800115CTL_PROTO(opt_lg_prof_interval)
Jason Evanse7339702010-10-23 18:37:06 -0700116CTL_PROTO(opt_prof_gdump)
Jason Evans0b25fe72012-04-17 16:39:33 -0700117CTL_PROTO(opt_prof_final)
Jason Evansd34f9e72010-02-11 13:19:21 -0800118CTL_PROTO(opt_prof_leak)
Jason Evansa881cd22010-10-02 15:18:50 -0700119CTL_PROTO(opt_prof_accum)
Jason Evans1cb181e2015-01-29 15:30:47 -0800120CTL_PROTO(tcache_create)
121CTL_PROTO(tcache_flush)
122CTL_PROTO(tcache_destroy)
Jason Evansdc2125c2017-01-04 10:21:53 -0800123CTL_PROTO(arena_i_initialized)
Jason Evans243f7a02016-02-19 20:09:31 -0800124CTL_PROTO(arena_i_decay)
Jason Evans64e458f2017-03-08 22:42:57 -0800125CTL_PROTO(arena_i_purge)
Jason Evans19ff2ce2016-04-22 14:37:17 -0700126CTL_PROTO(arena_i_reset)
Jason Evansedf1baf2017-01-03 17:21:59 -0800127CTL_PROTO(arena_i_destroy)
Jason Evans609ae592012-10-11 13:53:15 -0700128CTL_PROTO(arena_i_dss)
Jason Evans64e458f2017-03-08 22:42:57 -0800129CTL_PROTO(arena_i_dirty_decay_time)
130CTL_PROTO(arena_i_muzzy_decay_time)
Jason Evans9c305c92016-05-31 15:03:51 -0700131CTL_PROTO(arena_i_extent_hooks)
Jason Evans609ae592012-10-11 13:53:15 -0700132INDEX_PROTO(arena_i)
Jason Evans3c234352010-01-27 13:10:55 -0800133CTL_PROTO(arenas_bin_i_size)
134CTL_PROTO(arenas_bin_i_nregs)
Jason Evans498856f2016-05-29 18:34:50 -0700135CTL_PROTO(arenas_bin_i_slab_size)
Jason Evans3c234352010-01-27 13:10:55 -0800136INDEX_PROTO(arenas_bin_i)
Jason Evans7d63fed2016-05-31 14:50:21 -0700137CTL_PROTO(arenas_lextent_i_size)
138INDEX_PROTO(arenas_lextent_i)
Jason Evans3c234352010-01-27 13:10:55 -0800139CTL_PROTO(arenas_narenas)
Jason Evans64e458f2017-03-08 22:42:57 -0800140CTL_PROTO(arenas_dirty_decay_time)
141CTL_PROTO(arenas_muzzy_decay_time)
Jason Evans3c234352010-01-27 13:10:55 -0800142CTL_PROTO(arenas_quantum)
Jason Evansae4c7b42012-04-02 07:04:34 -0700143CTL_PROTO(arenas_page)
Jason Evansdafde142010-03-17 16:27:39 -0700144CTL_PROTO(arenas_tcache_max)
Jason Evans3c234352010-01-27 13:10:55 -0800145CTL_PROTO(arenas_nbins)
Jason Evansdafde142010-03-17 16:27:39 -0700146CTL_PROTO(arenas_nhbins)
Jason Evans7d63fed2016-05-31 14:50:21 -0700147CTL_PROTO(arenas_nlextents)
Jason Evans0f04bb12017-01-03 08:21:29 -0800148CTL_PROTO(arenas_create)
Jason Evansfc12c0b2014-10-03 23:25:30 -0700149CTL_PROTO(prof_thread_active_init)
Jason Evansf18c9822010-03-31 18:43:24 -0700150CTL_PROTO(prof_active)
Jason Evansd34f9e72010-02-11 13:19:21 -0800151CTL_PROTO(prof_dump)
Jason Evans5b8ed5b2015-01-25 21:16:57 -0800152CTL_PROTO(prof_gdump)
Jason Evans602c8e02014-08-18 16:22:13 -0700153CTL_PROTO(prof_reset)
Jason Evansd34f9e72010-02-11 13:19:21 -0800154CTL_PROTO(prof_interval)
Jason Evans602c8e02014-08-18 16:22:13 -0700155CTL_PROTO(lg_prof_sample)
Jason Evans3c234352010-01-27 13:10:55 -0800156CTL_PROTO(stats_arenas_i_small_allocated)
157CTL_PROTO(stats_arenas_i_small_nmalloc)
158CTL_PROTO(stats_arenas_i_small_ndalloc)
Jason Evans86815df2010-03-13 20:32:56 -0800159CTL_PROTO(stats_arenas_i_small_nrequests)
Jason Evans7d63fed2016-05-31 14:50:21 -0700160CTL_PROTO(stats_arenas_i_large_allocated)
161CTL_PROTO(stats_arenas_i_large_nmalloc)
162CTL_PROTO(stats_arenas_i_large_ndalloc)
163CTL_PROTO(stats_arenas_i_large_nrequests)
Jason Evans86815df2010-03-13 20:32:56 -0800164CTL_PROTO(stats_arenas_i_bins_j_nmalloc)
165CTL_PROTO(stats_arenas_i_bins_j_ndalloc)
Jason Evans3c234352010-01-27 13:10:55 -0800166CTL_PROTO(stats_arenas_i_bins_j_nrequests)
Jason Evans3c4d92e2014-10-12 22:53:59 -0700167CTL_PROTO(stats_arenas_i_bins_j_curregs)
Jason Evans3c234352010-01-27 13:10:55 -0800168CTL_PROTO(stats_arenas_i_bins_j_nfills)
169CTL_PROTO(stats_arenas_i_bins_j_nflushes)
Jason Evans498856f2016-05-29 18:34:50 -0700170CTL_PROTO(stats_arenas_i_bins_j_nslabs)
171CTL_PROTO(stats_arenas_i_bins_j_nreslabs)
172CTL_PROTO(stats_arenas_i_bins_j_curslabs)
Jason Evans3c234352010-01-27 13:10:55 -0800173INDEX_PROTO(stats_arenas_i_bins_j)
Jason Evans7d63fed2016-05-31 14:50:21 -0700174CTL_PROTO(stats_arenas_i_lextents_j_nmalloc)
175CTL_PROTO(stats_arenas_i_lextents_j_ndalloc)
176CTL_PROTO(stats_arenas_i_lextents_j_nrequests)
177CTL_PROTO(stats_arenas_i_lextents_j_curlextents)
178INDEX_PROTO(stats_arenas_i_lextents_j)
Jason Evans597632b2011-03-18 13:41:33 -0700179CTL_PROTO(stats_arenas_i_nthreads)
Jason Evans609ae592012-10-11 13:53:15 -0700180CTL_PROTO(stats_arenas_i_dss)
Jason Evans64e458f2017-03-08 22:42:57 -0800181CTL_PROTO(stats_arenas_i_dirty_decay_time)
182CTL_PROTO(stats_arenas_i_muzzy_decay_time)
Jason Evans3c234352010-01-27 13:10:55 -0800183CTL_PROTO(stats_arenas_i_pactive)
184CTL_PROTO(stats_arenas_i_pdirty)
Jason Evans64e458f2017-03-08 22:42:57 -0800185CTL_PROTO(stats_arenas_i_pmuzzy)
Jason Evans3c234352010-01-27 13:10:55 -0800186CTL_PROTO(stats_arenas_i_mapped)
Jason Evans04c3c0f2016-05-03 22:11:35 -0700187CTL_PROTO(stats_arenas_i_retained)
Jason Evans64e458f2017-03-08 22:42:57 -0800188CTL_PROTO(stats_arenas_i_dirty_npurge)
189CTL_PROTO(stats_arenas_i_dirty_nmadvise)
190CTL_PROTO(stats_arenas_i_dirty_purged)
191CTL_PROTO(stats_arenas_i_muzzy_npurge)
192CTL_PROTO(stats_arenas_i_muzzy_nmadvise)
193CTL_PROTO(stats_arenas_i_muzzy_purged)
Jason Evansa0dd3a42016-12-22 16:39:10 -0600194CTL_PROTO(stats_arenas_i_base)
195CTL_PROTO(stats_arenas_i_internal)
Qi Wang58424e62016-04-22 18:37:44 -0700196CTL_PROTO(stats_arenas_i_tcache_bytes)
Jason Evansa0dd3a42016-12-22 16:39:10 -0600197CTL_PROTO(stats_arenas_i_resident)
Jason Evans3c234352010-01-27 13:10:55 -0800198INDEX_PROTO(stats_arenas_i)
Jason Evans3c234352010-01-27 13:10:55 -0800199CTL_PROTO(stats_allocated)
200CTL_PROTO(stats_active)
Jason Evans4581b972014-11-27 17:22:36 -0200201CTL_PROTO(stats_metadata)
Jason Evans4acd75a2015-03-23 17:25:57 -0700202CTL_PROTO(stats_resident)
Jason Evans3c234352010-01-27 13:10:55 -0800203CTL_PROTO(stats_mapped)
Jason Evans04c3c0f2016-05-03 22:11:35 -0700204CTL_PROTO(stats_retained)
Jason Evans3c234352010-01-27 13:10:55 -0800205
Qi Wang64c5f5c2017-03-13 17:29:03 -0700206#define MUTEX_STATS_CTL_PROTO_GEN(n) \
Qi Wangca9074d2017-03-11 20:28:31 -0800207CTL_PROTO(stats_##n##_num_ops) \
208CTL_PROTO(stats_##n##_num_wait) \
209CTL_PROTO(stats_##n##_num_spin_acq) \
210CTL_PROTO(stats_##n##_num_owner_switch) \
211CTL_PROTO(stats_##n##_total_wait_time) \
212CTL_PROTO(stats_##n##_max_wait_time) \
213CTL_PROTO(stats_##n##_max_num_thds)
Qi Wang0fb5c0e2017-03-10 12:14:05 -0800214
Qi Wang64c5f5c2017-03-13 17:29:03 -0700215/* Global mutexes. */
216MUTEX_STATS_CTL_PROTO_GEN(mutexes_base)
217MUTEX_STATS_CTL_PROTO_GEN(mutexes_prof)
218MUTEX_STATS_CTL_PROTO_GEN(mutexes_ctl)
Qi Wangca9074d2017-03-11 20:28:31 -0800219
Qi Wang64c5f5c2017-03-13 17:29:03 -0700220/* Arena bin mutexes. */
221MUTEX_STATS_CTL_PROTO_GEN(arenas_i_bins_j_mutex)
Qi Wangca9074d2017-03-11 20:28:31 -0800222
Qi Wang64c5f5c2017-03-13 17:29:03 -0700223#define ARENA_MUTEXES_CTL_PROTO_GEN(n) \
224 MUTEX_STATS_CTL_PROTO_GEN(arenas_i_mutexes_##n)
225/* Per arena mutexes. */
226ARENA_MUTEXES_CTL_PROTO_GEN(large)
227ARENA_MUTEXES_CTL_PROTO_GEN(extent_freelist)
228ARENA_MUTEXES_CTL_PROTO_GEN(extents_cached)
229ARENA_MUTEXES_CTL_PROTO_GEN(extents_retained)
230ARENA_MUTEXES_CTL_PROTO_GEN(decay)
231ARENA_MUTEXES_CTL_PROTO_GEN(tcache)
232#undef ARENA_MUTEXES_CTL_PROTO_GEN
233#undef MUTEX_STATS_CTL_PROTO_GEN
234
235CTL_PROTO(stats_mutexes_reset)
Qi Wang0fb5c0e2017-03-10 12:14:05 -0800236
Jason Evans3c234352010-01-27 13:10:55 -0800237/******************************************************************************/
238/* mallctl tree. */
239
Jason Evansc0cc5db2017-01-19 21:41:41 -0800240#define NAME(n) {true}, n
241#define CHILD(t, c) \
Jason Evans65f343a2012-04-23 19:31:45 -0700242 sizeof(c##_node) / sizeof(ctl_##t##_node_t), \
243 (ctl_node_t *)c##_node, \
244 NULL
Jason Evansc0cc5db2017-01-19 21:41:41 -0800245#define CTL(c) 0, NULL, c##_ctl
Jason Evans3c234352010-01-27 13:10:55 -0800246
247/*
248 * Only handles internal indexed nodes, since there are currently no external
249 * ones.
250 */
Jason Evansc0cc5db2017-01-19 21:41:41 -0800251#define INDEX(i) {false}, i##_index
Jason Evans3c234352010-01-27 13:10:55 -0800252
Jason Evans602c8e02014-08-18 16:22:13 -0700253static const ctl_named_node_t thread_tcache_node[] = {
Jason Evansd4be8b72012-03-26 18:54:44 -0700254 {NAME("enabled"), CTL(thread_tcache_enabled)},
Jason Evanse7b8fa12012-03-16 17:09:32 -0700255 {NAME("flush"), CTL(thread_tcache_flush)}
Jason Evans3c234352010-01-27 13:10:55 -0800256};
Jason Evans3c234352010-01-27 13:10:55 -0800257
Jason Evans602c8e02014-08-18 16:22:13 -0700258static const ctl_named_node_t thread_prof_node[] = {
259 {NAME("name"), CTL(thread_prof_name)},
260 {NAME("active"), CTL(thread_prof_active)}
261};
262
Mike Hommey461ad5c2012-04-20 08:38:42 +0200263static const ctl_named_node_t thread_node[] = {
Jason Evans7372b152012-02-10 20:22:09 -0800264 {NAME("arena"), CTL(thread_arena)},
Jason Evans93443682010-10-20 17:39:18 -0700265 {NAME("allocated"), CTL(thread_allocated)},
Jason Evansecf229a2010-12-03 15:55:47 -0800266 {NAME("allocatedp"), CTL(thread_allocatedp)},
267 {NAME("deallocated"), CTL(thread_deallocated)},
Jason Evanse7b8fa12012-03-16 17:09:32 -0700268 {NAME("deallocatedp"), CTL(thread_deallocatedp)},
Jason Evans602c8e02014-08-18 16:22:13 -0700269 {NAME("tcache"), CHILD(named, thread_tcache)},
270 {NAME("prof"), CHILD(named, thread_prof)}
Jason Evansb267d0f2010-08-13 15:42:29 -0700271};
Jason Evansb267d0f2010-08-13 15:42:29 -0700272
Mike Hommey461ad5c2012-04-20 08:38:42 +0200273static const ctl_named_node_t config_node[] = {
Jason Evansf2bc8522015-07-17 16:38:25 -0700274 {NAME("cache_oblivious"), CTL(config_cache_oblivious)},
Jason Evans3c4d92e2014-10-12 22:53:59 -0700275 {NAME("debug"), CTL(config_debug)},
276 {NAME("fill"), CTL(config_fill)},
277 {NAME("lazy_lock"), CTL(config_lazy_lock)},
Jason Evansf8290092016-02-07 14:23:22 -0800278 {NAME("malloc_conf"), CTL(config_malloc_conf)},
Jason Evans3c4d92e2014-10-12 22:53:59 -0700279 {NAME("munmap"), CTL(config_munmap)},
280 {NAME("prof"), CTL(config_prof)},
281 {NAME("prof_libgcc"), CTL(config_prof_libgcc)},
282 {NAME("prof_libunwind"), CTL(config_prof_libunwind)},
283 {NAME("stats"), CTL(config_stats)},
284 {NAME("tcache"), CTL(config_tcache)},
285 {NAME("tls"), CTL(config_tls)},
286 {NAME("utrace"), CTL(config_utrace)},
Jason Evans3c4d92e2014-10-12 22:53:59 -0700287 {NAME("xmalloc"), CTL(config_xmalloc)}
Jason Evans3c234352010-01-27 13:10:55 -0800288};
289
Mike Hommey461ad5c2012-04-20 08:38:42 +0200290static const ctl_named_node_t opt_node[] = {
Jason Evans3c4d92e2014-10-12 22:53:59 -0700291 {NAME("abort"), CTL(opt_abort)},
292 {NAME("dss"), CTL(opt_dss)},
Jason Evans3c4d92e2014-10-12 22:53:59 -0700293 {NAME("narenas"), CTL(opt_narenas)},
Qi Wangec532e22017-02-02 17:02:05 -0800294 {NAME("percpu_arena"), CTL(opt_percpu_arena)},
Jason Evans64e458f2017-03-08 22:42:57 -0800295 {NAME("dirty_decay_time"), CTL(opt_dirty_decay_time)},
296 {NAME("muzzy_decay_time"), CTL(opt_muzzy_decay_time)},
Jason Evans3c4d92e2014-10-12 22:53:59 -0700297 {NAME("stats_print"), CTL(opt_stats_print)},
298 {NAME("junk"), CTL(opt_junk)},
299 {NAME("zero"), CTL(opt_zero)},
Jason Evans3c4d92e2014-10-12 22:53:59 -0700300 {NAME("utrace"), CTL(opt_utrace)},
301 {NAME("xmalloc"), CTL(opt_xmalloc)},
302 {NAME("tcache"), CTL(opt_tcache)},
303 {NAME("lg_tcache_max"), CTL(opt_lg_tcache_max)},
304 {NAME("prof"), CTL(opt_prof)},
305 {NAME("prof_prefix"), CTL(opt_prof_prefix)},
306 {NAME("prof_active"), CTL(opt_prof_active)},
Jason Evansfc12c0b2014-10-03 23:25:30 -0700307 {NAME("prof_thread_active_init"), CTL(opt_prof_thread_active_init)},
Jason Evans3c4d92e2014-10-12 22:53:59 -0700308 {NAME("lg_prof_sample"), CTL(opt_lg_prof_sample)},
309 {NAME("lg_prof_interval"), CTL(opt_lg_prof_interval)},
310 {NAME("prof_gdump"), CTL(opt_prof_gdump)},
311 {NAME("prof_final"), CTL(opt_prof_final)},
312 {NAME("prof_leak"), CTL(opt_prof_leak)},
313 {NAME("prof_accum"), CTL(opt_prof_accum)}
Jason Evans3c234352010-01-27 13:10:55 -0800314};
315
Jason Evans1cb181e2015-01-29 15:30:47 -0800316static const ctl_named_node_t tcache_node[] = {
317 {NAME("create"), CTL(tcache_create)},
318 {NAME("flush"), CTL(tcache_flush)},
319 {NAME("destroy"), CTL(tcache_destroy)}
320};
321
Jason Evans609ae592012-10-11 13:53:15 -0700322static const ctl_named_node_t arena_i_node[] = {
Jason Evansdc2125c2017-01-04 10:21:53 -0800323 {NAME("initialized"), CTL(arena_i_initialized)},
Jason Evans243f7a02016-02-19 20:09:31 -0800324 {NAME("decay"), CTL(arena_i_decay)},
Jason Evans64e458f2017-03-08 22:42:57 -0800325 {NAME("purge"), CTL(arena_i_purge)},
Jason Evans19ff2ce2016-04-22 14:37:17 -0700326 {NAME("reset"), CTL(arena_i_reset)},
Jason Evansedf1baf2017-01-03 17:21:59 -0800327 {NAME("destroy"), CTL(arena_i_destroy)},
Jason Evans3c4d92e2014-10-12 22:53:59 -0700328 {NAME("dss"), CTL(arena_i_dss)},
Jason Evans64e458f2017-03-08 22:42:57 -0800329 {NAME("dirty_decay_time"), CTL(arena_i_dirty_decay_time)},
330 {NAME("muzzy_decay_time"), CTL(arena_i_muzzy_decay_time)},
Jason Evans9c305c92016-05-31 15:03:51 -0700331 {NAME("extent_hooks"), CTL(arena_i_extent_hooks)}
Jason Evans609ae592012-10-11 13:53:15 -0700332};
333static const ctl_named_node_t super_arena_i_node[] = {
Jason Evans3c4d92e2014-10-12 22:53:59 -0700334 {NAME(""), CHILD(named, arena_i)}
Jason Evans609ae592012-10-11 13:53:15 -0700335};
336
337static const ctl_indexed_node_t arena_node[] = {
338 {INDEX(arena_i)}
339};
340
Mike Hommey461ad5c2012-04-20 08:38:42 +0200341static const ctl_named_node_t arenas_bin_i_node[] = {
Jason Evans3c4d92e2014-10-12 22:53:59 -0700342 {NAME("size"), CTL(arenas_bin_i_size)},
343 {NAME("nregs"), CTL(arenas_bin_i_nregs)},
Jason Evans498856f2016-05-29 18:34:50 -0700344 {NAME("slab_size"), CTL(arenas_bin_i_slab_size)}
Jason Evans3c234352010-01-27 13:10:55 -0800345};
Mike Hommey461ad5c2012-04-20 08:38:42 +0200346static const ctl_named_node_t super_arenas_bin_i_node[] = {
Jason Evans3c4d92e2014-10-12 22:53:59 -0700347 {NAME(""), CHILD(named, arenas_bin_i)}
Jason Evans3c234352010-01-27 13:10:55 -0800348};
349
Mike Hommey461ad5c2012-04-20 08:38:42 +0200350static const ctl_indexed_node_t arenas_bin_node[] = {
Jason Evans3c234352010-01-27 13:10:55 -0800351 {INDEX(arenas_bin_i)}
352};
353
Jason Evans7d63fed2016-05-31 14:50:21 -0700354static const ctl_named_node_t arenas_lextent_i_node[] = {
355 {NAME("size"), CTL(arenas_lextent_i_size)}
Jason Evans3c4d92e2014-10-12 22:53:59 -0700356};
Jason Evans7d63fed2016-05-31 14:50:21 -0700357static const ctl_named_node_t super_arenas_lextent_i_node[] = {
358 {NAME(""), CHILD(named, arenas_lextent_i)}
Jason Evans3c4d92e2014-10-12 22:53:59 -0700359};
360
Jason Evans7d63fed2016-05-31 14:50:21 -0700361static const ctl_indexed_node_t arenas_lextent_node[] = {
362 {INDEX(arenas_lextent_i)}
Jason Evans3c4d92e2014-10-12 22:53:59 -0700363};
364
Mike Hommey461ad5c2012-04-20 08:38:42 +0200365static const ctl_named_node_t arenas_node[] = {
Jason Evans3c4d92e2014-10-12 22:53:59 -0700366 {NAME("narenas"), CTL(arenas_narenas)},
Jason Evans64e458f2017-03-08 22:42:57 -0800367 {NAME("dirty_decay_time"), CTL(arenas_dirty_decay_time)},
368 {NAME("muzzy_decay_time"), CTL(arenas_muzzy_decay_time)},
Jason Evans3c4d92e2014-10-12 22:53:59 -0700369 {NAME("quantum"), CTL(arenas_quantum)},
370 {NAME("page"), CTL(arenas_page)},
371 {NAME("tcache_max"), CTL(arenas_tcache_max)},
372 {NAME("nbins"), CTL(arenas_nbins)},
373 {NAME("nhbins"), CTL(arenas_nhbins)},
374 {NAME("bin"), CHILD(indexed, arenas_bin)},
Jason Evans7d63fed2016-05-31 14:50:21 -0700375 {NAME("nlextents"), CTL(arenas_nlextents)},
376 {NAME("lextent"), CHILD(indexed, arenas_lextent)},
Jason Evans0f04bb12017-01-03 08:21:29 -0800377 {NAME("create"), CTL(arenas_create)}
Jason Evans3c234352010-01-27 13:10:55 -0800378};
379
Mike Hommey461ad5c2012-04-20 08:38:42 +0200380static const ctl_named_node_t prof_node[] = {
Jason Evansfc12c0b2014-10-03 23:25:30 -0700381 {NAME("thread_active_init"), CTL(prof_thread_active_init)},
Jason Evansf18c9822010-03-31 18:43:24 -0700382 {NAME("active"), CTL(prof_active)},
Jason Evansd34f9e72010-02-11 13:19:21 -0800383 {NAME("dump"), CTL(prof_dump)},
Jason Evans5b8ed5b2015-01-25 21:16:57 -0800384 {NAME("gdump"), CTL(prof_gdump)},
Jason Evans602c8e02014-08-18 16:22:13 -0700385 {NAME("reset"), CTL(prof_reset)},
386 {NAME("interval"), CTL(prof_interval)},
387 {NAME("lg_sample"), CTL(lg_prof_sample)}
Jason Evansd34f9e72010-02-11 13:19:21 -0800388};
Jason Evansd34f9e72010-02-11 13:19:21 -0800389
Mike Hommey461ad5c2012-04-20 08:38:42 +0200390static const ctl_named_node_t stats_arenas_i_small_node[] = {
Jason Evans3c4d92e2014-10-12 22:53:59 -0700391 {NAME("allocated"), CTL(stats_arenas_i_small_allocated)},
392 {NAME("nmalloc"), CTL(stats_arenas_i_small_nmalloc)},
393 {NAME("ndalloc"), CTL(stats_arenas_i_small_ndalloc)},
394 {NAME("nrequests"), CTL(stats_arenas_i_small_nrequests)}
Jason Evans3c234352010-01-27 13:10:55 -0800395};
396
Jason Evans7d63fed2016-05-31 14:50:21 -0700397static const ctl_named_node_t stats_arenas_i_large_node[] = {
398 {NAME("allocated"), CTL(stats_arenas_i_large_allocated)},
399 {NAME("nmalloc"), CTL(stats_arenas_i_large_nmalloc)},
400 {NAME("ndalloc"), CTL(stats_arenas_i_large_ndalloc)},
401 {NAME("nrequests"), CTL(stats_arenas_i_large_nrequests)}
Jason Evanse2deab72014-05-15 22:22:27 -0700402};
403
Qi Wang64c5f5c2017-03-13 17:29:03 -0700404#define MUTEX_PROF_DATA_NODE(prefix) \
Qi Wangca9074d2017-03-11 20:28:31 -0800405static const ctl_named_node_t stats_##prefix##_node[] = { \
Qi Wang0fb5c0e2017-03-10 12:14:05 -0800406 {NAME("num_ops"), \
Qi Wangca9074d2017-03-11 20:28:31 -0800407 CTL(stats_##prefix##_num_ops)}, \
Qi Wang0fb5c0e2017-03-10 12:14:05 -0800408 {NAME("num_wait"), \
Qi Wangca9074d2017-03-11 20:28:31 -0800409 CTL(stats_##prefix##_num_wait)}, \
Qi Wang0fb5c0e2017-03-10 12:14:05 -0800410 {NAME("num_spin_acq"), \
Qi Wangca9074d2017-03-11 20:28:31 -0800411 CTL(stats_##prefix##_num_spin_acq)}, \
Qi Wang0fb5c0e2017-03-10 12:14:05 -0800412 {NAME("num_owner_switch"), \
Qi Wangca9074d2017-03-11 20:28:31 -0800413 CTL(stats_##prefix##_num_owner_switch)}, \
Qi Wang0fb5c0e2017-03-10 12:14:05 -0800414 {NAME("total_wait_time"), \
Qi Wangca9074d2017-03-11 20:28:31 -0800415 CTL(stats_##prefix##_total_wait_time)}, \
Qi Wang0fb5c0e2017-03-10 12:14:05 -0800416 {NAME("max_wait_time"), \
Qi Wangca9074d2017-03-11 20:28:31 -0800417 CTL(stats_##prefix##_max_wait_time)}, \
Qi Wang0fb5c0e2017-03-10 12:14:05 -0800418 {NAME("max_num_thds"), \
Qi Wangca9074d2017-03-11 20:28:31 -0800419 CTL(stats_##prefix##_max_num_thds)} \
Qi Wang0fb5c0e2017-03-10 12:14:05 -0800420 /* Note that # of current waiting thread not provided. */ \
421};
422
Qi Wang64c5f5c2017-03-13 17:29:03 -0700423MUTEX_PROF_DATA_NODE(arenas_i_bins_j_mutex)
Qi Wangca9074d2017-03-11 20:28:31 -0800424
Mike Hommey461ad5c2012-04-20 08:38:42 +0200425static const ctl_named_node_t stats_arenas_i_bins_j_node[] = {
Jason Evans3c4d92e2014-10-12 22:53:59 -0700426 {NAME("nmalloc"), CTL(stats_arenas_i_bins_j_nmalloc)},
427 {NAME("ndalloc"), CTL(stats_arenas_i_bins_j_ndalloc)},
428 {NAME("nrequests"), CTL(stats_arenas_i_bins_j_nrequests)},
429 {NAME("curregs"), CTL(stats_arenas_i_bins_j_curregs)},
430 {NAME("nfills"), CTL(stats_arenas_i_bins_j_nfills)},
431 {NAME("nflushes"), CTL(stats_arenas_i_bins_j_nflushes)},
Jason Evans498856f2016-05-29 18:34:50 -0700432 {NAME("nslabs"), CTL(stats_arenas_i_bins_j_nslabs)},
433 {NAME("nreslabs"), CTL(stats_arenas_i_bins_j_nreslabs)},
Qi Wanga4f176a2017-03-03 19:58:43 -0800434 {NAME("curslabs"), CTL(stats_arenas_i_bins_j_curslabs)},
Qi Wang64c5f5c2017-03-13 17:29:03 -0700435 {NAME("mutex"), CHILD(named, stats_arenas_i_bins_j_mutex)}
Jason Evans3c234352010-01-27 13:10:55 -0800436};
Qi Wang0fb5c0e2017-03-10 12:14:05 -0800437
Mike Hommey461ad5c2012-04-20 08:38:42 +0200438static const ctl_named_node_t super_stats_arenas_i_bins_j_node[] = {
Jason Evans3c4d92e2014-10-12 22:53:59 -0700439 {NAME(""), CHILD(named, stats_arenas_i_bins_j)}
Jason Evans3c234352010-01-27 13:10:55 -0800440};
441
Mike Hommey461ad5c2012-04-20 08:38:42 +0200442static const ctl_indexed_node_t stats_arenas_i_bins_node[] = {
Jason Evans3c234352010-01-27 13:10:55 -0800443 {INDEX(stats_arenas_i_bins_j)}
444};
445
Jason Evans7d63fed2016-05-31 14:50:21 -0700446static const ctl_named_node_t stats_arenas_i_lextents_j_node[] = {
447 {NAME("nmalloc"), CTL(stats_arenas_i_lextents_j_nmalloc)},
448 {NAME("ndalloc"), CTL(stats_arenas_i_lextents_j_ndalloc)},
449 {NAME("nrequests"), CTL(stats_arenas_i_lextents_j_nrequests)},
450 {NAME("curlextents"), CTL(stats_arenas_i_lextents_j_curlextents)}
Jason Evans3c4d92e2014-10-12 22:53:59 -0700451};
Jason Evans7d63fed2016-05-31 14:50:21 -0700452static const ctl_named_node_t super_stats_arenas_i_lextents_j_node[] = {
453 {NAME(""), CHILD(named, stats_arenas_i_lextents_j)}
Jason Evans3c4d92e2014-10-12 22:53:59 -0700454};
455
Jason Evans7d63fed2016-05-31 14:50:21 -0700456static const ctl_indexed_node_t stats_arenas_i_lextents_node[] = {
457 {INDEX(stats_arenas_i_lextents_j)}
Jason Evans3c4d92e2014-10-12 22:53:59 -0700458};
459
Qi Wang64c5f5c2017-03-13 17:29:03 -0700460#define ARENA_MUTEX_PROF_DATA_NODE(n) MUTEX_PROF_DATA_NODE(arenas_i_mutexes_##n)
Qi Wangca9074d2017-03-11 20:28:31 -0800461
Qi Wang64c5f5c2017-03-13 17:29:03 -0700462ARENA_MUTEX_PROF_DATA_NODE(large)
463ARENA_MUTEX_PROF_DATA_NODE(extent_freelist)
464ARENA_MUTEX_PROF_DATA_NODE(extents_cached)
465ARENA_MUTEX_PROF_DATA_NODE(extents_retained)
466ARENA_MUTEX_PROF_DATA_NODE(decay)
467ARENA_MUTEX_PROF_DATA_NODE(tcache)
Qi Wang0fb5c0e2017-03-10 12:14:05 -0800468
Qi Wang64c5f5c2017-03-13 17:29:03 -0700469static const ctl_named_node_t stats_arenas_i_mutexes_node[] = {
470 {NAME("large"), CHILD(named, stats_arenas_i_mutexes_large)},
Qi Wang0fb5c0e2017-03-10 12:14:05 -0800471 {NAME("extent_freelist"),
Qi Wang64c5f5c2017-03-13 17:29:03 -0700472 CHILD(named, stats_arenas_i_mutexes_extent_freelist)},
Qi Wang0fb5c0e2017-03-10 12:14:05 -0800473 {NAME("extents_cached"),
Qi Wang64c5f5c2017-03-13 17:29:03 -0700474 CHILD(named, stats_arenas_i_mutexes_extents_cached)},
Qi Wang0fb5c0e2017-03-10 12:14:05 -0800475 {NAME("extents_retained"),
Qi Wang64c5f5c2017-03-13 17:29:03 -0700476 CHILD(named, stats_arenas_i_mutexes_extents_retained)},
477 {NAME("decay"), CHILD(named, stats_arenas_i_mutexes_decay)},
478 {NAME("tcache"), CHILD(named, stats_arenas_i_mutexes_tcache)}
Qi Wang0fb5c0e2017-03-10 12:14:05 -0800479};
Qi Wang0fb5c0e2017-03-10 12:14:05 -0800480
Mike Hommey461ad5c2012-04-20 08:38:42 +0200481static const ctl_named_node_t stats_arenas_i_node[] = {
Jason Evans3c4d92e2014-10-12 22:53:59 -0700482 {NAME("nthreads"), CTL(stats_arenas_i_nthreads)},
483 {NAME("dss"), CTL(stats_arenas_i_dss)},
Jason Evans64e458f2017-03-08 22:42:57 -0800484 {NAME("dirty_decay_time"), CTL(stats_arenas_i_dirty_decay_time)},
485 {NAME("muzzy_decay_time"), CTL(stats_arenas_i_muzzy_decay_time)},
Jason Evans3c4d92e2014-10-12 22:53:59 -0700486 {NAME("pactive"), CTL(stats_arenas_i_pactive)},
487 {NAME("pdirty"), CTL(stats_arenas_i_pdirty)},
Jason Evans64e458f2017-03-08 22:42:57 -0800488 {NAME("pmuzzy"), CTL(stats_arenas_i_pmuzzy)},
Jason Evans3c4d92e2014-10-12 22:53:59 -0700489 {NAME("mapped"), CTL(stats_arenas_i_mapped)},
Jason Evans04c3c0f2016-05-03 22:11:35 -0700490 {NAME("retained"), CTL(stats_arenas_i_retained)},
Jason Evans64e458f2017-03-08 22:42:57 -0800491 {NAME("dirty_npurge"), CTL(stats_arenas_i_dirty_npurge)},
492 {NAME("dirty_nmadvise"), CTL(stats_arenas_i_dirty_nmadvise)},
493 {NAME("dirty_purged"), CTL(stats_arenas_i_dirty_purged)},
494 {NAME("muzzy_npurge"), CTL(stats_arenas_i_muzzy_npurge)},
495 {NAME("muzzy_nmadvise"), CTL(stats_arenas_i_muzzy_nmadvise)},
496 {NAME("muzzy_purged"), CTL(stats_arenas_i_muzzy_purged)},
Jason Evansa0dd3a42016-12-22 16:39:10 -0600497 {NAME("base"), CTL(stats_arenas_i_base)},
498 {NAME("internal"), CTL(stats_arenas_i_internal)},
Qi Wang58424e62016-04-22 18:37:44 -0700499 {NAME("tcache_bytes"), CTL(stats_arenas_i_tcache_bytes)},
Jason Evansa0dd3a42016-12-22 16:39:10 -0600500 {NAME("resident"), CTL(stats_arenas_i_resident)},
Jason Evans3c4d92e2014-10-12 22:53:59 -0700501 {NAME("small"), CHILD(named, stats_arenas_i_small)},
Jason Evans7d63fed2016-05-31 14:50:21 -0700502 {NAME("large"), CHILD(named, stats_arenas_i_large)},
Jason Evans3c4d92e2014-10-12 22:53:59 -0700503 {NAME("bins"), CHILD(indexed, stats_arenas_i_bins)},
Qi Wang0fb5c0e2017-03-10 12:14:05 -0800504 {NAME("lextents"), CHILD(indexed, stats_arenas_i_lextents)},
Qi Wang64c5f5c2017-03-13 17:29:03 -0700505 {NAME("mutexes"), CHILD(named, stats_arenas_i_mutexes)}
Jason Evans3c234352010-01-27 13:10:55 -0800506};
Mike Hommey461ad5c2012-04-20 08:38:42 +0200507static const ctl_named_node_t super_stats_arenas_i_node[] = {
Jason Evans3c4d92e2014-10-12 22:53:59 -0700508 {NAME(""), CHILD(named, stats_arenas_i)}
Jason Evans3c234352010-01-27 13:10:55 -0800509};
510
Mike Hommey461ad5c2012-04-20 08:38:42 +0200511static const ctl_indexed_node_t stats_arenas_node[] = {
Jason Evans3c234352010-01-27 13:10:55 -0800512 {INDEX(stats_arenas_i)}
513};
514
Qi Wang64c5f5c2017-03-13 17:29:03 -0700515MUTEX_PROF_DATA_NODE(mutexes_base)
516MUTEX_PROF_DATA_NODE(mutexes_prof)
517MUTEX_PROF_DATA_NODE(mutexes_ctl)
518static const ctl_named_node_t stats_mutexes_node[] = {
519 {NAME("base"), CHILD(named, stats_mutexes_base)},
520 {NAME("prof"), CHILD(named, stats_mutexes_prof)},
521 {NAME("ctl"), CHILD(named, stats_mutexes_ctl)},
522 {NAME("reset"), CTL(stats_mutexes_reset)}
Qi Wangca9074d2017-03-11 20:28:31 -0800523};
524
Mike Hommey461ad5c2012-04-20 08:38:42 +0200525static const ctl_named_node_t stats_node[] = {
Jason Evans3c4d92e2014-10-12 22:53:59 -0700526 {NAME("allocated"), CTL(stats_allocated)},
527 {NAME("active"), CTL(stats_active)},
Jason Evans4581b972014-11-27 17:22:36 -0200528 {NAME("metadata"), CTL(stats_metadata)},
Jason Evans4acd75a2015-03-23 17:25:57 -0700529 {NAME("resident"), CTL(stats_resident)},
Jason Evans3c4d92e2014-10-12 22:53:59 -0700530 {NAME("mapped"), CTL(stats_mapped)},
Jason Evans04c3c0f2016-05-03 22:11:35 -0700531 {NAME("retained"), CTL(stats_retained)},
Qi Wang64c5f5c2017-03-13 17:29:03 -0700532 {NAME("mutexes"), CHILD(named, stats_mutexes)},
Jason Evans3c4d92e2014-10-12 22:53:59 -0700533 {NAME("arenas"), CHILD(indexed, stats_arenas)}
Jason Evans3c234352010-01-27 13:10:55 -0800534};
Qi Wang64c5f5c2017-03-13 17:29:03 -0700535#undef MUTEX_PROF_DATA_NODE
Jason Evans3c234352010-01-27 13:10:55 -0800536
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)},
Jason Evans65f343a2012-04-23 19:31:45 -0700540 {NAME("thread"), CHILD(named, thread)},
541 {NAME("config"), CHILD(named, config)},
542 {NAME("opt"), CHILD(named, opt)},
Jason Evans1cb181e2015-01-29 15:30:47 -0800543 {NAME("tcache"), CHILD(named, tcache)},
Jason Evans609ae592012-10-11 13:53:15 -0700544 {NAME("arena"), CHILD(indexed, arena)},
Jason Evans65f343a2012-04-23 19:31:45 -0700545 {NAME("arenas"), CHILD(named, arenas)},
546 {NAME("prof"), CHILD(named, prof)},
547 {NAME("stats"), CHILD(named, stats)}
Jason Evans3c234352010-01-27 13:10:55 -0800548};
Mike Hommey461ad5c2012-04-20 08:38:42 +0200549static const ctl_named_node_t super_root_node[] = {
Jason Evans65f343a2012-04-23 19:31:45 -0700550 {NAME(""), CHILD(named, root)}
Jason Evans3c234352010-01-27 13:10:55 -0800551};
552
553#undef NAME
554#undef CHILD
555#undef CTL
556#undef INDEX
557
558/******************************************************************************/
559
David Goldblatt4fc2acf2017-03-08 15:56:31 -0800560/*
561 * Sets *dst + *src non-atomically. This is safe, since everything is
562 * synchronized by the ctl mutex.
563 */
564static void
565accum_arena_stats_u64(arena_stats_u64_t *dst, arena_stats_u64_t *src) {
566#ifdef JEMALLOC_ATOMIC_U64
567 uint64_t cur_dst = atomic_load_u64(dst, ATOMIC_RELAXED);
568 uint64_t cur_src = atomic_load_u64(src, ATOMIC_RELAXED);
569 atomic_store_u64(dst, cur_dst + cur_src, ATOMIC_RELAXED);
570#else
571 *dst += *src;
572#endif
573}
574
575/* Likewise: with ctl mutex synchronization, reading is simple. */
576static uint64_t
577arena_stats_read_u64(arena_stats_u64_t *p) {
578#ifdef JEMALLOC_ATOMIC_U64
579 return atomic_load_u64(p, ATOMIC_RELAXED);
580#else
581 return *p;
582#endif
583}
584
David Goldblattee202ef2017-03-13 16:18:40 -0700585static void accum_atomic_zu(atomic_zu_t *dst, atomic_zu_t *src) {
586 size_t cur_dst = atomic_load_zu(dst, ATOMIC_RELAXED);
587 size_t cur_src = atomic_load_zu(src, ATOMIC_RELAXED);
588 atomic_store_zu(dst, cur_dst + cur_src, ATOMIC_RELAXED);
589}
590
David Goldblatt4fc2acf2017-03-08 15:56:31 -0800591/******************************************************************************/
592
Jason Evans3dc4e832017-01-03 07:27:42 -0800593static unsigned
Jason Evansc4c25922017-01-15 16:56:30 -0800594arenas_i2a_impl(size_t i, bool compat, bool validate) {
Jason Evans3dc4e832017-01-03 07:27:42 -0800595 unsigned a;
596
Jason Evans3dc4e832017-01-03 07:27:42 -0800597 switch (i) {
598 case MALLCTL_ARENAS_ALL:
599 a = 0;
600 break;
Jason Evansedf1baf2017-01-03 17:21:59 -0800601 case MALLCTL_ARENAS_DESTROYED:
602 a = 1;
603 break;
Jason Evans3dc4e832017-01-03 07:27:42 -0800604 default:
Jason Evans9eb1b1c2017-01-18 23:03:37 -0800605 if (compat && i == ctl_arenas->narenas) {
Jason Evans3dc4e832017-01-03 07:27:42 -0800606 /*
607 * Provide deprecated backward compatibility for
608 * accessing the merged stats at index narenas rather
609 * than via MALLCTL_ARENAS_ALL. This is scheduled for
610 * removal in 6.0.0.
611 */
612 a = 0;
Jason Evansc4c25922017-01-15 16:56:30 -0800613 } else if (validate && i >= ctl_arenas->narenas) {
Jason Evans3dc4e832017-01-03 07:27:42 -0800614 a = UINT_MAX;
Jason Evansc4c25922017-01-15 16:56:30 -0800615 } else {
Jason Evans3dc4e832017-01-03 07:27:42 -0800616 /*
617 * This function should never be called for an index
618 * more than one past the range of indices that have
Jason Evans9eb1b1c2017-01-18 23:03:37 -0800619 * initialized ctl data.
Jason Evans3dc4e832017-01-03 07:27:42 -0800620 */
Jason Evans9eb1b1c2017-01-18 23:03:37 -0800621 assert(i < ctl_arenas->narenas || (!validate && i ==
622 ctl_arenas->narenas));
Jason Evansedf1baf2017-01-03 17:21:59 -0800623 a = (unsigned)i + 2;
Jason Evans3dc4e832017-01-03 07:27:42 -0800624 }
625 break;
626 }
627
Jason Evansf4086432017-01-19 18:15:45 -0800628 return a;
Jason Evans3dc4e832017-01-03 07:27:42 -0800629}
630
Jason Evansedf1baf2017-01-03 17:21:59 -0800631static unsigned
Jason Evansc4c25922017-01-15 16:56:30 -0800632arenas_i2a(size_t i) {
Jason Evansf4086432017-01-19 18:15:45 -0800633 return arenas_i2a_impl(i, true, false);
Jason Evansedf1baf2017-01-03 17:21:59 -0800634}
635
Jason Evans9eb1b1c2017-01-18 23:03:37 -0800636static ctl_arena_t *
Jason Evansc4c25922017-01-15 16:56:30 -0800637arenas_i_impl(tsdn_t *tsdn, size_t i, bool compat, bool init) {
Jason Evans9eb1b1c2017-01-18 23:03:37 -0800638 ctl_arena_t *ret;
Jason Evansd778dd22017-01-03 12:40:54 -0800639
640 assert(!compat || !init);
641
Jason Evans9eb1b1c2017-01-18 23:03:37 -0800642 ret = ctl_arenas->arenas[arenas_i2a_impl(i, compat, false)];
Jason Evansd778dd22017-01-03 12:40:54 -0800643 if (init && ret == NULL) {
Jason Evans9eb1b1c2017-01-18 23:03:37 -0800644 if (config_stats) {
645 struct container_s {
646 ctl_arena_t ctl_arena;
647 ctl_arena_stats_t astats;
648 };
649 struct container_s *cont =
650 (struct container_s *)base_alloc(tsdn, b0get(),
651 sizeof(struct container_s), QUANTUM);
652 if (cont == NULL) {
653 return NULL;
654 }
655 ret = &cont->ctl_arena;
656 ret->astats = &cont->astats;
657 } else {
658 ret = (ctl_arena_t *)base_alloc(tsdn, b0get(),
659 sizeof(ctl_arena_t), QUANTUM);
660 if (ret == NULL) {
661 return NULL;
662 }
663 }
Jason Evansedf1baf2017-01-03 17:21:59 -0800664 ret->arena_ind = (unsigned)i;
Jason Evans9eb1b1c2017-01-18 23:03:37 -0800665 ctl_arenas->arenas[arenas_i2a_impl(i, compat, false)] = ret;
Jason Evansd778dd22017-01-03 12:40:54 -0800666 }
667
Jason Evans9eb1b1c2017-01-18 23:03:37 -0800668 assert(ret == NULL || arenas_i2a(ret->arena_ind) == arenas_i2a(i));
Jason Evansf4086432017-01-19 18:15:45 -0800669 return ret;
Jason Evansd778dd22017-01-03 12:40:54 -0800670}
671
Jason Evans9eb1b1c2017-01-18 23:03:37 -0800672static ctl_arena_t *
Jason Evansc4c25922017-01-15 16:56:30 -0800673arenas_i(size_t i) {
Jason Evans9eb1b1c2017-01-18 23:03:37 -0800674 ctl_arena_t *ret = arenas_i_impl(TSDN_NULL, i, true, false);
Jason Evansd778dd22017-01-03 12:40:54 -0800675 assert(ret != NULL);
Jason Evansf4086432017-01-19 18:15:45 -0800676 return ret;
Jason Evans3dc4e832017-01-03 07:27:42 -0800677}
678
Jason Evans3c234352010-01-27 13:10:55 -0800679static void
Jason Evansc4c25922017-01-15 16:56:30 -0800680ctl_arena_clear(ctl_arena_t *ctl_arena) {
Jason Evans9eb1b1c2017-01-18 23:03:37 -0800681 ctl_arena->nthreads = 0;
682 ctl_arena->dss = dss_prec_names[dss_prec_limit];
Jason Evans64e458f2017-03-08 22:42:57 -0800683 ctl_arena->dirty_decay_time = -1;
684 ctl_arena->muzzy_decay_time = -1;
Jason Evans9eb1b1c2017-01-18 23:03:37 -0800685 ctl_arena->pactive = 0;
686 ctl_arena->pdirty = 0;
Jason Evans64e458f2017-03-08 22:42:57 -0800687 ctl_arena->pmuzzy = 0;
Jason Evans7372b152012-02-10 20:22:09 -0800688 if (config_stats) {
Jason Evans9eb1b1c2017-01-18 23:03:37 -0800689 memset(&ctl_arena->astats->astats, 0, sizeof(arena_stats_t));
690 ctl_arena->astats->allocated_small = 0;
691 ctl_arena->astats->nmalloc_small = 0;
692 ctl_arena->astats->ndalloc_small = 0;
693 ctl_arena->astats->nrequests_small = 0;
694 memset(ctl_arena->astats->bstats, 0, NBINS *
695 sizeof(malloc_bin_stats_t));
696 memset(ctl_arena->astats->lstats, 0, (NSIZES - NBINS) *
Jason Evans7d63fed2016-05-31 14:50:21 -0700697 sizeof(malloc_large_stats_t));
Jason Evans7372b152012-02-10 20:22:09 -0800698 }
Jason Evans3c234352010-01-27 13:10:55 -0800699}
700
Jason Evans86815df2010-03-13 20:32:56 -0800701static void
Jason Evansc4c25922017-01-15 16:56:30 -0800702ctl_arena_stats_amerge(tsdn_t *tsdn, ctl_arena_t *ctl_arena, arena_t *arena) {
Jason Evans86815df2010-03-13 20:32:56 -0800703 unsigned i;
704
Jason Evans3c07f802016-02-27 20:40:13 -0800705 if (config_stats) {
Jason Evans9eb1b1c2017-01-18 23:03:37 -0800706 arena_stats_merge(tsdn, arena, &ctl_arena->nthreads,
Jason Evans64e458f2017-03-08 22:42:57 -0800707 &ctl_arena->dss, &ctl_arena->dirty_decay_time,
708 &ctl_arena->muzzy_decay_time, &ctl_arena->pactive,
709 &ctl_arena->pdirty, &ctl_arena->pmuzzy,
Jason Evans9eb1b1c2017-01-18 23:03:37 -0800710 &ctl_arena->astats->astats, ctl_arena->astats->bstats,
711 ctl_arena->astats->lstats);
Jason Evans86815df2010-03-13 20:32:56 -0800712
Jason Evans3c07f802016-02-27 20:40:13 -0800713 for (i = 0; i < NBINS; i++) {
Jason Evans9eb1b1c2017-01-18 23:03:37 -0800714 ctl_arena->astats->allocated_small +=
715 ctl_arena->astats->bstats[i].curregs *
Jason Evans3c07f802016-02-27 20:40:13 -0800716 index2size(i);
Jason Evans9eb1b1c2017-01-18 23:03:37 -0800717 ctl_arena->astats->nmalloc_small +=
718 ctl_arena->astats->bstats[i].nmalloc;
719 ctl_arena->astats->ndalloc_small +=
720 ctl_arena->astats->bstats[i].ndalloc;
721 ctl_arena->astats->nrequests_small +=
722 ctl_arena->astats->bstats[i].nrequests;
Jason Evans3c07f802016-02-27 20:40:13 -0800723 }
724 } else {
Jason Evans9eb1b1c2017-01-18 23:03:37 -0800725 arena_basic_stats_merge(tsdn, arena, &ctl_arena->nthreads,
Jason Evans64e458f2017-03-08 22:42:57 -0800726 &ctl_arena->dss, &ctl_arena->dirty_decay_time,
727 &ctl_arena->muzzy_decay_time, &ctl_arena->pactive,
728 &ctl_arena->pdirty, &ctl_arena->pmuzzy);
Jason Evans86815df2010-03-13 20:32:56 -0800729 }
Jason Evans86815df2010-03-13 20:32:56 -0800730}
731
732static void
Jason Evans9eb1b1c2017-01-18 23:03:37 -0800733ctl_arena_stats_sdmerge(ctl_arena_t *ctl_sdarena, ctl_arena_t *ctl_arena,
Jason Evansc4c25922017-01-15 16:56:30 -0800734 bool destroyed) {
Jason Evans86815df2010-03-13 20:32:56 -0800735 unsigned i;
736
Jason Evansedf1baf2017-01-03 17:21:59 -0800737 if (!destroyed) {
Jason Evans9eb1b1c2017-01-18 23:03:37 -0800738 ctl_sdarena->nthreads += ctl_arena->nthreads;
739 ctl_sdarena->pactive += ctl_arena->pactive;
740 ctl_sdarena->pdirty += ctl_arena->pdirty;
Jason Evans64e458f2017-03-08 22:42:57 -0800741 ctl_sdarena->pmuzzy += ctl_arena->pmuzzy;
Jason Evansedf1baf2017-01-03 17:21:59 -0800742 } else {
Jason Evans9eb1b1c2017-01-18 23:03:37 -0800743 assert(ctl_arena->nthreads == 0);
744 assert(ctl_arena->pactive == 0);
745 assert(ctl_arena->pdirty == 0);
Jason Evans64e458f2017-03-08 22:42:57 -0800746 assert(ctl_arena->pmuzzy == 0);
Jason Evansedf1baf2017-01-03 17:21:59 -0800747 }
Jason Evans86815df2010-03-13 20:32:56 -0800748
Jason Evans3c07f802016-02-27 20:40:13 -0800749 if (config_stats) {
Jason Evans9eb1b1c2017-01-18 23:03:37 -0800750 ctl_arena_stats_t *sdstats = ctl_sdarena->astats;
751 ctl_arena_stats_t *astats = ctl_arena->astats;
752
Jason Evansedf1baf2017-01-03 17:21:59 -0800753 if (!destroyed) {
David Goldblattee202ef2017-03-13 16:18:40 -0700754 accum_atomic_zu(&sdstats->astats.mapped,
755 &astats->astats.mapped);
756 accum_atomic_zu(&sdstats->astats.retained,
757 &astats->astats.retained);
Jason Evansedf1baf2017-01-03 17:21:59 -0800758 }
Jason Evans64e458f2017-03-08 22:42:57 -0800759
760 accum_arena_stats_u64(&sdstats->astats.decay_dirty.npurge,
761 &astats->astats.decay_dirty.npurge);
762 accum_arena_stats_u64(&sdstats->astats.decay_dirty.nmadvise,
763 &astats->astats.decay_dirty.nmadvise);
764 accum_arena_stats_u64(&sdstats->astats.decay_dirty.purged,
765 &astats->astats.decay_dirty.purged);
766
767 accum_arena_stats_u64(&sdstats->astats.decay_muzzy.npurge,
768 &astats->astats.decay_muzzy.npurge);
769 accum_arena_stats_u64(&sdstats->astats.decay_muzzy.nmadvise,
770 &astats->astats.decay_muzzy.nmadvise);
771 accum_arena_stats_u64(&sdstats->astats.decay_muzzy.purged,
772 &astats->astats.decay_muzzy.purged);
Jason Evans86815df2010-03-13 20:32:56 -0800773
Qi Wang64c5f5c2017-03-13 17:29:03 -0700774 malloc_mutex_prof_merge(&(sdstats->astats.large_mtx_data),
Qi Wang0fb5c0e2017-03-10 12:14:05 -0800775 &(astats->astats.large_mtx_data));
Qi Wang64c5f5c2017-03-13 17:29:03 -0700776 malloc_mutex_prof_merge(
Qi Wang0fb5c0e2017-03-10 12:14:05 -0800777 &(sdstats->astats.extent_freelist_mtx_data),
778 &(astats->astats.extent_freelist_mtx_data));
Qi Wang64c5f5c2017-03-13 17:29:03 -0700779 malloc_mutex_prof_merge(
Qi Wang0fb5c0e2017-03-10 12:14:05 -0800780 &(sdstats->astats.extents_cached_mtx_data),
781 &(astats->astats.extents_cached_mtx_data));
Qi Wang64c5f5c2017-03-13 17:29:03 -0700782 malloc_mutex_prof_merge(
Qi Wang0fb5c0e2017-03-10 12:14:05 -0800783 &(sdstats->astats.extents_retained_mtx_data),
784 &(astats->astats.extents_retained_mtx_data));
Qi Wang64c5f5c2017-03-13 17:29:03 -0700785 malloc_mutex_prof_merge(&(sdstats->astats.decay_mtx_data),
Qi Wang0fb5c0e2017-03-10 12:14:05 -0800786 &(astats->astats.decay_mtx_data));
Qi Wang64c5f5c2017-03-13 17:29:03 -0700787 malloc_mutex_prof_merge(&(sdstats->astats.tcache_mtx_data),
Qi Wang0fb5c0e2017-03-10 12:14:05 -0800788 &(astats->astats.tcache_mtx_data));
789
Jason Evansedf1baf2017-01-03 17:21:59 -0800790 if (!destroyed) {
David Goldblattee202ef2017-03-13 16:18:40 -0700791 accum_atomic_zu(&sdstats->astats.base,
792 &astats->astats.base);
793 accum_atomic_zu(&sdstats->astats.internal,
794 &astats->astats.internal);
795 accum_atomic_zu(&sdstats->astats.resident,
796 &astats->astats.resident);
Jason Evansc4c25922017-01-15 16:56:30 -0800797 } else {
David Goldblattee202ef2017-03-13 16:18:40 -0700798 assert(atomic_load_zu(
799 &astats->astats.internal, ATOMIC_RELAXED) == 0);
Jason Evansc4c25922017-01-15 16:56:30 -0800800 }
Jason Evans4581b972014-11-27 17:22:36 -0200801
Jason Evansc4c25922017-01-15 16:56:30 -0800802 if (!destroyed) {
Jason Evansedf1baf2017-01-03 17:21:59 -0800803 sdstats->allocated_small += astats->allocated_small;
Jason Evansc4c25922017-01-15 16:56:30 -0800804 } else {
Jason Evansedf1baf2017-01-03 17:21:59 -0800805 assert(astats->allocated_small == 0);
Jason Evansc4c25922017-01-15 16:56:30 -0800806 }
Jason Evansedf1baf2017-01-03 17:21:59 -0800807 sdstats->nmalloc_small += astats->nmalloc_small;
808 sdstats->ndalloc_small += astats->ndalloc_small;
809 sdstats->nrequests_small += astats->nrequests_small;
Jason Evans86815df2010-03-13 20:32:56 -0800810
Jason Evansedf1baf2017-01-03 17:21:59 -0800811 if (!destroyed) {
David Goldblattee202ef2017-03-13 16:18:40 -0700812 accum_atomic_zu(&sdstats->astats.allocated_large,
813 &astats->astats.allocated_large);
Jason Evansc4c25922017-01-15 16:56:30 -0800814 } else {
David Goldblattee202ef2017-03-13 16:18:40 -0700815 assert(atomic_load_zu(&astats->astats.allocated_large,
816 ATOMIC_RELAXED) == 0);
Jason Evansc4c25922017-01-15 16:56:30 -0800817 }
David Goldblatt4fc2acf2017-03-08 15:56:31 -0800818 accum_arena_stats_u64(&sdstats->astats.nmalloc_large,
819 &astats->astats.nmalloc_large);
820 accum_arena_stats_u64(&sdstats->astats.ndalloc_large,
821 &astats->astats.ndalloc_large);
822 accum_arena_stats_u64(&sdstats->astats.nrequests_large,
823 &astats->astats.nrequests_large);
Jason Evans86815df2010-03-13 20:32:56 -0800824
Qi Wang58424e62016-04-22 18:37:44 -0700825 if (config_tcache) {
David Goldblattee202ef2017-03-13 16:18:40 -0700826 accum_atomic_zu(&sdstats->astats.tcache_bytes,
827 &astats->astats.tcache_bytes);
Qi Wang58424e62016-04-22 18:37:44 -0700828 }
829
Jason Evans3c07f802016-02-27 20:40:13 -0800830 for (i = 0; i < NBINS; i++) {
Jason Evansedf1baf2017-01-03 17:21:59 -0800831 sdstats->bstats[i].nmalloc += astats->bstats[i].nmalloc;
832 sdstats->bstats[i].ndalloc += astats->bstats[i].ndalloc;
833 sdstats->bstats[i].nrequests +=
Jason Evans3c07f802016-02-27 20:40:13 -0800834 astats->bstats[i].nrequests;
Jason Evansedf1baf2017-01-03 17:21:59 -0800835 if (!destroyed) {
836 sdstats->bstats[i].curregs +=
837 astats->bstats[i].curregs;
Jason Evansc4c25922017-01-15 16:56:30 -0800838 } else {
Jason Evansedf1baf2017-01-03 17:21:59 -0800839 assert(astats->bstats[i].curregs == 0);
Jason Evansc4c25922017-01-15 16:56:30 -0800840 }
Jason Evans3c07f802016-02-27 20:40:13 -0800841 if (config_tcache) {
Jason Evansedf1baf2017-01-03 17:21:59 -0800842 sdstats->bstats[i].nfills +=
Jason Evans3c07f802016-02-27 20:40:13 -0800843 astats->bstats[i].nfills;
Jason Evansedf1baf2017-01-03 17:21:59 -0800844 sdstats->bstats[i].nflushes +=
Jason Evans3c07f802016-02-27 20:40:13 -0800845 astats->bstats[i].nflushes;
846 }
Jason Evansedf1baf2017-01-03 17:21:59 -0800847 sdstats->bstats[i].nslabs += astats->bstats[i].nslabs;
848 sdstats->bstats[i].reslabs += astats->bstats[i].reslabs;
849 if (!destroyed) {
850 sdstats->bstats[i].curslabs +=
851 astats->bstats[i].curslabs;
Jason Evansc4c25922017-01-15 16:56:30 -0800852 } else {
Jason Evansedf1baf2017-01-03 17:21:59 -0800853 assert(astats->bstats[i].curslabs == 0);
Jason Evansc4c25922017-01-15 16:56:30 -0800854 }
Qi Wang64c5f5c2017-03-13 17:29:03 -0700855 malloc_mutex_prof_merge(&sdstats->bstats[i].mutex_data,
856 &astats->bstats[i].mutex_data);
Jason Evans7372b152012-02-10 20:22:09 -0800857 }
Jason Evans3c4d92e2014-10-12 22:53:59 -0700858
Jason Evansed2c2422016-05-28 00:17:28 -0700859 for (i = 0; i < NSIZES - NBINS; i++) {
David Goldblatt4fc2acf2017-03-08 15:56:31 -0800860 accum_arena_stats_u64(&sdstats->lstats[i].nmalloc,
861 &astats->lstats[i].nmalloc);
862 accum_arena_stats_u64(&sdstats->lstats[i].ndalloc,
863 &astats->lstats[i].ndalloc);
864 accum_arena_stats_u64(&sdstats->lstats[i].nrequests,
865 &astats->lstats[i].nrequests);
Jason Evansedf1baf2017-01-03 17:21:59 -0800866 if (!destroyed) {
867 sdstats->lstats[i].curlextents +=
868 astats->lstats[i].curlextents;
Jason Evansc4c25922017-01-15 16:56:30 -0800869 } else {
Jason Evansedf1baf2017-01-03 17:21:59 -0800870 assert(astats->lstats[i].curlextents == 0);
Jason Evansc4c25922017-01-15 16:56:30 -0800871 }
Jason Evans3c07f802016-02-27 20:40:13 -0800872 }
Jason Evans3c4d92e2014-10-12 22:53:59 -0700873 }
Jason Evans86815df2010-03-13 20:32:56 -0800874}
Jason Evans86815df2010-03-13 20:32:56 -0800875
Jason Evans3c234352010-01-27 13:10:55 -0800876static void
Jason Evans9eb1b1c2017-01-18 23:03:37 -0800877ctl_arena_refresh(tsdn_t *tsdn, arena_t *arena, ctl_arena_t *ctl_sdarena,
Jason Evansc4c25922017-01-15 16:56:30 -0800878 unsigned i, bool destroyed) {
Jason Evans9eb1b1c2017-01-18 23:03:37 -0800879 ctl_arena_t *ctl_arena = arenas_i(i);
Jason Evans3c234352010-01-27 13:10:55 -0800880
Jason Evans9eb1b1c2017-01-18 23:03:37 -0800881 ctl_arena_clear(ctl_arena);
882 ctl_arena_stats_amerge(tsdn, ctl_arena, arena);
Jason Evans3c07f802016-02-27 20:40:13 -0800883 /* Merge into sum stats as well. */
Jason Evans9eb1b1c2017-01-18 23:03:37 -0800884 ctl_arena_stats_sdmerge(ctl_sdarena, ctl_arena, destroyed);
Jason Evans3c234352010-01-27 13:10:55 -0800885}
886
Jason Evansedf1baf2017-01-03 17:21:59 -0800887static unsigned
Jason Evansc4c25922017-01-15 16:56:30 -0800888ctl_arena_init(tsdn_t *tsdn, extent_hooks_t *extent_hooks) {
Jason Evansedf1baf2017-01-03 17:21:59 -0800889 unsigned arena_ind;
Jason Evans9eb1b1c2017-01-18 23:03:37 -0800890 ctl_arena_t *ctl_arena;
Jason Evansedf1baf2017-01-03 17:21:59 -0800891
Jason Evans9eb1b1c2017-01-18 23:03:37 -0800892 if ((ctl_arena = ql_last(&ctl_arenas->destroyed, destroyed_link)) !=
893 NULL) {
894 ql_remove(&ctl_arenas->destroyed, ctl_arena, destroyed_link);
895 arena_ind = ctl_arena->arena_ind;
Jason Evansc4c25922017-01-15 16:56:30 -0800896 } else {
Jason Evans9eb1b1c2017-01-18 23:03:37 -0800897 arena_ind = ctl_arenas->narenas;
Jason Evansc4c25922017-01-15 16:56:30 -0800898 }
Jason Evansd778dd22017-01-03 12:40:54 -0800899
900 /* Trigger stats allocation. */
Jason Evansc4c25922017-01-15 16:56:30 -0800901 if (arenas_i_impl(tsdn, arena_ind, false, true) == 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 Evans8bb31982014-10-07 23:14:57 -0700905 /* Initialize new arena. */
Jason Evansc4c25922017-01-15 16:56:30 -0800906 if (arena_init(tsdn, arena_ind, extent_hooks) == NULL) {
Jason Evansf4086432017-01-19 18:15:45 -0800907 return UINT_MAX;
Jason Evansc4c25922017-01-15 16:56:30 -0800908 }
Jason Evans609ae592012-10-11 13:53:15 -0700909
Jason Evansc4c25922017-01-15 16:56:30 -0800910 if (arena_ind == ctl_arenas->narenas) {
Jason Evans9eb1b1c2017-01-18 23:03:37 -0800911 ctl_arenas->narenas++;
Jason Evansc4c25922017-01-15 16:56:30 -0800912 }
Jason Evansedf1baf2017-01-03 17:21:59 -0800913
Jason Evansf4086432017-01-19 18:15:45 -0800914 return arena_ind;
Jason Evans609ae592012-10-11 13:53:15 -0700915}
916
Jason Evans3c234352010-01-27 13:10:55 -0800917static void
Jason Evansc4c25922017-01-15 16:56:30 -0800918ctl_refresh(tsdn_t *tsdn) {
Jason Evans3c234352010-01-27 13:10:55 -0800919 unsigned i;
Jason Evans9eb1b1c2017-01-18 23:03:37 -0800920 ctl_arena_t *ctl_sarena = arenas_i(MALLCTL_ARENAS_ALL);
921 VARIABLE_ARRAY(arena_t *, tarenas, ctl_arenas->narenas);
Jason Evans3c234352010-01-27 13:10:55 -0800922
Jason Evans3c234352010-01-27 13:10:55 -0800923 /*
Jason Evans13668262010-01-31 03:57:29 -0800924 * Clear sum stats, since they will be merged into by
Jason Evans3c234352010-01-27 13:10:55 -0800925 * ctl_arena_refresh().
926 */
Jason Evans9eb1b1c2017-01-18 23:03:37 -0800927 ctl_arena_clear(ctl_sarena);
Jason Evans3c234352010-01-27 13:10:55 -0800928
Jason Evans9eb1b1c2017-01-18 23:03:37 -0800929 for (i = 0; i < ctl_arenas->narenas; i++) {
Jason Evansc1e00ef2016-05-10 22:21:10 -0700930 tarenas[i] = arena_get(tsdn, i, false);
Jason Evans9eb1b1c2017-01-18 23:03:37 -0800931 }
Jason Evans8bb31982014-10-07 23:14:57 -0700932
Jason Evans9eb1b1c2017-01-18 23:03:37 -0800933 for (i = 0; i < ctl_arenas->narenas; i++) {
934 ctl_arena_t *ctl_arena = arenas_i(i);
Jason Evans3c234352010-01-27 13:10:55 -0800935 bool initialized = (tarenas[i] != NULL);
936
Jason Evans9eb1b1c2017-01-18 23:03:37 -0800937 ctl_arena->initialized = initialized;
938 if (initialized) {
939 ctl_arena_refresh(tsdn, tarenas[i], ctl_sarena, i,
940 false);
941 }
Jason Evans3c234352010-01-27 13:10:55 -0800942 }
943
Jason Evans7372b152012-02-10 20:22:09 -0800944 if (config_stats) {
Jason Evans9eb1b1c2017-01-18 23:03:37 -0800945 ctl_stats->allocated = ctl_sarena->astats->allocated_small +
David Goldblattee202ef2017-03-13 16:18:40 -0700946 atomic_load_zu(&ctl_sarena->astats->astats.allocated_large,
947 ATOMIC_RELAXED);
Jason Evans9eb1b1c2017-01-18 23:03:37 -0800948 ctl_stats->active = (ctl_sarena->pactive << LG_PAGE);
David Goldblattee202ef2017-03-13 16:18:40 -0700949 ctl_stats->metadata = atomic_load_zu(
950 &ctl_sarena->astats->astats.base, ATOMIC_RELAXED) +
951 atomic_load_zu(&ctl_sarena->astats->astats.internal,
952 ATOMIC_RELAXED);
953 ctl_stats->resident = atomic_load_zu(
954 &ctl_sarena->astats->astats.resident, ATOMIC_RELAXED);
955 ctl_stats->mapped = atomic_load_zu(
956 &ctl_sarena->astats->astats.mapped, ATOMIC_RELAXED);
957 ctl_stats->retained = atomic_load_zu(
958 &ctl_sarena->astats->astats.retained, ATOMIC_RELAXED);
Qi Wangca9074d2017-03-11 20:28:31 -0800959
960#define READ_GLOBAL_MUTEX_PROF_DATA(mtx, data) \
961 malloc_mutex_lock(tsdn, &mtx); \
Qi Wang64c5f5c2017-03-13 17:29:03 -0700962 malloc_mutex_prof_read(tsdn, &ctl_stats->data, &mtx); \
Qi Wangca9074d2017-03-11 20:28:31 -0800963 malloc_mutex_unlock(tsdn, &mtx);
964
965 READ_GLOBAL_MUTEX_PROF_DATA(b0get()->mtx, base_mtx_data);
Qi Wangbd2006a2017-03-12 01:28:52 -0800966 if (config_prof && opt_prof) {
967 READ_GLOBAL_MUTEX_PROF_DATA(bt2gctx_mtx, prof_mtx_data);
968 }
Qi Wangca9074d2017-03-11 20:28:31 -0800969 /* We own ctl mutex already. */
Qi Wang64c5f5c2017-03-13 17:29:03 -0700970 malloc_mutex_prof_read(tsdn, &ctl_stats->ctl_mtx_data, &ctl_mtx);
Qi Wangca9074d2017-03-11 20:28:31 -0800971#undef READ_GLOBAL_MUTEX_PROF_DATA
Jason Evans7372b152012-02-10 20:22:09 -0800972 }
Jason Evans9eb1b1c2017-01-18 23:03:37 -0800973 ctl_arenas->epoch++;
Jason Evans3c234352010-01-27 13:10:55 -0800974}
975
976static bool
Jason Evansc4c25922017-01-15 16:56:30 -0800977ctl_init(tsdn_t *tsdn) {
Jason Evansfc4dcfa2010-11-24 15:44:21 -0800978 bool ret;
Jason Evans3c234352010-01-27 13:10:55 -0800979
Jason Evansc1e00ef2016-05-10 22:21:10 -0700980 malloc_mutex_lock(tsdn, &ctl_mtx);
Jason Evans551ebc42014-10-03 10:16:09 -0700981 if (!ctl_initialized) {
Jason Evans9eb1b1c2017-01-18 23:03:37 -0800982 ctl_arena_t *ctl_sarena, *ctl_darena;
Jason Evansd778dd22017-01-03 12:40:54 -0800983 unsigned i;
984
Jason Evans3c234352010-01-27 13:10:55 -0800985 /*
Jason Evans9eb1b1c2017-01-18 23:03:37 -0800986 * Allocate demand-zeroed space for pointers to the full
987 * range of supported arena indices.
Jason Evans3c234352010-01-27 13:10:55 -0800988 */
Jason Evans9eb1b1c2017-01-18 23:03:37 -0800989 if (ctl_arenas == NULL) {
990 ctl_arenas = (ctl_arenas_t *)base_alloc(tsdn,
991 b0get(), sizeof(ctl_arenas_t), QUANTUM);
992 if (ctl_arenas == NULL) {
993 ret = true;
994 goto label_return;
995 }
996 }
997
998 if (config_stats && ctl_stats == NULL) {
Jason Evansd778dd22017-01-03 12:40:54 -0800999 ctl_stats = (ctl_stats_t *)base_alloc(tsdn, b0get(),
1000 sizeof(ctl_stats_t), QUANTUM);
1001 if (ctl_stats == NULL) {
1002 ret = true;
1003 goto label_return;
1004 }
1005 }
1006
1007 /*
Jason Evans9eb1b1c2017-01-18 23:03:37 -08001008 * Allocate space for the current full range of arenas
1009 * here rather than doing it lazily elsewhere, in order
1010 * to limit when OOM-caused errors can occur.
Jason Evansd778dd22017-01-03 12:40:54 -08001011 */
Jason Evans9eb1b1c2017-01-18 23:03:37 -08001012 if ((ctl_sarena = arenas_i_impl(tsdn, MALLCTL_ARENAS_ALL, false,
1013 true)) == NULL) {
1014 ret = true;
1015 goto label_return;
1016 }
1017 ctl_sarena->initialized = true;
1018
1019 if ((ctl_darena = arenas_i_impl(tsdn, MALLCTL_ARENAS_DESTROYED,
Jason Evansd778dd22017-01-03 12:40:54 -08001020 false, true)) == NULL) {
Jason Evansfc4dcfa2010-11-24 15:44:21 -08001021 ret = true;
Jason Evansa1ee7832012-04-10 15:07:44 -07001022 goto label_return;
Jason Evansfc4dcfa2010-11-24 15:44:21 -08001023 }
Jason Evans9eb1b1c2017-01-18 23:03:37 -08001024 ctl_arena_clear(ctl_darena);
Jason Evansedf1baf2017-01-03 17:21:59 -08001025 /*
Jason Evans9eb1b1c2017-01-18 23:03:37 -08001026 * Don't toggle ctl_darena to initialized until an arena is
1027 * actually destroyed, so that arena.<i>.initialized can be used
1028 * to query whether the stats are relevant.
Jason Evansedf1baf2017-01-03 17:21:59 -08001029 */
1030
Jason Evans9eb1b1c2017-01-18 23:03:37 -08001031 ctl_arenas->narenas = narenas_total_get();
1032 for (i = 0; i < ctl_arenas->narenas; i++) {
1033 if (arenas_i_impl(tsdn, i, false, true) == NULL) {
Jason Evansd778dd22017-01-03 12:40:54 -08001034 ret = true;
1035 goto label_return;
1036 }
1037 }
Jason Evans3c234352010-01-27 13:10:55 -08001038
Jason Evans9eb1b1c2017-01-18 23:03:37 -08001039 ql_new(&ctl_arenas->destroyed);
Jason Evansc1e00ef2016-05-10 22:21:10 -07001040 ctl_refresh(tsdn);
Jason Evans9eb1b1c2017-01-18 23:03:37 -08001041
Jason Evans3c234352010-01-27 13:10:55 -08001042 ctl_initialized = true;
1043 }
1044
Jason Evansfc4dcfa2010-11-24 15:44:21 -08001045 ret = false;
Jason Evansa1ee7832012-04-10 15:07:44 -07001046label_return:
Jason Evansc1e00ef2016-05-10 22:21:10 -07001047 malloc_mutex_unlock(tsdn, &ctl_mtx);
Jason Evansf4086432017-01-19 18:15:45 -08001048 return ret;
Jason Evans3c234352010-01-27 13:10:55 -08001049}
1050
1051static int
Jason Evansc1e00ef2016-05-10 22:21:10 -07001052ctl_lookup(tsdn_t *tsdn, const char *name, ctl_node_t const **nodesp,
Jason Evansc4c25922017-01-15 16:56:30 -08001053 size_t *mibp, size_t *depthp) {
Jason Evans3c234352010-01-27 13:10:55 -08001054 int ret;
1055 const char *elm, *tdot, *dot;
1056 size_t elen, i, j;
Mike Hommey461ad5c2012-04-20 08:38:42 +02001057 const ctl_named_node_t *node;
Jason Evans3c234352010-01-27 13:10:55 -08001058
1059 elm = name;
1060 /* Equivalent to strchrnul(). */
1061 dot = ((tdot = strchr(elm, '.')) != NULL) ? tdot : strchr(elm, '\0');
1062 elen = (size_t)((uintptr_t)dot - (uintptr_t)elm);
1063 if (elen == 0) {
1064 ret = ENOENT;
Jason Evansa1ee7832012-04-10 15:07:44 -07001065 goto label_return;
Jason Evans3c234352010-01-27 13:10:55 -08001066 }
1067 node = super_root_node;
1068 for (i = 0; i < *depthp; i++) {
Mike Hommey461ad5c2012-04-20 08:38:42 +02001069 assert(node);
1070 assert(node->nchildren > 0);
1071 if (ctl_named_node(node->children) != NULL) {
1072 const ctl_named_node_t *pnode = node;
Jason Evans3c234352010-01-27 13:10:55 -08001073
1074 /* Children are named. */
Mike Hommey461ad5c2012-04-20 08:38:42 +02001075 for (j = 0; j < node->nchildren; j++) {
1076 const ctl_named_node_t *child =
1077 ctl_named_children(node, j);
1078 if (strlen(child->name) == elen &&
1079 strncmp(elm, child->name, elen) == 0) {
Jason Evans3c234352010-01-27 13:10:55 -08001080 node = child;
Jason Evansc4c25922017-01-15 16:56:30 -08001081 if (nodesp != NULL) {
Mike Hommey461ad5c2012-04-20 08:38:42 +02001082 nodesp[i] =
1083 (const ctl_node_t *)node;
Jason Evansc4c25922017-01-15 16:56:30 -08001084 }
Jason Evans3c234352010-01-27 13:10:55 -08001085 mibp[i] = j;
1086 break;
1087 }
1088 }
1089 if (node == pnode) {
1090 ret = ENOENT;
Jason Evansa1ee7832012-04-10 15:07:44 -07001091 goto label_return;
Jason Evans3c234352010-01-27 13:10:55 -08001092 }
1093 } else {
Jason Evans41b6afb2012-02-02 22:04:57 -08001094 uintmax_t index;
Mike Hommey461ad5c2012-04-20 08:38:42 +02001095 const ctl_indexed_node_t *inode;
Jason Evans3c234352010-01-27 13:10:55 -08001096
1097 /* Children are indexed. */
Jason Evans41b6afb2012-02-02 22:04:57 -08001098 index = malloc_strtoumax(elm, NULL, 10);
1099 if (index == UINTMAX_MAX || index > SIZE_T_MAX) {
Jason Evans3c234352010-01-27 13:10:55 -08001100 ret = ENOENT;
Jason Evansa1ee7832012-04-10 15:07:44 -07001101 goto label_return;
Jason Evans3c234352010-01-27 13:10:55 -08001102 }
1103
Mike Hommey461ad5c2012-04-20 08:38:42 +02001104 inode = ctl_indexed_node(node->children);
Jason Evansc1e00ef2016-05-10 22:21:10 -07001105 node = inode->index(tsdn, mibp, *depthp, (size_t)index);
Jason Evans3c234352010-01-27 13:10:55 -08001106 if (node == NULL) {
1107 ret = ENOENT;
Jason Evansa1ee7832012-04-10 15:07:44 -07001108 goto label_return;
Jason Evans3c234352010-01-27 13:10:55 -08001109 }
1110
Jason Evansc4c25922017-01-15 16:56:30 -08001111 if (nodesp != NULL) {
Mike Hommey461ad5c2012-04-20 08:38:42 +02001112 nodesp[i] = (const ctl_node_t *)node;
Jason Evansc4c25922017-01-15 16:56:30 -08001113 }
Jason Evans3c234352010-01-27 13:10:55 -08001114 mibp[i] = (size_t)index;
1115 }
1116
1117 if (node->ctl != NULL) {
1118 /* Terminal node. */
1119 if (*dot != '\0') {
1120 /*
1121 * The name contains more elements than are
1122 * in this path through the tree.
1123 */
1124 ret = ENOENT;
Jason Evansa1ee7832012-04-10 15:07:44 -07001125 goto label_return;
Jason Evans3c234352010-01-27 13:10:55 -08001126 }
1127 /* Complete lookup successful. */
1128 *depthp = i + 1;
1129 break;
1130 }
1131
1132 /* Update elm. */
1133 if (*dot == '\0') {
1134 /* No more elements. */
1135 ret = ENOENT;
Jason Evansa1ee7832012-04-10 15:07:44 -07001136 goto label_return;
Jason Evans3c234352010-01-27 13:10:55 -08001137 }
1138 elm = &dot[1];
1139 dot = ((tdot = strchr(elm, '.')) != NULL) ? tdot :
1140 strchr(elm, '\0');
1141 elen = (size_t)((uintptr_t)dot - (uintptr_t)elm);
1142 }
1143
1144 ret = 0;
Jason Evansa1ee7832012-04-10 15:07:44 -07001145label_return:
Jason Evansf4086432017-01-19 18:15:45 -08001146 return ret;
Jason Evans3c234352010-01-27 13:10:55 -08001147}
1148
1149int
Jason Evansb2c0d632016-04-13 23:36:15 -07001150ctl_byname(tsd_t *tsd, const char *name, void *oldp, size_t *oldlenp,
Jason Evansc4c25922017-01-15 16:56:30 -08001151 void *newp, size_t newlen) {
Jason Evans3c234352010-01-27 13:10:55 -08001152 int ret;
1153 size_t depth;
1154 ctl_node_t const *nodes[CTL_MAX_DEPTH];
1155 size_t mib[CTL_MAX_DEPTH];
Mike Hommey461ad5c2012-04-20 08:38:42 +02001156 const ctl_named_node_t *node;
Jason Evans3c234352010-01-27 13:10:55 -08001157
Jason Evansc1e00ef2016-05-10 22:21:10 -07001158 if (!ctl_initialized && ctl_init(tsd_tsdn(tsd))) {
Jason Evans3c234352010-01-27 13:10:55 -08001159 ret = EAGAIN;
Jason Evansa1ee7832012-04-10 15:07:44 -07001160 goto label_return;
Jason Evans3c234352010-01-27 13:10:55 -08001161 }
1162
1163 depth = CTL_MAX_DEPTH;
Jason Evansc1e00ef2016-05-10 22:21:10 -07001164 ret = ctl_lookup(tsd_tsdn(tsd), name, nodes, mib, &depth);
Jason Evansc4c25922017-01-15 16:56:30 -08001165 if (ret != 0) {
Jason Evansa1ee7832012-04-10 15:07:44 -07001166 goto label_return;
Jason Evansc4c25922017-01-15 16:56:30 -08001167 }
Jason Evans3c234352010-01-27 13:10:55 -08001168
Mike Hommey461ad5c2012-04-20 08:38:42 +02001169 node = ctl_named_node(nodes[depth-1]);
Jason Evansc4c25922017-01-15 16:56:30 -08001170 if (node != NULL && node->ctl) {
Jason Evansb2c0d632016-04-13 23:36:15 -07001171 ret = node->ctl(tsd, mib, depth, oldp, oldlenp, newp, newlen);
Qi Wangaa1de062017-03-01 14:43:35 -08001172 } else {
Jason Evans3c234352010-01-27 13:10:55 -08001173 /* The name refers to a partial path through the ctl tree. */
1174 ret = ENOENT;
Jason Evans3c234352010-01-27 13:10:55 -08001175 }
Jason Evans3c234352010-01-27 13:10:55 -08001176
Jason Evansa1ee7832012-04-10 15:07:44 -07001177label_return:
Jason Evans3c234352010-01-27 13:10:55 -08001178 return(ret);
1179}
1180
1181int
Jason Evansc4c25922017-01-15 16:56:30 -08001182ctl_nametomib(tsdn_t *tsdn, const char *name, size_t *mibp, size_t *miblenp) {
Jason Evans3c234352010-01-27 13:10:55 -08001183 int ret;
1184
Jason Evansc1e00ef2016-05-10 22:21:10 -07001185 if (!ctl_initialized && ctl_init(tsdn)) {
Jason Evans3c234352010-01-27 13:10:55 -08001186 ret = EAGAIN;
Jason Evansa1ee7832012-04-10 15:07:44 -07001187 goto label_return;
Jason Evans3c234352010-01-27 13:10:55 -08001188 }
1189
Jason Evansc1e00ef2016-05-10 22:21:10 -07001190 ret = ctl_lookup(tsdn, name, NULL, mibp, miblenp);
Jason Evansa1ee7832012-04-10 15:07:44 -07001191label_return:
Jason Evans3c234352010-01-27 13:10:55 -08001192 return(ret);
1193}
1194
1195int
Jason Evansb2c0d632016-04-13 23:36:15 -07001196ctl_bymib(tsd_t *tsd, const size_t *mib, size_t miblen, void *oldp,
Jason Evansc4c25922017-01-15 16:56:30 -08001197 size_t *oldlenp, void *newp, size_t newlen) {
Jason Evans3c234352010-01-27 13:10:55 -08001198 int ret;
Mike Hommey461ad5c2012-04-20 08:38:42 +02001199 const ctl_named_node_t *node;
Jason Evans3c234352010-01-27 13:10:55 -08001200 size_t i;
1201
Jason Evansc1e00ef2016-05-10 22:21:10 -07001202 if (!ctl_initialized && ctl_init(tsd_tsdn(tsd))) {
Jason Evans3c234352010-01-27 13:10:55 -08001203 ret = EAGAIN;
Jason Evansa1ee7832012-04-10 15:07:44 -07001204 goto label_return;
Jason Evans3c234352010-01-27 13:10:55 -08001205 }
1206
1207 /* Iterate down the tree. */
1208 node = super_root_node;
1209 for (i = 0; i < miblen; i++) {
Mike Hommey461ad5c2012-04-20 08:38:42 +02001210 assert(node);
1211 assert(node->nchildren > 0);
1212 if (ctl_named_node(node->children) != NULL) {
Jason Evans3c234352010-01-27 13:10:55 -08001213 /* Children are named. */
Jason Evans6edbedd2017-01-04 07:51:49 -08001214 if (node->nchildren <= mib[i]) {
Jason Evans3c234352010-01-27 13:10:55 -08001215 ret = ENOENT;
Jason Evansa1ee7832012-04-10 15:07:44 -07001216 goto label_return;
Jason Evans3c234352010-01-27 13:10:55 -08001217 }
Mike Hommey461ad5c2012-04-20 08:38:42 +02001218 node = ctl_named_children(node, mib[i]);
Jason Evans3c234352010-01-27 13:10:55 -08001219 } else {
Mike Hommey461ad5c2012-04-20 08:38:42 +02001220 const ctl_indexed_node_t *inode;
Jason Evans3c234352010-01-27 13:10:55 -08001221
1222 /* Indexed element. */
Mike Hommey461ad5c2012-04-20 08:38:42 +02001223 inode = ctl_indexed_node(node->children);
Jason Evansc1e00ef2016-05-10 22:21:10 -07001224 node = inode->index(tsd_tsdn(tsd), mib, miblen, mib[i]);
Jason Evans3c234352010-01-27 13:10:55 -08001225 if (node == NULL) {
1226 ret = ENOENT;
Jason Evansa1ee7832012-04-10 15:07:44 -07001227 goto label_return;
Jason Evans3c234352010-01-27 13:10:55 -08001228 }
1229 }
1230 }
1231
1232 /* Call the ctl function. */
Jason Evansc4c25922017-01-15 16:56:30 -08001233 if (node && node->ctl) {
Jason Evansb2c0d632016-04-13 23:36:15 -07001234 ret = node->ctl(tsd, mib, miblen, oldp, oldlenp, newp, newlen);
Jason Evansc4c25922017-01-15 16:56:30 -08001235 } else {
Jason Evans3c234352010-01-27 13:10:55 -08001236 /* Partial MIB. */
1237 ret = ENOENT;
Jason Evans3c234352010-01-27 13:10:55 -08001238 }
Jason Evans3c234352010-01-27 13:10:55 -08001239
Jason Evansa1ee7832012-04-10 15:07:44 -07001240label_return:
Jason Evans3c234352010-01-27 13:10:55 -08001241 return(ret);
1242}
1243
1244bool
Jason Evansc4c25922017-01-15 16:56:30 -08001245ctl_boot(void) {
1246 if (malloc_mutex_init(&ctl_mtx, "ctl", WITNESS_RANK_CTL)) {
Jason Evansf4086432017-01-19 18:15:45 -08001247 return true;
Jason Evansc4c25922017-01-15 16:56:30 -08001248 }
Jason Evans3c234352010-01-27 13:10:55 -08001249
1250 ctl_initialized = false;
1251
Jason Evansf4086432017-01-19 18:15:45 -08001252 return false;
Jason Evans3c234352010-01-27 13:10:55 -08001253}
1254
Jason Evans20f1fc92012-10-09 14:46:22 -07001255void
Jason Evansc4c25922017-01-15 16:56:30 -08001256ctl_prefork(tsdn_t *tsdn) {
Jason Evansc1e00ef2016-05-10 22:21:10 -07001257 malloc_mutex_prefork(tsdn, &ctl_mtx);
Jason Evans20f1fc92012-10-09 14:46:22 -07001258}
1259
1260void
Jason Evansc4c25922017-01-15 16:56:30 -08001261ctl_postfork_parent(tsdn_t *tsdn) {
Jason Evansc1e00ef2016-05-10 22:21:10 -07001262 malloc_mutex_postfork_parent(tsdn, &ctl_mtx);
Jason Evans20f1fc92012-10-09 14:46:22 -07001263}
1264
1265void
Jason Evansc4c25922017-01-15 16:56:30 -08001266ctl_postfork_child(tsdn_t *tsdn) {
Jason Evansc1e00ef2016-05-10 22:21:10 -07001267 malloc_mutex_postfork_child(tsdn, &ctl_mtx);
Jason Evans20f1fc92012-10-09 14:46:22 -07001268}
1269
Jason Evans3c234352010-01-27 13:10:55 -08001270/******************************************************************************/
1271/* *_ctl() functions. */
1272
Jason Evansc0cc5db2017-01-19 21:41:41 -08001273#define READONLY() do { \
Jason Evans3c234352010-01-27 13:10:55 -08001274 if (newp != NULL || newlen != 0) { \
1275 ret = EPERM; \
Jason Evans6b9ed672012-04-25 13:12:46 -07001276 goto label_return; \
Jason Evans3c234352010-01-27 13:10:55 -08001277 } \
1278} while (0)
1279
Jason Evansc0cc5db2017-01-19 21:41:41 -08001280#define WRITEONLY() do { \
Jason Evans3c234352010-01-27 13:10:55 -08001281 if (oldp != NULL || oldlenp != NULL) { \
1282 ret = EPERM; \
Jason Evans6b9ed672012-04-25 13:12:46 -07001283 goto label_return; \
Jason Evans3c234352010-01-27 13:10:55 -08001284 } \
1285} while (0)
1286
Jason Evansc0cc5db2017-01-19 21:41:41 -08001287#define READ_XOR_WRITE() do { \
Jason Evansfc12c0b2014-10-03 23:25:30 -07001288 if ((oldp != NULL && oldlenp != NULL) && (newp != NULL || \
1289 newlen != 0)) { \
1290 ret = EPERM; \
1291 goto label_return; \
1292 } \
1293} while (0)
1294
Jason Evansc0cc5db2017-01-19 21:41:41 -08001295#define READ(v, t) do { \
Jason Evans3c234352010-01-27 13:10:55 -08001296 if (oldp != NULL && oldlenp != NULL) { \
1297 if (*oldlenp != sizeof(t)) { \
1298 size_t copylen = (sizeof(t) <= *oldlenp) \
1299 ? sizeof(t) : *oldlenp; \
Jason Evans6eb84fb2012-11-29 22:13:04 -08001300 memcpy(oldp, (void *)&(v), copylen); \
Jason Evans3c234352010-01-27 13:10:55 -08001301 ret = EINVAL; \
Jason Evans6b9ed672012-04-25 13:12:46 -07001302 goto label_return; \
Jason Evansb49a3342015-07-28 11:28:19 -04001303 } \
1304 *(t *)oldp = (v); \
Jason Evans3c234352010-01-27 13:10:55 -08001305 } \
1306} while (0)
1307
Jason Evansc0cc5db2017-01-19 21:41:41 -08001308#define WRITE(v, t) do { \
Jason Evans3c234352010-01-27 13:10:55 -08001309 if (newp != NULL) { \
1310 if (newlen != sizeof(t)) { \
1311 ret = EINVAL; \
Jason Evans6b9ed672012-04-25 13:12:46 -07001312 goto label_return; \
Jason Evans3c234352010-01-27 13:10:55 -08001313 } \
Jason Evans6eb84fb2012-11-29 22:13:04 -08001314 (v) = *(t *)newp; \
Jason Evans3c234352010-01-27 13:10:55 -08001315 } \
1316} while (0)
1317
Jason Evansc0cc5db2017-01-19 21:41:41 -08001318#define MIB_UNSIGNED(v, i) do { \
Jason Evans6edbedd2017-01-04 07:51:49 -08001319 if (mib[i] > UINT_MAX) { \
1320 ret = EFAULT; \
1321 goto label_return; \
1322 } \
1323 v = (unsigned)mib[i]; \
1324} while (0)
1325
Jason Evans7372b152012-02-10 20:22:09 -08001326/*
1327 * There's a lot of code duplication in the following macros due to limitations
1328 * in how nested cpp macros are expanded.
1329 */
Jason Evansc0cc5db2017-01-19 21:41:41 -08001330#define CTL_RO_CLGEN(c, l, n, v, t) \
Jason Evans7372b152012-02-10 20:22:09 -08001331static int \
Jason Evansb2c0d632016-04-13 23:36:15 -07001332n##_ctl(tsd_t *tsd, const size_t *mib, size_t miblen, void *oldp, \
Jason Evansc4c25922017-01-15 16:56:30 -08001333 size_t *oldlenp, void *newp, size_t newlen) { \
Jason Evans7372b152012-02-10 20:22:09 -08001334 int ret; \
1335 t oldval; \
1336 \
Jason Evansc4c25922017-01-15 16:56:30 -08001337 if (!(c)) { \
Jason Evansf4086432017-01-19 18:15:45 -08001338 return ENOENT; \
Jason Evansc4c25922017-01-15 16:56:30 -08001339 } \
1340 if (l) { \
Jason Evansc1e00ef2016-05-10 22:21:10 -07001341 malloc_mutex_lock(tsd_tsdn(tsd), &ctl_mtx); \
Jason Evansc4c25922017-01-15 16:56:30 -08001342 } \
Jason Evans7372b152012-02-10 20:22:09 -08001343 READONLY(); \
Jason Evans6eb84fb2012-11-29 22:13:04 -08001344 oldval = (v); \
Jason Evans7372b152012-02-10 20:22:09 -08001345 READ(oldval, t); \
1346 \
1347 ret = 0; \
Jason Evans6b9ed672012-04-25 13:12:46 -07001348label_return: \
Jason Evansc4c25922017-01-15 16:56:30 -08001349 if (l) { \
Jason Evansc1e00ef2016-05-10 22:21:10 -07001350 malloc_mutex_unlock(tsd_tsdn(tsd), &ctl_mtx); \
Jason Evansc4c25922017-01-15 16:56:30 -08001351 } \
Jason Evansf4086432017-01-19 18:15:45 -08001352 return ret; \
Jason Evans7372b152012-02-10 20:22:09 -08001353}
1354
Jason Evansc0cc5db2017-01-19 21:41:41 -08001355#define CTL_RO_CGEN(c, n, v, t) \
Jason Evans7372b152012-02-10 20:22:09 -08001356static int \
Jason Evansb2c0d632016-04-13 23:36:15 -07001357n##_ctl(tsd_t *tsd, const size_t *mib, size_t miblen, void *oldp, \
Jason Evansc4c25922017-01-15 16:56:30 -08001358 size_t *oldlenp, void *newp, size_t newlen) { \
Jason Evans7372b152012-02-10 20:22:09 -08001359 int ret; \
1360 t oldval; \
1361 \
Jason Evansc4c25922017-01-15 16:56:30 -08001362 if (!(c)) { \
Jason Evansf4086432017-01-19 18:15:45 -08001363 return ENOENT; \
Jason Evansc4c25922017-01-15 16:56:30 -08001364 } \
Jason Evansc1e00ef2016-05-10 22:21:10 -07001365 malloc_mutex_lock(tsd_tsdn(tsd), &ctl_mtx); \
Jason Evans7372b152012-02-10 20:22:09 -08001366 READONLY(); \
Jason Evans6eb84fb2012-11-29 22:13:04 -08001367 oldval = (v); \
Jason Evans7372b152012-02-10 20:22:09 -08001368 READ(oldval, t); \
1369 \
1370 ret = 0; \
Jason Evans6b9ed672012-04-25 13:12:46 -07001371label_return: \
Jason Evansc1e00ef2016-05-10 22:21:10 -07001372 malloc_mutex_unlock(tsd_tsdn(tsd), &ctl_mtx); \
Jason Evansf4086432017-01-19 18:15:45 -08001373 return ret; \
Jason Evans7372b152012-02-10 20:22:09 -08001374}
1375
Jason Evansc0cc5db2017-01-19 21:41:41 -08001376#define CTL_RO_GEN(n, v, t) \
Jason Evans3c234352010-01-27 13:10:55 -08001377static int \
Jason Evansb2c0d632016-04-13 23:36:15 -07001378n##_ctl(tsd_t *tsd, const size_t *mib, size_t miblen, void *oldp, \
Jason Evansc4c25922017-01-15 16:56:30 -08001379 size_t *oldlenp, void *newp, size_t newlen) { \
Jason Evans3c234352010-01-27 13:10:55 -08001380 int ret; \
1381 t oldval; \
1382 \
Jason Evansc1e00ef2016-05-10 22:21:10 -07001383 malloc_mutex_lock(tsd_tsdn(tsd), &ctl_mtx); \
Jason Evansfc4dcfa2010-11-24 15:44:21 -08001384 READONLY(); \
Jason Evans6eb84fb2012-11-29 22:13:04 -08001385 oldval = (v); \
Jason Evansfc4dcfa2010-11-24 15:44:21 -08001386 READ(oldval, t); \
1387 \
1388 ret = 0; \
Jason Evans6b9ed672012-04-25 13:12:46 -07001389label_return: \
Jason Evansc1e00ef2016-05-10 22:21:10 -07001390 malloc_mutex_unlock(tsd_tsdn(tsd), &ctl_mtx); \
Jason Evansf4086432017-01-19 18:15:45 -08001391 return ret; \
Jason Evansfc4dcfa2010-11-24 15:44:21 -08001392}
1393
1394/*
1395 * ctl_mtx is not acquired, under the assumption that no pertinent data will
1396 * mutate during the call.
1397 */
Jason Evansc0cc5db2017-01-19 21:41:41 -08001398#define CTL_RO_NL_CGEN(c, n, v, t) \
Jason Evans7372b152012-02-10 20:22:09 -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 Evans7372b152012-02-10 20:22:09 -08001402 int ret; \
1403 t oldval; \
1404 \
Jason Evansc4c25922017-01-15 16:56:30 -08001405 if (!(c)) { \
Jason Evansf4086432017-01-19 18:15:45 -08001406 return ENOENT; \
Jason Evansc4c25922017-01-15 16:56:30 -08001407 } \
Jason Evans7372b152012-02-10 20:22:09 -08001408 READONLY(); \
Jason Evans6eb84fb2012-11-29 22:13:04 -08001409 oldval = (v); \
Jason Evans7372b152012-02-10 20:22:09 -08001410 READ(oldval, t); \
1411 \
1412 ret = 0; \
Jason Evans6b9ed672012-04-25 13:12:46 -07001413label_return: \
Jason Evansf4086432017-01-19 18:15:45 -08001414 return ret; \
Jason Evans7372b152012-02-10 20:22:09 -08001415}
1416
Jason Evansc0cc5db2017-01-19 21:41:41 -08001417#define CTL_RO_NL_GEN(n, v, t) \
Jason Evansfc4dcfa2010-11-24 15:44:21 -08001418static int \
Jason Evansb2c0d632016-04-13 23:36:15 -07001419n##_ctl(tsd_t *tsd, const size_t *mib, size_t miblen, void *oldp, \
Jason Evansc4c25922017-01-15 16:56:30 -08001420 size_t *oldlenp, void *newp, size_t newlen) { \
Jason Evansfc4dcfa2010-11-24 15:44:21 -08001421 int ret; \
1422 t oldval; \
1423 \
Jason Evans3c234352010-01-27 13:10:55 -08001424 READONLY(); \
Jason Evans6eb84fb2012-11-29 22:13:04 -08001425 oldval = (v); \
Jason Evans3c234352010-01-27 13:10:55 -08001426 READ(oldval, t); \
1427 \
1428 ret = 0; \
Jason Evans6b9ed672012-04-25 13:12:46 -07001429label_return: \
Jason Evansf4086432017-01-19 18:15:45 -08001430 return ret; \
Jason Evans3c234352010-01-27 13:10:55 -08001431}
1432
Jason Evansc0cc5db2017-01-19 21:41:41 -08001433#define CTL_TSD_RO_NL_CGEN(c, n, m, t) \
Jason Evans5460aa62014-09-22 21:09:23 -07001434static int \
Jason Evansb2c0d632016-04-13 23:36:15 -07001435n##_ctl(tsd_t *tsd, const size_t *mib, size_t miblen, void *oldp, \
Jason Evansc4c25922017-01-15 16:56:30 -08001436 size_t *oldlenp, void *newp, size_t newlen) { \
Jason Evans5460aa62014-09-22 21:09:23 -07001437 int ret; \
1438 t oldval; \
Jason Evans5460aa62014-09-22 21:09:23 -07001439 \
Jason Evansc4c25922017-01-15 16:56:30 -08001440 if (!(c)) { \
Jason Evansf4086432017-01-19 18:15:45 -08001441 return ENOENT; \
Jason Evansc4c25922017-01-15 16:56:30 -08001442 } \
Jason Evans5460aa62014-09-22 21:09:23 -07001443 READONLY(); \
Jason Evans5460aa62014-09-22 21:09:23 -07001444 oldval = (m(tsd)); \
1445 READ(oldval, t); \
1446 \
1447 ret = 0; \
1448label_return: \
Jason Evansf4086432017-01-19 18:15:45 -08001449 return ret; \
Jason Evans5460aa62014-09-22 21:09:23 -07001450}
1451
Jason Evansc0cc5db2017-01-19 21:41:41 -08001452#define CTL_RO_CONFIG_GEN(n, t) \
Jason Evans3c234352010-01-27 13:10:55 -08001453static int \
Jason Evansb2c0d632016-04-13 23:36:15 -07001454n##_ctl(tsd_t *tsd, const size_t *mib, size_t miblen, void *oldp, \
Jason Evansc4c25922017-01-15 16:56:30 -08001455 size_t *oldlenp, void *newp, size_t newlen) { \
Jason Evans3c234352010-01-27 13:10:55 -08001456 int ret; \
Jason Evansf8290092016-02-07 14:23:22 -08001457 t oldval; \
Jason Evans3c234352010-01-27 13:10:55 -08001458 \
1459 READONLY(); \
Jason Evans7372b152012-02-10 20:22:09 -08001460 oldval = n; \
Jason Evansf8290092016-02-07 14:23:22 -08001461 READ(oldval, t); \
Jason Evans3c234352010-01-27 13:10:55 -08001462 \
1463 ret = 0; \
Jason Evans6b9ed672012-04-25 13:12:46 -07001464label_return: \
Jason Evansf4086432017-01-19 18:15:45 -08001465 return ret; \
Jason Evans3c234352010-01-27 13:10:55 -08001466}
1467
Jason Evansd8a39002013-12-19 21:40:41 -08001468/******************************************************************************/
1469
Jason Evansfc4dcfa2010-11-24 15:44:21 -08001470CTL_RO_NL_GEN(version, JEMALLOC_VERSION, const char *)
Jason Evansa40bc7a2010-03-02 13:01:16 -08001471
Jason Evans3c234352010-01-27 13:10:55 -08001472static int
Jason Evansb2c0d632016-04-13 23:36:15 -07001473epoch_ctl(tsd_t *tsd, const size_t *mib, size_t miblen, void *oldp,
Jason Evansc4c25922017-01-15 16:56:30 -08001474 size_t *oldlenp, void *newp, size_t newlen) {
Jason Evans3c234352010-01-27 13:10:55 -08001475 int ret;
Jason Evans3ab682d2013-10-19 17:19:49 -07001476 UNUSED uint64_t newval;
Jason Evans3c234352010-01-27 13:10:55 -08001477
Jason Evansc1e00ef2016-05-10 22:21:10 -07001478 malloc_mutex_lock(tsd_tsdn(tsd), &ctl_mtx);
Jason Evans3c234352010-01-27 13:10:55 -08001479 WRITE(newval, uint64_t);
Jason Evansc4c25922017-01-15 16:56:30 -08001480 if (newp != NULL) {
Jason Evansc1e00ef2016-05-10 22:21:10 -07001481 ctl_refresh(tsd_tsdn(tsd));
Jason Evansc4c25922017-01-15 16:56:30 -08001482 }
Jason Evans9eb1b1c2017-01-18 23:03:37 -08001483 READ(ctl_arenas->epoch, uint64_t);
Jason Evans3c234352010-01-27 13:10:55 -08001484
1485 ret = 0;
Jason Evansa1ee7832012-04-10 15:07:44 -07001486label_return:
Jason Evansc1e00ef2016-05-10 22:21:10 -07001487 malloc_mutex_unlock(tsd_tsdn(tsd), &ctl_mtx);
Jason Evansf4086432017-01-19 18:15:45 -08001488 return ret;
Jason Evans3c234352010-01-27 13:10:55 -08001489}
1490
Jason Evansd8a39002013-12-19 21:40:41 -08001491/******************************************************************************/
Jason Evansd4be8b72012-03-26 18:54:44 -07001492
Jason Evansf8290092016-02-07 14:23:22 -08001493CTL_RO_CONFIG_GEN(config_cache_oblivious, bool)
1494CTL_RO_CONFIG_GEN(config_debug, bool)
1495CTL_RO_CONFIG_GEN(config_fill, bool)
1496CTL_RO_CONFIG_GEN(config_lazy_lock, bool)
1497CTL_RO_CONFIG_GEN(config_malloc_conf, const char *)
1498CTL_RO_CONFIG_GEN(config_munmap, bool)
1499CTL_RO_CONFIG_GEN(config_prof, bool)
1500CTL_RO_CONFIG_GEN(config_prof_libgcc, bool)
1501CTL_RO_CONFIG_GEN(config_prof_libunwind, bool)
1502CTL_RO_CONFIG_GEN(config_stats, bool)
1503CTL_RO_CONFIG_GEN(config_tcache, bool)
1504CTL_RO_CONFIG_GEN(config_tls, bool)
1505CTL_RO_CONFIG_GEN(config_utrace, bool)
Jason Evansf8290092016-02-07 14:23:22 -08001506CTL_RO_CONFIG_GEN(config_xmalloc, bool)
Jason Evansd4be8b72012-03-26 18:54:44 -07001507
Jason Evansd8a39002013-12-19 21:40:41 -08001508/******************************************************************************/
Jason Evansd4be8b72012-03-26 18:54:44 -07001509
Jason Evansd8a39002013-12-19 21:40:41 -08001510CTL_RO_NL_GEN(opt_abort, opt_abort, bool)
1511CTL_RO_NL_GEN(opt_dss, opt_dss, const char *)
Jason Evans8f683b92016-02-24 11:03:40 -08001512CTL_RO_NL_GEN(opt_narenas, opt_narenas, unsigned)
Qi Wangec532e22017-02-02 17:02:05 -08001513CTL_RO_NL_GEN(opt_percpu_arena, opt_percpu_arena, const char *)
Jason Evans64e458f2017-03-08 22:42:57 -08001514CTL_RO_NL_GEN(opt_dirty_decay_time, opt_dirty_decay_time, ssize_t)
1515CTL_RO_NL_GEN(opt_muzzy_decay_time, opt_muzzy_decay_time, ssize_t)
Jason Evansd8a39002013-12-19 21:40:41 -08001516CTL_RO_NL_GEN(opt_stats_print, opt_stats_print, bool)
Guilherme Goncalves2c5cb612014-12-08 19:12:41 -02001517CTL_RO_NL_CGEN(config_fill, opt_junk, opt_junk, const char *)
Jason Evansd8a39002013-12-19 21:40:41 -08001518CTL_RO_NL_CGEN(config_fill, opt_zero, opt_zero, bool)
1519CTL_RO_NL_CGEN(config_utrace, opt_utrace, opt_utrace, bool)
Jason Evansd8a39002013-12-19 21:40:41 -08001520CTL_RO_NL_CGEN(config_xmalloc, opt_xmalloc, opt_xmalloc, bool)
1521CTL_RO_NL_CGEN(config_tcache, opt_tcache, opt_tcache, bool)
1522CTL_RO_NL_CGEN(config_tcache, opt_lg_tcache_max, opt_lg_tcache_max, ssize_t)
1523CTL_RO_NL_CGEN(config_prof, opt_prof, opt_prof, bool)
1524CTL_RO_NL_CGEN(config_prof, opt_prof_prefix, opt_prof_prefix, const char *)
Jason Evansfc12c0b2014-10-03 23:25:30 -07001525CTL_RO_NL_CGEN(config_prof, opt_prof_active, opt_prof_active, bool)
1526CTL_RO_NL_CGEN(config_prof, opt_prof_thread_active_init,
1527 opt_prof_thread_active_init, bool)
Jason Evansd8a39002013-12-19 21:40:41 -08001528CTL_RO_NL_CGEN(config_prof, opt_lg_prof_sample, opt_lg_prof_sample, size_t)
1529CTL_RO_NL_CGEN(config_prof, opt_prof_accum, opt_prof_accum, bool)
1530CTL_RO_NL_CGEN(config_prof, opt_lg_prof_interval, opt_lg_prof_interval, ssize_t)
1531CTL_RO_NL_CGEN(config_prof, opt_prof_gdump, opt_prof_gdump, bool)
1532CTL_RO_NL_CGEN(config_prof, opt_prof_final, opt_prof_final, bool)
1533CTL_RO_NL_CGEN(config_prof, opt_prof_leak, opt_prof_leak, bool)
Jason Evansd4be8b72012-03-26 18:54:44 -07001534
Jason Evansd8a39002013-12-19 21:40:41 -08001535/******************************************************************************/
Jason Evans3c234352010-01-27 13:10:55 -08001536
Jason Evansb267d0f2010-08-13 15:42:29 -07001537static int
Jason Evansb2c0d632016-04-13 23:36:15 -07001538thread_arena_ctl(tsd_t *tsd, const size_t *mib, size_t miblen, void *oldp,
Jason Evansc4c25922017-01-15 16:56:30 -08001539 size_t *oldlenp, void *newp, size_t newlen) {
Jason Evansb267d0f2010-08-13 15:42:29 -07001540 int ret;
Jason Evans1cb181e2015-01-29 15:30:47 -08001541 arena_t *oldarena;
Jason Evansb267d0f2010-08-13 15:42:29 -07001542 unsigned newind, oldind;
1543
Jason Evans90827a32016-05-03 15:00:42 -07001544 oldarena = arena_choose(tsd, NULL);
Jason Evansc4c25922017-01-15 16:56:30 -08001545 if (oldarena == NULL) {
Jason Evansf4086432017-01-19 18:15:45 -08001546 return EAGAIN;
Jason Evansc4c25922017-01-15 16:56:30 -08001547 }
Jason Evansa0dd3a42016-12-22 16:39:10 -06001548 newind = oldind = arena_ind_get(oldarena);
Jason Evansa7153a02011-03-14 11:39:49 -07001549 WRITE(newind, unsigned);
1550 READ(oldind, unsigned);
Qi Wangec532e22017-02-02 17:02:05 -08001551
Jason Evansb267d0f2010-08-13 15:42:29 -07001552 if (newind != oldind) {
Jason Evans1cb181e2015-01-29 15:30:47 -08001553 arena_t *newarena;
1554
Jason Evansb6c08672016-10-03 10:37:12 -07001555 if (newind >= narenas_total_get()) {
Jason Evansb267d0f2010-08-13 15:42:29 -07001556 /* New arena index is out of range. */
1557 ret = EFAULT;
Jason Evansa1ee7832012-04-10 15:07:44 -07001558 goto label_return;
Jason Evansb267d0f2010-08-13 15:42:29 -07001559 }
1560
Qi Wangec532e22017-02-02 17:02:05 -08001561 if (have_percpu_arena &&
1562 (percpu_arena_mode != percpu_arena_disabled)) {
1563 if (newind < percpu_arena_ind_limit()) {
1564 /*
1565 * If perCPU arena is enabled, thread_arena
1566 * control is not allowed for the auto arena
1567 * range.
1568 */
1569 ret = EPERM;
1570 goto label_return;
1571 }
1572 }
1573
Jason Evansb267d0f2010-08-13 15:42:29 -07001574 /* Initialize arena if necessary. */
Jason Evansc1e00ef2016-05-10 22:21:10 -07001575 newarena = arena_get(tsd_tsdn(tsd), newind, true);
Jason Evans1cb181e2015-01-29 15:30:47 -08001576 if (newarena == NULL) {
Jason Evansb267d0f2010-08-13 15:42:29 -07001577 ret = EAGAIN;
Jason Evansa1ee7832012-04-10 15:07:44 -07001578 goto label_return;
Jason Evansb267d0f2010-08-13 15:42:29 -07001579 }
Jason Evans8bb31982014-10-07 23:14:57 -07001580 /* Set new arena/tcache associations. */
1581 arena_migrate(tsd, oldind, newind);
Jason Evans7372b152012-02-10 20:22:09 -08001582 if (config_tcache) {
Jason Evans5460aa62014-09-22 21:09:23 -07001583 tcache_t *tcache = tsd_tcache_get(tsd);
Jason Evans1cb181e2015-01-29 15:30:47 -08001584 if (tcache != NULL) {
Jason Evansc1e00ef2016-05-10 22:21:10 -07001585 tcache_arena_reassociate(tsd_tsdn(tsd), tcache,
Qi Wang01f47f12017-03-06 12:51:41 -08001586 newarena);
Jason Evans1cb181e2015-01-29 15:30:47 -08001587 }
Jason Evans624f2f32010-12-29 12:21:05 -08001588 }
Jason Evansb267d0f2010-08-13 15:42:29 -07001589 }
1590
1591 ret = 0;
Jason Evansa1ee7832012-04-10 15:07:44 -07001592label_return:
Jason Evansf4086432017-01-19 18:15:45 -08001593 return ret;
Jason Evansb267d0f2010-08-13 15:42:29 -07001594}
Jason Evansb267d0f2010-08-13 15:42:29 -07001595
Jason Evans5460aa62014-09-22 21:09:23 -07001596CTL_TSD_RO_NL_CGEN(config_stats, thread_allocated, tsd_thread_allocated_get,
1597 uint64_t)
1598CTL_TSD_RO_NL_CGEN(config_stats, thread_allocatedp, tsd_thread_allocatedp_get,
1599 uint64_t *)
1600CTL_TSD_RO_NL_CGEN(config_stats, thread_deallocated, tsd_thread_deallocated_get,
1601 uint64_t)
1602CTL_TSD_RO_NL_CGEN(config_stats, thread_deallocatedp,
1603 tsd_thread_deallocatedp_get, uint64_t *)
Jason Evans93443682010-10-20 17:39:18 -07001604
Jason Evansd8a39002013-12-19 21:40:41 -08001605static int
Jason Evansb2c0d632016-04-13 23:36:15 -07001606thread_tcache_enabled_ctl(tsd_t *tsd, const size_t *mib, size_t miblen,
Jason Evansc4c25922017-01-15 16:56:30 -08001607 void *oldp, size_t *oldlenp, void *newp, size_t newlen) {
Jason Evansd8a39002013-12-19 21:40:41 -08001608 int ret;
1609 bool oldval;
Jason Evans3c234352010-01-27 13:10:55 -08001610
Jason Evansc4c25922017-01-15 16:56:30 -08001611 if (!config_tcache) {
Jason Evansf4086432017-01-19 18:15:45 -08001612 return ENOENT;
Jason Evansc4c25922017-01-15 16:56:30 -08001613 }
Jason Evans3c234352010-01-27 13:10:55 -08001614
Jason Evansd8a39002013-12-19 21:40:41 -08001615 oldval = tcache_enabled_get();
1616 if (newp != NULL) {
1617 if (newlen != sizeof(bool)) {
1618 ret = EINVAL;
1619 goto label_return;
1620 }
1621 tcache_enabled_set(*(bool *)newp);
1622 }
1623 READ(oldval, bool);
Jason Evans3c234352010-01-27 13:10:55 -08001624
Jason Evansd8a39002013-12-19 21:40:41 -08001625 ret = 0;
1626label_return:
Jason Evansf4086432017-01-19 18:15:45 -08001627 return ret;
Jason Evansd8a39002013-12-19 21:40:41 -08001628}
1629
1630static int
Jason Evansb2c0d632016-04-13 23:36:15 -07001631thread_tcache_flush_ctl(tsd_t *tsd, const size_t *mib, size_t miblen,
Jason Evansc4c25922017-01-15 16:56:30 -08001632 void *oldp, size_t *oldlenp, void *newp, size_t newlen) {
Jason Evansd8a39002013-12-19 21:40:41 -08001633 int ret;
1634
Jason Evansc4c25922017-01-15 16:56:30 -08001635 if (!config_tcache) {
Jason Evansf4086432017-01-19 18:15:45 -08001636 return ENOENT;
Jason Evansc4c25922017-01-15 16:56:30 -08001637 }
Jason Evansd8a39002013-12-19 21:40:41 -08001638
1639 READONLY();
1640 WRITEONLY();
1641
1642 tcache_flush();
1643
1644 ret = 0;
1645label_return:
Jason Evansf4086432017-01-19 18:15:45 -08001646 return ret;
Jason Evansd8a39002013-12-19 21:40:41 -08001647}
Jason Evans3c234352010-01-27 13:10:55 -08001648
Jason Evans602c8e02014-08-18 16:22:13 -07001649static int
Jason Evansb2c0d632016-04-13 23:36:15 -07001650thread_prof_name_ctl(tsd_t *tsd, const size_t *mib, size_t miblen, void *oldp,
Jason Evansc4c25922017-01-15 16:56:30 -08001651 size_t *oldlenp, void *newp, size_t newlen) {
Jason Evans602c8e02014-08-18 16:22:13 -07001652 int ret;
Jason Evans602c8e02014-08-18 16:22:13 -07001653
Jason Evansc4c25922017-01-15 16:56:30 -08001654 if (!config_prof) {
Jason Evansf4086432017-01-19 18:15:45 -08001655 return ENOENT;
Jason Evansc4c25922017-01-15 16:56:30 -08001656 }
Jason Evans602c8e02014-08-18 16:22:13 -07001657
Jason Evansfc12c0b2014-10-03 23:25:30 -07001658 READ_XOR_WRITE();
1659
Jason Evans602c8e02014-08-18 16:22:13 -07001660 if (newp != NULL) {
1661 if (newlen != sizeof(const char *)) {
1662 ret = EINVAL;
1663 goto label_return;
1664 }
Jason Evans5460aa62014-09-22 21:09:23 -07001665
Jason Evansfc12c0b2014-10-03 23:25:30 -07001666 if ((ret = prof_thread_name_set(tsd, *(const char **)newp)) !=
Jason Evansc4c25922017-01-15 16:56:30 -08001667 0) {
Jason Evans602c8e02014-08-18 16:22:13 -07001668 goto label_return;
Jason Evansc4c25922017-01-15 16:56:30 -08001669 }
Jason Evansfc12c0b2014-10-03 23:25:30 -07001670 } else {
Jason Evansb2c0d632016-04-13 23:36:15 -07001671 const char *oldname = prof_thread_name_get(tsd);
Jason Evansfc12c0b2014-10-03 23:25:30 -07001672 READ(oldname, const char *);
Jason Evans602c8e02014-08-18 16:22:13 -07001673 }
Jason Evans602c8e02014-08-18 16:22:13 -07001674
1675 ret = 0;
1676label_return:
Jason Evansf4086432017-01-19 18:15:45 -08001677 return ret;
Jason Evans602c8e02014-08-18 16:22:13 -07001678}
1679
1680static int
Jason Evansb2c0d632016-04-13 23:36:15 -07001681thread_prof_active_ctl(tsd_t *tsd, const size_t *mib, size_t miblen, void *oldp,
Jason Evansc4c25922017-01-15 16:56:30 -08001682 size_t *oldlenp, void *newp, size_t newlen) {
Jason Evans602c8e02014-08-18 16:22:13 -07001683 int ret;
1684 bool oldval;
1685
Jason Evansc4c25922017-01-15 16:56:30 -08001686 if (!config_prof) {
Jason Evansf4086432017-01-19 18:15:45 -08001687 return ENOENT;
Jason Evansc4c25922017-01-15 16:56:30 -08001688 }
Jason Evans602c8e02014-08-18 16:22:13 -07001689
Jason Evansb2c0d632016-04-13 23:36:15 -07001690 oldval = prof_thread_active_get(tsd);
Jason Evans602c8e02014-08-18 16:22:13 -07001691 if (newp != NULL) {
1692 if (newlen != sizeof(bool)) {
1693 ret = EINVAL;
1694 goto label_return;
1695 }
Jason Evansb2c0d632016-04-13 23:36:15 -07001696 if (prof_thread_active_set(tsd, *(bool *)newp)) {
Jason Evans602c8e02014-08-18 16:22:13 -07001697 ret = EAGAIN;
1698 goto label_return;
1699 }
1700 }
1701 READ(oldval, bool);
1702
1703 ret = 0;
1704label_return:
Jason Evansf4086432017-01-19 18:15:45 -08001705 return ret;
Jason Evans602c8e02014-08-18 16:22:13 -07001706}
1707
Jason Evans3c234352010-01-27 13:10:55 -08001708/******************************************************************************/
1709
Jason Evans1cb181e2015-01-29 15:30:47 -08001710static int
Jason Evansb2c0d632016-04-13 23:36:15 -07001711tcache_create_ctl(tsd_t *tsd, const size_t *mib, size_t miblen, void *oldp,
Jason Evansc4c25922017-01-15 16:56:30 -08001712 size_t *oldlenp, void *newp, size_t newlen) {
Jason Evans1cb181e2015-01-29 15:30:47 -08001713 int ret;
Jason Evans1cb181e2015-01-29 15:30:47 -08001714 unsigned tcache_ind;
1715
Jason Evansc4c25922017-01-15 16:56:30 -08001716 if (!config_tcache) {
Jason Evansf4086432017-01-19 18:15:45 -08001717 return ENOENT;
Jason Evansc4c25922017-01-15 16:56:30 -08001718 }
Jason Evans1cb181e2015-01-29 15:30:47 -08001719
Jason Evans1cb181e2015-01-29 15:30:47 -08001720 READONLY();
Jason Evansb54d1602016-10-20 23:59:12 -07001721 if (tcaches_create(tsd, &tcache_ind)) {
Jason Evans1cb181e2015-01-29 15:30:47 -08001722 ret = EFAULT;
1723 goto label_return;
1724 }
1725 READ(tcache_ind, unsigned);
1726
1727 ret = 0;
1728label_return:
Jason Evansf4086432017-01-19 18:15:45 -08001729 return ret;
Jason Evans1cb181e2015-01-29 15:30:47 -08001730}
1731
1732static int
Jason Evansb2c0d632016-04-13 23:36:15 -07001733tcache_flush_ctl(tsd_t *tsd, const size_t *mib, size_t miblen, void *oldp,
Jason Evansc4c25922017-01-15 16:56:30 -08001734 size_t *oldlenp, void *newp, size_t newlen) {
Jason Evans1cb181e2015-01-29 15:30:47 -08001735 int ret;
Jason Evans1cb181e2015-01-29 15:30:47 -08001736 unsigned tcache_ind;
1737
Jason Evansc4c25922017-01-15 16:56:30 -08001738 if (!config_tcache) {
Jason Evansf4086432017-01-19 18:15:45 -08001739 return ENOENT;
Jason Evansc4c25922017-01-15 16:56:30 -08001740 }
Jason Evans1cb181e2015-01-29 15:30:47 -08001741
Jason Evans1cb181e2015-01-29 15:30:47 -08001742 WRITEONLY();
1743 tcache_ind = UINT_MAX;
1744 WRITE(tcache_ind, unsigned);
1745 if (tcache_ind == UINT_MAX) {
1746 ret = EFAULT;
1747 goto label_return;
1748 }
1749 tcaches_flush(tsd, tcache_ind);
1750
1751 ret = 0;
1752label_return:
Jason Evansf4086432017-01-19 18:15:45 -08001753 return ret;
Jason Evans1cb181e2015-01-29 15:30:47 -08001754}
1755
1756static int
Jason Evansb2c0d632016-04-13 23:36:15 -07001757tcache_destroy_ctl(tsd_t *tsd, const size_t *mib, size_t miblen, void *oldp,
Jason Evansc4c25922017-01-15 16:56:30 -08001758 size_t *oldlenp, void *newp, size_t newlen) {
Jason Evans1cb181e2015-01-29 15:30:47 -08001759 int ret;
Jason Evans1cb181e2015-01-29 15:30:47 -08001760 unsigned tcache_ind;
1761
Jason Evansc4c25922017-01-15 16:56:30 -08001762 if (!config_tcache) {
Jason Evansf4086432017-01-19 18:15:45 -08001763 return ENOENT;
Jason Evansc4c25922017-01-15 16:56:30 -08001764 }
Jason Evans1cb181e2015-01-29 15:30:47 -08001765
Jason Evans1cb181e2015-01-29 15:30:47 -08001766 WRITEONLY();
1767 tcache_ind = UINT_MAX;
1768 WRITE(tcache_ind, unsigned);
1769 if (tcache_ind == UINT_MAX) {
1770 ret = EFAULT;
1771 goto label_return;
1772 }
1773 tcaches_destroy(tsd, tcache_ind);
1774
1775 ret = 0;
1776label_return:
Jason Evansf4086432017-01-19 18:15:45 -08001777 return ret;
Jason Evans1cb181e2015-01-29 15:30:47 -08001778}
1779
1780/******************************************************************************/
1781
Jason Evansdc2125c2017-01-04 10:21:53 -08001782static int
1783arena_i_initialized_ctl(tsd_t *tsd, const size_t *mib, size_t miblen,
Jason Evansc4c25922017-01-15 16:56:30 -08001784 void *oldp, size_t *oldlenp, void *newp, size_t newlen) {
Jason Evansdc2125c2017-01-04 10:21:53 -08001785 int ret;
1786 tsdn_t *tsdn = tsd_tsdn(tsd);
1787 unsigned arena_ind;
1788 bool initialized;
1789
1790 READONLY();
1791 MIB_UNSIGNED(arena_ind, 1);
1792
1793 malloc_mutex_lock(tsdn, &ctl_mtx);
Jason Evans9eb1b1c2017-01-18 23:03:37 -08001794 initialized = arenas_i(arena_ind)->initialized;
Jason Evansdc2125c2017-01-04 10:21:53 -08001795 malloc_mutex_unlock(tsdn, &ctl_mtx);
1796
1797 READ(initialized, bool);
1798
1799 ret = 0;
1800label_return:
Jason Evansf4086432017-01-19 18:15:45 -08001801 return ret;
Jason Evansdc2125c2017-01-04 10:21:53 -08001802}
1803
Jason Evans34457f52012-11-03 21:18:28 -07001804static void
Jason Evans64e458f2017-03-08 22:42:57 -08001805arena_i_decay(tsdn_t *tsdn, unsigned arena_ind, bool all) {
Jason Evansc1e00ef2016-05-10 22:21:10 -07001806 malloc_mutex_lock(tsdn, &ctl_mtx);
Jason Evans243f7a02016-02-19 20:09:31 -08001807 {
Jason Evans9eb1b1c2017-01-18 23:03:37 -08001808 unsigned narenas = ctl_arenas->narenas;
Jason Evans609ae592012-10-11 13:53:15 -07001809
Jason Evans3dc4e832017-01-03 07:27:42 -08001810 /*
1811 * Access via index narenas is deprecated, and scheduled for
1812 * removal in 6.0.0.
1813 */
1814 if (arena_ind == MALLCTL_ARENAS_ALL || arena_ind == narenas) {
Jason Evans243f7a02016-02-19 20:09:31 -08001815 unsigned i;
Jason Evans243f7a02016-02-19 20:09:31 -08001816 VARIABLE_ARRAY(arena_t *, tarenas, narenas);
1817
Jason Evansc4c25922017-01-15 16:56:30 -08001818 for (i = 0; i < narenas; i++) {
Jason Evansc1e00ef2016-05-10 22:21:10 -07001819 tarenas[i] = arena_get(tsdn, i, false);
Jason Evansc4c25922017-01-15 16:56:30 -08001820 }
Jason Evans243f7a02016-02-19 20:09:31 -08001821
1822 /*
1823 * No further need to hold ctl_mtx, since narenas and
1824 * tarenas contain everything needed below.
1825 */
Jason Evansc1e00ef2016-05-10 22:21:10 -07001826 malloc_mutex_unlock(tsdn, &ctl_mtx);
Jason Evans243f7a02016-02-19 20:09:31 -08001827
1828 for (i = 0; i < narenas; i++) {
Jason Evansc4c25922017-01-15 16:56:30 -08001829 if (tarenas[i] != NULL) {
Jason Evans64e458f2017-03-08 22:42:57 -08001830 arena_decay(tsdn, tarenas[i], all);
Jason Evansc4c25922017-01-15 16:56:30 -08001831 }
Jason Evans243f7a02016-02-19 20:09:31 -08001832 }
1833 } else {
1834 arena_t *tarena;
1835
1836 assert(arena_ind < narenas);
1837
Jason Evansc1e00ef2016-05-10 22:21:10 -07001838 tarena = arena_get(tsdn, arena_ind, false);
Jason Evans243f7a02016-02-19 20:09:31 -08001839
1840 /* No further need to hold ctl_mtx. */
Jason Evansc1e00ef2016-05-10 22:21:10 -07001841 malloc_mutex_unlock(tsdn, &ctl_mtx);
Jason Evans243f7a02016-02-19 20:09:31 -08001842
Jason Evansc4c25922017-01-15 16:56:30 -08001843 if (tarena != NULL) {
Jason Evans64e458f2017-03-08 22:42:57 -08001844 arena_decay(tsdn, tarena, all);
Jason Evansc4c25922017-01-15 16:56:30 -08001845 }
Jason Evans609ae592012-10-11 13:53:15 -07001846 }
1847 }
Jason Evans609ae592012-10-11 13:53:15 -07001848}
1849
1850static int
Jason Evansb2c0d632016-04-13 23:36:15 -07001851arena_i_decay_ctl(tsd_t *tsd, const size_t *mib, size_t miblen, void *oldp,
Jason Evansc4c25922017-01-15 16:56:30 -08001852 size_t *oldlenp, void *newp, size_t newlen) {
Jason Evans243f7a02016-02-19 20:09:31 -08001853 int ret;
Jason Evans6edbedd2017-01-04 07:51:49 -08001854 unsigned arena_ind;
Jason Evans243f7a02016-02-19 20:09:31 -08001855
1856 READONLY();
1857 WRITEONLY();
Jason Evans6edbedd2017-01-04 07:51:49 -08001858 MIB_UNSIGNED(arena_ind, 1);
Jason Evans64e458f2017-03-08 22:42:57 -08001859 arena_i_decay(tsd_tsdn(tsd), arena_ind, false);
1860
1861 ret = 0;
1862label_return:
1863 return ret;
1864}
1865
1866static int
1867arena_i_purge_ctl(tsd_t *tsd, const size_t *mib, size_t miblen, void *oldp,
1868 size_t *oldlenp, void *newp, size_t newlen) {
1869 int ret;
1870 unsigned arena_ind;
1871
1872 READONLY();
1873 WRITEONLY();
1874 MIB_UNSIGNED(arena_ind, 1);
1875 arena_i_decay(tsd_tsdn(tsd), arena_ind, true);
Jason Evans609ae592012-10-11 13:53:15 -07001876
Jason Evans34457f52012-11-03 21:18:28 -07001877 ret = 0;
Jason Evans609ae592012-10-11 13:53:15 -07001878label_return:
Jason Evansf4086432017-01-19 18:15:45 -08001879 return ret;
Jason Evans609ae592012-10-11 13:53:15 -07001880}
1881
1882static int
Jason Evansedf1baf2017-01-03 17:21:59 -08001883arena_i_reset_destroy_helper(tsd_t *tsd, const size_t *mib, size_t miblen,
1884 void *oldp, size_t *oldlenp, void *newp, size_t newlen, unsigned *arena_ind,
Jason Evansc4c25922017-01-15 16:56:30 -08001885 arena_t **arena) {
Jason Evansedf1baf2017-01-03 17:21:59 -08001886 int ret;
1887
1888 READONLY();
1889 WRITEONLY();
1890 MIB_UNSIGNED(*arena_ind, 1);
1891
1892 if (*arena_ind < narenas_auto) {
1893 ret = EFAULT;
1894 goto label_return;
1895 }
1896
1897 *arena = arena_get(tsd_tsdn(tsd), *arena_ind, false);
1898 if (*arena == NULL) {
1899 ret = EFAULT;
1900 goto label_return;
1901 }
1902
1903 ret = 0;
1904label_return:
Jason Evansf4086432017-01-19 18:15:45 -08001905 return ret;
Jason Evansedf1baf2017-01-03 17:21:59 -08001906}
1907
1908static int
Jason Evans19ff2ce2016-04-22 14:37:17 -07001909arena_i_reset_ctl(tsd_t *tsd, const size_t *mib, size_t miblen, void *oldp,
Jason Evansc4c25922017-01-15 16:56:30 -08001910 size_t *oldlenp, void *newp, size_t newlen) {
Jason Evans19ff2ce2016-04-22 14:37:17 -07001911 int ret;
1912 unsigned arena_ind;
1913 arena_t *arena;
1914
Jason Evansedf1baf2017-01-03 17:21:59 -08001915 ret = arena_i_reset_destroy_helper(tsd, mib, miblen, oldp, oldlenp,
1916 newp, newlen, &arena_ind, &arena);
Jason Evansc4c25922017-01-15 16:56:30 -08001917 if (ret != 0) {
Jason Evansf4086432017-01-19 18:15:45 -08001918 return ret;
Jason Evansc4c25922017-01-15 16:56:30 -08001919 }
Jason Evans19ff2ce2016-04-22 14:37:17 -07001920
Jason Evansedf1baf2017-01-03 17:21:59 -08001921 arena_reset(tsd, arena);
Jason Evans19ff2ce2016-04-22 14:37:17 -07001922
Jason Evansf4086432017-01-19 18:15:45 -08001923 return ret;
Jason Evansedf1baf2017-01-03 17:21:59 -08001924}
1925
1926static int
1927arena_i_destroy_ctl(tsd_t *tsd, const size_t *mib, size_t miblen, void *oldp,
Jason Evansc4c25922017-01-15 16:56:30 -08001928 size_t *oldlenp, void *newp, size_t newlen) {
Jason Evansedf1baf2017-01-03 17:21:59 -08001929 int ret;
1930 unsigned arena_ind;
1931 arena_t *arena;
Jason Evans9eb1b1c2017-01-18 23:03:37 -08001932 ctl_arena_t *ctl_darena, *ctl_arena;
Jason Evansedf1baf2017-01-03 17:21:59 -08001933
1934 ret = arena_i_reset_destroy_helper(tsd, mib, miblen, oldp, oldlenp,
1935 newp, newlen, &arena_ind, &arena);
Jason Evansc4c25922017-01-15 16:56:30 -08001936 if (ret != 0) {
Jason Evansedf1baf2017-01-03 17:21:59 -08001937 goto label_return;
Jason Evansc4c25922017-01-15 16:56:30 -08001938 }
Jason Evansedf1baf2017-01-03 17:21:59 -08001939
1940 if (arena_nthreads_get(arena, false) != 0 || arena_nthreads_get(arena,
1941 true) != 0) {
Jason Evans3dc4e832017-01-03 07:27:42 -08001942 ret = EFAULT;
1943 goto label_return;
1944 }
Jason Evans19ff2ce2016-04-22 14:37:17 -07001945
Jason Evansedf1baf2017-01-03 17:21:59 -08001946 /* Merge stats after resetting and purging arena. */
Jason Evans19ff2ce2016-04-22 14:37:17 -07001947 arena_reset(tsd, arena);
Jason Evans64e458f2017-03-08 22:42:57 -08001948 arena_decay(tsd_tsdn(tsd), arena, true);
Jason Evans9eb1b1c2017-01-18 23:03:37 -08001949 ctl_darena = arenas_i(MALLCTL_ARENAS_DESTROYED);
1950 ctl_darena->initialized = true;
1951 ctl_arena_refresh(tsd_tsdn(tsd), arena, ctl_darena, arena_ind, true);
Jason Evansedf1baf2017-01-03 17:21:59 -08001952 /* Destroy arena. */
1953 arena_destroy(tsd, arena);
Jason Evans9eb1b1c2017-01-18 23:03:37 -08001954 ctl_arena = arenas_i(arena_ind);
1955 ctl_arena->initialized = false;
Jason Evansedf1baf2017-01-03 17:21:59 -08001956 /* Record arena index for later recycling via arenas.create. */
Jason Evans9eb1b1c2017-01-18 23:03:37 -08001957 ql_elm_new(ctl_arena, destroyed_link);
1958 ql_tail_insert(&ctl_arenas->destroyed, ctl_arena, destroyed_link);
Jason Evans19ff2ce2016-04-22 14:37:17 -07001959
Jason Evansedf1baf2017-01-03 17:21:59 -08001960 assert(ret == 0);
Jason Evans19ff2ce2016-04-22 14:37:17 -07001961label_return:
Jason Evansf4086432017-01-19 18:15:45 -08001962 return ret;
Jason Evans19ff2ce2016-04-22 14:37:17 -07001963}
1964
1965static int
Jason Evansb2c0d632016-04-13 23:36:15 -07001966arena_i_dss_ctl(tsd_t *tsd, const size_t *mib, size_t miblen, void *oldp,
Jason Evansc4c25922017-01-15 16:56:30 -08001967 size_t *oldlenp, void *newp, size_t newlen) {
Jason Evans586c8ed2014-08-15 12:20:20 -07001968 int ret;
1969 const char *dss = NULL;
Jason Evans6edbedd2017-01-04 07:51:49 -08001970 unsigned arena_ind;
Jason Evans609ae592012-10-11 13:53:15 -07001971 dss_prec_t dss_prec_old = dss_prec_limit;
1972 dss_prec_t dss_prec = dss_prec_limit;
1973
Jason Evansc1e00ef2016-05-10 22:21:10 -07001974 malloc_mutex_lock(tsd_tsdn(tsd), &ctl_mtx);
Jason Evans609ae592012-10-11 13:53:15 -07001975 WRITE(dss, const char *);
Jason Evans6edbedd2017-01-04 07:51:49 -08001976 MIB_UNSIGNED(arena_ind, 1);
Jason Evans586c8ed2014-08-15 12:20:20 -07001977 if (dss != NULL) {
1978 int i;
1979 bool match = false;
1980
1981 for (i = 0; i < dss_prec_limit; i++) {
1982 if (strcmp(dss_prec_names[i], dss) == 0) {
1983 dss_prec = i;
1984 match = true;
1985 break;
1986 }
Jason Evans609ae592012-10-11 13:53:15 -07001987 }
Jason Evans586c8ed2014-08-15 12:20:20 -07001988
Jason Evans551ebc42014-10-03 10:16:09 -07001989 if (!match) {
Jason Evans586c8ed2014-08-15 12:20:20 -07001990 ret = EINVAL;
1991 goto label_return;
1992 }
Jason Evans609ae592012-10-11 13:53:15 -07001993 }
1994
Jason Evans3dc4e832017-01-03 07:27:42 -08001995 /*
1996 * Access via index narenas is deprecated, and scheduled for removal in
1997 * 6.0.0.
1998 */
Jason Evansd778dd22017-01-03 12:40:54 -08001999 if (arena_ind == MALLCTL_ARENAS_ALL || arena_ind ==
Jason Evans9eb1b1c2017-01-18 23:03:37 -08002000 ctl_arenas->narenas) {
Jason Evans3dc4e832017-01-03 07:27:42 -08002001 if (dss_prec != dss_prec_limit &&
2002 extent_dss_prec_set(dss_prec)) {
2003 ret = EFAULT;
2004 goto label_return;
2005 }
2006 dss_prec_old = extent_dss_prec_get();
2007 } else {
Jason Evansc1e00ef2016-05-10 22:21:10 -07002008 arena_t *arena = arena_get(tsd_tsdn(tsd), arena_ind, false);
Jason Evans586c8ed2014-08-15 12:20:20 -07002009 if (arena == NULL || (dss_prec != dss_prec_limit &&
Jason Evansb7795222017-02-12 16:34:36 -08002010 arena_dss_prec_set(arena, dss_prec))) {
Jason Evans586c8ed2014-08-15 12:20:20 -07002011 ret = EFAULT;
2012 goto label_return;
2013 }
Jason Evansb7795222017-02-12 16:34:36 -08002014 dss_prec_old = arena_dss_prec_get(arena);
Jason Evans609ae592012-10-11 13:53:15 -07002015 }
Jason Evans586c8ed2014-08-15 12:20:20 -07002016
Jason Evans609ae592012-10-11 13:53:15 -07002017 dss = dss_prec_names[dss_prec_old];
2018 READ(dss, const char *);
Jason Evans609ae592012-10-11 13:53:15 -07002019
2020 ret = 0;
2021label_return:
Jason Evansc1e00ef2016-05-10 22:21:10 -07002022 malloc_mutex_unlock(tsd_tsdn(tsd), &ctl_mtx);
Jason Evansf4086432017-01-19 18:15:45 -08002023 return ret;
Jason Evans609ae592012-10-11 13:53:15 -07002024}
2025
aravindfb7fe502014-05-05 15:16:56 -07002026static int
Jason Evans64e458f2017-03-08 22:42:57 -08002027arena_i_decay_time_ctl_impl(tsd_t *tsd, const size_t *mib, size_t miblen,
2028 void *oldp, size_t *oldlenp, void *newp, size_t newlen, bool dirty) {
Jason Evans243f7a02016-02-19 20:09:31 -08002029 int ret;
Jason Evans6edbedd2017-01-04 07:51:49 -08002030 unsigned arena_ind;
Jason Evans243f7a02016-02-19 20:09:31 -08002031 arena_t *arena;
2032
Jason Evans6edbedd2017-01-04 07:51:49 -08002033 MIB_UNSIGNED(arena_ind, 1);
Jason Evansc1e00ef2016-05-10 22:21:10 -07002034 arena = arena_get(tsd_tsdn(tsd), arena_ind, false);
Jason Evans243f7a02016-02-19 20:09:31 -08002035 if (arena == NULL) {
2036 ret = EFAULT;
2037 goto label_return;
2038 }
2039
2040 if (oldp != NULL && oldlenp != NULL) {
Jason Evans64e458f2017-03-08 22:42:57 -08002041 size_t oldval = dirty ? arena_dirty_decay_time_get(arena) :
2042 arena_muzzy_decay_time_get(arena);
Jason Evans243f7a02016-02-19 20:09:31 -08002043 READ(oldval, ssize_t);
2044 }
2045 if (newp != NULL) {
2046 if (newlen != sizeof(ssize_t)) {
2047 ret = EINVAL;
2048 goto label_return;
2049 }
Jason Evans64e458f2017-03-08 22:42:57 -08002050 if (dirty ? arena_dirty_decay_time_set(tsd_tsdn(tsd), arena,
2051 *(ssize_t *)newp) :
2052 arena_muzzy_decay_time_set(tsd_tsdn(tsd), arena,
Jason Evansc1e00ef2016-05-10 22:21:10 -07002053 *(ssize_t *)newp)) {
Jason Evans243f7a02016-02-19 20:09:31 -08002054 ret = EFAULT;
2055 goto label_return;
2056 }
2057 }
2058
2059 ret = 0;
2060label_return:
Jason Evansf4086432017-01-19 18:15:45 -08002061 return ret;
Jason Evans243f7a02016-02-19 20:09:31 -08002062}
2063
2064static int
Jason Evans64e458f2017-03-08 22:42:57 -08002065arena_i_dirty_decay_time_ctl(tsd_t *tsd, const size_t *mib, size_t miblen,
2066 void *oldp, size_t *oldlenp, void *newp, size_t newlen) {
2067 return arena_i_decay_time_ctl_impl(tsd, mib, miblen, oldp, oldlenp,
2068 newp, newlen, true);
2069}
2070
2071static int
2072arena_i_muzzy_decay_time_ctl(tsd_t *tsd, const size_t *mib, size_t miblen,
2073 void *oldp, size_t *oldlenp, void *newp, size_t newlen) {
2074 return arena_i_decay_time_ctl_impl(tsd, mib, miblen, oldp, oldlenp,
2075 newp, newlen, false);
2076}
2077
2078static int
Jason Evans9c305c92016-05-31 15:03:51 -07002079arena_i_extent_hooks_ctl(tsd_t *tsd, const size_t *mib, size_t miblen,
Jason Evansc4c25922017-01-15 16:56:30 -08002080 void *oldp, size_t *oldlenp, void *newp, size_t newlen) {
Jason Evansb49a3342015-07-28 11:28:19 -04002081 int ret;
Jason Evans6edbedd2017-01-04 07:51:49 -08002082 unsigned arena_ind;
Jason Evansb49a3342015-07-28 11:28:19 -04002083 arena_t *arena;
2084
Jason Evansc1e00ef2016-05-10 22:21:10 -07002085 malloc_mutex_lock(tsd_tsdn(tsd), &ctl_mtx);
Jason Evans6edbedd2017-01-04 07:51:49 -08002086 MIB_UNSIGNED(arena_ind, 1);
Jason Evansb49a3342015-07-28 11:28:19 -04002087 if (arena_ind < narenas_total_get() && (arena =
Jason Evansc1e00ef2016-05-10 22:21:10 -07002088 arena_get(tsd_tsdn(tsd), arena_ind, false)) != NULL) {
Jason Evansb49a3342015-07-28 11:28:19 -04002089 if (newp != NULL) {
Jason Evansf02fec82016-06-03 19:39:14 -07002090 extent_hooks_t *old_extent_hooks;
2091 extent_hooks_t *new_extent_hooks
2092 JEMALLOC_CC_SILENCE_INIT(NULL);
Jason Evansf8f05422016-06-03 12:05:53 -07002093 WRITE(new_extent_hooks, extent_hooks_t *);
2094 old_extent_hooks = extent_hooks_set(arena,
2095 new_extent_hooks);
2096 READ(old_extent_hooks, extent_hooks_t *);
Jason Evansb49a3342015-07-28 11:28:19 -04002097 } else {
Jason Evansf8f05422016-06-03 12:05:53 -07002098 extent_hooks_t *old_extent_hooks =
2099 extent_hooks_get(arena);
2100 READ(old_extent_hooks, extent_hooks_t *);
Jason Evansb49a3342015-07-28 11:28:19 -04002101 }
2102 } else {
2103 ret = EFAULT;
2104 goto label_return;
2105 }
2106 ret = 0;
2107label_return:
Jason Evansc1e00ef2016-05-10 22:21:10 -07002108 malloc_mutex_unlock(tsd_tsdn(tsd), &ctl_mtx);
Jason Evansf4086432017-01-19 18:15:45 -08002109 return ret;
aravindfb7fe502014-05-05 15:16:56 -07002110}
2111
Jason Evans609ae592012-10-11 13:53:15 -07002112static const ctl_named_node_t *
Jason Evansc4c25922017-01-15 16:56:30 -08002113arena_i_index(tsdn_t *tsdn, const size_t *mib, size_t miblen, size_t i) {
Jason Evansb2c0d632016-04-13 23:36:15 -07002114 const ctl_named_node_t *ret;
Jason Evans609ae592012-10-11 13:53:15 -07002115
Jason Evansc1e00ef2016-05-10 22:21:10 -07002116 malloc_mutex_lock(tsdn, &ctl_mtx);
Jason Evansedf1baf2017-01-03 17:21:59 -08002117 switch (i) {
2118 case MALLCTL_ARENAS_ALL:
2119 case MALLCTL_ARENAS_DESTROYED:
2120 break;
2121 default:
Jason Evans9eb1b1c2017-01-18 23:03:37 -08002122 if (i > ctl_arenas->narenas) {
Jason Evansedf1baf2017-01-03 17:21:59 -08002123 ret = NULL;
2124 goto label_return;
2125 }
2126 break;
Jason Evans609ae592012-10-11 13:53:15 -07002127 }
2128
2129 ret = super_arena_i_node;
2130label_return:
Jason Evansc1e00ef2016-05-10 22:21:10 -07002131 malloc_mutex_unlock(tsdn, &ctl_mtx);
Jason Evansf4086432017-01-19 18:15:45 -08002132 return ret;
Jason Evans609ae592012-10-11 13:53:15 -07002133}
2134
Jason Evans609ae592012-10-11 13:53:15 -07002135/******************************************************************************/
2136
Jason Evans609ae592012-10-11 13:53:15 -07002137static int
Jason Evansb2c0d632016-04-13 23:36:15 -07002138arenas_narenas_ctl(tsd_t *tsd, const size_t *mib, size_t miblen, void *oldp,
Jason Evansc4c25922017-01-15 16:56:30 -08002139 size_t *oldlenp, void *newp, size_t newlen) {
Jason Evans609ae592012-10-11 13:53:15 -07002140 int ret;
2141 unsigned narenas;
2142
Jason Evansc1e00ef2016-05-10 22:21:10 -07002143 malloc_mutex_lock(tsd_tsdn(tsd), &ctl_mtx);
Jason Evans609ae592012-10-11 13:53:15 -07002144 READONLY();
2145 if (*oldlenp != sizeof(unsigned)) {
2146 ret = EINVAL;
2147 goto label_return;
2148 }
Jason Evans9eb1b1c2017-01-18 23:03:37 -08002149 narenas = ctl_arenas->narenas;
Jason Evans609ae592012-10-11 13:53:15 -07002150 READ(narenas, unsigned);
2151
2152 ret = 0;
2153label_return:
Jason Evansc1e00ef2016-05-10 22:21:10 -07002154 malloc_mutex_unlock(tsd_tsdn(tsd), &ctl_mtx);
Jason Evansf4086432017-01-19 18:15:45 -08002155 return ret;
Jason Evans609ae592012-10-11 13:53:15 -07002156}
Jason Evans3c234352010-01-27 13:10:55 -08002157
2158static int
Jason Evans64e458f2017-03-08 22:42:57 -08002159arenas_decay_time_ctl_impl(tsd_t *tsd, const size_t *mib, size_t miblen,
2160 void *oldp, size_t *oldlenp, void *newp, size_t newlen, bool dirty) {
Jason Evans243f7a02016-02-19 20:09:31 -08002161 int ret;
2162
2163 if (oldp != NULL && oldlenp != NULL) {
Jason Evans64e458f2017-03-08 22:42:57 -08002164 size_t oldval = (dirty ? arena_dirty_decay_time_default_get() :
2165 arena_muzzy_decay_time_default_get());
Jason Evans243f7a02016-02-19 20:09:31 -08002166 READ(oldval, ssize_t);
2167 }
2168 if (newp != NULL) {
2169 if (newlen != sizeof(ssize_t)) {
2170 ret = EINVAL;
2171 goto label_return;
2172 }
Jason Evans64e458f2017-03-08 22:42:57 -08002173 if (dirty ? arena_dirty_decay_time_default_set(*(ssize_t *)newp)
2174 : arena_muzzy_decay_time_default_set(*(ssize_t *)newp)) {
Jason Evans243f7a02016-02-19 20:09:31 -08002175 ret = EFAULT;
2176 goto label_return;
2177 }
2178 }
2179
2180 ret = 0;
2181label_return:
Jason Evansf4086432017-01-19 18:15:45 -08002182 return ret;
Jason Evans243f7a02016-02-19 20:09:31 -08002183}
2184
Jason Evans64e458f2017-03-08 22:42:57 -08002185static int
2186arenas_dirty_decay_time_ctl(tsd_t *tsd, const size_t *mib, size_t miblen,
2187 void *oldp, size_t *oldlenp, void *newp, size_t newlen) {
2188 return arenas_decay_time_ctl_impl(tsd, mib, miblen, oldp, oldlenp, newp,
2189 newlen, true);
2190}
2191
2192static int
2193arenas_muzzy_decay_time_ctl(tsd_t *tsd, const size_t *mib, size_t miblen,
2194 void *oldp, size_t *oldlenp, void *newp, size_t newlen) {
2195 return arenas_decay_time_ctl_impl(tsd, mib, miblen, oldp, oldlenp, newp,
2196 newlen, false);
2197}
2198
Jason Evansfc4dcfa2010-11-24 15:44:21 -08002199CTL_RO_NL_GEN(arenas_quantum, QUANTUM, size_t)
Jason Evansae4c7b42012-04-02 07:04:34 -07002200CTL_RO_NL_GEN(arenas_page, PAGE, size_t)
Jason Evans7372b152012-02-10 20:22:09 -08002201CTL_RO_NL_CGEN(config_tcache, arenas_tcache_max, tcache_maxclass, size_t)
Jason Evansb1726102012-02-28 16:50:47 -08002202CTL_RO_NL_GEN(arenas_nbins, NBINS, unsigned)
Jason Evans7372b152012-02-10 20:22:09 -08002203CTL_RO_NL_CGEN(config_tcache, arenas_nhbins, nhbins, unsigned)
Jason Evansd8a39002013-12-19 21:40:41 -08002204CTL_RO_NL_GEN(arenas_bin_i_size, arena_bin_info[mib[2]].reg_size, size_t)
2205CTL_RO_NL_GEN(arenas_bin_i_nregs, arena_bin_info[mib[2]].nregs, uint32_t)
Jason Evans498856f2016-05-29 18:34:50 -07002206CTL_RO_NL_GEN(arenas_bin_i_slab_size, arena_bin_info[mib[2]].slab_size, size_t)
Jason Evansd8a39002013-12-19 21:40:41 -08002207static const ctl_named_node_t *
Jason Evansc4c25922017-01-15 16:56:30 -08002208arenas_bin_i_index(tsdn_t *tsdn, const size_t *mib, size_t miblen, size_t i) {
2209 if (i > NBINS) {
Jason Evansf4086432017-01-19 18:15:45 -08002210 return NULL;
Jason Evansc4c25922017-01-15 16:56:30 -08002211 }
Jason Evansf4086432017-01-19 18:15:45 -08002212 return super_arenas_bin_i_node;
Jason Evansd8a39002013-12-19 21:40:41 -08002213}
2214
Jason Evans7d63fed2016-05-31 14:50:21 -07002215CTL_RO_NL_GEN(arenas_nlextents, NSIZES - NBINS, unsigned)
2216CTL_RO_NL_GEN(arenas_lextent_i_size, index2size(NBINS+(szind_t)mib[2]), size_t)
Jason Evans3c4d92e2014-10-12 22:53:59 -07002217static const ctl_named_node_t *
Jason Evansc4c25922017-01-15 16:56:30 -08002218arenas_lextent_i_index(tsdn_t *tsdn, const size_t *mib, size_t miblen,
2219 size_t i) {
2220 if (i > NSIZES - NBINS) {
Jason Evansf4086432017-01-19 18:15:45 -08002221 return NULL;
Jason Evansc4c25922017-01-15 16:56:30 -08002222 }
Jason Evansf4086432017-01-19 18:15:45 -08002223 return super_arenas_lextent_i_node;
Jason Evans3c4d92e2014-10-12 22:53:59 -07002224}
2225
Jason Evans6005f072010-09-30 16:55:08 -07002226static int
Jason Evans0f04bb12017-01-03 08:21:29 -08002227arenas_create_ctl(tsd_t *tsd, const size_t *mib, size_t miblen, void *oldp,
Jason Evansc4c25922017-01-15 16:56:30 -08002228 size_t *oldlenp, void *newp, size_t newlen) {
Jason Evans609ae592012-10-11 13:53:15 -07002229 int ret;
Jason Evansa0dd3a42016-12-22 16:39:10 -06002230 extent_hooks_t *extent_hooks;
Jason Evansedf1baf2017-01-03 17:21:59 -08002231 unsigned arena_ind;
Jason Evans609ae592012-10-11 13:53:15 -07002232
Jason Evansc1e00ef2016-05-10 22:21:10 -07002233 malloc_mutex_lock(tsd_tsdn(tsd), &ctl_mtx);
Jason Evansa0dd3a42016-12-22 16:39:10 -06002234
2235 extent_hooks = (extent_hooks_t *)&extent_hooks_default;
2236 WRITE(extent_hooks, extent_hooks_t *);
Jason Evansedf1baf2017-01-03 17:21:59 -08002237 if ((arena_ind = ctl_arena_init(tsd_tsdn(tsd), extent_hooks)) ==
2238 UINT_MAX) {
Jason Evans609ae592012-10-11 13:53:15 -07002239 ret = EAGAIN;
2240 goto label_return;
2241 }
Jason Evansedf1baf2017-01-03 17:21:59 -08002242 READ(arena_ind, unsigned);
Jason Evans609ae592012-10-11 13:53:15 -07002243
Jason Evans6005f072010-09-30 16:55:08 -07002244 ret = 0;
Jason Evansa1ee7832012-04-10 15:07:44 -07002245label_return:
Jason Evansc1e00ef2016-05-10 22:21:10 -07002246 malloc_mutex_unlock(tsd_tsdn(tsd), &ctl_mtx);
Jason Evansf4086432017-01-19 18:15:45 -08002247 return ret;
Jason Evans6005f072010-09-30 16:55:08 -07002248}
2249
Jason Evans3c234352010-01-27 13:10:55 -08002250/******************************************************************************/
2251
Jason Evansd34f9e72010-02-11 13:19:21 -08002252static int
Jason Evansb2c0d632016-04-13 23:36:15 -07002253prof_thread_active_init_ctl(tsd_t *tsd, const size_t *mib, size_t miblen,
Jason Evansc4c25922017-01-15 16:56:30 -08002254 void *oldp, size_t *oldlenp, void *newp, size_t newlen) {
Jason Evansb2c0d632016-04-13 23:36:15 -07002255 int ret;
2256 bool oldval;
2257
Jason Evansc4c25922017-01-15 16:56:30 -08002258 if (!config_prof) {
Jason Evansf4086432017-01-19 18:15:45 -08002259 return ENOENT;
Jason Evansc4c25922017-01-15 16:56:30 -08002260 }
Jason Evansb2c0d632016-04-13 23:36:15 -07002261
2262 if (newp != NULL) {
2263 if (newlen != sizeof(bool)) {
2264 ret = EINVAL;
2265 goto label_return;
2266 }
Jason Evansc1e00ef2016-05-10 22:21:10 -07002267 oldval = prof_thread_active_init_set(tsd_tsdn(tsd),
2268 *(bool *)newp);
Jason Evansc4c25922017-01-15 16:56:30 -08002269 } else {
Jason Evansc1e00ef2016-05-10 22:21:10 -07002270 oldval = prof_thread_active_init_get(tsd_tsdn(tsd));
Jason Evansc4c25922017-01-15 16:56:30 -08002271 }
Jason Evansb2c0d632016-04-13 23:36:15 -07002272 READ(oldval, bool);
2273
2274 ret = 0;
2275label_return:
Jason Evansf4086432017-01-19 18:15:45 -08002276 return ret;
Jason Evansb2c0d632016-04-13 23:36:15 -07002277}
2278
2279static int
2280prof_active_ctl(tsd_t *tsd, const size_t *mib, size_t miblen, void *oldp,
Jason Evansc4c25922017-01-15 16:56:30 -08002281 size_t *oldlenp, void *newp, size_t newlen) {
Jason Evansfc12c0b2014-10-03 23:25:30 -07002282 int ret;
2283 bool oldval;
2284
Jason Evansc4c25922017-01-15 16:56:30 -08002285 if (!config_prof) {
Jason Evansf4086432017-01-19 18:15:45 -08002286 return ENOENT;
Jason Evansc4c25922017-01-15 16:56:30 -08002287 }
Jason Evansfc12c0b2014-10-03 23:25:30 -07002288
2289 if (newp != NULL) {
2290 if (newlen != sizeof(bool)) {
2291 ret = EINVAL;
2292 goto label_return;
2293 }
Jason Evansc1e00ef2016-05-10 22:21:10 -07002294 oldval = prof_active_set(tsd_tsdn(tsd), *(bool *)newp);
Jason Evansc4c25922017-01-15 16:56:30 -08002295 } else {
Jason Evansc1e00ef2016-05-10 22:21:10 -07002296 oldval = prof_active_get(tsd_tsdn(tsd));
Jason Evansc4c25922017-01-15 16:56:30 -08002297 }
Jason Evansfc12c0b2014-10-03 23:25:30 -07002298 READ(oldval, bool);
2299
2300 ret = 0;
2301label_return:
Jason Evansf4086432017-01-19 18:15:45 -08002302 return ret;
Jason Evansfc12c0b2014-10-03 23:25:30 -07002303}
2304
2305static int
Jason Evansb2c0d632016-04-13 23:36:15 -07002306prof_dump_ctl(tsd_t *tsd, const size_t *mib, size_t miblen, void *oldp,
Jason Evansc4c25922017-01-15 16:56:30 -08002307 size_t *oldlenp, void *newp, size_t newlen) {
Jason Evansd34f9e72010-02-11 13:19:21 -08002308 int ret;
Jason Evans22ca8552010-03-02 11:57:30 -08002309 const char *filename = NULL;
Jason Evansd34f9e72010-02-11 13:19:21 -08002310
Jason Evansc4c25922017-01-15 16:56:30 -08002311 if (!config_prof) {
Jason Evansf4086432017-01-19 18:15:45 -08002312 return ENOENT;
Jason Evansc4c25922017-01-15 16:56:30 -08002313 }
Jason Evans7372b152012-02-10 20:22:09 -08002314
Jason Evans22ca8552010-03-02 11:57:30 -08002315 WRITEONLY();
2316 WRITE(filename, const char *);
Jason Evansd34f9e72010-02-11 13:19:21 -08002317
Jason Evansb2c0d632016-04-13 23:36:15 -07002318 if (prof_mdump(tsd, filename)) {
Jason Evans22ca8552010-03-02 11:57:30 -08002319 ret = EFAULT;
Jason Evansa1ee7832012-04-10 15:07:44 -07002320 goto label_return;
Jason Evans22ca8552010-03-02 11:57:30 -08002321 }
Jason Evansd34f9e72010-02-11 13:19:21 -08002322
2323 ret = 0;
Jason Evansa1ee7832012-04-10 15:07:44 -07002324label_return:
Jason Evansf4086432017-01-19 18:15:45 -08002325 return ret;
Jason Evansd34f9e72010-02-11 13:19:21 -08002326}
2327
Jason Evans602c8e02014-08-18 16:22:13 -07002328static int
Jason Evansb2c0d632016-04-13 23:36:15 -07002329prof_gdump_ctl(tsd_t *tsd, const size_t *mib, size_t miblen, void *oldp,
Jason Evansc4c25922017-01-15 16:56:30 -08002330 size_t *oldlenp, void *newp, size_t newlen) {
Jason Evans5b8ed5b2015-01-25 21:16:57 -08002331 int ret;
2332 bool oldval;
2333
Jason Evansc4c25922017-01-15 16:56:30 -08002334 if (!config_prof) {
Jason Evansf4086432017-01-19 18:15:45 -08002335 return ENOENT;
Jason Evansc4c25922017-01-15 16:56:30 -08002336 }
Jason Evans5b8ed5b2015-01-25 21:16:57 -08002337
2338 if (newp != NULL) {
2339 if (newlen != sizeof(bool)) {
2340 ret = EINVAL;
2341 goto label_return;
2342 }
Jason Evansc1e00ef2016-05-10 22:21:10 -07002343 oldval = prof_gdump_set(tsd_tsdn(tsd), *(bool *)newp);
Jason Evansc4c25922017-01-15 16:56:30 -08002344 } else {
Jason Evansc1e00ef2016-05-10 22:21:10 -07002345 oldval = prof_gdump_get(tsd_tsdn(tsd));
Jason Evansc4c25922017-01-15 16:56:30 -08002346 }
Jason Evans5b8ed5b2015-01-25 21:16:57 -08002347 READ(oldval, bool);
2348
2349 ret = 0;
2350label_return:
Jason Evansf4086432017-01-19 18:15:45 -08002351 return ret;
Jason Evans5b8ed5b2015-01-25 21:16:57 -08002352}
2353
2354static int
Jason Evansb2c0d632016-04-13 23:36:15 -07002355prof_reset_ctl(tsd_t *tsd, const size_t *mib, size_t miblen, void *oldp,
Jason Evansc4c25922017-01-15 16:56:30 -08002356 size_t *oldlenp, void *newp, size_t newlen) {
Jason Evans602c8e02014-08-18 16:22:13 -07002357 int ret;
2358 size_t lg_sample = lg_prof_sample;
2359
Jason Evansc4c25922017-01-15 16:56:30 -08002360 if (!config_prof) {
Jason Evansf4086432017-01-19 18:15:45 -08002361 return ENOENT;
Jason Evansc4c25922017-01-15 16:56:30 -08002362 }
Jason Evans602c8e02014-08-18 16:22:13 -07002363
2364 WRITEONLY();
2365 WRITE(lg_sample, size_t);
Jason Evansc4c25922017-01-15 16:56:30 -08002366 if (lg_sample >= (sizeof(uint64_t) << 3)) {
Jason Evans602c8e02014-08-18 16:22:13 -07002367 lg_sample = (sizeof(uint64_t) << 3) - 1;
Jason Evansc4c25922017-01-15 16:56:30 -08002368 }
Jason Evans602c8e02014-08-18 16:22:13 -07002369
Jason Evansb54d1602016-10-20 23:59:12 -07002370 prof_reset(tsd, lg_sample);
Jason Evans602c8e02014-08-18 16:22:13 -07002371
2372 ret = 0;
2373label_return:
Jason Evansf4086432017-01-19 18:15:45 -08002374 return ret;
Jason Evans602c8e02014-08-18 16:22:13 -07002375}
2376
Jason Evans7372b152012-02-10 20:22:09 -08002377CTL_RO_NL_CGEN(config_prof, prof_interval, prof_interval, uint64_t)
Jason Evans602c8e02014-08-18 16:22:13 -07002378CTL_RO_NL_CGEN(config_prof, lg_prof_sample, lg_prof_sample, size_t)
Jason Evansd34f9e72010-02-11 13:19:21 -08002379
2380/******************************************************************************/
2381
Jason Evansd778dd22017-01-03 12:40:54 -08002382CTL_RO_CGEN(config_stats, stats_allocated, ctl_stats->allocated, size_t)
2383CTL_RO_CGEN(config_stats, stats_active, ctl_stats->active, size_t)
2384CTL_RO_CGEN(config_stats, stats_metadata, ctl_stats->metadata, size_t)
2385CTL_RO_CGEN(config_stats, stats_resident, ctl_stats->resident, size_t)
2386CTL_RO_CGEN(config_stats, stats_mapped, ctl_stats->mapped, size_t)
2387CTL_RO_CGEN(config_stats, stats_retained, ctl_stats->retained, size_t)
Jason Evansd8a39002013-12-19 21:40:41 -08002388
Jason Evans9eb1b1c2017-01-18 23:03:37 -08002389CTL_RO_GEN(stats_arenas_i_dss, arenas_i(mib[2])->dss, const char *)
Jason Evans64e458f2017-03-08 22:42:57 -08002390CTL_RO_GEN(stats_arenas_i_dirty_decay_time, arenas_i(mib[2])->dirty_decay_time,
2391 ssize_t)
2392CTL_RO_GEN(stats_arenas_i_muzzy_decay_time, arenas_i(mib[2])->muzzy_decay_time,
Jason Evans243f7a02016-02-19 20:09:31 -08002393 ssize_t)
Jason Evans9eb1b1c2017-01-18 23:03:37 -08002394CTL_RO_GEN(stats_arenas_i_nthreads, arenas_i(mib[2])->nthreads, unsigned)
2395CTL_RO_GEN(stats_arenas_i_pactive, arenas_i(mib[2])->pactive, size_t)
2396CTL_RO_GEN(stats_arenas_i_pdirty, arenas_i(mib[2])->pdirty, size_t)
Jason Evans64e458f2017-03-08 22:42:57 -08002397CTL_RO_GEN(stats_arenas_i_pmuzzy, arenas_i(mib[2])->pmuzzy, size_t)
Jason Evansd8a39002013-12-19 21:40:41 -08002398CTL_RO_CGEN(config_stats, stats_arenas_i_mapped,
David Goldblattee202ef2017-03-13 16:18:40 -07002399 atomic_load_zu(&arenas_i(mib[2])->astats->astats.mapped, ATOMIC_RELAXED),
2400 size_t)
Jason Evans04c3c0f2016-05-03 22:11:35 -07002401CTL_RO_CGEN(config_stats, stats_arenas_i_retained,
David Goldblattee202ef2017-03-13 16:18:40 -07002402 atomic_load_zu(&arenas_i(mib[2])->astats->astats.retained, ATOMIC_RELAXED),
2403 size_t)
Jason Evans64e458f2017-03-08 22:42:57 -08002404
2405CTL_RO_CGEN(config_stats, stats_arenas_i_dirty_npurge,
2406 arena_stats_read_u64(&arenas_i(mib[2])->astats->astats.decay_dirty.npurge),
2407 uint64_t)
2408CTL_RO_CGEN(config_stats, stats_arenas_i_dirty_nmadvise,
2409 arena_stats_read_u64(
2410 &arenas_i(mib[2])->astats->astats.decay_dirty.nmadvise), uint64_t)
2411CTL_RO_CGEN(config_stats, stats_arenas_i_dirty_purged,
2412 arena_stats_read_u64(&arenas_i(mib[2])->astats->astats.decay_dirty.purged),
2413 uint64_t)
2414
2415CTL_RO_CGEN(config_stats, stats_arenas_i_muzzy_npurge,
2416 arena_stats_read_u64(&arenas_i(mib[2])->astats->astats.decay_muzzy.npurge),
2417 uint64_t)
2418CTL_RO_CGEN(config_stats, stats_arenas_i_muzzy_nmadvise,
2419 arena_stats_read_u64(
2420 &arenas_i(mib[2])->astats->astats.decay_muzzy.nmadvise), uint64_t)
2421CTL_RO_CGEN(config_stats, stats_arenas_i_muzzy_purged,
2422 arena_stats_read_u64(&arenas_i(mib[2])->astats->astats.decay_muzzy.purged),
2423 uint64_t)
2424
Jason Evansa0dd3a42016-12-22 16:39:10 -06002425CTL_RO_CGEN(config_stats, stats_arenas_i_base,
David Goldblattee202ef2017-03-13 16:18:40 -07002426 atomic_load_zu(&arenas_i(mib[2])->astats->astats.base, ATOMIC_RELAXED),
2427 size_t)
Jason Evansa0dd3a42016-12-22 16:39:10 -06002428CTL_RO_CGEN(config_stats, stats_arenas_i_internal,
David Goldblattee202ef2017-03-13 16:18:40 -07002429 atomic_load_zu(&arenas_i(mib[2])->astats->astats.internal, ATOMIC_RELAXED),
2430 size_t)
Qi Wang58424e62016-04-22 18:37:44 -07002431CTL_RO_CGEN(config_stats && config_tcache, stats_arenas_i_tcache_bytes,
David Goldblattee202ef2017-03-13 16:18:40 -07002432 atomic_load_zu(&arenas_i(mib[2])->astats->astats.tcache_bytes,
2433 ATOMIC_RELAXED), size_t)
Jason Evansa0dd3a42016-12-22 16:39:10 -06002434CTL_RO_CGEN(config_stats, stats_arenas_i_resident,
David Goldblattee202ef2017-03-13 16:18:40 -07002435 atomic_load_zu(&arenas_i(mib[2])->astats->astats.resident, ATOMIC_RELAXED),
2436 size_t)
Jason Evansd8a39002013-12-19 21:40:41 -08002437
Jason Evans7372b152012-02-10 20:22:09 -08002438CTL_RO_CGEN(config_stats, stats_arenas_i_small_allocated,
Jason Evans9eb1b1c2017-01-18 23:03:37 -08002439 arenas_i(mib[2])->astats->allocated_small, size_t)
Jason Evans7372b152012-02-10 20:22:09 -08002440CTL_RO_CGEN(config_stats, stats_arenas_i_small_nmalloc,
Jason Evans9eb1b1c2017-01-18 23:03:37 -08002441 arenas_i(mib[2])->astats->nmalloc_small, uint64_t)
Jason Evans7372b152012-02-10 20:22:09 -08002442CTL_RO_CGEN(config_stats, stats_arenas_i_small_ndalloc,
Jason Evans9eb1b1c2017-01-18 23:03:37 -08002443 arenas_i(mib[2])->astats->ndalloc_small, uint64_t)
Jason Evans7372b152012-02-10 20:22:09 -08002444CTL_RO_CGEN(config_stats, stats_arenas_i_small_nrequests,
Jason Evans9eb1b1c2017-01-18 23:03:37 -08002445 arenas_i(mib[2])->astats->nrequests_small, uint64_t)
Jason Evans7d63fed2016-05-31 14:50:21 -07002446CTL_RO_CGEN(config_stats, stats_arenas_i_large_allocated,
David Goldblattee202ef2017-03-13 16:18:40 -07002447 atomic_load_zu(&arenas_i(mib[2])->astats->astats.allocated_large,
2448 ATOMIC_RELAXED), size_t)
Jason Evans7d63fed2016-05-31 14:50:21 -07002449CTL_RO_CGEN(config_stats, stats_arenas_i_large_nmalloc,
David Goldblatt4fc2acf2017-03-08 15:56:31 -08002450 arena_stats_read_u64(&arenas_i(mib[2])->astats->astats.nmalloc_large),
2451 uint64_t)
Jason Evans7d63fed2016-05-31 14:50:21 -07002452CTL_RO_CGEN(config_stats, stats_arenas_i_large_ndalloc,
David Goldblatt4fc2acf2017-03-08 15:56:31 -08002453 arena_stats_read_u64(&arenas_i(mib[2])->astats->astats.ndalloc_large),
2454 uint64_t)
Jason Evans7d63fed2016-05-31 14:50:21 -07002455CTL_RO_CGEN(config_stats, stats_arenas_i_large_nrequests,
David Goldblatt4fc2acf2017-03-08 15:56:31 -08002456 arena_stats_read_u64(&arenas_i(mib[2])->astats->astats.nmalloc_large),
2457 uint64_t) /* Intentional. */
Jason Evans3c234352010-01-27 13:10:55 -08002458
Qi Wang0fb5c0e2017-03-10 12:14:05 -08002459/* Lock profiling related APIs below. */
Qi Wang64c5f5c2017-03-13 17:29:03 -07002460#define RO_MUTEX_CTL_GEN(n, l) \
Qi Wangca9074d2017-03-11 20:28:31 -08002461CTL_RO_CGEN(config_stats, stats_##n##_num_ops, \
2462 l.n_lock_ops, uint64_t) \
2463CTL_RO_CGEN(config_stats, stats_##n##_num_wait, \
2464 l.n_wait_times, uint64_t) \
2465CTL_RO_CGEN(config_stats, stats_##n##_num_spin_acq, \
2466 l.n_spin_acquired, uint64_t) \
2467CTL_RO_CGEN(config_stats, stats_##n##_num_owner_switch, \
2468 l.n_owner_switches, uint64_t) \
2469CTL_RO_CGEN(config_stats, stats_##n##_total_wait_time, \
2470 l.tot_wait_time, uint64_t) \
2471CTL_RO_CGEN(config_stats, stats_##n##_max_wait_time, \
2472 l.max_wait_time, uint64_t) \
2473CTL_RO_CGEN(config_stats, stats_##n##_max_num_thds, \
2474 l.max_n_thds, uint64_t)
Qi Wang0fb5c0e2017-03-10 12:14:05 -08002475
Qi Wang64c5f5c2017-03-13 17:29:03 -07002476/* Global mutexes. */
2477#define MTX(mutex) \
2478 RO_MUTEX_CTL_GEN(mutexes_##mutex, ctl_stats->mutex##_mtx_data)
Qi Wangca9074d2017-03-11 20:28:31 -08002479GLOBAL_PROF_MUTEXES
2480#undef MTX
2481
2482/* arena->bins[j].lock */
Qi Wang64c5f5c2017-03-13 17:29:03 -07002483RO_MUTEX_CTL_GEN(arenas_i_bins_j_mutex,
2484 arenas_i(mib[2])->astats->bstats[mib[4]].mutex_data)
Qi Wangca9074d2017-03-11 20:28:31 -08002485
Qi Wang64c5f5c2017-03-13 17:29:03 -07002486/* Per arena mutexes */
2487#define ARENAS_ASTATS_MUTEX_CTL_GEN(l, d) \
2488 RO_MUTEX_CTL_GEN(arenas_i_mutexes_##l, arenas_i(mib[2])->astats->astats.d)
Qi Wang0fb5c0e2017-03-10 12:14:05 -08002489/* arena->large_mtx */
Qi Wang64c5f5c2017-03-13 17:29:03 -07002490ARENAS_ASTATS_MUTEX_CTL_GEN(large, large_mtx_data)
Qi Wang0fb5c0e2017-03-10 12:14:05 -08002491/* arena->extent_freelist_mtx */
Qi Wang64c5f5c2017-03-13 17:29:03 -07002492ARENAS_ASTATS_MUTEX_CTL_GEN(extent_freelist, extent_freelist_mtx_data)
Qi Wang0fb5c0e2017-03-10 12:14:05 -08002493/* arena->extents_cached.mtx */
Qi Wang64c5f5c2017-03-13 17:29:03 -07002494ARENAS_ASTATS_MUTEX_CTL_GEN(extents_cached, extents_cached_mtx_data)
Qi Wang0fb5c0e2017-03-10 12:14:05 -08002495/* arena->extents_retained.mtx */
Qi Wang64c5f5c2017-03-13 17:29:03 -07002496ARENAS_ASTATS_MUTEX_CTL_GEN(extents_retained, extents_retained_mtx_data)
Qi Wang0fb5c0e2017-03-10 12:14:05 -08002497/* arena->decay.mtx */
Qi Wang64c5f5c2017-03-13 17:29:03 -07002498ARENAS_ASTATS_MUTEX_CTL_GEN(decay, decay_mtx_data)
Qi Wang0fb5c0e2017-03-10 12:14:05 -08002499/* arena->tcache_ql_mtx */
Qi Wang64c5f5c2017-03-13 17:29:03 -07002500ARENAS_ASTATS_MUTEX_CTL_GEN(tcache, tcache_mtx_data)
2501#undef ARENAS_ASTATS_MUTEX_CTL_GEN
2502#undef RO_MUTEX_CTL_GEN
2503
2504/* Resets all mutex stats, including global, arena and bin mutexes. */
2505static int
2506stats_mutexes_reset_ctl(tsd_t *tsd, const size_t *mib, size_t miblen,
2507 void *oldp, size_t *oldlenp, void *newp, size_t newlen) {
2508 if (!config_stats) {
2509 return ENOENT;
2510 }
2511
2512 tsdn_t *tsdn = tsd_tsdn(tsd);
2513
2514#define MUTEX_PROF_RESET(mtx) \
2515 malloc_mutex_lock(tsdn, &mtx); \
2516 malloc_mutex_prof_data_reset(tsdn, &mtx); \
2517 malloc_mutex_unlock(tsdn, &mtx);
2518
2519 /* Global mutexes: base, prof and ctl. */
2520 MUTEX_PROF_RESET(b0get()->mtx);
2521 if (config_prof && opt_prof) {
2522 MUTEX_PROF_RESET(bt2gctx_mtx);
2523 }
2524 MUTEX_PROF_RESET(ctl_mtx);
2525
2526 /* Per arena mutexes. */
2527 unsigned n = narenas_total_get();
2528
2529 for (unsigned i = 0; i < n; i++) {
2530 arena_t *arena = arena_get(tsdn, i, false);
2531 if (!arena) {
2532 continue;
2533 }
2534 MUTEX_PROF_RESET(arena->large_mtx);
2535 MUTEX_PROF_RESET(arena->extent_freelist_mtx);
2536 MUTEX_PROF_RESET(arena->extents_cached.mtx);
2537 MUTEX_PROF_RESET(arena->extents_retained.mtx);
2538 MUTEX_PROF_RESET(arena->decay.mtx);
2539 if (config_tcache) {
2540 MUTEX_PROF_RESET(arena->tcache_ql_mtx);
2541 }
2542
2543 for (szind_t i = 0; i < NBINS; i++) {
2544 arena_bin_t *bin = &arena->bins[i];
2545 MUTEX_PROF_RESET(bin->lock);
2546 }
2547 }
2548#undef MUTEX_PROF_RESET
2549 return 0;
2550}
Qi Wang0fb5c0e2017-03-10 12:14:05 -08002551
Jason Evans7372b152012-02-10 20:22:09 -08002552CTL_RO_CGEN(config_stats, stats_arenas_i_bins_j_nmalloc,
Jason Evans9eb1b1c2017-01-18 23:03:37 -08002553 arenas_i(mib[2])->astats->bstats[mib[4]].nmalloc, uint64_t)
Jason Evans7372b152012-02-10 20:22:09 -08002554CTL_RO_CGEN(config_stats, stats_arenas_i_bins_j_ndalloc,
Jason Evans9eb1b1c2017-01-18 23:03:37 -08002555 arenas_i(mib[2])->astats->bstats[mib[4]].ndalloc, uint64_t)
Jason Evans7372b152012-02-10 20:22:09 -08002556CTL_RO_CGEN(config_stats, stats_arenas_i_bins_j_nrequests,
Jason Evans9eb1b1c2017-01-18 23:03:37 -08002557 arenas_i(mib[2])->astats->bstats[mib[4]].nrequests, uint64_t)
Jason Evans3c4d92e2014-10-12 22:53:59 -07002558CTL_RO_CGEN(config_stats, stats_arenas_i_bins_j_curregs,
Jason Evans9eb1b1c2017-01-18 23:03:37 -08002559 arenas_i(mib[2])->astats->bstats[mib[4]].curregs, size_t)
Jason Evans7372b152012-02-10 20:22:09 -08002560CTL_RO_CGEN(config_stats && config_tcache, stats_arenas_i_bins_j_nfills,
Jason Evans9eb1b1c2017-01-18 23:03:37 -08002561 arenas_i(mib[2])->astats->bstats[mib[4]].nfills, uint64_t)
Jason Evans7372b152012-02-10 20:22:09 -08002562CTL_RO_CGEN(config_stats && config_tcache, stats_arenas_i_bins_j_nflushes,
Jason Evans9eb1b1c2017-01-18 23:03:37 -08002563 arenas_i(mib[2])->astats->bstats[mib[4]].nflushes, uint64_t)
Jason Evans498856f2016-05-29 18:34:50 -07002564CTL_RO_CGEN(config_stats, stats_arenas_i_bins_j_nslabs,
Jason Evans9eb1b1c2017-01-18 23:03:37 -08002565 arenas_i(mib[2])->astats->bstats[mib[4]].nslabs, uint64_t)
Jason Evans498856f2016-05-29 18:34:50 -07002566CTL_RO_CGEN(config_stats, stats_arenas_i_bins_j_nreslabs,
Jason Evans9eb1b1c2017-01-18 23:03:37 -08002567 arenas_i(mib[2])->astats->bstats[mib[4]].reslabs, uint64_t)
Jason Evans498856f2016-05-29 18:34:50 -07002568CTL_RO_CGEN(config_stats, stats_arenas_i_bins_j_curslabs,
Jason Evans9eb1b1c2017-01-18 23:03:37 -08002569 arenas_i(mib[2])->astats->bstats[mib[4]].curslabs, size_t)
Jason Evans3c234352010-01-27 13:10:55 -08002570
Jason Evans609ae592012-10-11 13:53:15 -07002571static const ctl_named_node_t *
Jason Evansc1e00ef2016-05-10 22:21:10 -07002572stats_arenas_i_bins_j_index(tsdn_t *tsdn, const size_t *mib, size_t miblen,
Jason Evansc4c25922017-01-15 16:56:30 -08002573 size_t j) {
2574 if (j > NBINS) {
Jason Evansf4086432017-01-19 18:15:45 -08002575 return NULL;
Jason Evansc4c25922017-01-15 16:56:30 -08002576 }
Jason Evansf4086432017-01-19 18:15:45 -08002577 return super_stats_arenas_i_bins_j_node;
Jason Evans3c234352010-01-27 13:10:55 -08002578}
2579
Jason Evans7d63fed2016-05-31 14:50:21 -07002580CTL_RO_CGEN(config_stats, stats_arenas_i_lextents_j_nmalloc,
David Goldblatt4fc2acf2017-03-08 15:56:31 -08002581 arena_stats_read_u64(&arenas_i(mib[2])->astats->lstats[mib[4]].nmalloc),
2582 uint64_t)
Jason Evans7d63fed2016-05-31 14:50:21 -07002583CTL_RO_CGEN(config_stats, stats_arenas_i_lextents_j_ndalloc,
David Goldblatt4fc2acf2017-03-08 15:56:31 -08002584 arena_stats_read_u64(&arenas_i(mib[2])->astats->lstats[mib[4]].ndalloc),
2585 uint64_t)
Jason Evans7d63fed2016-05-31 14:50:21 -07002586CTL_RO_CGEN(config_stats, stats_arenas_i_lextents_j_nrequests,
Jason Evans64e458f2017-03-08 22:42:57 -08002587 arena_stats_read_u64(&arenas_i(mib[2])->astats->lstats[mib[4]].nrequests),
2588 uint64_t)
Jason Evans7d63fed2016-05-31 14:50:21 -07002589CTL_RO_CGEN(config_stats, stats_arenas_i_lextents_j_curlextents,
Jason Evans9eb1b1c2017-01-18 23:03:37 -08002590 arenas_i(mib[2])->astats->lstats[mib[4]].curlextents, size_t)
Jason Evans3c4d92e2014-10-12 22:53:59 -07002591
2592static const ctl_named_node_t *
Jason Evans7d63fed2016-05-31 14:50:21 -07002593stats_arenas_i_lextents_j_index(tsdn_t *tsdn, const size_t *mib, size_t miblen,
Jason Evansc4c25922017-01-15 16:56:30 -08002594 size_t j) {
2595 if (j > NSIZES - NBINS) {
Jason Evansf4086432017-01-19 18:15:45 -08002596 return NULL;
Jason Evansc4c25922017-01-15 16:56:30 -08002597 }
Jason Evansf4086432017-01-19 18:15:45 -08002598 return super_stats_arenas_i_lextents_j_node;
Jason Evans3c4d92e2014-10-12 22:53:59 -07002599}
2600
Jason Evans609ae592012-10-11 13:53:15 -07002601static const ctl_named_node_t *
Jason Evansc4c25922017-01-15 16:56:30 -08002602stats_arenas_i_index(tsdn_t *tsdn, const size_t *mib, size_t miblen, size_t i) {
Jason Evans3dc4e832017-01-03 07:27:42 -08002603 const ctl_named_node_t *ret;
2604 size_t a;
Jason Evans3c234352010-01-27 13:10:55 -08002605
Jason Evansc1e00ef2016-05-10 22:21:10 -07002606 malloc_mutex_lock(tsdn, &ctl_mtx);
Jason Evans9eb1b1c2017-01-18 23:03:37 -08002607 a = arenas_i2a_impl(i, true, true);
2608 if (a == UINT_MAX || !ctl_arenas->arenas[a]->initialized) {
Jason Evansfc4dcfa2010-11-24 15:44:21 -08002609 ret = NULL;
Jason Evansa1ee7832012-04-10 15:07:44 -07002610 goto label_return;
Jason Evansfc4dcfa2010-11-24 15:44:21 -08002611 }
2612
2613 ret = super_stats_arenas_i_node;
Jason Evansa1ee7832012-04-10 15:07:44 -07002614label_return:
Jason Evansc1e00ef2016-05-10 22:21:10 -07002615 malloc_mutex_unlock(tsdn, &ctl_mtx);
Jason Evansf4086432017-01-19 18:15:45 -08002616 return ret;
Jason Evans3c234352010-01-27 13:10:55 -08002617}