blob: c054ded6f7deffbcfd3913c10bdc3f73a6a1aa99 [file] [log] [blame]
Jason Evansc0cc5db2017-01-19 21:41:41 -08001#define JEMALLOC_CTL_C_
David Goldblatt743d9402017-04-10 18:17:55 -07002#include "jemalloc/internal/jemalloc_preamble.h"
3#include "jemalloc/internal/jemalloc_internal_includes.h"
Jason Evans3c234352010-01-27 13:10:55 -08004
David Goldblattd9ec36e2017-04-11 14:43:12 -07005#include "jemalloc/internal/assert.h"
David Goldblatt418d96a2017-04-17 16:17:02 -07006#include "jemalloc/internal/nstime.h"
David Goldblatt31b43212017-04-19 15:09:01 -07007#include "jemalloc/internal/size_classes.h"
David Goldblattf692e6c2017-04-11 13:31:16 -07008#include "jemalloc/internal/util.h"
9
Jason Evans3c234352010-01-27 13:10:55 -080010/******************************************************************************/
11/* Data. */
12
Jason Evansfc4dcfa2010-11-24 15:44:21 -080013/*
14 * ctl_mtx protects the following:
Jason Evansd778dd22017-01-03 12:40:54 -080015 * - ctl_stats->*
Jason Evansfc4dcfa2010-11-24 15:44:21 -080016 */
Jason Evans3c234352010-01-27 13:10:55 -080017static malloc_mutex_t ctl_mtx;
18static bool ctl_initialized;
Jason Evansd778dd22017-01-03 12:40:54 -080019static ctl_stats_t *ctl_stats;
Jason Evans9eb1b1c2017-01-18 23:03:37 -080020static ctl_arenas_t *ctl_arenas;
Jason Evans3c234352010-01-27 13:10:55 -080021
22/******************************************************************************/
Mike Hommey461ad5c2012-04-20 08:38:42 +020023/* Helpers for named and indexed nodes. */
24
David Goldblatt4d2e4bf2017-04-21 09:37:34 -070025static const ctl_named_node_t *
Jason Evansc4c25922017-01-15 16:56:30 -080026ctl_named_node(const ctl_node_t *node) {
Mike Hommey461ad5c2012-04-20 08:38:42 +020027 return ((node->named) ? (const ctl_named_node_t *)node : NULL);
28}
29
David Goldblatt4d2e4bf2017-04-21 09:37:34 -070030static const ctl_named_node_t *
Jason Evansc4c25922017-01-15 16:56:30 -080031ctl_named_children(const ctl_named_node_t *node, size_t index) {
Mike Hommey461ad5c2012-04-20 08:38:42 +020032 const ctl_named_node_t *children = ctl_named_node(node->children);
33
34 return (children ? &children[index] : NULL);
35}
36
David Goldblatt4d2e4bf2017-04-21 09:37:34 -070037static const ctl_indexed_node_t *
Jason Evansc4c25922017-01-15 16:56:30 -080038ctl_indexed_node(const ctl_node_t *node) {
Jason Evans551ebc42014-10-03 10:16:09 -070039 return (!node->named ? (const ctl_indexed_node_t *)node : NULL);
Mike Hommey461ad5c2012-04-20 08:38:42 +020040}
41
42/******************************************************************************/
Jason Evans3c234352010-01-27 13:10:55 -080043/* Function prototypes for non-inline static functions. */
44
Jason Evansc0cc5db2017-01-19 21:41:41 -080045#define CTL_PROTO(n) \
Jason Evansb2c0d632016-04-13 23:36:15 -070046static int n##_ctl(tsd_t *tsd, const size_t *mib, size_t miblen, \
47 void *oldp, size_t *oldlenp, void *newp, size_t newlen);
Jason Evans3c234352010-01-27 13:10:55 -080048
Jason Evansc0cc5db2017-01-19 21:41:41 -080049#define INDEX_PROTO(n) \
Jason Evansc1e00ef2016-05-10 22:21:10 -070050static const ctl_named_node_t *n##_index(tsdn_t *tsdn, \
Jason Evansb2c0d632016-04-13 23:36:15 -070051 const size_t *mib, size_t miblen, size_t i);
Jason Evans3c234352010-01-27 13:10:55 -080052
Jason Evansa40bc7a2010-03-02 13:01:16 -080053CTL_PROTO(version)
Jason Evans3c234352010-01-27 13:10:55 -080054CTL_PROTO(epoch)
Jason Evansd4be8b72012-03-26 18:54:44 -070055CTL_PROTO(thread_tcache_enabled)
Jason Evanse7b8fa12012-03-16 17:09:32 -070056CTL_PROTO(thread_tcache_flush)
Jason Evans602c8e02014-08-18 16:22:13 -070057CTL_PROTO(thread_prof_name)
58CTL_PROTO(thread_prof_active)
Jason Evansb267d0f2010-08-13 15:42:29 -070059CTL_PROTO(thread_arena)
Jason Evans93443682010-10-20 17:39:18 -070060CTL_PROTO(thread_allocated)
Jason Evansecf229a2010-12-03 15:55:47 -080061CTL_PROTO(thread_allocatedp)
Jason Evans93443682010-10-20 17:39:18 -070062CTL_PROTO(thread_deallocated)
Jason Evansecf229a2010-12-03 15:55:47 -080063CTL_PROTO(thread_deallocatedp)
Jason Evansf2bc8522015-07-17 16:38:25 -070064CTL_PROTO(config_cache_oblivious)
Jason Evans3c234352010-01-27 13:10:55 -080065CTL_PROTO(config_debug)
Jason Evans3c234352010-01-27 13:10:55 -080066CTL_PROTO(config_fill)
67CTL_PROTO(config_lazy_lock)
Jason Evansf8290092016-02-07 14:23:22 -080068CTL_PROTO(config_malloc_conf)
Jason Evans59ae2762012-04-16 17:52:27 -070069CTL_PROTO(config_munmap)
Jason Evansd34f9e72010-02-11 13:19:21 -080070CTL_PROTO(config_prof)
71CTL_PROTO(config_prof_libgcc)
72CTL_PROTO(config_prof_libunwind)
Jason Evans3c234352010-01-27 13:10:55 -080073CTL_PROTO(config_stats)
Jason Evansb1476112012-04-05 13:36:17 -070074CTL_PROTO(config_utrace)
Jason Evans3c234352010-01-27 13:10:55 -080075CTL_PROTO(config_xmalloc)
76CTL_PROTO(opt_abort)
Jason Evans609ae592012-10-11 13:53:15 -070077CTL_PROTO(opt_dss)
Jason Evanse7339702010-10-23 18:37:06 -070078CTL_PROTO(opt_narenas)
Qi Wangec532e22017-02-02 17:02:05 -080079CTL_PROTO(opt_percpu_arena)
Jason Evans64e458f2017-03-08 22:42:57 -080080CTL_PROTO(opt_dirty_decay_time)
81CTL_PROTO(opt_muzzy_decay_time)
Jason Evanse7339702010-10-23 18:37:06 -070082CTL_PROTO(opt_stats_print)
Jason Evans3c234352010-01-27 13:10:55 -080083CTL_PROTO(opt_junk)
Jason Evanse7339702010-10-23 18:37:06 -070084CTL_PROTO(opt_zero)
Jason Evansb1476112012-04-05 13:36:17 -070085CTL_PROTO(opt_utrace)
Jason Evans3c234352010-01-27 13:10:55 -080086CTL_PROTO(opt_xmalloc)
Jason Evans3fa9a2f2010-03-07 15:34:14 -080087CTL_PROTO(opt_tcache)
Jason Evansf3ca7c82012-04-04 16:16:09 -070088CTL_PROTO(opt_lg_tcache_max)
Jason Evansd34f9e72010-02-11 13:19:21 -080089CTL_PROTO(opt_prof)
Jason Evanse7339702010-10-23 18:37:06 -070090CTL_PROTO(opt_prof_prefix)
Jason Evansf18c9822010-03-31 18:43:24 -070091CTL_PROTO(opt_prof_active)
Jason Evansfc12c0b2014-10-03 23:25:30 -070092CTL_PROTO(opt_prof_thread_active_init)
Jason Evansb9477e72010-03-01 20:15:26 -080093CTL_PROTO(opt_lg_prof_sample)
Jason Evansd34f9e72010-02-11 13:19:21 -080094CTL_PROTO(opt_lg_prof_interval)
Jason Evanse7339702010-10-23 18:37:06 -070095CTL_PROTO(opt_prof_gdump)
Jason Evans0b25fe72012-04-17 16:39:33 -070096CTL_PROTO(opt_prof_final)
Jason Evansd34f9e72010-02-11 13:19:21 -080097CTL_PROTO(opt_prof_leak)
Jason Evansa881cd22010-10-02 15:18:50 -070098CTL_PROTO(opt_prof_accum)
Jason Evans1cb181e2015-01-29 15:30:47 -080099CTL_PROTO(tcache_create)
100CTL_PROTO(tcache_flush)
101CTL_PROTO(tcache_destroy)
Jason Evansdc2125c2017-01-04 10:21:53 -0800102CTL_PROTO(arena_i_initialized)
Jason Evans243f7a02016-02-19 20:09:31 -0800103CTL_PROTO(arena_i_decay)
Jason Evans64e458f2017-03-08 22:42:57 -0800104CTL_PROTO(arena_i_purge)
Jason Evans19ff2ce2016-04-22 14:37:17 -0700105CTL_PROTO(arena_i_reset)
Jason Evansedf1baf2017-01-03 17:21:59 -0800106CTL_PROTO(arena_i_destroy)
Jason Evans609ae592012-10-11 13:53:15 -0700107CTL_PROTO(arena_i_dss)
Jason Evans64e458f2017-03-08 22:42:57 -0800108CTL_PROTO(arena_i_dirty_decay_time)
109CTL_PROTO(arena_i_muzzy_decay_time)
Jason Evans9c305c92016-05-31 15:03:51 -0700110CTL_PROTO(arena_i_extent_hooks)
Jason Evans609ae592012-10-11 13:53:15 -0700111INDEX_PROTO(arena_i)
Jason Evans3c234352010-01-27 13:10:55 -0800112CTL_PROTO(arenas_bin_i_size)
113CTL_PROTO(arenas_bin_i_nregs)
Jason Evans498856f2016-05-29 18:34:50 -0700114CTL_PROTO(arenas_bin_i_slab_size)
Jason Evans3c234352010-01-27 13:10:55 -0800115INDEX_PROTO(arenas_bin_i)
Jason Evans7d63fed2016-05-31 14:50:21 -0700116CTL_PROTO(arenas_lextent_i_size)
117INDEX_PROTO(arenas_lextent_i)
Jason Evans3c234352010-01-27 13:10:55 -0800118CTL_PROTO(arenas_narenas)
Jason Evans64e458f2017-03-08 22:42:57 -0800119CTL_PROTO(arenas_dirty_decay_time)
120CTL_PROTO(arenas_muzzy_decay_time)
Jason Evans3c234352010-01-27 13:10:55 -0800121CTL_PROTO(arenas_quantum)
Jason Evansae4c7b42012-04-02 07:04:34 -0700122CTL_PROTO(arenas_page)
Jason Evansdafde142010-03-17 16:27:39 -0700123CTL_PROTO(arenas_tcache_max)
Jason Evans3c234352010-01-27 13:10:55 -0800124CTL_PROTO(arenas_nbins)
Jason Evansdafde142010-03-17 16:27:39 -0700125CTL_PROTO(arenas_nhbins)
Jason Evans7d63fed2016-05-31 14:50:21 -0700126CTL_PROTO(arenas_nlextents)
Jason Evans0f04bb12017-01-03 08:21:29 -0800127CTL_PROTO(arenas_create)
Jason Evansfc12c0b2014-10-03 23:25:30 -0700128CTL_PROTO(prof_thread_active_init)
Jason Evansf18c9822010-03-31 18:43:24 -0700129CTL_PROTO(prof_active)
Jason Evansd34f9e72010-02-11 13:19:21 -0800130CTL_PROTO(prof_dump)
Jason Evans5b8ed5b2015-01-25 21:16:57 -0800131CTL_PROTO(prof_gdump)
Jason Evans602c8e02014-08-18 16:22:13 -0700132CTL_PROTO(prof_reset)
Jason Evansd34f9e72010-02-11 13:19:21 -0800133CTL_PROTO(prof_interval)
Jason Evans602c8e02014-08-18 16:22:13 -0700134CTL_PROTO(lg_prof_sample)
Jason Evans3c234352010-01-27 13:10:55 -0800135CTL_PROTO(stats_arenas_i_small_allocated)
136CTL_PROTO(stats_arenas_i_small_nmalloc)
137CTL_PROTO(stats_arenas_i_small_ndalloc)
Jason Evans86815df2010-03-13 20:32:56 -0800138CTL_PROTO(stats_arenas_i_small_nrequests)
Jason Evans7d63fed2016-05-31 14:50:21 -0700139CTL_PROTO(stats_arenas_i_large_allocated)
140CTL_PROTO(stats_arenas_i_large_nmalloc)
141CTL_PROTO(stats_arenas_i_large_ndalloc)
142CTL_PROTO(stats_arenas_i_large_nrequests)
Jason Evans86815df2010-03-13 20:32:56 -0800143CTL_PROTO(stats_arenas_i_bins_j_nmalloc)
144CTL_PROTO(stats_arenas_i_bins_j_ndalloc)
Jason Evans3c234352010-01-27 13:10:55 -0800145CTL_PROTO(stats_arenas_i_bins_j_nrequests)
Jason Evans3c4d92e2014-10-12 22:53:59 -0700146CTL_PROTO(stats_arenas_i_bins_j_curregs)
Jason Evans3c234352010-01-27 13:10:55 -0800147CTL_PROTO(stats_arenas_i_bins_j_nfills)
148CTL_PROTO(stats_arenas_i_bins_j_nflushes)
Jason Evans498856f2016-05-29 18:34:50 -0700149CTL_PROTO(stats_arenas_i_bins_j_nslabs)
150CTL_PROTO(stats_arenas_i_bins_j_nreslabs)
151CTL_PROTO(stats_arenas_i_bins_j_curslabs)
Jason Evans3c234352010-01-27 13:10:55 -0800152INDEX_PROTO(stats_arenas_i_bins_j)
Jason Evans7d63fed2016-05-31 14:50:21 -0700153CTL_PROTO(stats_arenas_i_lextents_j_nmalloc)
154CTL_PROTO(stats_arenas_i_lextents_j_ndalloc)
155CTL_PROTO(stats_arenas_i_lextents_j_nrequests)
156CTL_PROTO(stats_arenas_i_lextents_j_curlextents)
157INDEX_PROTO(stats_arenas_i_lextents_j)
Jason Evans597632b2011-03-18 13:41:33 -0700158CTL_PROTO(stats_arenas_i_nthreads)
Jason Evans609ae592012-10-11 13:53:15 -0700159CTL_PROTO(stats_arenas_i_dss)
Jason Evans64e458f2017-03-08 22:42:57 -0800160CTL_PROTO(stats_arenas_i_dirty_decay_time)
161CTL_PROTO(stats_arenas_i_muzzy_decay_time)
Jason Evans3c234352010-01-27 13:10:55 -0800162CTL_PROTO(stats_arenas_i_pactive)
163CTL_PROTO(stats_arenas_i_pdirty)
Jason Evans64e458f2017-03-08 22:42:57 -0800164CTL_PROTO(stats_arenas_i_pmuzzy)
Jason Evans3c234352010-01-27 13:10:55 -0800165CTL_PROTO(stats_arenas_i_mapped)
Jason Evans04c3c0f2016-05-03 22:11:35 -0700166CTL_PROTO(stats_arenas_i_retained)
Jason Evans64e458f2017-03-08 22:42:57 -0800167CTL_PROTO(stats_arenas_i_dirty_npurge)
168CTL_PROTO(stats_arenas_i_dirty_nmadvise)
169CTL_PROTO(stats_arenas_i_dirty_purged)
170CTL_PROTO(stats_arenas_i_muzzy_npurge)
171CTL_PROTO(stats_arenas_i_muzzy_nmadvise)
172CTL_PROTO(stats_arenas_i_muzzy_purged)
Jason Evansa0dd3a42016-12-22 16:39:10 -0600173CTL_PROTO(stats_arenas_i_base)
174CTL_PROTO(stats_arenas_i_internal)
Qi Wang58424e62016-04-22 18:37:44 -0700175CTL_PROTO(stats_arenas_i_tcache_bytes)
Jason Evansa0dd3a42016-12-22 16:39:10 -0600176CTL_PROTO(stats_arenas_i_resident)
Jason Evans3c234352010-01-27 13:10:55 -0800177INDEX_PROTO(stats_arenas_i)
Jason Evans3c234352010-01-27 13:10:55 -0800178CTL_PROTO(stats_allocated)
179CTL_PROTO(stats_active)
Jason Evans4581b972014-11-27 17:22:36 -0200180CTL_PROTO(stats_metadata)
Jason Evans4acd75a2015-03-23 17:25:57 -0700181CTL_PROTO(stats_resident)
Jason Evans3c234352010-01-27 13:10:55 -0800182CTL_PROTO(stats_mapped)
Jason Evans04c3c0f2016-05-03 22:11:35 -0700183CTL_PROTO(stats_retained)
Jason Evans3c234352010-01-27 13:10:55 -0800184
Qi Wang64c5f5c2017-03-13 17:29:03 -0700185#define MUTEX_STATS_CTL_PROTO_GEN(n) \
Qi Wangca9074d2017-03-11 20:28:31 -0800186CTL_PROTO(stats_##n##_num_ops) \
187CTL_PROTO(stats_##n##_num_wait) \
188CTL_PROTO(stats_##n##_num_spin_acq) \
189CTL_PROTO(stats_##n##_num_owner_switch) \
190CTL_PROTO(stats_##n##_total_wait_time) \
191CTL_PROTO(stats_##n##_max_wait_time) \
192CTL_PROTO(stats_##n##_max_num_thds)
Qi Wang0fb5c0e2017-03-10 12:14:05 -0800193
Qi Wang64c5f5c2017-03-13 17:29:03 -0700194/* Global mutexes. */
Qi Wangd3fde1c2017-03-21 11:56:38 -0700195#define OP(mtx) MUTEX_STATS_CTL_PROTO_GEN(mutexes_##mtx)
196GLOBAL_PROF_MUTEXES
197#undef OP
198
199/* Per arena mutexes. */
200#define OP(mtx) MUTEX_STATS_CTL_PROTO_GEN(arenas_i_mutexes_##mtx)
201ARENA_PROF_MUTEXES
202#undef OP
Qi Wangca9074d2017-03-11 20:28:31 -0800203
Qi Wang64c5f5c2017-03-13 17:29:03 -0700204/* Arena bin mutexes. */
205MUTEX_STATS_CTL_PROTO_GEN(arenas_i_bins_j_mutex)
Qi Wang64c5f5c2017-03-13 17:29:03 -0700206#undef MUTEX_STATS_CTL_PROTO_GEN
207
208CTL_PROTO(stats_mutexes_reset)
Qi Wang0fb5c0e2017-03-10 12:14:05 -0800209
Jason Evans3c234352010-01-27 13:10:55 -0800210/******************************************************************************/
211/* mallctl tree. */
212
Jason Evansc0cc5db2017-01-19 21:41:41 -0800213#define NAME(n) {true}, n
214#define CHILD(t, c) \
Jason Evans65f343a2012-04-23 19:31:45 -0700215 sizeof(c##_node) / sizeof(ctl_##t##_node_t), \
216 (ctl_node_t *)c##_node, \
217 NULL
Jason Evansc0cc5db2017-01-19 21:41:41 -0800218#define CTL(c) 0, NULL, c##_ctl
Jason Evans3c234352010-01-27 13:10:55 -0800219
220/*
221 * Only handles internal indexed nodes, since there are currently no external
222 * ones.
223 */
Jason Evansc0cc5db2017-01-19 21:41:41 -0800224#define INDEX(i) {false}, i##_index
Jason Evans3c234352010-01-27 13:10:55 -0800225
Jason Evans602c8e02014-08-18 16:22:13 -0700226static const ctl_named_node_t thread_tcache_node[] = {
Jason Evansd4be8b72012-03-26 18:54:44 -0700227 {NAME("enabled"), CTL(thread_tcache_enabled)},
Jason Evanse7b8fa12012-03-16 17:09:32 -0700228 {NAME("flush"), CTL(thread_tcache_flush)}
Jason Evans3c234352010-01-27 13:10:55 -0800229};
Jason Evans3c234352010-01-27 13:10:55 -0800230
Jason Evans602c8e02014-08-18 16:22:13 -0700231static const ctl_named_node_t thread_prof_node[] = {
232 {NAME("name"), CTL(thread_prof_name)},
233 {NAME("active"), CTL(thread_prof_active)}
234};
235
Mike Hommey461ad5c2012-04-20 08:38:42 +0200236static const ctl_named_node_t thread_node[] = {
Jason Evans7372b152012-02-10 20:22:09 -0800237 {NAME("arena"), CTL(thread_arena)},
Jason Evans93443682010-10-20 17:39:18 -0700238 {NAME("allocated"), CTL(thread_allocated)},
Jason Evansecf229a2010-12-03 15:55:47 -0800239 {NAME("allocatedp"), CTL(thread_allocatedp)},
240 {NAME("deallocated"), CTL(thread_deallocated)},
Jason Evanse7b8fa12012-03-16 17:09:32 -0700241 {NAME("deallocatedp"), CTL(thread_deallocatedp)},
Jason Evans602c8e02014-08-18 16:22:13 -0700242 {NAME("tcache"), CHILD(named, thread_tcache)},
243 {NAME("prof"), CHILD(named, thread_prof)}
Jason Evansb267d0f2010-08-13 15:42:29 -0700244};
Jason Evansb267d0f2010-08-13 15:42:29 -0700245
Mike Hommey461ad5c2012-04-20 08:38:42 +0200246static const ctl_named_node_t config_node[] = {
Jason Evansf2bc8522015-07-17 16:38:25 -0700247 {NAME("cache_oblivious"), CTL(config_cache_oblivious)},
Jason Evans3c4d92e2014-10-12 22:53:59 -0700248 {NAME("debug"), CTL(config_debug)},
249 {NAME("fill"), CTL(config_fill)},
250 {NAME("lazy_lock"), CTL(config_lazy_lock)},
Jason Evansf8290092016-02-07 14:23:22 -0800251 {NAME("malloc_conf"), CTL(config_malloc_conf)},
Jason Evans3c4d92e2014-10-12 22:53:59 -0700252 {NAME("munmap"), CTL(config_munmap)},
253 {NAME("prof"), CTL(config_prof)},
254 {NAME("prof_libgcc"), CTL(config_prof_libgcc)},
255 {NAME("prof_libunwind"), CTL(config_prof_libunwind)},
256 {NAME("stats"), CTL(config_stats)},
Jason Evans3c4d92e2014-10-12 22:53:59 -0700257 {NAME("utrace"), CTL(config_utrace)},
Jason Evans3c4d92e2014-10-12 22:53:59 -0700258 {NAME("xmalloc"), CTL(config_xmalloc)}
Jason Evans3c234352010-01-27 13:10:55 -0800259};
260
Mike Hommey461ad5c2012-04-20 08:38:42 +0200261static const ctl_named_node_t opt_node[] = {
Jason Evans3c4d92e2014-10-12 22:53:59 -0700262 {NAME("abort"), CTL(opt_abort)},
263 {NAME("dss"), CTL(opt_dss)},
Jason Evans3c4d92e2014-10-12 22:53:59 -0700264 {NAME("narenas"), CTL(opt_narenas)},
Qi Wangec532e22017-02-02 17:02:05 -0800265 {NAME("percpu_arena"), CTL(opt_percpu_arena)},
Jason Evans64e458f2017-03-08 22:42:57 -0800266 {NAME("dirty_decay_time"), CTL(opt_dirty_decay_time)},
267 {NAME("muzzy_decay_time"), CTL(opt_muzzy_decay_time)},
Jason Evans3c4d92e2014-10-12 22:53:59 -0700268 {NAME("stats_print"), CTL(opt_stats_print)},
269 {NAME("junk"), CTL(opt_junk)},
270 {NAME("zero"), CTL(opt_zero)},
Jason Evans3c4d92e2014-10-12 22:53:59 -0700271 {NAME("utrace"), CTL(opt_utrace)},
272 {NAME("xmalloc"), CTL(opt_xmalloc)},
273 {NAME("tcache"), CTL(opt_tcache)},
274 {NAME("lg_tcache_max"), CTL(opt_lg_tcache_max)},
275 {NAME("prof"), CTL(opt_prof)},
276 {NAME("prof_prefix"), CTL(opt_prof_prefix)},
277 {NAME("prof_active"), CTL(opt_prof_active)},
Jason Evansfc12c0b2014-10-03 23:25:30 -0700278 {NAME("prof_thread_active_init"), CTL(opt_prof_thread_active_init)},
Jason Evans3c4d92e2014-10-12 22:53:59 -0700279 {NAME("lg_prof_sample"), CTL(opt_lg_prof_sample)},
280 {NAME("lg_prof_interval"), CTL(opt_lg_prof_interval)},
281 {NAME("prof_gdump"), CTL(opt_prof_gdump)},
282 {NAME("prof_final"), CTL(opt_prof_final)},
283 {NAME("prof_leak"), CTL(opt_prof_leak)},
284 {NAME("prof_accum"), CTL(opt_prof_accum)}
Jason Evans3c234352010-01-27 13:10:55 -0800285};
286
Jason Evans1cb181e2015-01-29 15:30:47 -0800287static const ctl_named_node_t tcache_node[] = {
288 {NAME("create"), CTL(tcache_create)},
289 {NAME("flush"), CTL(tcache_flush)},
290 {NAME("destroy"), CTL(tcache_destroy)}
291};
292
Jason Evans609ae592012-10-11 13:53:15 -0700293static const ctl_named_node_t arena_i_node[] = {
Jason Evansdc2125c2017-01-04 10:21:53 -0800294 {NAME("initialized"), CTL(arena_i_initialized)},
Jason Evans243f7a02016-02-19 20:09:31 -0800295 {NAME("decay"), CTL(arena_i_decay)},
Jason Evans64e458f2017-03-08 22:42:57 -0800296 {NAME("purge"), CTL(arena_i_purge)},
Jason Evans19ff2ce2016-04-22 14:37:17 -0700297 {NAME("reset"), CTL(arena_i_reset)},
Jason Evansedf1baf2017-01-03 17:21:59 -0800298 {NAME("destroy"), CTL(arena_i_destroy)},
Jason Evans3c4d92e2014-10-12 22:53:59 -0700299 {NAME("dss"), CTL(arena_i_dss)},
Jason Evans64e458f2017-03-08 22:42:57 -0800300 {NAME("dirty_decay_time"), CTL(arena_i_dirty_decay_time)},
301 {NAME("muzzy_decay_time"), CTL(arena_i_muzzy_decay_time)},
Jason Evans9c305c92016-05-31 15:03:51 -0700302 {NAME("extent_hooks"), CTL(arena_i_extent_hooks)}
Jason Evans609ae592012-10-11 13:53:15 -0700303};
304static const ctl_named_node_t super_arena_i_node[] = {
Jason Evans3c4d92e2014-10-12 22:53:59 -0700305 {NAME(""), CHILD(named, arena_i)}
Jason Evans609ae592012-10-11 13:53:15 -0700306};
307
308static const ctl_indexed_node_t arena_node[] = {
309 {INDEX(arena_i)}
310};
311
Mike Hommey461ad5c2012-04-20 08:38:42 +0200312static const ctl_named_node_t arenas_bin_i_node[] = {
Jason Evans3c4d92e2014-10-12 22:53:59 -0700313 {NAME("size"), CTL(arenas_bin_i_size)},
314 {NAME("nregs"), CTL(arenas_bin_i_nregs)},
Jason Evans498856f2016-05-29 18:34:50 -0700315 {NAME("slab_size"), CTL(arenas_bin_i_slab_size)}
Jason Evans3c234352010-01-27 13:10:55 -0800316};
Mike Hommey461ad5c2012-04-20 08:38:42 +0200317static const ctl_named_node_t super_arenas_bin_i_node[] = {
Jason Evans3c4d92e2014-10-12 22:53:59 -0700318 {NAME(""), CHILD(named, arenas_bin_i)}
Jason Evans3c234352010-01-27 13:10:55 -0800319};
320
Mike Hommey461ad5c2012-04-20 08:38:42 +0200321static const ctl_indexed_node_t arenas_bin_node[] = {
Jason Evans3c234352010-01-27 13:10:55 -0800322 {INDEX(arenas_bin_i)}
323};
324
Jason Evans7d63fed2016-05-31 14:50:21 -0700325static const ctl_named_node_t arenas_lextent_i_node[] = {
326 {NAME("size"), CTL(arenas_lextent_i_size)}
Jason Evans3c4d92e2014-10-12 22:53:59 -0700327};
Jason Evans7d63fed2016-05-31 14:50:21 -0700328static const ctl_named_node_t super_arenas_lextent_i_node[] = {
329 {NAME(""), CHILD(named, arenas_lextent_i)}
Jason Evans3c4d92e2014-10-12 22:53:59 -0700330};
331
Jason Evans7d63fed2016-05-31 14:50:21 -0700332static const ctl_indexed_node_t arenas_lextent_node[] = {
333 {INDEX(arenas_lextent_i)}
Jason Evans3c4d92e2014-10-12 22:53:59 -0700334};
335
Mike Hommey461ad5c2012-04-20 08:38:42 +0200336static const ctl_named_node_t arenas_node[] = {
Jason Evans3c4d92e2014-10-12 22:53:59 -0700337 {NAME("narenas"), CTL(arenas_narenas)},
Jason Evans64e458f2017-03-08 22:42:57 -0800338 {NAME("dirty_decay_time"), CTL(arenas_dirty_decay_time)},
339 {NAME("muzzy_decay_time"), CTL(arenas_muzzy_decay_time)},
Jason Evans3c4d92e2014-10-12 22:53:59 -0700340 {NAME("quantum"), CTL(arenas_quantum)},
341 {NAME("page"), CTL(arenas_page)},
342 {NAME("tcache_max"), CTL(arenas_tcache_max)},
343 {NAME("nbins"), CTL(arenas_nbins)},
344 {NAME("nhbins"), CTL(arenas_nhbins)},
345 {NAME("bin"), CHILD(indexed, arenas_bin)},
Jason Evans7d63fed2016-05-31 14:50:21 -0700346 {NAME("nlextents"), CTL(arenas_nlextents)},
347 {NAME("lextent"), CHILD(indexed, arenas_lextent)},
Jason Evans0f04bb12017-01-03 08:21:29 -0800348 {NAME("create"), CTL(arenas_create)}
Jason Evans3c234352010-01-27 13:10:55 -0800349};
350
Mike Hommey461ad5c2012-04-20 08:38:42 +0200351static const ctl_named_node_t prof_node[] = {
Jason Evansfc12c0b2014-10-03 23:25:30 -0700352 {NAME("thread_active_init"), CTL(prof_thread_active_init)},
Jason Evansf18c9822010-03-31 18:43:24 -0700353 {NAME("active"), CTL(prof_active)},
Jason Evansd34f9e72010-02-11 13:19:21 -0800354 {NAME("dump"), CTL(prof_dump)},
Jason Evans5b8ed5b2015-01-25 21:16:57 -0800355 {NAME("gdump"), CTL(prof_gdump)},
Jason Evans602c8e02014-08-18 16:22:13 -0700356 {NAME("reset"), CTL(prof_reset)},
357 {NAME("interval"), CTL(prof_interval)},
358 {NAME("lg_sample"), CTL(lg_prof_sample)}
Jason Evansd34f9e72010-02-11 13:19:21 -0800359};
Jason Evansd34f9e72010-02-11 13:19:21 -0800360
Mike Hommey461ad5c2012-04-20 08:38:42 +0200361static const ctl_named_node_t stats_arenas_i_small_node[] = {
Jason Evans3c4d92e2014-10-12 22:53:59 -0700362 {NAME("allocated"), CTL(stats_arenas_i_small_allocated)},
363 {NAME("nmalloc"), CTL(stats_arenas_i_small_nmalloc)},
364 {NAME("ndalloc"), CTL(stats_arenas_i_small_ndalloc)},
365 {NAME("nrequests"), CTL(stats_arenas_i_small_nrequests)}
Jason Evans3c234352010-01-27 13:10:55 -0800366};
367
Jason Evans7d63fed2016-05-31 14:50:21 -0700368static const ctl_named_node_t stats_arenas_i_large_node[] = {
369 {NAME("allocated"), CTL(stats_arenas_i_large_allocated)},
370 {NAME("nmalloc"), CTL(stats_arenas_i_large_nmalloc)},
371 {NAME("ndalloc"), CTL(stats_arenas_i_large_ndalloc)},
372 {NAME("nrequests"), CTL(stats_arenas_i_large_nrequests)}
Jason Evanse2deab72014-05-15 22:22:27 -0700373};
374
Qi Wang64c5f5c2017-03-13 17:29:03 -0700375#define MUTEX_PROF_DATA_NODE(prefix) \
Qi Wangca9074d2017-03-11 20:28:31 -0800376static const ctl_named_node_t stats_##prefix##_node[] = { \
Qi Wang0fb5c0e2017-03-10 12:14:05 -0800377 {NAME("num_ops"), \
Qi Wangca9074d2017-03-11 20:28:31 -0800378 CTL(stats_##prefix##_num_ops)}, \
Qi Wang0fb5c0e2017-03-10 12:14:05 -0800379 {NAME("num_wait"), \
Qi Wangca9074d2017-03-11 20:28:31 -0800380 CTL(stats_##prefix##_num_wait)}, \
Qi Wang0fb5c0e2017-03-10 12:14:05 -0800381 {NAME("num_spin_acq"), \
Qi Wangca9074d2017-03-11 20:28:31 -0800382 CTL(stats_##prefix##_num_spin_acq)}, \
Qi Wang0fb5c0e2017-03-10 12:14:05 -0800383 {NAME("num_owner_switch"), \
Qi Wangca9074d2017-03-11 20:28:31 -0800384 CTL(stats_##prefix##_num_owner_switch)}, \
Qi Wang0fb5c0e2017-03-10 12:14:05 -0800385 {NAME("total_wait_time"), \
Qi Wangca9074d2017-03-11 20:28:31 -0800386 CTL(stats_##prefix##_total_wait_time)}, \
Qi Wang0fb5c0e2017-03-10 12:14:05 -0800387 {NAME("max_wait_time"), \
Qi Wangca9074d2017-03-11 20:28:31 -0800388 CTL(stats_##prefix##_max_wait_time)}, \
Qi Wang0fb5c0e2017-03-10 12:14:05 -0800389 {NAME("max_num_thds"), \
Qi Wangca9074d2017-03-11 20:28:31 -0800390 CTL(stats_##prefix##_max_num_thds)} \
Qi Wang0fb5c0e2017-03-10 12:14:05 -0800391 /* Note that # of current waiting thread not provided. */ \
392};
393
Qi Wang64c5f5c2017-03-13 17:29:03 -0700394MUTEX_PROF_DATA_NODE(arenas_i_bins_j_mutex)
Qi Wangca9074d2017-03-11 20:28:31 -0800395
Mike Hommey461ad5c2012-04-20 08:38:42 +0200396static const ctl_named_node_t stats_arenas_i_bins_j_node[] = {
Jason Evans3c4d92e2014-10-12 22:53:59 -0700397 {NAME("nmalloc"), CTL(stats_arenas_i_bins_j_nmalloc)},
398 {NAME("ndalloc"), CTL(stats_arenas_i_bins_j_ndalloc)},
399 {NAME("nrequests"), CTL(stats_arenas_i_bins_j_nrequests)},
400 {NAME("curregs"), CTL(stats_arenas_i_bins_j_curregs)},
401 {NAME("nfills"), CTL(stats_arenas_i_bins_j_nfills)},
402 {NAME("nflushes"), CTL(stats_arenas_i_bins_j_nflushes)},
Jason Evans498856f2016-05-29 18:34:50 -0700403 {NAME("nslabs"), CTL(stats_arenas_i_bins_j_nslabs)},
404 {NAME("nreslabs"), CTL(stats_arenas_i_bins_j_nreslabs)},
Qi Wanga4f176a2017-03-03 19:58:43 -0800405 {NAME("curslabs"), CTL(stats_arenas_i_bins_j_curslabs)},
Qi Wang64c5f5c2017-03-13 17:29:03 -0700406 {NAME("mutex"), CHILD(named, stats_arenas_i_bins_j_mutex)}
Jason Evans3c234352010-01-27 13:10:55 -0800407};
Qi Wang0fb5c0e2017-03-10 12:14:05 -0800408
Mike Hommey461ad5c2012-04-20 08:38:42 +0200409static const ctl_named_node_t super_stats_arenas_i_bins_j_node[] = {
Jason Evans3c4d92e2014-10-12 22:53:59 -0700410 {NAME(""), CHILD(named, stats_arenas_i_bins_j)}
Jason Evans3c234352010-01-27 13:10:55 -0800411};
412
Mike Hommey461ad5c2012-04-20 08:38:42 +0200413static const ctl_indexed_node_t stats_arenas_i_bins_node[] = {
Jason Evans3c234352010-01-27 13:10:55 -0800414 {INDEX(stats_arenas_i_bins_j)}
415};
416
Jason Evans7d63fed2016-05-31 14:50:21 -0700417static const ctl_named_node_t stats_arenas_i_lextents_j_node[] = {
418 {NAME("nmalloc"), CTL(stats_arenas_i_lextents_j_nmalloc)},
419 {NAME("ndalloc"), CTL(stats_arenas_i_lextents_j_ndalloc)},
420 {NAME("nrequests"), CTL(stats_arenas_i_lextents_j_nrequests)},
421 {NAME("curlextents"), CTL(stats_arenas_i_lextents_j_curlextents)}
Jason Evans3c4d92e2014-10-12 22:53:59 -0700422};
Jason Evans7d63fed2016-05-31 14:50:21 -0700423static const ctl_named_node_t super_stats_arenas_i_lextents_j_node[] = {
424 {NAME(""), CHILD(named, stats_arenas_i_lextents_j)}
Jason Evans3c4d92e2014-10-12 22:53:59 -0700425};
426
Jason Evans7d63fed2016-05-31 14:50:21 -0700427static const ctl_indexed_node_t stats_arenas_i_lextents_node[] = {
428 {INDEX(stats_arenas_i_lextents_j)}
Jason Evans3c4d92e2014-10-12 22:53:59 -0700429};
430
Qi Wangd3fde1c2017-03-21 11:56:38 -0700431#define OP(mtx) MUTEX_PROF_DATA_NODE(arenas_i_mutexes_##mtx)
432ARENA_PROF_MUTEXES
433#undef OP
Qi Wang0fb5c0e2017-03-10 12:14:05 -0800434
Qi Wang64c5f5c2017-03-13 17:29:03 -0700435static const ctl_named_node_t stats_arenas_i_mutexes_node[] = {
Qi Wangd3fde1c2017-03-21 11:56:38 -0700436#define OP(mtx) {NAME(#mtx), CHILD(named, stats_arenas_i_mutexes_##mtx)},
437ARENA_PROF_MUTEXES
438#undef OP
Qi Wang0fb5c0e2017-03-10 12:14:05 -0800439};
Qi Wang0fb5c0e2017-03-10 12:14:05 -0800440
Mike Hommey461ad5c2012-04-20 08:38:42 +0200441static const ctl_named_node_t stats_arenas_i_node[] = {
Jason Evans3c4d92e2014-10-12 22:53:59 -0700442 {NAME("nthreads"), CTL(stats_arenas_i_nthreads)},
443 {NAME("dss"), CTL(stats_arenas_i_dss)},
Jason Evans64e458f2017-03-08 22:42:57 -0800444 {NAME("dirty_decay_time"), CTL(stats_arenas_i_dirty_decay_time)},
445 {NAME("muzzy_decay_time"), CTL(stats_arenas_i_muzzy_decay_time)},
Jason Evans3c4d92e2014-10-12 22:53:59 -0700446 {NAME("pactive"), CTL(stats_arenas_i_pactive)},
447 {NAME("pdirty"), CTL(stats_arenas_i_pdirty)},
Jason Evans64e458f2017-03-08 22:42:57 -0800448 {NAME("pmuzzy"), CTL(stats_arenas_i_pmuzzy)},
Jason Evans3c4d92e2014-10-12 22:53:59 -0700449 {NAME("mapped"), CTL(stats_arenas_i_mapped)},
Jason Evans04c3c0f2016-05-03 22:11:35 -0700450 {NAME("retained"), CTL(stats_arenas_i_retained)},
Jason Evans64e458f2017-03-08 22:42:57 -0800451 {NAME("dirty_npurge"), CTL(stats_arenas_i_dirty_npurge)},
452 {NAME("dirty_nmadvise"), CTL(stats_arenas_i_dirty_nmadvise)},
453 {NAME("dirty_purged"), CTL(stats_arenas_i_dirty_purged)},
454 {NAME("muzzy_npurge"), CTL(stats_arenas_i_muzzy_npurge)},
455 {NAME("muzzy_nmadvise"), CTL(stats_arenas_i_muzzy_nmadvise)},
456 {NAME("muzzy_purged"), CTL(stats_arenas_i_muzzy_purged)},
Jason Evansa0dd3a42016-12-22 16:39:10 -0600457 {NAME("base"), CTL(stats_arenas_i_base)},
458 {NAME("internal"), CTL(stats_arenas_i_internal)},
Qi Wang58424e62016-04-22 18:37:44 -0700459 {NAME("tcache_bytes"), CTL(stats_arenas_i_tcache_bytes)},
Jason Evansa0dd3a42016-12-22 16:39:10 -0600460 {NAME("resident"), CTL(stats_arenas_i_resident)},
Jason Evans3c4d92e2014-10-12 22:53:59 -0700461 {NAME("small"), CHILD(named, stats_arenas_i_small)},
Jason Evans7d63fed2016-05-31 14:50:21 -0700462 {NAME("large"), CHILD(named, stats_arenas_i_large)},
Jason Evans3c4d92e2014-10-12 22:53:59 -0700463 {NAME("bins"), CHILD(indexed, stats_arenas_i_bins)},
Qi Wang0fb5c0e2017-03-10 12:14:05 -0800464 {NAME("lextents"), CHILD(indexed, stats_arenas_i_lextents)},
Qi Wang64c5f5c2017-03-13 17:29:03 -0700465 {NAME("mutexes"), CHILD(named, stats_arenas_i_mutexes)}
Jason Evans3c234352010-01-27 13:10:55 -0800466};
Mike Hommey461ad5c2012-04-20 08:38:42 +0200467static const ctl_named_node_t super_stats_arenas_i_node[] = {
Jason Evans3c4d92e2014-10-12 22:53:59 -0700468 {NAME(""), CHILD(named, stats_arenas_i)}
Jason Evans3c234352010-01-27 13:10:55 -0800469};
470
Mike Hommey461ad5c2012-04-20 08:38:42 +0200471static const ctl_indexed_node_t stats_arenas_node[] = {
Jason Evans3c234352010-01-27 13:10:55 -0800472 {INDEX(stats_arenas_i)}
473};
474
Qi Wangd3fde1c2017-03-21 11:56:38 -0700475#define OP(mtx) MUTEX_PROF_DATA_NODE(mutexes_##mtx)
476GLOBAL_PROF_MUTEXES
477#undef OP
478
Qi Wang64c5f5c2017-03-13 17:29:03 -0700479static const ctl_named_node_t stats_mutexes_node[] = {
Qi Wangd3fde1c2017-03-21 11:56:38 -0700480#define OP(mtx) {NAME(#mtx), CHILD(named, stats_mutexes_##mtx)},
481GLOBAL_PROF_MUTEXES
482#undef OP
Qi Wang64c5f5c2017-03-13 17:29:03 -0700483 {NAME("reset"), CTL(stats_mutexes_reset)}
Qi Wangca9074d2017-03-11 20:28:31 -0800484};
Qi Wangd3fde1c2017-03-21 11:56:38 -0700485#undef MUTEX_PROF_DATA_NODE
Qi Wangca9074d2017-03-11 20:28:31 -0800486
Mike Hommey461ad5c2012-04-20 08:38:42 +0200487static const ctl_named_node_t stats_node[] = {
Jason Evans3c4d92e2014-10-12 22:53:59 -0700488 {NAME("allocated"), CTL(stats_allocated)},
489 {NAME("active"), CTL(stats_active)},
Jason Evans4581b972014-11-27 17:22:36 -0200490 {NAME("metadata"), CTL(stats_metadata)},
Jason Evans4acd75a2015-03-23 17:25:57 -0700491 {NAME("resident"), CTL(stats_resident)},
Jason Evans3c4d92e2014-10-12 22:53:59 -0700492 {NAME("mapped"), CTL(stats_mapped)},
Jason Evans04c3c0f2016-05-03 22:11:35 -0700493 {NAME("retained"), CTL(stats_retained)},
Qi Wang64c5f5c2017-03-13 17:29:03 -0700494 {NAME("mutexes"), CHILD(named, stats_mutexes)},
Jason Evans3c4d92e2014-10-12 22:53:59 -0700495 {NAME("arenas"), CHILD(indexed, stats_arenas)}
Jason Evans3c234352010-01-27 13:10:55 -0800496};
497
Mike Hommey461ad5c2012-04-20 08:38:42 +0200498static const ctl_named_node_t root_node[] = {
Jason Evansa40bc7a2010-03-02 13:01:16 -0800499 {NAME("version"), CTL(version)},
Jason Evans3c234352010-01-27 13:10:55 -0800500 {NAME("epoch"), CTL(epoch)},
Jason Evans65f343a2012-04-23 19:31:45 -0700501 {NAME("thread"), CHILD(named, thread)},
502 {NAME("config"), CHILD(named, config)},
503 {NAME("opt"), CHILD(named, opt)},
Jason Evans1cb181e2015-01-29 15:30:47 -0800504 {NAME("tcache"), CHILD(named, tcache)},
Jason Evans609ae592012-10-11 13:53:15 -0700505 {NAME("arena"), CHILD(indexed, arena)},
Jason Evans65f343a2012-04-23 19:31:45 -0700506 {NAME("arenas"), CHILD(named, arenas)},
507 {NAME("prof"), CHILD(named, prof)},
508 {NAME("stats"), CHILD(named, stats)}
Jason Evans3c234352010-01-27 13:10:55 -0800509};
Mike Hommey461ad5c2012-04-20 08:38:42 +0200510static const ctl_named_node_t super_root_node[] = {
Jason Evans65f343a2012-04-23 19:31:45 -0700511 {NAME(""), CHILD(named, root)}
Jason Evans3c234352010-01-27 13:10:55 -0800512};
513
514#undef NAME
515#undef CHILD
516#undef CTL
517#undef INDEX
518
519/******************************************************************************/
520
David Goldblatt4fc2acf2017-03-08 15:56:31 -0800521/*
522 * Sets *dst + *src non-atomically. This is safe, since everything is
523 * synchronized by the ctl mutex.
524 */
525static void
526accum_arena_stats_u64(arena_stats_u64_t *dst, arena_stats_u64_t *src) {
527#ifdef JEMALLOC_ATOMIC_U64
528 uint64_t cur_dst = atomic_load_u64(dst, ATOMIC_RELAXED);
529 uint64_t cur_src = atomic_load_u64(src, ATOMIC_RELAXED);
530 atomic_store_u64(dst, cur_dst + cur_src, ATOMIC_RELAXED);
531#else
532 *dst += *src;
533#endif
534}
535
536/* Likewise: with ctl mutex synchronization, reading is simple. */
537static uint64_t
538arena_stats_read_u64(arena_stats_u64_t *p) {
539#ifdef JEMALLOC_ATOMIC_U64
540 return atomic_load_u64(p, ATOMIC_RELAXED);
541#else
542 return *p;
543#endif
544}
545
David Goldblattee202ef2017-03-13 16:18:40 -0700546static void accum_atomic_zu(atomic_zu_t *dst, atomic_zu_t *src) {
547 size_t cur_dst = atomic_load_zu(dst, ATOMIC_RELAXED);
548 size_t cur_src = atomic_load_zu(src, ATOMIC_RELAXED);
549 atomic_store_zu(dst, cur_dst + cur_src, ATOMIC_RELAXED);
550}
551
David Goldblatt4fc2acf2017-03-08 15:56:31 -0800552/******************************************************************************/
553
Jason Evans3dc4e832017-01-03 07:27:42 -0800554static unsigned
Jason Evansc4c25922017-01-15 16:56:30 -0800555arenas_i2a_impl(size_t i, bool compat, bool validate) {
Jason Evans3dc4e832017-01-03 07:27:42 -0800556 unsigned a;
557
Jason Evans3dc4e832017-01-03 07:27:42 -0800558 switch (i) {
559 case MALLCTL_ARENAS_ALL:
560 a = 0;
561 break;
Jason Evansedf1baf2017-01-03 17:21:59 -0800562 case MALLCTL_ARENAS_DESTROYED:
563 a = 1;
564 break;
Jason Evans3dc4e832017-01-03 07:27:42 -0800565 default:
Jason Evans9eb1b1c2017-01-18 23:03:37 -0800566 if (compat && i == ctl_arenas->narenas) {
Jason Evans3dc4e832017-01-03 07:27:42 -0800567 /*
568 * Provide deprecated backward compatibility for
569 * accessing the merged stats at index narenas rather
570 * than via MALLCTL_ARENAS_ALL. This is scheduled for
571 * removal in 6.0.0.
572 */
573 a = 0;
Jason Evansc4c25922017-01-15 16:56:30 -0800574 } else if (validate && i >= ctl_arenas->narenas) {
Jason Evans3dc4e832017-01-03 07:27:42 -0800575 a = UINT_MAX;
Jason Evansc4c25922017-01-15 16:56:30 -0800576 } else {
Jason Evans3dc4e832017-01-03 07:27:42 -0800577 /*
578 * This function should never be called for an index
579 * more than one past the range of indices that have
Jason Evans9eb1b1c2017-01-18 23:03:37 -0800580 * initialized ctl data.
Jason Evans3dc4e832017-01-03 07:27:42 -0800581 */
Jason Evans9eb1b1c2017-01-18 23:03:37 -0800582 assert(i < ctl_arenas->narenas || (!validate && i ==
583 ctl_arenas->narenas));
Jason Evansedf1baf2017-01-03 17:21:59 -0800584 a = (unsigned)i + 2;
Jason Evans3dc4e832017-01-03 07:27:42 -0800585 }
586 break;
587 }
588
Jason Evansf4086432017-01-19 18:15:45 -0800589 return a;
Jason Evans3dc4e832017-01-03 07:27:42 -0800590}
591
Jason Evansedf1baf2017-01-03 17:21:59 -0800592static unsigned
Jason Evansc4c25922017-01-15 16:56:30 -0800593arenas_i2a(size_t i) {
Jason Evansf4086432017-01-19 18:15:45 -0800594 return arenas_i2a_impl(i, true, false);
Jason Evansedf1baf2017-01-03 17:21:59 -0800595}
596
Jason Evans9eb1b1c2017-01-18 23:03:37 -0800597static ctl_arena_t *
Jason Evansc4c25922017-01-15 16:56:30 -0800598arenas_i_impl(tsdn_t *tsdn, size_t i, bool compat, bool init) {
Jason Evans9eb1b1c2017-01-18 23:03:37 -0800599 ctl_arena_t *ret;
Jason Evansd778dd22017-01-03 12:40:54 -0800600
601 assert(!compat || !init);
602
Jason Evans9eb1b1c2017-01-18 23:03:37 -0800603 ret = ctl_arenas->arenas[arenas_i2a_impl(i, compat, false)];
Jason Evansd778dd22017-01-03 12:40:54 -0800604 if (init && ret == NULL) {
Jason Evans9eb1b1c2017-01-18 23:03:37 -0800605 if (config_stats) {
606 struct container_s {
607 ctl_arena_t ctl_arena;
608 ctl_arena_stats_t astats;
609 };
610 struct container_s *cont =
611 (struct container_s *)base_alloc(tsdn, b0get(),
612 sizeof(struct container_s), QUANTUM);
613 if (cont == NULL) {
614 return NULL;
615 }
616 ret = &cont->ctl_arena;
617 ret->astats = &cont->astats;
618 } else {
619 ret = (ctl_arena_t *)base_alloc(tsdn, b0get(),
620 sizeof(ctl_arena_t), QUANTUM);
621 if (ret == NULL) {
622 return NULL;
623 }
624 }
Jason Evansedf1baf2017-01-03 17:21:59 -0800625 ret->arena_ind = (unsigned)i;
Jason Evans9eb1b1c2017-01-18 23:03:37 -0800626 ctl_arenas->arenas[arenas_i2a_impl(i, compat, false)] = ret;
Jason Evansd778dd22017-01-03 12:40:54 -0800627 }
628
Jason Evans9eb1b1c2017-01-18 23:03:37 -0800629 assert(ret == NULL || arenas_i2a(ret->arena_ind) == arenas_i2a(i));
Jason Evansf4086432017-01-19 18:15:45 -0800630 return ret;
Jason Evansd778dd22017-01-03 12:40:54 -0800631}
632
Jason Evans9eb1b1c2017-01-18 23:03:37 -0800633static ctl_arena_t *
Jason Evansc4c25922017-01-15 16:56:30 -0800634arenas_i(size_t i) {
Jason Evans9eb1b1c2017-01-18 23:03:37 -0800635 ctl_arena_t *ret = arenas_i_impl(TSDN_NULL, i, true, false);
Jason Evansd778dd22017-01-03 12:40:54 -0800636 assert(ret != NULL);
Jason Evansf4086432017-01-19 18:15:45 -0800637 return ret;
Jason Evans3dc4e832017-01-03 07:27:42 -0800638}
639
Jason Evans3c234352010-01-27 13:10:55 -0800640static void
Jason Evansc4c25922017-01-15 16:56:30 -0800641ctl_arena_clear(ctl_arena_t *ctl_arena) {
Jason Evans9eb1b1c2017-01-18 23:03:37 -0800642 ctl_arena->nthreads = 0;
643 ctl_arena->dss = dss_prec_names[dss_prec_limit];
Jason Evans64e458f2017-03-08 22:42:57 -0800644 ctl_arena->dirty_decay_time = -1;
645 ctl_arena->muzzy_decay_time = -1;
Jason Evans9eb1b1c2017-01-18 23:03:37 -0800646 ctl_arena->pactive = 0;
647 ctl_arena->pdirty = 0;
Jason Evans64e458f2017-03-08 22:42:57 -0800648 ctl_arena->pmuzzy = 0;
Jason Evans7372b152012-02-10 20:22:09 -0800649 if (config_stats) {
Jason Evans9eb1b1c2017-01-18 23:03:37 -0800650 memset(&ctl_arena->astats->astats, 0, sizeof(arena_stats_t));
651 ctl_arena->astats->allocated_small = 0;
652 ctl_arena->astats->nmalloc_small = 0;
653 ctl_arena->astats->ndalloc_small = 0;
654 ctl_arena->astats->nrequests_small = 0;
655 memset(ctl_arena->astats->bstats, 0, NBINS *
656 sizeof(malloc_bin_stats_t));
657 memset(ctl_arena->astats->lstats, 0, (NSIZES - NBINS) *
Jason Evans7d63fed2016-05-31 14:50:21 -0700658 sizeof(malloc_large_stats_t));
Jason Evans7372b152012-02-10 20:22:09 -0800659 }
Jason Evans3c234352010-01-27 13:10:55 -0800660}
661
Jason Evans86815df2010-03-13 20:32:56 -0800662static void
Jason Evansc4c25922017-01-15 16:56:30 -0800663ctl_arena_stats_amerge(tsdn_t *tsdn, ctl_arena_t *ctl_arena, arena_t *arena) {
Jason Evans86815df2010-03-13 20:32:56 -0800664 unsigned i;
665
Jason Evans3c07f802016-02-27 20:40:13 -0800666 if (config_stats) {
Jason Evans9eb1b1c2017-01-18 23:03:37 -0800667 arena_stats_merge(tsdn, arena, &ctl_arena->nthreads,
Jason Evans64e458f2017-03-08 22:42:57 -0800668 &ctl_arena->dss, &ctl_arena->dirty_decay_time,
669 &ctl_arena->muzzy_decay_time, &ctl_arena->pactive,
670 &ctl_arena->pdirty, &ctl_arena->pmuzzy,
Jason Evans9eb1b1c2017-01-18 23:03:37 -0800671 &ctl_arena->astats->astats, ctl_arena->astats->bstats,
672 ctl_arena->astats->lstats);
Jason Evans86815df2010-03-13 20:32:56 -0800673
Jason Evans3c07f802016-02-27 20:40:13 -0800674 for (i = 0; i < NBINS; i++) {
Jason Evans9eb1b1c2017-01-18 23:03:37 -0800675 ctl_arena->astats->allocated_small +=
676 ctl_arena->astats->bstats[i].curregs *
Jason Evans3c07f802016-02-27 20:40:13 -0800677 index2size(i);
Jason Evans9eb1b1c2017-01-18 23:03:37 -0800678 ctl_arena->astats->nmalloc_small +=
679 ctl_arena->astats->bstats[i].nmalloc;
680 ctl_arena->astats->ndalloc_small +=
681 ctl_arena->astats->bstats[i].ndalloc;
682 ctl_arena->astats->nrequests_small +=
683 ctl_arena->astats->bstats[i].nrequests;
Jason Evans3c07f802016-02-27 20:40:13 -0800684 }
685 } else {
Jason Evans9eb1b1c2017-01-18 23:03:37 -0800686 arena_basic_stats_merge(tsdn, arena, &ctl_arena->nthreads,
Jason Evans64e458f2017-03-08 22:42:57 -0800687 &ctl_arena->dss, &ctl_arena->dirty_decay_time,
688 &ctl_arena->muzzy_decay_time, &ctl_arena->pactive,
689 &ctl_arena->pdirty, &ctl_arena->pmuzzy);
Jason Evans86815df2010-03-13 20:32:56 -0800690 }
Jason Evans86815df2010-03-13 20:32:56 -0800691}
692
693static void
Jason Evans9eb1b1c2017-01-18 23:03:37 -0800694ctl_arena_stats_sdmerge(ctl_arena_t *ctl_sdarena, ctl_arena_t *ctl_arena,
Jason Evansc4c25922017-01-15 16:56:30 -0800695 bool destroyed) {
Jason Evans86815df2010-03-13 20:32:56 -0800696 unsigned i;
697
Jason Evansedf1baf2017-01-03 17:21:59 -0800698 if (!destroyed) {
Jason Evans9eb1b1c2017-01-18 23:03:37 -0800699 ctl_sdarena->nthreads += ctl_arena->nthreads;
700 ctl_sdarena->pactive += ctl_arena->pactive;
701 ctl_sdarena->pdirty += ctl_arena->pdirty;
Jason Evans64e458f2017-03-08 22:42:57 -0800702 ctl_sdarena->pmuzzy += ctl_arena->pmuzzy;
Jason Evansedf1baf2017-01-03 17:21:59 -0800703 } else {
Jason Evans9eb1b1c2017-01-18 23:03:37 -0800704 assert(ctl_arena->nthreads == 0);
705 assert(ctl_arena->pactive == 0);
706 assert(ctl_arena->pdirty == 0);
Jason Evans64e458f2017-03-08 22:42:57 -0800707 assert(ctl_arena->pmuzzy == 0);
Jason Evansedf1baf2017-01-03 17:21:59 -0800708 }
Jason Evans86815df2010-03-13 20:32:56 -0800709
Jason Evans3c07f802016-02-27 20:40:13 -0800710 if (config_stats) {
Jason Evans9eb1b1c2017-01-18 23:03:37 -0800711 ctl_arena_stats_t *sdstats = ctl_sdarena->astats;
712 ctl_arena_stats_t *astats = ctl_arena->astats;
713
Jason Evansedf1baf2017-01-03 17:21:59 -0800714 if (!destroyed) {
David Goldblattee202ef2017-03-13 16:18:40 -0700715 accum_atomic_zu(&sdstats->astats.mapped,
716 &astats->astats.mapped);
717 accum_atomic_zu(&sdstats->astats.retained,
718 &astats->astats.retained);
Jason Evansedf1baf2017-01-03 17:21:59 -0800719 }
Jason Evans64e458f2017-03-08 22:42:57 -0800720
721 accum_arena_stats_u64(&sdstats->astats.decay_dirty.npurge,
722 &astats->astats.decay_dirty.npurge);
723 accum_arena_stats_u64(&sdstats->astats.decay_dirty.nmadvise,
724 &astats->astats.decay_dirty.nmadvise);
725 accum_arena_stats_u64(&sdstats->astats.decay_dirty.purged,
726 &astats->astats.decay_dirty.purged);
727
728 accum_arena_stats_u64(&sdstats->astats.decay_muzzy.npurge,
729 &astats->astats.decay_muzzy.npurge);
730 accum_arena_stats_u64(&sdstats->astats.decay_muzzy.nmadvise,
731 &astats->astats.decay_muzzy.nmadvise);
732 accum_arena_stats_u64(&sdstats->astats.decay_muzzy.purged,
733 &astats->astats.decay_muzzy.purged);
Jason Evans86815df2010-03-13 20:32:56 -0800734
Qi Wangd3fde1c2017-03-21 11:56:38 -0700735#define OP(mtx) malloc_mutex_prof_merge( \
736 &(sdstats->astats.mutex_prof_data[ \
737 arena_prof_mutex_##mtx]), \
738 &(astats->astats.mutex_prof_data[ \
739 arena_prof_mutex_##mtx]));
740ARENA_PROF_MUTEXES
741#undef OP
Jason Evansedf1baf2017-01-03 17:21:59 -0800742 if (!destroyed) {
David Goldblattee202ef2017-03-13 16:18:40 -0700743 accum_atomic_zu(&sdstats->astats.base,
744 &astats->astats.base);
745 accum_atomic_zu(&sdstats->astats.internal,
746 &astats->astats.internal);
747 accum_atomic_zu(&sdstats->astats.resident,
748 &astats->astats.resident);
Jason Evansc4c25922017-01-15 16:56:30 -0800749 } else {
David Goldblattee202ef2017-03-13 16:18:40 -0700750 assert(atomic_load_zu(
751 &astats->astats.internal, ATOMIC_RELAXED) == 0);
Jason Evansc4c25922017-01-15 16:56:30 -0800752 }
Jason Evans4581b972014-11-27 17:22:36 -0200753
Jason Evansc4c25922017-01-15 16:56:30 -0800754 if (!destroyed) {
Jason Evansedf1baf2017-01-03 17:21:59 -0800755 sdstats->allocated_small += astats->allocated_small;
Jason Evansc4c25922017-01-15 16:56:30 -0800756 } else {
Jason Evansedf1baf2017-01-03 17:21:59 -0800757 assert(astats->allocated_small == 0);
Jason Evansc4c25922017-01-15 16:56:30 -0800758 }
Jason Evansedf1baf2017-01-03 17:21:59 -0800759 sdstats->nmalloc_small += astats->nmalloc_small;
760 sdstats->ndalloc_small += astats->ndalloc_small;
761 sdstats->nrequests_small += astats->nrequests_small;
Jason Evans86815df2010-03-13 20:32:56 -0800762
Jason Evansedf1baf2017-01-03 17:21:59 -0800763 if (!destroyed) {
David Goldblattee202ef2017-03-13 16:18:40 -0700764 accum_atomic_zu(&sdstats->astats.allocated_large,
765 &astats->astats.allocated_large);
Jason Evansc4c25922017-01-15 16:56:30 -0800766 } else {
David Goldblattee202ef2017-03-13 16:18:40 -0700767 assert(atomic_load_zu(&astats->astats.allocated_large,
768 ATOMIC_RELAXED) == 0);
Jason Evansc4c25922017-01-15 16:56:30 -0800769 }
David Goldblatt4fc2acf2017-03-08 15:56:31 -0800770 accum_arena_stats_u64(&sdstats->astats.nmalloc_large,
771 &astats->astats.nmalloc_large);
772 accum_arena_stats_u64(&sdstats->astats.ndalloc_large,
773 &astats->astats.ndalloc_large);
774 accum_arena_stats_u64(&sdstats->astats.nrequests_large,
775 &astats->astats.nrequests_large);
Jason Evans86815df2010-03-13 20:32:56 -0800776
Jason Evans4403c9a2017-04-20 17:21:37 -0700777 accum_atomic_zu(&sdstats->astats.tcache_bytes,
778 &astats->astats.tcache_bytes);
Qi Wang58424e62016-04-22 18:37:44 -0700779
Jason Evans3c07f802016-02-27 20:40:13 -0800780 for (i = 0; i < NBINS; i++) {
Jason Evansedf1baf2017-01-03 17:21:59 -0800781 sdstats->bstats[i].nmalloc += astats->bstats[i].nmalloc;
782 sdstats->bstats[i].ndalloc += astats->bstats[i].ndalloc;
783 sdstats->bstats[i].nrequests +=
Jason Evans3c07f802016-02-27 20:40:13 -0800784 astats->bstats[i].nrequests;
Jason Evansedf1baf2017-01-03 17:21:59 -0800785 if (!destroyed) {
786 sdstats->bstats[i].curregs +=
787 astats->bstats[i].curregs;
Jason Evansc4c25922017-01-15 16:56:30 -0800788 } else {
Jason Evansedf1baf2017-01-03 17:21:59 -0800789 assert(astats->bstats[i].curregs == 0);
Jason Evansc4c25922017-01-15 16:56:30 -0800790 }
Jason Evans4403c9a2017-04-20 17:21:37 -0700791 sdstats->bstats[i].nfills += astats->bstats[i].nfills;
792 sdstats->bstats[i].nflushes +=
793 astats->bstats[i].nflushes;
Jason Evansedf1baf2017-01-03 17:21:59 -0800794 sdstats->bstats[i].nslabs += astats->bstats[i].nslabs;
795 sdstats->bstats[i].reslabs += astats->bstats[i].reslabs;
796 if (!destroyed) {
797 sdstats->bstats[i].curslabs +=
798 astats->bstats[i].curslabs;
Jason Evansc4c25922017-01-15 16:56:30 -0800799 } else {
Jason Evansedf1baf2017-01-03 17:21:59 -0800800 assert(astats->bstats[i].curslabs == 0);
Jason Evansc4c25922017-01-15 16:56:30 -0800801 }
Qi Wang64c5f5c2017-03-13 17:29:03 -0700802 malloc_mutex_prof_merge(&sdstats->bstats[i].mutex_data,
803 &astats->bstats[i].mutex_data);
Jason Evans7372b152012-02-10 20:22:09 -0800804 }
Jason Evans3c4d92e2014-10-12 22:53:59 -0700805
Jason Evansed2c2422016-05-28 00:17:28 -0700806 for (i = 0; i < NSIZES - NBINS; i++) {
David Goldblatt4fc2acf2017-03-08 15:56:31 -0800807 accum_arena_stats_u64(&sdstats->lstats[i].nmalloc,
808 &astats->lstats[i].nmalloc);
809 accum_arena_stats_u64(&sdstats->lstats[i].ndalloc,
810 &astats->lstats[i].ndalloc);
811 accum_arena_stats_u64(&sdstats->lstats[i].nrequests,
812 &astats->lstats[i].nrequests);
Jason Evansedf1baf2017-01-03 17:21:59 -0800813 if (!destroyed) {
814 sdstats->lstats[i].curlextents +=
815 astats->lstats[i].curlextents;
Jason Evansc4c25922017-01-15 16:56:30 -0800816 } else {
Jason Evansedf1baf2017-01-03 17:21:59 -0800817 assert(astats->lstats[i].curlextents == 0);
Jason Evansc4c25922017-01-15 16:56:30 -0800818 }
Jason Evans3c07f802016-02-27 20:40:13 -0800819 }
Jason Evans3c4d92e2014-10-12 22:53:59 -0700820 }
Jason Evans86815df2010-03-13 20:32:56 -0800821}
Jason Evans86815df2010-03-13 20:32:56 -0800822
Jason Evans3c234352010-01-27 13:10:55 -0800823static void
Jason Evans9eb1b1c2017-01-18 23:03:37 -0800824ctl_arena_refresh(tsdn_t *tsdn, arena_t *arena, ctl_arena_t *ctl_sdarena,
Jason Evansc4c25922017-01-15 16:56:30 -0800825 unsigned i, bool destroyed) {
Jason Evans9eb1b1c2017-01-18 23:03:37 -0800826 ctl_arena_t *ctl_arena = arenas_i(i);
Jason Evans3c234352010-01-27 13:10:55 -0800827
Jason Evans9eb1b1c2017-01-18 23:03:37 -0800828 ctl_arena_clear(ctl_arena);
829 ctl_arena_stats_amerge(tsdn, ctl_arena, arena);
Jason Evans3c07f802016-02-27 20:40:13 -0800830 /* Merge into sum stats as well. */
Jason Evans9eb1b1c2017-01-18 23:03:37 -0800831 ctl_arena_stats_sdmerge(ctl_sdarena, ctl_arena, destroyed);
Jason Evans3c234352010-01-27 13:10:55 -0800832}
833
Jason Evansedf1baf2017-01-03 17:21:59 -0800834static unsigned
Jason Evansc4c25922017-01-15 16:56:30 -0800835ctl_arena_init(tsdn_t *tsdn, extent_hooks_t *extent_hooks) {
Jason Evansedf1baf2017-01-03 17:21:59 -0800836 unsigned arena_ind;
Jason Evans9eb1b1c2017-01-18 23:03:37 -0800837 ctl_arena_t *ctl_arena;
Jason Evansedf1baf2017-01-03 17:21:59 -0800838
Jason Evans9eb1b1c2017-01-18 23:03:37 -0800839 if ((ctl_arena = ql_last(&ctl_arenas->destroyed, destroyed_link)) !=
840 NULL) {
841 ql_remove(&ctl_arenas->destroyed, ctl_arena, destroyed_link);
842 arena_ind = ctl_arena->arena_ind;
Jason Evansc4c25922017-01-15 16:56:30 -0800843 } else {
Jason Evans9eb1b1c2017-01-18 23:03:37 -0800844 arena_ind = ctl_arenas->narenas;
Jason Evansc4c25922017-01-15 16:56:30 -0800845 }
Jason Evansd778dd22017-01-03 12:40:54 -0800846
847 /* Trigger stats allocation. */
Jason Evansc4c25922017-01-15 16:56:30 -0800848 if (arenas_i_impl(tsdn, arena_ind, false, true) == NULL) {
Jason Evansf4086432017-01-19 18:15:45 -0800849 return UINT_MAX;
Jason Evansc4c25922017-01-15 16:56:30 -0800850 }
Jason Evans609ae592012-10-11 13:53:15 -0700851
Jason Evans8bb31982014-10-07 23:14:57 -0700852 /* Initialize new arena. */
Jason Evansc4c25922017-01-15 16:56:30 -0800853 if (arena_init(tsdn, arena_ind, extent_hooks) == NULL) {
Jason Evansf4086432017-01-19 18:15:45 -0800854 return UINT_MAX;
Jason Evansc4c25922017-01-15 16:56:30 -0800855 }
Jason Evans609ae592012-10-11 13:53:15 -0700856
Jason Evansc4c25922017-01-15 16:56:30 -0800857 if (arena_ind == ctl_arenas->narenas) {
Jason Evans9eb1b1c2017-01-18 23:03:37 -0800858 ctl_arenas->narenas++;
Jason Evansc4c25922017-01-15 16:56:30 -0800859 }
Jason Evansedf1baf2017-01-03 17:21:59 -0800860
Jason Evansf4086432017-01-19 18:15:45 -0800861 return arena_ind;
Jason Evans609ae592012-10-11 13:53:15 -0700862}
863
Jason Evans3c234352010-01-27 13:10:55 -0800864static void
Jason Evansc4c25922017-01-15 16:56:30 -0800865ctl_refresh(tsdn_t *tsdn) {
Jason Evans3c234352010-01-27 13:10:55 -0800866 unsigned i;
Jason Evans9eb1b1c2017-01-18 23:03:37 -0800867 ctl_arena_t *ctl_sarena = arenas_i(MALLCTL_ARENAS_ALL);
868 VARIABLE_ARRAY(arena_t *, tarenas, ctl_arenas->narenas);
Jason Evans3c234352010-01-27 13:10:55 -0800869
Jason Evans3c234352010-01-27 13:10:55 -0800870 /*
Jason Evans13668262010-01-31 03:57:29 -0800871 * Clear sum stats, since they will be merged into by
Jason Evans3c234352010-01-27 13:10:55 -0800872 * ctl_arena_refresh().
873 */
Jason Evans9eb1b1c2017-01-18 23:03:37 -0800874 ctl_arena_clear(ctl_sarena);
Jason Evans3c234352010-01-27 13:10:55 -0800875
Jason Evans9eb1b1c2017-01-18 23:03:37 -0800876 for (i = 0; i < ctl_arenas->narenas; i++) {
Jason Evansc1e00ef2016-05-10 22:21:10 -0700877 tarenas[i] = arena_get(tsdn, i, false);
Jason Evans9eb1b1c2017-01-18 23:03:37 -0800878 }
Jason Evans8bb31982014-10-07 23:14:57 -0700879
Jason Evans9eb1b1c2017-01-18 23:03:37 -0800880 for (i = 0; i < ctl_arenas->narenas; i++) {
881 ctl_arena_t *ctl_arena = arenas_i(i);
Jason Evans3c234352010-01-27 13:10:55 -0800882 bool initialized = (tarenas[i] != NULL);
883
Jason Evans9eb1b1c2017-01-18 23:03:37 -0800884 ctl_arena->initialized = initialized;
885 if (initialized) {
886 ctl_arena_refresh(tsdn, tarenas[i], ctl_sarena, i,
887 false);
888 }
Jason Evans3c234352010-01-27 13:10:55 -0800889 }
890
Jason Evans7372b152012-02-10 20:22:09 -0800891 if (config_stats) {
Jason Evans9eb1b1c2017-01-18 23:03:37 -0800892 ctl_stats->allocated = ctl_sarena->astats->allocated_small +
David Goldblattee202ef2017-03-13 16:18:40 -0700893 atomic_load_zu(&ctl_sarena->astats->astats.allocated_large,
894 ATOMIC_RELAXED);
Jason Evans9eb1b1c2017-01-18 23:03:37 -0800895 ctl_stats->active = (ctl_sarena->pactive << LG_PAGE);
David Goldblattee202ef2017-03-13 16:18:40 -0700896 ctl_stats->metadata = atomic_load_zu(
897 &ctl_sarena->astats->astats.base, ATOMIC_RELAXED) +
898 atomic_load_zu(&ctl_sarena->astats->astats.internal,
899 ATOMIC_RELAXED);
900 ctl_stats->resident = atomic_load_zu(
901 &ctl_sarena->astats->astats.resident, ATOMIC_RELAXED);
902 ctl_stats->mapped = atomic_load_zu(
903 &ctl_sarena->astats->astats.mapped, ATOMIC_RELAXED);
904 ctl_stats->retained = atomic_load_zu(
905 &ctl_sarena->astats->astats.retained, ATOMIC_RELAXED);
Qi Wangca9074d2017-03-11 20:28:31 -0800906
Qi Wangd3fde1c2017-03-21 11:56:38 -0700907#define READ_GLOBAL_MUTEX_PROF_DATA(i, mtx) \
Qi Wangca9074d2017-03-11 20:28:31 -0800908 malloc_mutex_lock(tsdn, &mtx); \
Qi Wangd3fde1c2017-03-21 11:56:38 -0700909 malloc_mutex_prof_read(tsdn, &ctl_stats->mutex_prof_data[i], &mtx); \
Qi Wangca9074d2017-03-11 20:28:31 -0800910 malloc_mutex_unlock(tsdn, &mtx);
911
Qi Wangbd2006a2017-03-12 01:28:52 -0800912 if (config_prof && opt_prof) {
Qi Wangd3fde1c2017-03-21 11:56:38 -0700913 READ_GLOBAL_MUTEX_PROF_DATA(global_prof_mutex_prof,
914 bt2gctx_mtx);
Qi Wangbd2006a2017-03-12 01:28:52 -0800915 }
Qi Wangca9074d2017-03-11 20:28:31 -0800916 /* We own ctl mutex already. */
Qi Wangd3fde1c2017-03-21 11:56:38 -0700917 malloc_mutex_prof_read(tsdn,
918 &ctl_stats->mutex_prof_data[global_prof_mutex_ctl],
919 &ctl_mtx);
Qi Wangca9074d2017-03-11 20:28:31 -0800920#undef READ_GLOBAL_MUTEX_PROF_DATA
Jason Evans7372b152012-02-10 20:22:09 -0800921 }
Jason Evans9eb1b1c2017-01-18 23:03:37 -0800922 ctl_arenas->epoch++;
Jason Evans3c234352010-01-27 13:10:55 -0800923}
924
925static bool
Jason Evansc4c25922017-01-15 16:56:30 -0800926ctl_init(tsdn_t *tsdn) {
Jason Evansfc4dcfa2010-11-24 15:44:21 -0800927 bool ret;
Jason Evans3c234352010-01-27 13:10:55 -0800928
Jason Evansc1e00ef2016-05-10 22:21:10 -0700929 malloc_mutex_lock(tsdn, &ctl_mtx);
Jason Evans551ebc42014-10-03 10:16:09 -0700930 if (!ctl_initialized) {
Jason Evans9eb1b1c2017-01-18 23:03:37 -0800931 ctl_arena_t *ctl_sarena, *ctl_darena;
Jason Evansd778dd22017-01-03 12:40:54 -0800932 unsigned i;
933
Jason Evans3c234352010-01-27 13:10:55 -0800934 /*
Jason Evans9eb1b1c2017-01-18 23:03:37 -0800935 * Allocate demand-zeroed space for pointers to the full
936 * range of supported arena indices.
Jason Evans3c234352010-01-27 13:10:55 -0800937 */
Jason Evans9eb1b1c2017-01-18 23:03:37 -0800938 if (ctl_arenas == NULL) {
939 ctl_arenas = (ctl_arenas_t *)base_alloc(tsdn,
940 b0get(), sizeof(ctl_arenas_t), QUANTUM);
941 if (ctl_arenas == NULL) {
942 ret = true;
943 goto label_return;
944 }
945 }
946
947 if (config_stats && ctl_stats == NULL) {
Jason Evansd778dd22017-01-03 12:40:54 -0800948 ctl_stats = (ctl_stats_t *)base_alloc(tsdn, b0get(),
949 sizeof(ctl_stats_t), QUANTUM);
950 if (ctl_stats == NULL) {
951 ret = true;
952 goto label_return;
953 }
954 }
955
956 /*
Jason Evans9eb1b1c2017-01-18 23:03:37 -0800957 * Allocate space for the current full range of arenas
958 * here rather than doing it lazily elsewhere, in order
959 * to limit when OOM-caused errors can occur.
Jason Evansd778dd22017-01-03 12:40:54 -0800960 */
Jason Evans9eb1b1c2017-01-18 23:03:37 -0800961 if ((ctl_sarena = arenas_i_impl(tsdn, MALLCTL_ARENAS_ALL, false,
962 true)) == NULL) {
963 ret = true;
964 goto label_return;
965 }
966 ctl_sarena->initialized = true;
967
968 if ((ctl_darena = arenas_i_impl(tsdn, MALLCTL_ARENAS_DESTROYED,
Jason Evansd778dd22017-01-03 12:40:54 -0800969 false, true)) == NULL) {
Jason Evansfc4dcfa2010-11-24 15:44:21 -0800970 ret = true;
Jason Evansa1ee7832012-04-10 15:07:44 -0700971 goto label_return;
Jason Evansfc4dcfa2010-11-24 15:44:21 -0800972 }
Jason Evans9eb1b1c2017-01-18 23:03:37 -0800973 ctl_arena_clear(ctl_darena);
Jason Evansedf1baf2017-01-03 17:21:59 -0800974 /*
Jason Evans9eb1b1c2017-01-18 23:03:37 -0800975 * Don't toggle ctl_darena to initialized until an arena is
976 * actually destroyed, so that arena.<i>.initialized can be used
977 * to query whether the stats are relevant.
Jason Evansedf1baf2017-01-03 17:21:59 -0800978 */
979
Jason Evans9eb1b1c2017-01-18 23:03:37 -0800980 ctl_arenas->narenas = narenas_total_get();
981 for (i = 0; i < ctl_arenas->narenas; i++) {
982 if (arenas_i_impl(tsdn, i, false, true) == NULL) {
Jason Evansd778dd22017-01-03 12:40:54 -0800983 ret = true;
984 goto label_return;
985 }
986 }
Jason Evans3c234352010-01-27 13:10:55 -0800987
Jason Evans9eb1b1c2017-01-18 23:03:37 -0800988 ql_new(&ctl_arenas->destroyed);
Jason Evansc1e00ef2016-05-10 22:21:10 -0700989 ctl_refresh(tsdn);
Jason Evans9eb1b1c2017-01-18 23:03:37 -0800990
Jason Evans3c234352010-01-27 13:10:55 -0800991 ctl_initialized = true;
992 }
993
Jason Evansfc4dcfa2010-11-24 15:44:21 -0800994 ret = false;
Jason Evansa1ee7832012-04-10 15:07:44 -0700995label_return:
Jason Evansc1e00ef2016-05-10 22:21:10 -0700996 malloc_mutex_unlock(tsdn, &ctl_mtx);
Jason Evansf4086432017-01-19 18:15:45 -0800997 return ret;
Jason Evans3c234352010-01-27 13:10:55 -0800998}
999
1000static int
Jason Evansc1e00ef2016-05-10 22:21:10 -07001001ctl_lookup(tsdn_t *tsdn, const char *name, ctl_node_t const **nodesp,
Jason Evansc4c25922017-01-15 16:56:30 -08001002 size_t *mibp, size_t *depthp) {
Jason Evans3c234352010-01-27 13:10:55 -08001003 int ret;
1004 const char *elm, *tdot, *dot;
1005 size_t elen, i, j;
Mike Hommey461ad5c2012-04-20 08:38:42 +02001006 const ctl_named_node_t *node;
Jason Evans3c234352010-01-27 13:10:55 -08001007
1008 elm = name;
1009 /* Equivalent to strchrnul(). */
1010 dot = ((tdot = strchr(elm, '.')) != NULL) ? tdot : strchr(elm, '\0');
1011 elen = (size_t)((uintptr_t)dot - (uintptr_t)elm);
1012 if (elen == 0) {
1013 ret = ENOENT;
Jason Evansa1ee7832012-04-10 15:07:44 -07001014 goto label_return;
Jason Evans3c234352010-01-27 13:10:55 -08001015 }
1016 node = super_root_node;
1017 for (i = 0; i < *depthp; i++) {
Mike Hommey461ad5c2012-04-20 08:38:42 +02001018 assert(node);
1019 assert(node->nchildren > 0);
1020 if (ctl_named_node(node->children) != NULL) {
1021 const ctl_named_node_t *pnode = node;
Jason Evans3c234352010-01-27 13:10:55 -08001022
1023 /* Children are named. */
Mike Hommey461ad5c2012-04-20 08:38:42 +02001024 for (j = 0; j < node->nchildren; j++) {
1025 const ctl_named_node_t *child =
1026 ctl_named_children(node, j);
1027 if (strlen(child->name) == elen &&
1028 strncmp(elm, child->name, elen) == 0) {
Jason Evans3c234352010-01-27 13:10:55 -08001029 node = child;
Jason Evansc4c25922017-01-15 16:56:30 -08001030 if (nodesp != NULL) {
Mike Hommey461ad5c2012-04-20 08:38:42 +02001031 nodesp[i] =
1032 (const ctl_node_t *)node;
Jason Evansc4c25922017-01-15 16:56:30 -08001033 }
Jason Evans3c234352010-01-27 13:10:55 -08001034 mibp[i] = j;
1035 break;
1036 }
1037 }
1038 if (node == pnode) {
1039 ret = ENOENT;
Jason Evansa1ee7832012-04-10 15:07:44 -07001040 goto label_return;
Jason Evans3c234352010-01-27 13:10:55 -08001041 }
1042 } else {
Jason Evans41b6afb2012-02-02 22:04:57 -08001043 uintmax_t index;
Mike Hommey461ad5c2012-04-20 08:38:42 +02001044 const ctl_indexed_node_t *inode;
Jason Evans3c234352010-01-27 13:10:55 -08001045
1046 /* Children are indexed. */
Jason Evans41b6afb2012-02-02 22:04:57 -08001047 index = malloc_strtoumax(elm, NULL, 10);
1048 if (index == UINTMAX_MAX || index > SIZE_T_MAX) {
Jason Evans3c234352010-01-27 13:10:55 -08001049 ret = ENOENT;
Jason Evansa1ee7832012-04-10 15:07:44 -07001050 goto label_return;
Jason Evans3c234352010-01-27 13:10:55 -08001051 }
1052
Mike Hommey461ad5c2012-04-20 08:38:42 +02001053 inode = ctl_indexed_node(node->children);
Jason Evansc1e00ef2016-05-10 22:21:10 -07001054 node = inode->index(tsdn, mibp, *depthp, (size_t)index);
Jason Evans3c234352010-01-27 13:10:55 -08001055 if (node == NULL) {
1056 ret = ENOENT;
Jason Evansa1ee7832012-04-10 15:07:44 -07001057 goto label_return;
Jason Evans3c234352010-01-27 13:10:55 -08001058 }
1059
Jason Evansc4c25922017-01-15 16:56:30 -08001060 if (nodesp != NULL) {
Mike Hommey461ad5c2012-04-20 08:38:42 +02001061 nodesp[i] = (const ctl_node_t *)node;
Jason Evansc4c25922017-01-15 16:56:30 -08001062 }
Jason Evans3c234352010-01-27 13:10:55 -08001063 mibp[i] = (size_t)index;
1064 }
1065
1066 if (node->ctl != NULL) {
1067 /* Terminal node. */
1068 if (*dot != '\0') {
1069 /*
1070 * The name contains more elements than are
1071 * in this path through the tree.
1072 */
1073 ret = ENOENT;
Jason Evansa1ee7832012-04-10 15:07:44 -07001074 goto label_return;
Jason Evans3c234352010-01-27 13:10:55 -08001075 }
1076 /* Complete lookup successful. */
1077 *depthp = i + 1;
1078 break;
1079 }
1080
1081 /* Update elm. */
1082 if (*dot == '\0') {
1083 /* No more elements. */
1084 ret = ENOENT;
Jason Evansa1ee7832012-04-10 15:07:44 -07001085 goto label_return;
Jason Evans3c234352010-01-27 13:10:55 -08001086 }
1087 elm = &dot[1];
1088 dot = ((tdot = strchr(elm, '.')) != NULL) ? tdot :
1089 strchr(elm, '\0');
1090 elen = (size_t)((uintptr_t)dot - (uintptr_t)elm);
1091 }
1092
1093 ret = 0;
Jason Evansa1ee7832012-04-10 15:07:44 -07001094label_return:
Jason Evansf4086432017-01-19 18:15:45 -08001095 return ret;
Jason Evans3c234352010-01-27 13:10:55 -08001096}
1097
1098int
Jason Evansb2c0d632016-04-13 23:36:15 -07001099ctl_byname(tsd_t *tsd, const char *name, void *oldp, size_t *oldlenp,
Jason Evansc4c25922017-01-15 16:56:30 -08001100 void *newp, size_t newlen) {
Jason Evans3c234352010-01-27 13:10:55 -08001101 int ret;
1102 size_t depth;
1103 ctl_node_t const *nodes[CTL_MAX_DEPTH];
1104 size_t mib[CTL_MAX_DEPTH];
Mike Hommey461ad5c2012-04-20 08:38:42 +02001105 const ctl_named_node_t *node;
Jason Evans3c234352010-01-27 13:10:55 -08001106
Jason Evansc1e00ef2016-05-10 22:21:10 -07001107 if (!ctl_initialized && ctl_init(tsd_tsdn(tsd))) {
Jason Evans3c234352010-01-27 13:10:55 -08001108 ret = EAGAIN;
Jason Evansa1ee7832012-04-10 15:07:44 -07001109 goto label_return;
Jason Evans3c234352010-01-27 13:10:55 -08001110 }
1111
1112 depth = CTL_MAX_DEPTH;
Jason Evansc1e00ef2016-05-10 22:21:10 -07001113 ret = ctl_lookup(tsd_tsdn(tsd), name, nodes, mib, &depth);
Jason Evansc4c25922017-01-15 16:56:30 -08001114 if (ret != 0) {
Jason Evansa1ee7832012-04-10 15:07:44 -07001115 goto label_return;
Jason Evansc4c25922017-01-15 16:56:30 -08001116 }
Jason Evans3c234352010-01-27 13:10:55 -08001117
Mike Hommey461ad5c2012-04-20 08:38:42 +02001118 node = ctl_named_node(nodes[depth-1]);
Jason Evansc4c25922017-01-15 16:56:30 -08001119 if (node != NULL && node->ctl) {
Jason Evansb2c0d632016-04-13 23:36:15 -07001120 ret = node->ctl(tsd, mib, depth, oldp, oldlenp, newp, newlen);
Qi Wangaa1de062017-03-01 14:43:35 -08001121 } else {
Jason Evans3c234352010-01-27 13:10:55 -08001122 /* The name refers to a partial path through the ctl tree. */
1123 ret = ENOENT;
Jason Evans3c234352010-01-27 13:10:55 -08001124 }
Jason Evans3c234352010-01-27 13:10:55 -08001125
Jason Evansa1ee7832012-04-10 15:07:44 -07001126label_return:
Jason Evans3c234352010-01-27 13:10:55 -08001127 return(ret);
1128}
1129
1130int
Jason Evansc4c25922017-01-15 16:56:30 -08001131ctl_nametomib(tsdn_t *tsdn, const char *name, size_t *mibp, size_t *miblenp) {
Jason Evans3c234352010-01-27 13:10:55 -08001132 int ret;
1133
Jason Evansc1e00ef2016-05-10 22:21:10 -07001134 if (!ctl_initialized && ctl_init(tsdn)) {
Jason Evans3c234352010-01-27 13:10:55 -08001135 ret = EAGAIN;
Jason Evansa1ee7832012-04-10 15:07:44 -07001136 goto label_return;
Jason Evans3c234352010-01-27 13:10:55 -08001137 }
1138
Jason Evansc1e00ef2016-05-10 22:21:10 -07001139 ret = ctl_lookup(tsdn, name, NULL, mibp, miblenp);
Jason Evansa1ee7832012-04-10 15:07:44 -07001140label_return:
Jason Evans3c234352010-01-27 13:10:55 -08001141 return(ret);
1142}
1143
1144int
Jason Evansb2c0d632016-04-13 23:36:15 -07001145ctl_bymib(tsd_t *tsd, const size_t *mib, size_t miblen, void *oldp,
Jason Evansc4c25922017-01-15 16:56:30 -08001146 size_t *oldlenp, void *newp, size_t newlen) {
Jason Evans3c234352010-01-27 13:10:55 -08001147 int ret;
Mike Hommey461ad5c2012-04-20 08:38:42 +02001148 const ctl_named_node_t *node;
Jason Evans3c234352010-01-27 13:10:55 -08001149 size_t i;
1150
Jason Evansc1e00ef2016-05-10 22:21:10 -07001151 if (!ctl_initialized && ctl_init(tsd_tsdn(tsd))) {
Jason Evans3c234352010-01-27 13:10:55 -08001152 ret = EAGAIN;
Jason Evansa1ee7832012-04-10 15:07:44 -07001153 goto label_return;
Jason Evans3c234352010-01-27 13:10:55 -08001154 }
1155
1156 /* Iterate down the tree. */
1157 node = super_root_node;
1158 for (i = 0; i < miblen; i++) {
Mike Hommey461ad5c2012-04-20 08:38:42 +02001159 assert(node);
1160 assert(node->nchildren > 0);
1161 if (ctl_named_node(node->children) != NULL) {
Jason Evans3c234352010-01-27 13:10:55 -08001162 /* Children are named. */
Jason Evans6edbedd2017-01-04 07:51:49 -08001163 if (node->nchildren <= mib[i]) {
Jason Evans3c234352010-01-27 13:10:55 -08001164 ret = ENOENT;
Jason Evansa1ee7832012-04-10 15:07:44 -07001165 goto label_return;
Jason Evans3c234352010-01-27 13:10:55 -08001166 }
Mike Hommey461ad5c2012-04-20 08:38:42 +02001167 node = ctl_named_children(node, mib[i]);
Jason Evans3c234352010-01-27 13:10:55 -08001168 } else {
Mike Hommey461ad5c2012-04-20 08:38:42 +02001169 const ctl_indexed_node_t *inode;
Jason Evans3c234352010-01-27 13:10:55 -08001170
1171 /* Indexed element. */
Mike Hommey461ad5c2012-04-20 08:38:42 +02001172 inode = ctl_indexed_node(node->children);
Jason Evansc1e00ef2016-05-10 22:21:10 -07001173 node = inode->index(tsd_tsdn(tsd), mib, miblen, mib[i]);
Jason Evans3c234352010-01-27 13:10:55 -08001174 if (node == NULL) {
1175 ret = ENOENT;
Jason Evansa1ee7832012-04-10 15:07:44 -07001176 goto label_return;
Jason Evans3c234352010-01-27 13:10:55 -08001177 }
1178 }
1179 }
1180
1181 /* Call the ctl function. */
Jason Evansc4c25922017-01-15 16:56:30 -08001182 if (node && node->ctl) {
Jason Evansb2c0d632016-04-13 23:36:15 -07001183 ret = node->ctl(tsd, mib, miblen, oldp, oldlenp, newp, newlen);
Jason Evansc4c25922017-01-15 16:56:30 -08001184 } else {
Jason Evans3c234352010-01-27 13:10:55 -08001185 /* Partial MIB. */
1186 ret = ENOENT;
Jason Evans3c234352010-01-27 13:10:55 -08001187 }
Jason Evans3c234352010-01-27 13:10:55 -08001188
Jason Evansa1ee7832012-04-10 15:07:44 -07001189label_return:
Jason Evans3c234352010-01-27 13:10:55 -08001190 return(ret);
1191}
1192
1193bool
Jason Evansc4c25922017-01-15 16:56:30 -08001194ctl_boot(void) {
1195 if (malloc_mutex_init(&ctl_mtx, "ctl", WITNESS_RANK_CTL)) {
Jason Evansf4086432017-01-19 18:15:45 -08001196 return true;
Jason Evansc4c25922017-01-15 16:56:30 -08001197 }
Jason Evans3c234352010-01-27 13:10:55 -08001198
1199 ctl_initialized = false;
1200
Jason Evansf4086432017-01-19 18:15:45 -08001201 return false;
Jason Evans3c234352010-01-27 13:10:55 -08001202}
1203
Jason Evans20f1fc92012-10-09 14:46:22 -07001204void
Jason Evansc4c25922017-01-15 16:56:30 -08001205ctl_prefork(tsdn_t *tsdn) {
Jason Evansc1e00ef2016-05-10 22:21:10 -07001206 malloc_mutex_prefork(tsdn, &ctl_mtx);
Jason Evans20f1fc92012-10-09 14:46:22 -07001207}
1208
1209void
Jason Evansc4c25922017-01-15 16:56:30 -08001210ctl_postfork_parent(tsdn_t *tsdn) {
Jason Evansc1e00ef2016-05-10 22:21:10 -07001211 malloc_mutex_postfork_parent(tsdn, &ctl_mtx);
Jason Evans20f1fc92012-10-09 14:46:22 -07001212}
1213
1214void
Jason Evansc4c25922017-01-15 16:56:30 -08001215ctl_postfork_child(tsdn_t *tsdn) {
Jason Evansc1e00ef2016-05-10 22:21:10 -07001216 malloc_mutex_postfork_child(tsdn, &ctl_mtx);
Jason Evans20f1fc92012-10-09 14:46:22 -07001217}
1218
Jason Evans3c234352010-01-27 13:10:55 -08001219/******************************************************************************/
1220/* *_ctl() functions. */
1221
Jason Evansc0cc5db2017-01-19 21:41:41 -08001222#define READONLY() do { \
Jason Evans3c234352010-01-27 13:10:55 -08001223 if (newp != NULL || newlen != 0) { \
1224 ret = EPERM; \
Jason Evans6b9ed672012-04-25 13:12:46 -07001225 goto label_return; \
Jason Evans3c234352010-01-27 13:10:55 -08001226 } \
1227} while (0)
1228
Jason Evansc0cc5db2017-01-19 21:41:41 -08001229#define WRITEONLY() do { \
Jason Evans3c234352010-01-27 13:10:55 -08001230 if (oldp != NULL || oldlenp != NULL) { \
1231 ret = EPERM; \
Jason Evans6b9ed672012-04-25 13:12:46 -07001232 goto label_return; \
Jason Evans3c234352010-01-27 13:10:55 -08001233 } \
1234} while (0)
1235
Jason Evansc0cc5db2017-01-19 21:41:41 -08001236#define READ_XOR_WRITE() do { \
Jason Evansfc12c0b2014-10-03 23:25:30 -07001237 if ((oldp != NULL && oldlenp != NULL) && (newp != NULL || \
1238 newlen != 0)) { \
1239 ret = EPERM; \
1240 goto label_return; \
1241 } \
1242} while (0)
1243
Jason Evansc0cc5db2017-01-19 21:41:41 -08001244#define READ(v, t) do { \
Jason Evans3c234352010-01-27 13:10:55 -08001245 if (oldp != NULL && oldlenp != NULL) { \
1246 if (*oldlenp != sizeof(t)) { \
1247 size_t copylen = (sizeof(t) <= *oldlenp) \
1248 ? sizeof(t) : *oldlenp; \
Jason Evans6eb84fb2012-11-29 22:13:04 -08001249 memcpy(oldp, (void *)&(v), copylen); \
Jason Evans3c234352010-01-27 13:10:55 -08001250 ret = EINVAL; \
Jason Evans6b9ed672012-04-25 13:12:46 -07001251 goto label_return; \
Jason Evansb49a3342015-07-28 11:28:19 -04001252 } \
1253 *(t *)oldp = (v); \
Jason Evans3c234352010-01-27 13:10:55 -08001254 } \
1255} while (0)
1256
Jason Evansc0cc5db2017-01-19 21:41:41 -08001257#define WRITE(v, t) do { \
Jason Evans3c234352010-01-27 13:10:55 -08001258 if (newp != NULL) { \
1259 if (newlen != sizeof(t)) { \
1260 ret = EINVAL; \
Jason Evans6b9ed672012-04-25 13:12:46 -07001261 goto label_return; \
Jason Evans3c234352010-01-27 13:10:55 -08001262 } \
Jason Evans6eb84fb2012-11-29 22:13:04 -08001263 (v) = *(t *)newp; \
Jason Evans3c234352010-01-27 13:10:55 -08001264 } \
1265} while (0)
1266
Jason Evansc0cc5db2017-01-19 21:41:41 -08001267#define MIB_UNSIGNED(v, i) do { \
Jason Evans6edbedd2017-01-04 07:51:49 -08001268 if (mib[i] > UINT_MAX) { \
1269 ret = EFAULT; \
1270 goto label_return; \
1271 } \
1272 v = (unsigned)mib[i]; \
1273} while (0)
1274
Jason Evans7372b152012-02-10 20:22:09 -08001275/*
1276 * There's a lot of code duplication in the following macros due to limitations
1277 * in how nested cpp macros are expanded.
1278 */
Jason Evansc0cc5db2017-01-19 21:41:41 -08001279#define CTL_RO_CLGEN(c, l, n, v, t) \
Jason Evans7372b152012-02-10 20:22:09 -08001280static int \
Jason Evansb2c0d632016-04-13 23:36:15 -07001281n##_ctl(tsd_t *tsd, const size_t *mib, size_t miblen, void *oldp, \
Jason Evansc4c25922017-01-15 16:56:30 -08001282 size_t *oldlenp, void *newp, size_t newlen) { \
Jason Evans7372b152012-02-10 20:22:09 -08001283 int ret; \
1284 t oldval; \
1285 \
Jason Evansc4c25922017-01-15 16:56:30 -08001286 if (!(c)) { \
Jason Evansf4086432017-01-19 18:15:45 -08001287 return ENOENT; \
Jason Evansc4c25922017-01-15 16:56:30 -08001288 } \
1289 if (l) { \
Jason Evansc1e00ef2016-05-10 22:21:10 -07001290 malloc_mutex_lock(tsd_tsdn(tsd), &ctl_mtx); \
Jason Evansc4c25922017-01-15 16:56:30 -08001291 } \
Jason Evans7372b152012-02-10 20:22:09 -08001292 READONLY(); \
Jason Evans6eb84fb2012-11-29 22:13:04 -08001293 oldval = (v); \
Jason Evans7372b152012-02-10 20:22:09 -08001294 READ(oldval, t); \
1295 \
1296 ret = 0; \
Jason Evans6b9ed672012-04-25 13:12:46 -07001297label_return: \
Jason Evansc4c25922017-01-15 16:56:30 -08001298 if (l) { \
Jason Evansc1e00ef2016-05-10 22:21:10 -07001299 malloc_mutex_unlock(tsd_tsdn(tsd), &ctl_mtx); \
Jason Evansc4c25922017-01-15 16:56:30 -08001300 } \
Jason Evansf4086432017-01-19 18:15:45 -08001301 return ret; \
Jason Evans7372b152012-02-10 20:22:09 -08001302}
1303
Jason Evansc0cc5db2017-01-19 21:41:41 -08001304#define CTL_RO_CGEN(c, n, v, t) \
Jason Evans7372b152012-02-10 20:22:09 -08001305static int \
Jason Evansb2c0d632016-04-13 23:36:15 -07001306n##_ctl(tsd_t *tsd, const size_t *mib, size_t miblen, void *oldp, \
Jason Evansc4c25922017-01-15 16:56:30 -08001307 size_t *oldlenp, void *newp, size_t newlen) { \
Jason Evans7372b152012-02-10 20:22:09 -08001308 int ret; \
1309 t oldval; \
1310 \
Jason Evansc4c25922017-01-15 16:56:30 -08001311 if (!(c)) { \
Jason Evansf4086432017-01-19 18:15:45 -08001312 return ENOENT; \
Jason Evansc4c25922017-01-15 16:56:30 -08001313 } \
Jason Evansc1e00ef2016-05-10 22:21:10 -07001314 malloc_mutex_lock(tsd_tsdn(tsd), &ctl_mtx); \
Jason Evans7372b152012-02-10 20:22:09 -08001315 READONLY(); \
Jason Evans6eb84fb2012-11-29 22:13:04 -08001316 oldval = (v); \
Jason Evans7372b152012-02-10 20:22:09 -08001317 READ(oldval, t); \
1318 \
1319 ret = 0; \
Jason Evans6b9ed672012-04-25 13:12:46 -07001320label_return: \
Jason Evansc1e00ef2016-05-10 22:21:10 -07001321 malloc_mutex_unlock(tsd_tsdn(tsd), &ctl_mtx); \
Jason Evansf4086432017-01-19 18:15:45 -08001322 return ret; \
Jason Evans7372b152012-02-10 20:22:09 -08001323}
1324
Jason Evansc0cc5db2017-01-19 21:41:41 -08001325#define CTL_RO_GEN(n, v, t) \
Jason Evans3c234352010-01-27 13:10:55 -08001326static int \
Jason Evansb2c0d632016-04-13 23:36:15 -07001327n##_ctl(tsd_t *tsd, const size_t *mib, size_t miblen, void *oldp, \
Jason Evansc4c25922017-01-15 16:56:30 -08001328 size_t *oldlenp, void *newp, size_t newlen) { \
Jason Evans3c234352010-01-27 13:10:55 -08001329 int ret; \
1330 t oldval; \
1331 \
Jason Evansc1e00ef2016-05-10 22:21:10 -07001332 malloc_mutex_lock(tsd_tsdn(tsd), &ctl_mtx); \
Jason Evansfc4dcfa2010-11-24 15:44:21 -08001333 READONLY(); \
Jason Evans6eb84fb2012-11-29 22:13:04 -08001334 oldval = (v); \
Jason Evansfc4dcfa2010-11-24 15:44:21 -08001335 READ(oldval, t); \
1336 \
1337 ret = 0; \
Jason Evans6b9ed672012-04-25 13:12:46 -07001338label_return: \
Jason Evansc1e00ef2016-05-10 22:21:10 -07001339 malloc_mutex_unlock(tsd_tsdn(tsd), &ctl_mtx); \
Jason Evansf4086432017-01-19 18:15:45 -08001340 return ret; \
Jason Evansfc4dcfa2010-11-24 15:44:21 -08001341}
1342
1343/*
1344 * ctl_mtx is not acquired, under the assumption that no pertinent data will
1345 * mutate during the call.
1346 */
Jason Evansc0cc5db2017-01-19 21:41:41 -08001347#define CTL_RO_NL_CGEN(c, n, v, t) \
Jason Evans7372b152012-02-10 20:22:09 -08001348static int \
Jason Evansb2c0d632016-04-13 23:36:15 -07001349n##_ctl(tsd_t *tsd, const size_t *mib, size_t miblen, void *oldp, \
Jason Evansc4c25922017-01-15 16:56:30 -08001350 size_t *oldlenp, void *newp, size_t newlen) { \
Jason Evans7372b152012-02-10 20:22:09 -08001351 int ret; \
1352 t oldval; \
1353 \
Jason Evansc4c25922017-01-15 16:56:30 -08001354 if (!(c)) { \
Jason Evansf4086432017-01-19 18:15:45 -08001355 return ENOENT; \
Jason Evansc4c25922017-01-15 16:56:30 -08001356 } \
Jason Evans7372b152012-02-10 20:22:09 -08001357 READONLY(); \
Jason Evans6eb84fb2012-11-29 22:13:04 -08001358 oldval = (v); \
Jason Evans7372b152012-02-10 20:22:09 -08001359 READ(oldval, t); \
1360 \
1361 ret = 0; \
Jason Evans6b9ed672012-04-25 13:12:46 -07001362label_return: \
Jason Evansf4086432017-01-19 18:15:45 -08001363 return ret; \
Jason Evans7372b152012-02-10 20:22:09 -08001364}
1365
Jason Evansc0cc5db2017-01-19 21:41:41 -08001366#define CTL_RO_NL_GEN(n, v, t) \
Jason Evansfc4dcfa2010-11-24 15:44:21 -08001367static int \
Jason Evansb2c0d632016-04-13 23:36:15 -07001368n##_ctl(tsd_t *tsd, const size_t *mib, size_t miblen, void *oldp, \
Jason Evansc4c25922017-01-15 16:56:30 -08001369 size_t *oldlenp, void *newp, size_t newlen) { \
Jason Evansfc4dcfa2010-11-24 15:44:21 -08001370 int ret; \
1371 t oldval; \
1372 \
Jason Evans3c234352010-01-27 13:10:55 -08001373 READONLY(); \
Jason Evans6eb84fb2012-11-29 22:13:04 -08001374 oldval = (v); \
Jason Evans3c234352010-01-27 13:10:55 -08001375 READ(oldval, t); \
1376 \
1377 ret = 0; \
Jason Evans6b9ed672012-04-25 13:12:46 -07001378label_return: \
Jason Evansf4086432017-01-19 18:15:45 -08001379 return ret; \
Jason Evans3c234352010-01-27 13:10:55 -08001380}
1381
Jason Evansc0cc5db2017-01-19 21:41:41 -08001382#define CTL_TSD_RO_NL_CGEN(c, n, m, t) \
Jason Evans5460aa62014-09-22 21:09:23 -07001383static int \
Jason Evansb2c0d632016-04-13 23:36:15 -07001384n##_ctl(tsd_t *tsd, const size_t *mib, size_t miblen, void *oldp, \
Jason Evansc4c25922017-01-15 16:56:30 -08001385 size_t *oldlenp, void *newp, size_t newlen) { \
Jason Evans5460aa62014-09-22 21:09:23 -07001386 int ret; \
1387 t oldval; \
Jason Evans5460aa62014-09-22 21:09:23 -07001388 \
Jason Evansc4c25922017-01-15 16:56:30 -08001389 if (!(c)) { \
Jason Evansf4086432017-01-19 18:15:45 -08001390 return ENOENT; \
Jason Evansc4c25922017-01-15 16:56:30 -08001391 } \
Jason Evans5460aa62014-09-22 21:09:23 -07001392 READONLY(); \
Jason Evans5460aa62014-09-22 21:09:23 -07001393 oldval = (m(tsd)); \
1394 READ(oldval, t); \
1395 \
1396 ret = 0; \
1397label_return: \
Jason Evansf4086432017-01-19 18:15:45 -08001398 return ret; \
Jason Evans5460aa62014-09-22 21:09:23 -07001399}
1400
Jason Evansc0cc5db2017-01-19 21:41:41 -08001401#define CTL_RO_CONFIG_GEN(n, t) \
Jason Evans3c234352010-01-27 13:10:55 -08001402static int \
Jason Evansb2c0d632016-04-13 23:36:15 -07001403n##_ctl(tsd_t *tsd, const size_t *mib, size_t miblen, void *oldp, \
Jason Evansc4c25922017-01-15 16:56:30 -08001404 size_t *oldlenp, void *newp, size_t newlen) { \
Jason Evans3c234352010-01-27 13:10:55 -08001405 int ret; \
Jason Evansf8290092016-02-07 14:23:22 -08001406 t oldval; \
Jason Evans3c234352010-01-27 13:10:55 -08001407 \
1408 READONLY(); \
Jason Evans7372b152012-02-10 20:22:09 -08001409 oldval = n; \
Jason Evansf8290092016-02-07 14:23:22 -08001410 READ(oldval, t); \
Jason Evans3c234352010-01-27 13:10:55 -08001411 \
1412 ret = 0; \
Jason Evans6b9ed672012-04-25 13:12:46 -07001413label_return: \
Jason Evansf4086432017-01-19 18:15:45 -08001414 return ret; \
Jason Evans3c234352010-01-27 13:10:55 -08001415}
1416
Jason Evansd8a39002013-12-19 21:40:41 -08001417/******************************************************************************/
1418
Jason Evansfc4dcfa2010-11-24 15:44:21 -08001419CTL_RO_NL_GEN(version, JEMALLOC_VERSION, const char *)
Jason Evansa40bc7a2010-03-02 13:01:16 -08001420
Jason Evans3c234352010-01-27 13:10:55 -08001421static int
Jason Evansb2c0d632016-04-13 23:36:15 -07001422epoch_ctl(tsd_t *tsd, const size_t *mib, size_t miblen, void *oldp,
Jason Evansc4c25922017-01-15 16:56:30 -08001423 size_t *oldlenp, void *newp, size_t newlen) {
Jason Evans3c234352010-01-27 13:10:55 -08001424 int ret;
Jason Evans3ab682d2013-10-19 17:19:49 -07001425 UNUSED uint64_t newval;
Jason Evans3c234352010-01-27 13:10:55 -08001426
Jason Evansc1e00ef2016-05-10 22:21:10 -07001427 malloc_mutex_lock(tsd_tsdn(tsd), &ctl_mtx);
Jason Evans3c234352010-01-27 13:10:55 -08001428 WRITE(newval, uint64_t);
Jason Evansc4c25922017-01-15 16:56:30 -08001429 if (newp != NULL) {
Jason Evansc1e00ef2016-05-10 22:21:10 -07001430 ctl_refresh(tsd_tsdn(tsd));
Jason Evansc4c25922017-01-15 16:56:30 -08001431 }
Jason Evans9eb1b1c2017-01-18 23:03:37 -08001432 READ(ctl_arenas->epoch, uint64_t);
Jason Evans3c234352010-01-27 13:10:55 -08001433
1434 ret = 0;
Jason Evansa1ee7832012-04-10 15:07:44 -07001435label_return:
Jason Evansc1e00ef2016-05-10 22:21:10 -07001436 malloc_mutex_unlock(tsd_tsdn(tsd), &ctl_mtx);
Jason Evansf4086432017-01-19 18:15:45 -08001437 return ret;
Jason Evans3c234352010-01-27 13:10:55 -08001438}
1439
Jason Evansd8a39002013-12-19 21:40:41 -08001440/******************************************************************************/
Jason Evansd4be8b72012-03-26 18:54:44 -07001441
Jason Evansf8290092016-02-07 14:23:22 -08001442CTL_RO_CONFIG_GEN(config_cache_oblivious, bool)
1443CTL_RO_CONFIG_GEN(config_debug, bool)
1444CTL_RO_CONFIG_GEN(config_fill, bool)
1445CTL_RO_CONFIG_GEN(config_lazy_lock, bool)
1446CTL_RO_CONFIG_GEN(config_malloc_conf, const char *)
1447CTL_RO_CONFIG_GEN(config_munmap, bool)
1448CTL_RO_CONFIG_GEN(config_prof, bool)
1449CTL_RO_CONFIG_GEN(config_prof_libgcc, bool)
1450CTL_RO_CONFIG_GEN(config_prof_libunwind, bool)
1451CTL_RO_CONFIG_GEN(config_stats, bool)
Jason Evansf8290092016-02-07 14:23:22 -08001452CTL_RO_CONFIG_GEN(config_utrace, bool)
Jason Evansf8290092016-02-07 14:23:22 -08001453CTL_RO_CONFIG_GEN(config_xmalloc, bool)
Jason Evansd4be8b72012-03-26 18:54:44 -07001454
Jason Evansd8a39002013-12-19 21:40:41 -08001455/******************************************************************************/
Jason Evansd4be8b72012-03-26 18:54:44 -07001456
Jason Evansd8a39002013-12-19 21:40:41 -08001457CTL_RO_NL_GEN(opt_abort, opt_abort, bool)
1458CTL_RO_NL_GEN(opt_dss, opt_dss, const char *)
Jason Evans8f683b92016-02-24 11:03:40 -08001459CTL_RO_NL_GEN(opt_narenas, opt_narenas, unsigned)
Qi Wangec532e22017-02-02 17:02:05 -08001460CTL_RO_NL_GEN(opt_percpu_arena, opt_percpu_arena, const char *)
Jason Evans64e458f2017-03-08 22:42:57 -08001461CTL_RO_NL_GEN(opt_dirty_decay_time, opt_dirty_decay_time, ssize_t)
1462CTL_RO_NL_GEN(opt_muzzy_decay_time, opt_muzzy_decay_time, ssize_t)
Jason Evansd8a39002013-12-19 21:40:41 -08001463CTL_RO_NL_GEN(opt_stats_print, opt_stats_print, bool)
Guilherme Goncalves2c5cb612014-12-08 19:12:41 -02001464CTL_RO_NL_CGEN(config_fill, opt_junk, opt_junk, const char *)
Jason Evansd8a39002013-12-19 21:40:41 -08001465CTL_RO_NL_CGEN(config_fill, opt_zero, opt_zero, bool)
1466CTL_RO_NL_CGEN(config_utrace, opt_utrace, opt_utrace, bool)
Jason Evansd8a39002013-12-19 21:40:41 -08001467CTL_RO_NL_CGEN(config_xmalloc, opt_xmalloc, opt_xmalloc, bool)
Jason Evans4403c9a2017-04-20 17:21:37 -07001468CTL_RO_NL_GEN(opt_tcache, opt_tcache, bool)
1469CTL_RO_NL_GEN(opt_lg_tcache_max, opt_lg_tcache_max, ssize_t)
Jason Evansd8a39002013-12-19 21:40:41 -08001470CTL_RO_NL_CGEN(config_prof, opt_prof, opt_prof, bool)
1471CTL_RO_NL_CGEN(config_prof, opt_prof_prefix, opt_prof_prefix, const char *)
Jason Evansfc12c0b2014-10-03 23:25:30 -07001472CTL_RO_NL_CGEN(config_prof, opt_prof_active, opt_prof_active, bool)
1473CTL_RO_NL_CGEN(config_prof, opt_prof_thread_active_init,
1474 opt_prof_thread_active_init, bool)
Jason Evansd8a39002013-12-19 21:40:41 -08001475CTL_RO_NL_CGEN(config_prof, opt_lg_prof_sample, opt_lg_prof_sample, size_t)
1476CTL_RO_NL_CGEN(config_prof, opt_prof_accum, opt_prof_accum, bool)
1477CTL_RO_NL_CGEN(config_prof, opt_lg_prof_interval, opt_lg_prof_interval, ssize_t)
1478CTL_RO_NL_CGEN(config_prof, opt_prof_gdump, opt_prof_gdump, bool)
1479CTL_RO_NL_CGEN(config_prof, opt_prof_final, opt_prof_final, bool)
1480CTL_RO_NL_CGEN(config_prof, opt_prof_leak, opt_prof_leak, bool)
Jason Evansd4be8b72012-03-26 18:54:44 -07001481
Jason Evansd8a39002013-12-19 21:40:41 -08001482/******************************************************************************/
Jason Evans3c234352010-01-27 13:10:55 -08001483
Jason Evansb267d0f2010-08-13 15:42:29 -07001484static int
Jason Evansb2c0d632016-04-13 23:36:15 -07001485thread_arena_ctl(tsd_t *tsd, const size_t *mib, size_t miblen, void *oldp,
Jason Evansc4c25922017-01-15 16:56:30 -08001486 size_t *oldlenp, void *newp, size_t newlen) {
Jason Evansb267d0f2010-08-13 15:42:29 -07001487 int ret;
Jason Evans1cb181e2015-01-29 15:30:47 -08001488 arena_t *oldarena;
Jason Evansb267d0f2010-08-13 15:42:29 -07001489 unsigned newind, oldind;
1490
Jason Evans90827a32016-05-03 15:00:42 -07001491 oldarena = arena_choose(tsd, NULL);
Jason Evansc4c25922017-01-15 16:56:30 -08001492 if (oldarena == NULL) {
Jason Evansf4086432017-01-19 18:15:45 -08001493 return EAGAIN;
Jason Evansc4c25922017-01-15 16:56:30 -08001494 }
Jason Evansa0dd3a42016-12-22 16:39:10 -06001495 newind = oldind = arena_ind_get(oldarena);
Jason Evansa7153a02011-03-14 11:39:49 -07001496 WRITE(newind, unsigned);
1497 READ(oldind, unsigned);
Qi Wangec532e22017-02-02 17:02:05 -08001498
Jason Evansb267d0f2010-08-13 15:42:29 -07001499 if (newind != oldind) {
Jason Evans1cb181e2015-01-29 15:30:47 -08001500 arena_t *newarena;
1501
Jason Evansb6c08672016-10-03 10:37:12 -07001502 if (newind >= narenas_total_get()) {
Jason Evansb267d0f2010-08-13 15:42:29 -07001503 /* New arena index is out of range. */
1504 ret = EFAULT;
Jason Evansa1ee7832012-04-10 15:07:44 -07001505 goto label_return;
Jason Evansb267d0f2010-08-13 15:42:29 -07001506 }
1507
Qi Wangec532e22017-02-02 17:02:05 -08001508 if (have_percpu_arena &&
1509 (percpu_arena_mode != percpu_arena_disabled)) {
1510 if (newind < percpu_arena_ind_limit()) {
1511 /*
1512 * If perCPU arena is enabled, thread_arena
1513 * control is not allowed for the auto arena
1514 * range.
1515 */
1516 ret = EPERM;
1517 goto label_return;
1518 }
1519 }
1520
Jason Evansb267d0f2010-08-13 15:42:29 -07001521 /* Initialize arena if necessary. */
Jason Evansc1e00ef2016-05-10 22:21:10 -07001522 newarena = arena_get(tsd_tsdn(tsd), newind, true);
Jason Evans1cb181e2015-01-29 15:30:47 -08001523 if (newarena == NULL) {
Jason Evansb267d0f2010-08-13 15:42:29 -07001524 ret = EAGAIN;
Jason Evansa1ee7832012-04-10 15:07:44 -07001525 goto label_return;
Jason Evansb267d0f2010-08-13 15:42:29 -07001526 }
Jason Evans8bb31982014-10-07 23:14:57 -07001527 /* Set new arena/tcache associations. */
1528 arena_migrate(tsd, oldind, newind);
Jason Evans4403c9a2017-04-20 17:21:37 -07001529 if (tcache_available(tsd)) {
1530 tcache_arena_reassociate(tsd_tsdn(tsd),
1531 tsd_tcachep_get(tsd), newarena);
Jason Evans624f2f32010-12-29 12:21:05 -08001532 }
Jason Evansb267d0f2010-08-13 15:42:29 -07001533 }
1534
1535 ret = 0;
Jason Evansa1ee7832012-04-10 15:07:44 -07001536label_return:
Jason Evansf4086432017-01-19 18:15:45 -08001537 return ret;
Jason Evansb267d0f2010-08-13 15:42:29 -07001538}
Jason Evansb267d0f2010-08-13 15:42:29 -07001539
Jason Evans5460aa62014-09-22 21:09:23 -07001540CTL_TSD_RO_NL_CGEN(config_stats, thread_allocated, tsd_thread_allocated_get,
1541 uint64_t)
1542CTL_TSD_RO_NL_CGEN(config_stats, thread_allocatedp, tsd_thread_allocatedp_get,
1543 uint64_t *)
1544CTL_TSD_RO_NL_CGEN(config_stats, thread_deallocated, tsd_thread_deallocated_get,
1545 uint64_t)
1546CTL_TSD_RO_NL_CGEN(config_stats, thread_deallocatedp,
1547 tsd_thread_deallocatedp_get, uint64_t *)
Jason Evans93443682010-10-20 17:39:18 -07001548
Jason Evansd8a39002013-12-19 21:40:41 -08001549static int
Jason Evansb2c0d632016-04-13 23:36:15 -07001550thread_tcache_enabled_ctl(tsd_t *tsd, const size_t *mib, size_t miblen,
Jason Evansc4c25922017-01-15 16:56:30 -08001551 void *oldp, size_t *oldlenp, void *newp, size_t newlen) {
Jason Evansd8a39002013-12-19 21:40:41 -08001552 int ret;
1553 bool oldval;
Jason Evans3c234352010-01-27 13:10:55 -08001554
Qi Wangfde3e202017-03-27 21:50:38 -07001555 oldval = tcache_enabled_get(tsd);
Jason Evansd8a39002013-12-19 21:40:41 -08001556 if (newp != NULL) {
1557 if (newlen != sizeof(bool)) {
1558 ret = EINVAL;
1559 goto label_return;
1560 }
Qi Wangfde3e202017-03-27 21:50:38 -07001561 tcache_enabled_set(tsd, *(bool *)newp);
Jason Evansd8a39002013-12-19 21:40:41 -08001562 }
1563 READ(oldval, bool);
Jason Evans3c234352010-01-27 13:10:55 -08001564
Jason Evansd8a39002013-12-19 21:40:41 -08001565 ret = 0;
1566label_return:
Jason Evansf4086432017-01-19 18:15:45 -08001567 return ret;
Jason Evansd8a39002013-12-19 21:40:41 -08001568}
1569
1570static int
Jason Evansb2c0d632016-04-13 23:36:15 -07001571thread_tcache_flush_ctl(tsd_t *tsd, const size_t *mib, size_t miblen,
Jason Evansc4c25922017-01-15 16:56:30 -08001572 void *oldp, size_t *oldlenp, void *newp, size_t newlen) {
Jason Evansd8a39002013-12-19 21:40:41 -08001573 int ret;
1574
Jason Evans4403c9a2017-04-20 17:21:37 -07001575 if (!tcache_available(tsd)) {
1576 ret = EFAULT;
1577 goto label_return;
Jason Evansc4c25922017-01-15 16:56:30 -08001578 }
Jason Evansd8a39002013-12-19 21:40:41 -08001579
1580 READONLY();
1581 WRITEONLY();
1582
1583 tcache_flush();
1584
1585 ret = 0;
1586label_return:
Jason Evansf4086432017-01-19 18:15:45 -08001587 return ret;
Jason Evansd8a39002013-12-19 21:40:41 -08001588}
Jason Evans3c234352010-01-27 13:10:55 -08001589
Jason Evans602c8e02014-08-18 16:22:13 -07001590static int
Jason Evansb2c0d632016-04-13 23:36:15 -07001591thread_prof_name_ctl(tsd_t *tsd, const size_t *mib, size_t miblen, void *oldp,
Jason Evansc4c25922017-01-15 16:56:30 -08001592 size_t *oldlenp, void *newp, size_t newlen) {
Jason Evans602c8e02014-08-18 16:22:13 -07001593 int ret;
Jason Evans602c8e02014-08-18 16:22:13 -07001594
Jason Evansc4c25922017-01-15 16:56:30 -08001595 if (!config_prof) {
Jason Evansf4086432017-01-19 18:15:45 -08001596 return ENOENT;
Jason Evansc4c25922017-01-15 16:56:30 -08001597 }
Jason Evans602c8e02014-08-18 16:22:13 -07001598
Jason Evansfc12c0b2014-10-03 23:25:30 -07001599 READ_XOR_WRITE();
1600
Jason Evans602c8e02014-08-18 16:22:13 -07001601 if (newp != NULL) {
1602 if (newlen != sizeof(const char *)) {
1603 ret = EINVAL;
1604 goto label_return;
1605 }
Jason Evans5460aa62014-09-22 21:09:23 -07001606
Jason Evansfc12c0b2014-10-03 23:25:30 -07001607 if ((ret = prof_thread_name_set(tsd, *(const char **)newp)) !=
Jason Evansc4c25922017-01-15 16:56:30 -08001608 0) {
Jason Evans602c8e02014-08-18 16:22:13 -07001609 goto label_return;
Jason Evansc4c25922017-01-15 16:56:30 -08001610 }
Jason Evansfc12c0b2014-10-03 23:25:30 -07001611 } else {
Jason Evansb2c0d632016-04-13 23:36:15 -07001612 const char *oldname = prof_thread_name_get(tsd);
Jason Evansfc12c0b2014-10-03 23:25:30 -07001613 READ(oldname, const char *);
Jason Evans602c8e02014-08-18 16:22:13 -07001614 }
Jason Evans602c8e02014-08-18 16:22:13 -07001615
1616 ret = 0;
1617label_return:
Jason Evansf4086432017-01-19 18:15:45 -08001618 return ret;
Jason Evans602c8e02014-08-18 16:22:13 -07001619}
1620
1621static int
Jason Evansb2c0d632016-04-13 23:36:15 -07001622thread_prof_active_ctl(tsd_t *tsd, const size_t *mib, size_t miblen, void *oldp,
Jason Evansc4c25922017-01-15 16:56:30 -08001623 size_t *oldlenp, void *newp, size_t newlen) {
Jason Evans602c8e02014-08-18 16:22:13 -07001624 int ret;
1625 bool oldval;
1626
Jason Evansc4c25922017-01-15 16:56:30 -08001627 if (!config_prof) {
Jason Evansf4086432017-01-19 18:15:45 -08001628 return ENOENT;
Jason Evansc4c25922017-01-15 16:56:30 -08001629 }
Jason Evans602c8e02014-08-18 16:22:13 -07001630
Jason Evansb2c0d632016-04-13 23:36:15 -07001631 oldval = prof_thread_active_get(tsd);
Jason Evans602c8e02014-08-18 16:22:13 -07001632 if (newp != NULL) {
1633 if (newlen != sizeof(bool)) {
1634 ret = EINVAL;
1635 goto label_return;
1636 }
Jason Evansb2c0d632016-04-13 23:36:15 -07001637 if (prof_thread_active_set(tsd, *(bool *)newp)) {
Jason Evans602c8e02014-08-18 16:22:13 -07001638 ret = EAGAIN;
1639 goto label_return;
1640 }
1641 }
1642 READ(oldval, bool);
1643
1644 ret = 0;
1645label_return:
Jason Evansf4086432017-01-19 18:15:45 -08001646 return ret;
Jason Evans602c8e02014-08-18 16:22:13 -07001647}
1648
Jason Evans3c234352010-01-27 13:10:55 -08001649/******************************************************************************/
1650
Jason Evans1cb181e2015-01-29 15:30:47 -08001651static int
Jason Evansb2c0d632016-04-13 23:36:15 -07001652tcache_create_ctl(tsd_t *tsd, const size_t *mib, size_t miblen, void *oldp,
Jason Evansc4c25922017-01-15 16:56:30 -08001653 size_t *oldlenp, void *newp, size_t newlen) {
Jason Evans1cb181e2015-01-29 15:30:47 -08001654 int ret;
Jason Evans1cb181e2015-01-29 15:30:47 -08001655 unsigned tcache_ind;
1656
Jason Evans1cb181e2015-01-29 15:30:47 -08001657 READONLY();
Jason Evansb54d1602016-10-20 23:59:12 -07001658 if (tcaches_create(tsd, &tcache_ind)) {
Jason Evans1cb181e2015-01-29 15:30:47 -08001659 ret = EFAULT;
1660 goto label_return;
1661 }
1662 READ(tcache_ind, unsigned);
1663
1664 ret = 0;
1665label_return:
Jason Evansf4086432017-01-19 18:15:45 -08001666 return ret;
Jason Evans1cb181e2015-01-29 15:30:47 -08001667}
1668
1669static int
Jason Evansb2c0d632016-04-13 23:36:15 -07001670tcache_flush_ctl(tsd_t *tsd, const size_t *mib, size_t miblen, void *oldp,
Jason Evansc4c25922017-01-15 16:56:30 -08001671 size_t *oldlenp, void *newp, size_t newlen) {
Jason Evans1cb181e2015-01-29 15:30:47 -08001672 int ret;
Jason Evans1cb181e2015-01-29 15:30:47 -08001673 unsigned tcache_ind;
1674
Jason Evans1cb181e2015-01-29 15:30:47 -08001675 WRITEONLY();
1676 tcache_ind = UINT_MAX;
1677 WRITE(tcache_ind, unsigned);
1678 if (tcache_ind == UINT_MAX) {
1679 ret = EFAULT;
1680 goto label_return;
1681 }
1682 tcaches_flush(tsd, tcache_ind);
1683
1684 ret = 0;
1685label_return:
Jason Evansf4086432017-01-19 18:15:45 -08001686 return ret;
Jason Evans1cb181e2015-01-29 15:30:47 -08001687}
1688
1689static int
Jason Evansb2c0d632016-04-13 23:36:15 -07001690tcache_destroy_ctl(tsd_t *tsd, const size_t *mib, size_t miblen, void *oldp,
Jason Evansc4c25922017-01-15 16:56:30 -08001691 size_t *oldlenp, void *newp, size_t newlen) {
Jason Evans1cb181e2015-01-29 15:30:47 -08001692 int ret;
Jason Evans1cb181e2015-01-29 15:30:47 -08001693 unsigned tcache_ind;
1694
Jason Evans1cb181e2015-01-29 15:30:47 -08001695 WRITEONLY();
1696 tcache_ind = UINT_MAX;
1697 WRITE(tcache_ind, unsigned);
1698 if (tcache_ind == UINT_MAX) {
1699 ret = EFAULT;
1700 goto label_return;
1701 }
1702 tcaches_destroy(tsd, tcache_ind);
1703
1704 ret = 0;
1705label_return:
Jason Evansf4086432017-01-19 18:15:45 -08001706 return ret;
Jason Evans1cb181e2015-01-29 15:30:47 -08001707}
1708
1709/******************************************************************************/
1710
Jason Evansdc2125c2017-01-04 10:21:53 -08001711static int
1712arena_i_initialized_ctl(tsd_t *tsd, const size_t *mib, size_t miblen,
Jason Evansc4c25922017-01-15 16:56:30 -08001713 void *oldp, size_t *oldlenp, void *newp, size_t newlen) {
Jason Evansdc2125c2017-01-04 10:21:53 -08001714 int ret;
1715 tsdn_t *tsdn = tsd_tsdn(tsd);
1716 unsigned arena_ind;
1717 bool initialized;
1718
1719 READONLY();
1720 MIB_UNSIGNED(arena_ind, 1);
1721
1722 malloc_mutex_lock(tsdn, &ctl_mtx);
Jason Evans9eb1b1c2017-01-18 23:03:37 -08001723 initialized = arenas_i(arena_ind)->initialized;
Jason Evansdc2125c2017-01-04 10:21:53 -08001724 malloc_mutex_unlock(tsdn, &ctl_mtx);
1725
1726 READ(initialized, bool);
1727
1728 ret = 0;
1729label_return:
Jason Evansf4086432017-01-19 18:15:45 -08001730 return ret;
Jason Evansdc2125c2017-01-04 10:21:53 -08001731}
1732
Jason Evans34457f52012-11-03 21:18:28 -07001733static void
Jason Evans64e458f2017-03-08 22:42:57 -08001734arena_i_decay(tsdn_t *tsdn, unsigned arena_ind, bool all) {
Jason Evansc1e00ef2016-05-10 22:21:10 -07001735 malloc_mutex_lock(tsdn, &ctl_mtx);
Jason Evans243f7a02016-02-19 20:09:31 -08001736 {
Jason Evans9eb1b1c2017-01-18 23:03:37 -08001737 unsigned narenas = ctl_arenas->narenas;
Jason Evans609ae592012-10-11 13:53:15 -07001738
Jason Evans3dc4e832017-01-03 07:27:42 -08001739 /*
1740 * Access via index narenas is deprecated, and scheduled for
1741 * removal in 6.0.0.
1742 */
1743 if (arena_ind == MALLCTL_ARENAS_ALL || arena_ind == narenas) {
Jason Evans243f7a02016-02-19 20:09:31 -08001744 unsigned i;
Jason Evans243f7a02016-02-19 20:09:31 -08001745 VARIABLE_ARRAY(arena_t *, tarenas, narenas);
1746
Jason Evansc4c25922017-01-15 16:56:30 -08001747 for (i = 0; i < narenas; i++) {
Jason Evansc1e00ef2016-05-10 22:21:10 -07001748 tarenas[i] = arena_get(tsdn, i, false);
Jason Evansc4c25922017-01-15 16:56:30 -08001749 }
Jason Evans243f7a02016-02-19 20:09:31 -08001750
1751 /*
1752 * No further need to hold ctl_mtx, since narenas and
1753 * tarenas contain everything needed below.
1754 */
Jason Evansc1e00ef2016-05-10 22:21:10 -07001755 malloc_mutex_unlock(tsdn, &ctl_mtx);
Jason Evans243f7a02016-02-19 20:09:31 -08001756
1757 for (i = 0; i < narenas; i++) {
Jason Evansc4c25922017-01-15 16:56:30 -08001758 if (tarenas[i] != NULL) {
Jason Evans64e458f2017-03-08 22:42:57 -08001759 arena_decay(tsdn, tarenas[i], all);
Jason Evansc4c25922017-01-15 16:56:30 -08001760 }
Jason Evans243f7a02016-02-19 20:09:31 -08001761 }
1762 } else {
1763 arena_t *tarena;
1764
1765 assert(arena_ind < narenas);
1766
Jason Evansc1e00ef2016-05-10 22:21:10 -07001767 tarena = arena_get(tsdn, arena_ind, false);
Jason Evans243f7a02016-02-19 20:09:31 -08001768
1769 /* No further need to hold ctl_mtx. */
Jason Evansc1e00ef2016-05-10 22:21:10 -07001770 malloc_mutex_unlock(tsdn, &ctl_mtx);
Jason Evans243f7a02016-02-19 20:09:31 -08001771
Jason Evansc4c25922017-01-15 16:56:30 -08001772 if (tarena != NULL) {
Jason Evans64e458f2017-03-08 22:42:57 -08001773 arena_decay(tsdn, tarena, all);
Jason Evansc4c25922017-01-15 16:56:30 -08001774 }
Jason Evans609ae592012-10-11 13:53:15 -07001775 }
1776 }
Jason Evans609ae592012-10-11 13:53:15 -07001777}
1778
1779static int
Jason Evansb2c0d632016-04-13 23:36:15 -07001780arena_i_decay_ctl(tsd_t *tsd, const size_t *mib, size_t miblen, void *oldp,
Jason Evansc4c25922017-01-15 16:56:30 -08001781 size_t *oldlenp, void *newp, size_t newlen) {
Jason Evans243f7a02016-02-19 20:09:31 -08001782 int ret;
Jason Evans6edbedd2017-01-04 07:51:49 -08001783 unsigned arena_ind;
Jason Evans243f7a02016-02-19 20:09:31 -08001784
1785 READONLY();
1786 WRITEONLY();
Jason Evans6edbedd2017-01-04 07:51:49 -08001787 MIB_UNSIGNED(arena_ind, 1);
Jason Evans64e458f2017-03-08 22:42:57 -08001788 arena_i_decay(tsd_tsdn(tsd), arena_ind, false);
1789
1790 ret = 0;
1791label_return:
1792 return ret;
1793}
1794
1795static int
1796arena_i_purge_ctl(tsd_t *tsd, const size_t *mib, size_t miblen, void *oldp,
1797 size_t *oldlenp, void *newp, size_t newlen) {
1798 int ret;
1799 unsigned arena_ind;
1800
1801 READONLY();
1802 WRITEONLY();
1803 MIB_UNSIGNED(arena_ind, 1);
1804 arena_i_decay(tsd_tsdn(tsd), arena_ind, true);
Jason Evans609ae592012-10-11 13:53:15 -07001805
Jason Evans34457f52012-11-03 21:18:28 -07001806 ret = 0;
Jason Evans609ae592012-10-11 13:53:15 -07001807label_return:
Jason Evansf4086432017-01-19 18:15:45 -08001808 return ret;
Jason Evans609ae592012-10-11 13:53:15 -07001809}
1810
1811static int
Jason Evansedf1baf2017-01-03 17:21:59 -08001812arena_i_reset_destroy_helper(tsd_t *tsd, const size_t *mib, size_t miblen,
1813 void *oldp, size_t *oldlenp, void *newp, size_t newlen, unsigned *arena_ind,
Jason Evansc4c25922017-01-15 16:56:30 -08001814 arena_t **arena) {
Jason Evansedf1baf2017-01-03 17:21:59 -08001815 int ret;
1816
1817 READONLY();
1818 WRITEONLY();
1819 MIB_UNSIGNED(*arena_ind, 1);
1820
Jason Evansedf1baf2017-01-03 17:21:59 -08001821 *arena = arena_get(tsd_tsdn(tsd), *arena_ind, false);
Qi Wang5aa46f02017-04-20 15:19:02 -07001822 if (*arena == NULL || arena_is_auto(*arena)) {
Jason Evansedf1baf2017-01-03 17:21:59 -08001823 ret = EFAULT;
1824 goto label_return;
1825 }
1826
1827 ret = 0;
1828label_return:
Jason Evansf4086432017-01-19 18:15:45 -08001829 return ret;
Jason Evansedf1baf2017-01-03 17:21:59 -08001830}
1831
1832static int
Jason Evans19ff2ce2016-04-22 14:37:17 -07001833arena_i_reset_ctl(tsd_t *tsd, const size_t *mib, size_t miblen, void *oldp,
Jason Evansc4c25922017-01-15 16:56:30 -08001834 size_t *oldlenp, void *newp, size_t newlen) {
Jason Evans19ff2ce2016-04-22 14:37:17 -07001835 int ret;
1836 unsigned arena_ind;
1837 arena_t *arena;
1838
Jason Evansedf1baf2017-01-03 17:21:59 -08001839 ret = arena_i_reset_destroy_helper(tsd, mib, miblen, oldp, oldlenp,
1840 newp, newlen, &arena_ind, &arena);
Jason Evansc4c25922017-01-15 16:56:30 -08001841 if (ret != 0) {
Jason Evansf4086432017-01-19 18:15:45 -08001842 return ret;
Jason Evansc4c25922017-01-15 16:56:30 -08001843 }
Jason Evans19ff2ce2016-04-22 14:37:17 -07001844
Jason Evansedf1baf2017-01-03 17:21:59 -08001845 arena_reset(tsd, arena);
Jason Evans19ff2ce2016-04-22 14:37:17 -07001846
Jason Evansf4086432017-01-19 18:15:45 -08001847 return ret;
Jason Evansedf1baf2017-01-03 17:21:59 -08001848}
1849
1850static int
1851arena_i_destroy_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 Evansedf1baf2017-01-03 17:21:59 -08001853 int ret;
1854 unsigned arena_ind;
1855 arena_t *arena;
Jason Evans9eb1b1c2017-01-18 23:03:37 -08001856 ctl_arena_t *ctl_darena, *ctl_arena;
Jason Evansedf1baf2017-01-03 17:21:59 -08001857
1858 ret = arena_i_reset_destroy_helper(tsd, mib, miblen, oldp, oldlenp,
1859 newp, newlen, &arena_ind, &arena);
Jason Evansc4c25922017-01-15 16:56:30 -08001860 if (ret != 0) {
Jason Evansedf1baf2017-01-03 17:21:59 -08001861 goto label_return;
Jason Evansc4c25922017-01-15 16:56:30 -08001862 }
Jason Evansedf1baf2017-01-03 17:21:59 -08001863
1864 if (arena_nthreads_get(arena, false) != 0 || arena_nthreads_get(arena,
1865 true) != 0) {
Jason Evans3dc4e832017-01-03 07:27:42 -08001866 ret = EFAULT;
1867 goto label_return;
1868 }
Jason Evans19ff2ce2016-04-22 14:37:17 -07001869
Jason Evansedf1baf2017-01-03 17:21:59 -08001870 /* Merge stats after resetting and purging arena. */
Jason Evans19ff2ce2016-04-22 14:37:17 -07001871 arena_reset(tsd, arena);
Jason Evans64e458f2017-03-08 22:42:57 -08001872 arena_decay(tsd_tsdn(tsd), arena, true);
Jason Evans9eb1b1c2017-01-18 23:03:37 -08001873 ctl_darena = arenas_i(MALLCTL_ARENAS_DESTROYED);
1874 ctl_darena->initialized = true;
1875 ctl_arena_refresh(tsd_tsdn(tsd), arena, ctl_darena, arena_ind, true);
Jason Evansedf1baf2017-01-03 17:21:59 -08001876 /* Destroy arena. */
1877 arena_destroy(tsd, arena);
Jason Evans9eb1b1c2017-01-18 23:03:37 -08001878 ctl_arena = arenas_i(arena_ind);
1879 ctl_arena->initialized = false;
Jason Evansedf1baf2017-01-03 17:21:59 -08001880 /* Record arena index for later recycling via arenas.create. */
Jason Evans9eb1b1c2017-01-18 23:03:37 -08001881 ql_elm_new(ctl_arena, destroyed_link);
1882 ql_tail_insert(&ctl_arenas->destroyed, ctl_arena, destroyed_link);
Jason Evans19ff2ce2016-04-22 14:37:17 -07001883
Jason Evansedf1baf2017-01-03 17:21:59 -08001884 assert(ret == 0);
Jason Evans19ff2ce2016-04-22 14:37:17 -07001885label_return:
Jason Evansf4086432017-01-19 18:15:45 -08001886 return ret;
Jason Evans19ff2ce2016-04-22 14:37:17 -07001887}
1888
1889static int
Jason Evansb2c0d632016-04-13 23:36:15 -07001890arena_i_dss_ctl(tsd_t *tsd, const size_t *mib, size_t miblen, void *oldp,
Jason Evansc4c25922017-01-15 16:56:30 -08001891 size_t *oldlenp, void *newp, size_t newlen) {
Jason Evans586c8ed2014-08-15 12:20:20 -07001892 int ret;
1893 const char *dss = NULL;
Jason Evans6edbedd2017-01-04 07:51:49 -08001894 unsigned arena_ind;
Jason Evans609ae592012-10-11 13:53:15 -07001895 dss_prec_t dss_prec_old = dss_prec_limit;
1896 dss_prec_t dss_prec = dss_prec_limit;
1897
Jason Evansc1e00ef2016-05-10 22:21:10 -07001898 malloc_mutex_lock(tsd_tsdn(tsd), &ctl_mtx);
Jason Evans609ae592012-10-11 13:53:15 -07001899 WRITE(dss, const char *);
Jason Evans6edbedd2017-01-04 07:51:49 -08001900 MIB_UNSIGNED(arena_ind, 1);
Jason Evans586c8ed2014-08-15 12:20:20 -07001901 if (dss != NULL) {
1902 int i;
1903 bool match = false;
1904
1905 for (i = 0; i < dss_prec_limit; i++) {
1906 if (strcmp(dss_prec_names[i], dss) == 0) {
1907 dss_prec = i;
1908 match = true;
1909 break;
1910 }
Jason Evans609ae592012-10-11 13:53:15 -07001911 }
Jason Evans586c8ed2014-08-15 12:20:20 -07001912
Jason Evans551ebc42014-10-03 10:16:09 -07001913 if (!match) {
Jason Evans586c8ed2014-08-15 12:20:20 -07001914 ret = EINVAL;
1915 goto label_return;
1916 }
Jason Evans609ae592012-10-11 13:53:15 -07001917 }
1918
Jason Evans3dc4e832017-01-03 07:27:42 -08001919 /*
1920 * Access via index narenas is deprecated, and scheduled for removal in
1921 * 6.0.0.
1922 */
Jason Evansd778dd22017-01-03 12:40:54 -08001923 if (arena_ind == MALLCTL_ARENAS_ALL || arena_ind ==
Jason Evans9eb1b1c2017-01-18 23:03:37 -08001924 ctl_arenas->narenas) {
Jason Evans3dc4e832017-01-03 07:27:42 -08001925 if (dss_prec != dss_prec_limit &&
1926 extent_dss_prec_set(dss_prec)) {
1927 ret = EFAULT;
1928 goto label_return;
1929 }
1930 dss_prec_old = extent_dss_prec_get();
1931 } else {
Jason Evansc1e00ef2016-05-10 22:21:10 -07001932 arena_t *arena = arena_get(tsd_tsdn(tsd), arena_ind, false);
Jason Evans586c8ed2014-08-15 12:20:20 -07001933 if (arena == NULL || (dss_prec != dss_prec_limit &&
Jason Evansb7795222017-02-12 16:34:36 -08001934 arena_dss_prec_set(arena, dss_prec))) {
Jason Evans586c8ed2014-08-15 12:20:20 -07001935 ret = EFAULT;
1936 goto label_return;
1937 }
Jason Evansb7795222017-02-12 16:34:36 -08001938 dss_prec_old = arena_dss_prec_get(arena);
Jason Evans609ae592012-10-11 13:53:15 -07001939 }
Jason Evans586c8ed2014-08-15 12:20:20 -07001940
Jason Evans609ae592012-10-11 13:53:15 -07001941 dss = dss_prec_names[dss_prec_old];
1942 READ(dss, const char *);
Jason Evans609ae592012-10-11 13:53:15 -07001943
1944 ret = 0;
1945label_return:
Jason Evansc1e00ef2016-05-10 22:21:10 -07001946 malloc_mutex_unlock(tsd_tsdn(tsd), &ctl_mtx);
Jason Evansf4086432017-01-19 18:15:45 -08001947 return ret;
Jason Evans609ae592012-10-11 13:53:15 -07001948}
1949
aravindfb7fe502014-05-05 15:16:56 -07001950static int
Jason Evans64e458f2017-03-08 22:42:57 -08001951arena_i_decay_time_ctl_impl(tsd_t *tsd, const size_t *mib, size_t miblen,
1952 void *oldp, size_t *oldlenp, void *newp, size_t newlen, bool dirty) {
Jason Evans243f7a02016-02-19 20:09:31 -08001953 int ret;
Jason Evans6edbedd2017-01-04 07:51:49 -08001954 unsigned arena_ind;
Jason Evans243f7a02016-02-19 20:09:31 -08001955 arena_t *arena;
1956
Jason Evans6edbedd2017-01-04 07:51:49 -08001957 MIB_UNSIGNED(arena_ind, 1);
Jason Evansc1e00ef2016-05-10 22:21:10 -07001958 arena = arena_get(tsd_tsdn(tsd), arena_ind, false);
Jason Evans243f7a02016-02-19 20:09:31 -08001959 if (arena == NULL) {
1960 ret = EFAULT;
1961 goto label_return;
1962 }
1963
1964 if (oldp != NULL && oldlenp != NULL) {
Jason Evans64e458f2017-03-08 22:42:57 -08001965 size_t oldval = dirty ? arena_dirty_decay_time_get(arena) :
1966 arena_muzzy_decay_time_get(arena);
Jason Evans243f7a02016-02-19 20:09:31 -08001967 READ(oldval, ssize_t);
1968 }
1969 if (newp != NULL) {
1970 if (newlen != sizeof(ssize_t)) {
1971 ret = EINVAL;
1972 goto label_return;
1973 }
Jason Evans64e458f2017-03-08 22:42:57 -08001974 if (dirty ? arena_dirty_decay_time_set(tsd_tsdn(tsd), arena,
1975 *(ssize_t *)newp) :
1976 arena_muzzy_decay_time_set(tsd_tsdn(tsd), arena,
Jason Evansc1e00ef2016-05-10 22:21:10 -07001977 *(ssize_t *)newp)) {
Jason Evans243f7a02016-02-19 20:09:31 -08001978 ret = EFAULT;
1979 goto label_return;
1980 }
1981 }
1982
1983 ret = 0;
1984label_return:
Jason Evansf4086432017-01-19 18:15:45 -08001985 return ret;
Jason Evans243f7a02016-02-19 20:09:31 -08001986}
1987
1988static int
Jason Evans64e458f2017-03-08 22:42:57 -08001989arena_i_dirty_decay_time_ctl(tsd_t *tsd, const size_t *mib, size_t miblen,
1990 void *oldp, size_t *oldlenp, void *newp, size_t newlen) {
1991 return arena_i_decay_time_ctl_impl(tsd, mib, miblen, oldp, oldlenp,
1992 newp, newlen, true);
1993}
1994
1995static int
1996arena_i_muzzy_decay_time_ctl(tsd_t *tsd, const size_t *mib, size_t miblen,
1997 void *oldp, size_t *oldlenp, void *newp, size_t newlen) {
1998 return arena_i_decay_time_ctl_impl(tsd, mib, miblen, oldp, oldlenp,
1999 newp, newlen, false);
2000}
2001
2002static int
Jason Evans9c305c92016-05-31 15:03:51 -07002003arena_i_extent_hooks_ctl(tsd_t *tsd, const size_t *mib, size_t miblen,
Jason Evansc4c25922017-01-15 16:56:30 -08002004 void *oldp, size_t *oldlenp, void *newp, size_t newlen) {
Jason Evansb49a3342015-07-28 11:28:19 -04002005 int ret;
Jason Evans6edbedd2017-01-04 07:51:49 -08002006 unsigned arena_ind;
Jason Evansb49a3342015-07-28 11:28:19 -04002007 arena_t *arena;
2008
Jason Evansc1e00ef2016-05-10 22:21:10 -07002009 malloc_mutex_lock(tsd_tsdn(tsd), &ctl_mtx);
Jason Evans6edbedd2017-01-04 07:51:49 -08002010 MIB_UNSIGNED(arena_ind, 1);
Jason Evansb49a3342015-07-28 11:28:19 -04002011 if (arena_ind < narenas_total_get() && (arena =
Jason Evansc1e00ef2016-05-10 22:21:10 -07002012 arena_get(tsd_tsdn(tsd), arena_ind, false)) != NULL) {
Jason Evansb49a3342015-07-28 11:28:19 -04002013 if (newp != NULL) {
Jason Evansf02fec82016-06-03 19:39:14 -07002014 extent_hooks_t *old_extent_hooks;
2015 extent_hooks_t *new_extent_hooks
2016 JEMALLOC_CC_SILENCE_INIT(NULL);
Jason Evansf8f05422016-06-03 12:05:53 -07002017 WRITE(new_extent_hooks, extent_hooks_t *);
2018 old_extent_hooks = extent_hooks_set(arena,
2019 new_extent_hooks);
2020 READ(old_extent_hooks, extent_hooks_t *);
Jason Evansb49a3342015-07-28 11:28:19 -04002021 } else {
Jason Evansf8f05422016-06-03 12:05:53 -07002022 extent_hooks_t *old_extent_hooks =
2023 extent_hooks_get(arena);
2024 READ(old_extent_hooks, extent_hooks_t *);
Jason Evansb49a3342015-07-28 11:28:19 -04002025 }
2026 } else {
2027 ret = EFAULT;
2028 goto label_return;
2029 }
2030 ret = 0;
2031label_return:
Jason Evansc1e00ef2016-05-10 22:21:10 -07002032 malloc_mutex_unlock(tsd_tsdn(tsd), &ctl_mtx);
Jason Evansf4086432017-01-19 18:15:45 -08002033 return ret;
aravindfb7fe502014-05-05 15:16:56 -07002034}
2035
Jason Evans609ae592012-10-11 13:53:15 -07002036static const ctl_named_node_t *
Jason Evansc4c25922017-01-15 16:56:30 -08002037arena_i_index(tsdn_t *tsdn, const size_t *mib, size_t miblen, size_t i) {
Jason Evansb2c0d632016-04-13 23:36:15 -07002038 const ctl_named_node_t *ret;
Jason Evans609ae592012-10-11 13:53:15 -07002039
Jason Evansc1e00ef2016-05-10 22:21:10 -07002040 malloc_mutex_lock(tsdn, &ctl_mtx);
Jason Evansedf1baf2017-01-03 17:21:59 -08002041 switch (i) {
2042 case MALLCTL_ARENAS_ALL:
2043 case MALLCTL_ARENAS_DESTROYED:
2044 break;
2045 default:
Jason Evans9eb1b1c2017-01-18 23:03:37 -08002046 if (i > ctl_arenas->narenas) {
Jason Evansedf1baf2017-01-03 17:21:59 -08002047 ret = NULL;
2048 goto label_return;
2049 }
2050 break;
Jason Evans609ae592012-10-11 13:53:15 -07002051 }
2052
2053 ret = super_arena_i_node;
2054label_return:
Jason Evansc1e00ef2016-05-10 22:21:10 -07002055 malloc_mutex_unlock(tsdn, &ctl_mtx);
Jason Evansf4086432017-01-19 18:15:45 -08002056 return ret;
Jason Evans609ae592012-10-11 13:53:15 -07002057}
2058
Jason Evans609ae592012-10-11 13:53:15 -07002059/******************************************************************************/
2060
Jason Evans609ae592012-10-11 13:53:15 -07002061static int
Jason Evansb2c0d632016-04-13 23:36:15 -07002062arenas_narenas_ctl(tsd_t *tsd, const size_t *mib, size_t miblen, void *oldp,
Jason Evansc4c25922017-01-15 16:56:30 -08002063 size_t *oldlenp, void *newp, size_t newlen) {
Jason Evans609ae592012-10-11 13:53:15 -07002064 int ret;
2065 unsigned narenas;
2066
Jason Evansc1e00ef2016-05-10 22:21:10 -07002067 malloc_mutex_lock(tsd_tsdn(tsd), &ctl_mtx);
Jason Evans609ae592012-10-11 13:53:15 -07002068 READONLY();
2069 if (*oldlenp != sizeof(unsigned)) {
2070 ret = EINVAL;
2071 goto label_return;
2072 }
Jason Evans9eb1b1c2017-01-18 23:03:37 -08002073 narenas = ctl_arenas->narenas;
Jason Evans609ae592012-10-11 13:53:15 -07002074 READ(narenas, unsigned);
2075
2076 ret = 0;
2077label_return:
Jason Evansc1e00ef2016-05-10 22:21:10 -07002078 malloc_mutex_unlock(tsd_tsdn(tsd), &ctl_mtx);
Jason Evansf4086432017-01-19 18:15:45 -08002079 return ret;
Jason Evans609ae592012-10-11 13:53:15 -07002080}
Jason Evans3c234352010-01-27 13:10:55 -08002081
2082static int
Jason Evans64e458f2017-03-08 22:42:57 -08002083arenas_decay_time_ctl_impl(tsd_t *tsd, const size_t *mib, size_t miblen,
2084 void *oldp, size_t *oldlenp, void *newp, size_t newlen, bool dirty) {
Jason Evans243f7a02016-02-19 20:09:31 -08002085 int ret;
2086
2087 if (oldp != NULL && oldlenp != NULL) {
Jason Evans64e458f2017-03-08 22:42:57 -08002088 size_t oldval = (dirty ? arena_dirty_decay_time_default_get() :
2089 arena_muzzy_decay_time_default_get());
Jason Evans243f7a02016-02-19 20:09:31 -08002090 READ(oldval, ssize_t);
2091 }
2092 if (newp != NULL) {
2093 if (newlen != sizeof(ssize_t)) {
2094 ret = EINVAL;
2095 goto label_return;
2096 }
Jason Evans64e458f2017-03-08 22:42:57 -08002097 if (dirty ? arena_dirty_decay_time_default_set(*(ssize_t *)newp)
2098 : arena_muzzy_decay_time_default_set(*(ssize_t *)newp)) {
Jason Evans243f7a02016-02-19 20:09:31 -08002099 ret = EFAULT;
2100 goto label_return;
2101 }
2102 }
2103
2104 ret = 0;
2105label_return:
Jason Evansf4086432017-01-19 18:15:45 -08002106 return ret;
Jason Evans243f7a02016-02-19 20:09:31 -08002107}
2108
Jason Evans64e458f2017-03-08 22:42:57 -08002109static int
2110arenas_dirty_decay_time_ctl(tsd_t *tsd, const size_t *mib, size_t miblen,
2111 void *oldp, size_t *oldlenp, void *newp, size_t newlen) {
2112 return arenas_decay_time_ctl_impl(tsd, mib, miblen, oldp, oldlenp, newp,
2113 newlen, true);
2114}
2115
2116static int
2117arenas_muzzy_decay_time_ctl(tsd_t *tsd, const size_t *mib, size_t miblen,
2118 void *oldp, size_t *oldlenp, void *newp, size_t newlen) {
2119 return arenas_decay_time_ctl_impl(tsd, mib, miblen, oldp, oldlenp, newp,
2120 newlen, false);
2121}
2122
Jason Evansfc4dcfa2010-11-24 15:44:21 -08002123CTL_RO_NL_GEN(arenas_quantum, QUANTUM, size_t)
Jason Evansae4c7b42012-04-02 07:04:34 -07002124CTL_RO_NL_GEN(arenas_page, PAGE, size_t)
Jason Evans4403c9a2017-04-20 17:21:37 -07002125CTL_RO_NL_GEN(arenas_tcache_max, tcache_maxclass, size_t)
Jason Evansb1726102012-02-28 16:50:47 -08002126CTL_RO_NL_GEN(arenas_nbins, NBINS, unsigned)
Jason Evans4403c9a2017-04-20 17:21:37 -07002127CTL_RO_NL_GEN(arenas_nhbins, nhbins, unsigned)
Jason Evansd8a39002013-12-19 21:40:41 -08002128CTL_RO_NL_GEN(arenas_bin_i_size, arena_bin_info[mib[2]].reg_size, size_t)
2129CTL_RO_NL_GEN(arenas_bin_i_nregs, arena_bin_info[mib[2]].nregs, uint32_t)
Jason Evans498856f2016-05-29 18:34:50 -07002130CTL_RO_NL_GEN(arenas_bin_i_slab_size, arena_bin_info[mib[2]].slab_size, size_t)
Jason Evansd8a39002013-12-19 21:40:41 -08002131static const ctl_named_node_t *
Jason Evansc4c25922017-01-15 16:56:30 -08002132arenas_bin_i_index(tsdn_t *tsdn, const size_t *mib, size_t miblen, size_t i) {
2133 if (i > NBINS) {
Jason Evansf4086432017-01-19 18:15:45 -08002134 return NULL;
Jason Evansc4c25922017-01-15 16:56:30 -08002135 }
Jason Evansf4086432017-01-19 18:15:45 -08002136 return super_arenas_bin_i_node;
Jason Evansd8a39002013-12-19 21:40:41 -08002137}
2138
Jason Evans7d63fed2016-05-31 14:50:21 -07002139CTL_RO_NL_GEN(arenas_nlextents, NSIZES - NBINS, unsigned)
2140CTL_RO_NL_GEN(arenas_lextent_i_size, index2size(NBINS+(szind_t)mib[2]), size_t)
Jason Evans3c4d92e2014-10-12 22:53:59 -07002141static const ctl_named_node_t *
Jason Evansc4c25922017-01-15 16:56:30 -08002142arenas_lextent_i_index(tsdn_t *tsdn, const size_t *mib, size_t miblen,
2143 size_t i) {
2144 if (i > NSIZES - NBINS) {
Jason Evansf4086432017-01-19 18:15:45 -08002145 return NULL;
Jason Evansc4c25922017-01-15 16:56:30 -08002146 }
Jason Evansf4086432017-01-19 18:15:45 -08002147 return super_arenas_lextent_i_node;
Jason Evans3c4d92e2014-10-12 22:53:59 -07002148}
2149
Jason Evans6005f072010-09-30 16:55:08 -07002150static int
Jason Evans0f04bb12017-01-03 08:21:29 -08002151arenas_create_ctl(tsd_t *tsd, const size_t *mib, size_t miblen, void *oldp,
Jason Evansc4c25922017-01-15 16:56:30 -08002152 size_t *oldlenp, void *newp, size_t newlen) {
Jason Evans609ae592012-10-11 13:53:15 -07002153 int ret;
Jason Evansa0dd3a42016-12-22 16:39:10 -06002154 extent_hooks_t *extent_hooks;
Jason Evansedf1baf2017-01-03 17:21:59 -08002155 unsigned arena_ind;
Jason Evans609ae592012-10-11 13:53:15 -07002156
Jason Evansc1e00ef2016-05-10 22:21:10 -07002157 malloc_mutex_lock(tsd_tsdn(tsd), &ctl_mtx);
Jason Evansa0dd3a42016-12-22 16:39:10 -06002158
2159 extent_hooks = (extent_hooks_t *)&extent_hooks_default;
2160 WRITE(extent_hooks, extent_hooks_t *);
Jason Evansedf1baf2017-01-03 17:21:59 -08002161 if ((arena_ind = ctl_arena_init(tsd_tsdn(tsd), extent_hooks)) ==
2162 UINT_MAX) {
Jason Evans609ae592012-10-11 13:53:15 -07002163 ret = EAGAIN;
2164 goto label_return;
2165 }
Jason Evansedf1baf2017-01-03 17:21:59 -08002166 READ(arena_ind, unsigned);
Jason Evans609ae592012-10-11 13:53:15 -07002167
Jason Evans6005f072010-09-30 16:55:08 -07002168 ret = 0;
Jason Evansa1ee7832012-04-10 15:07:44 -07002169label_return:
Jason Evansc1e00ef2016-05-10 22:21:10 -07002170 malloc_mutex_unlock(tsd_tsdn(tsd), &ctl_mtx);
Jason Evansf4086432017-01-19 18:15:45 -08002171 return ret;
Jason Evans6005f072010-09-30 16:55:08 -07002172}
2173
Jason Evans3c234352010-01-27 13:10:55 -08002174/******************************************************************************/
2175
Jason Evansd34f9e72010-02-11 13:19:21 -08002176static int
Jason Evansb2c0d632016-04-13 23:36:15 -07002177prof_thread_active_init_ctl(tsd_t *tsd, const size_t *mib, size_t miblen,
Jason Evansc4c25922017-01-15 16:56:30 -08002178 void *oldp, size_t *oldlenp, void *newp, size_t newlen) {
Jason Evansb2c0d632016-04-13 23:36:15 -07002179 int ret;
2180 bool oldval;
2181
Jason Evansc4c25922017-01-15 16:56:30 -08002182 if (!config_prof) {
Jason Evansf4086432017-01-19 18:15:45 -08002183 return ENOENT;
Jason Evansc4c25922017-01-15 16:56:30 -08002184 }
Jason Evansb2c0d632016-04-13 23:36:15 -07002185
2186 if (newp != NULL) {
2187 if (newlen != sizeof(bool)) {
2188 ret = EINVAL;
2189 goto label_return;
2190 }
Jason Evansc1e00ef2016-05-10 22:21:10 -07002191 oldval = prof_thread_active_init_set(tsd_tsdn(tsd),
2192 *(bool *)newp);
Jason Evansc4c25922017-01-15 16:56:30 -08002193 } else {
Jason Evansc1e00ef2016-05-10 22:21:10 -07002194 oldval = prof_thread_active_init_get(tsd_tsdn(tsd));
Jason Evansc4c25922017-01-15 16:56:30 -08002195 }
Jason Evansb2c0d632016-04-13 23:36:15 -07002196 READ(oldval, bool);
2197
2198 ret = 0;
2199label_return:
Jason Evansf4086432017-01-19 18:15:45 -08002200 return ret;
Jason Evansb2c0d632016-04-13 23:36:15 -07002201}
2202
2203static int
2204prof_active_ctl(tsd_t *tsd, const size_t *mib, size_t miblen, void *oldp,
Jason Evansc4c25922017-01-15 16:56:30 -08002205 size_t *oldlenp, void *newp, size_t newlen) {
Jason Evansfc12c0b2014-10-03 23:25:30 -07002206 int ret;
2207 bool oldval;
2208
Jason Evansc4c25922017-01-15 16:56:30 -08002209 if (!config_prof) {
Jason Evansf4086432017-01-19 18:15:45 -08002210 return ENOENT;
Jason Evansc4c25922017-01-15 16:56:30 -08002211 }
Jason Evansfc12c0b2014-10-03 23:25:30 -07002212
2213 if (newp != NULL) {
2214 if (newlen != sizeof(bool)) {
2215 ret = EINVAL;
2216 goto label_return;
2217 }
Jason Evansc1e00ef2016-05-10 22:21:10 -07002218 oldval = prof_active_set(tsd_tsdn(tsd), *(bool *)newp);
Jason Evansc4c25922017-01-15 16:56:30 -08002219 } else {
Jason Evansc1e00ef2016-05-10 22:21:10 -07002220 oldval = prof_active_get(tsd_tsdn(tsd));
Jason Evansc4c25922017-01-15 16:56:30 -08002221 }
Jason Evansfc12c0b2014-10-03 23:25:30 -07002222 READ(oldval, bool);
2223
2224 ret = 0;
2225label_return:
Jason Evansf4086432017-01-19 18:15:45 -08002226 return ret;
Jason Evansfc12c0b2014-10-03 23:25:30 -07002227}
2228
2229static int
Jason Evansb2c0d632016-04-13 23:36:15 -07002230prof_dump_ctl(tsd_t *tsd, const size_t *mib, size_t miblen, void *oldp,
Jason Evansc4c25922017-01-15 16:56:30 -08002231 size_t *oldlenp, void *newp, size_t newlen) {
Jason Evansd34f9e72010-02-11 13:19:21 -08002232 int ret;
Jason Evans22ca8552010-03-02 11:57:30 -08002233 const char *filename = NULL;
Jason Evansd34f9e72010-02-11 13:19:21 -08002234
Jason Evansc4c25922017-01-15 16:56:30 -08002235 if (!config_prof) {
Jason Evansf4086432017-01-19 18:15:45 -08002236 return ENOENT;
Jason Evansc4c25922017-01-15 16:56:30 -08002237 }
Jason Evans7372b152012-02-10 20:22:09 -08002238
Jason Evans22ca8552010-03-02 11:57:30 -08002239 WRITEONLY();
2240 WRITE(filename, const char *);
Jason Evansd34f9e72010-02-11 13:19:21 -08002241
Jason Evansb2c0d632016-04-13 23:36:15 -07002242 if (prof_mdump(tsd, filename)) {
Jason Evans22ca8552010-03-02 11:57:30 -08002243 ret = EFAULT;
Jason Evansa1ee7832012-04-10 15:07:44 -07002244 goto label_return;
Jason Evans22ca8552010-03-02 11:57:30 -08002245 }
Jason Evansd34f9e72010-02-11 13:19:21 -08002246
2247 ret = 0;
Jason Evansa1ee7832012-04-10 15:07:44 -07002248label_return:
Jason Evansf4086432017-01-19 18:15:45 -08002249 return ret;
Jason Evansd34f9e72010-02-11 13:19:21 -08002250}
2251
Jason Evans602c8e02014-08-18 16:22:13 -07002252static int
Jason Evansb2c0d632016-04-13 23:36:15 -07002253prof_gdump_ctl(tsd_t *tsd, const size_t *mib, size_t miblen, void *oldp,
Jason Evansc4c25922017-01-15 16:56:30 -08002254 size_t *oldlenp, void *newp, size_t newlen) {
Jason Evans5b8ed5b2015-01-25 21:16:57 -08002255 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 Evans5b8ed5b2015-01-25 21:16:57 -08002261
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_gdump_set(tsd_tsdn(tsd), *(bool *)newp);
Jason Evansc4c25922017-01-15 16:56:30 -08002268 } else {
Jason Evansc1e00ef2016-05-10 22:21:10 -07002269 oldval = prof_gdump_get(tsd_tsdn(tsd));
Jason Evansc4c25922017-01-15 16:56:30 -08002270 }
Jason Evans5b8ed5b2015-01-25 21:16:57 -08002271 READ(oldval, bool);
2272
2273 ret = 0;
2274label_return:
Jason Evansf4086432017-01-19 18:15:45 -08002275 return ret;
Jason Evans5b8ed5b2015-01-25 21:16:57 -08002276}
2277
2278static int
Jason Evansb2c0d632016-04-13 23:36:15 -07002279prof_reset_ctl(tsd_t *tsd, const size_t *mib, size_t miblen, void *oldp,
Jason Evansc4c25922017-01-15 16:56:30 -08002280 size_t *oldlenp, void *newp, size_t newlen) {
Jason Evans602c8e02014-08-18 16:22:13 -07002281 int ret;
2282 size_t lg_sample = lg_prof_sample;
2283
Jason Evansc4c25922017-01-15 16:56:30 -08002284 if (!config_prof) {
Jason Evansf4086432017-01-19 18:15:45 -08002285 return ENOENT;
Jason Evansc4c25922017-01-15 16:56:30 -08002286 }
Jason Evans602c8e02014-08-18 16:22:13 -07002287
2288 WRITEONLY();
2289 WRITE(lg_sample, size_t);
Jason Evansc4c25922017-01-15 16:56:30 -08002290 if (lg_sample >= (sizeof(uint64_t) << 3)) {
Jason Evans602c8e02014-08-18 16:22:13 -07002291 lg_sample = (sizeof(uint64_t) << 3) - 1;
Jason Evansc4c25922017-01-15 16:56:30 -08002292 }
Jason Evans602c8e02014-08-18 16:22:13 -07002293
Jason Evansb54d1602016-10-20 23:59:12 -07002294 prof_reset(tsd, lg_sample);
Jason Evans602c8e02014-08-18 16:22:13 -07002295
2296 ret = 0;
2297label_return:
Jason Evansf4086432017-01-19 18:15:45 -08002298 return ret;
Jason Evans602c8e02014-08-18 16:22:13 -07002299}
2300
Jason Evans7372b152012-02-10 20:22:09 -08002301CTL_RO_NL_CGEN(config_prof, prof_interval, prof_interval, uint64_t)
Jason Evans602c8e02014-08-18 16:22:13 -07002302CTL_RO_NL_CGEN(config_prof, lg_prof_sample, lg_prof_sample, size_t)
Jason Evansd34f9e72010-02-11 13:19:21 -08002303
2304/******************************************************************************/
2305
Jason Evansd778dd22017-01-03 12:40:54 -08002306CTL_RO_CGEN(config_stats, stats_allocated, ctl_stats->allocated, size_t)
2307CTL_RO_CGEN(config_stats, stats_active, ctl_stats->active, size_t)
2308CTL_RO_CGEN(config_stats, stats_metadata, ctl_stats->metadata, size_t)
2309CTL_RO_CGEN(config_stats, stats_resident, ctl_stats->resident, size_t)
2310CTL_RO_CGEN(config_stats, stats_mapped, ctl_stats->mapped, size_t)
2311CTL_RO_CGEN(config_stats, stats_retained, ctl_stats->retained, size_t)
Jason Evansd8a39002013-12-19 21:40:41 -08002312
Jason Evans9eb1b1c2017-01-18 23:03:37 -08002313CTL_RO_GEN(stats_arenas_i_dss, arenas_i(mib[2])->dss, const char *)
Jason Evans64e458f2017-03-08 22:42:57 -08002314CTL_RO_GEN(stats_arenas_i_dirty_decay_time, arenas_i(mib[2])->dirty_decay_time,
2315 ssize_t)
2316CTL_RO_GEN(stats_arenas_i_muzzy_decay_time, arenas_i(mib[2])->muzzy_decay_time,
Jason Evans243f7a02016-02-19 20:09:31 -08002317 ssize_t)
Jason Evans9eb1b1c2017-01-18 23:03:37 -08002318CTL_RO_GEN(stats_arenas_i_nthreads, arenas_i(mib[2])->nthreads, unsigned)
2319CTL_RO_GEN(stats_arenas_i_pactive, arenas_i(mib[2])->pactive, size_t)
2320CTL_RO_GEN(stats_arenas_i_pdirty, arenas_i(mib[2])->pdirty, size_t)
Jason Evans64e458f2017-03-08 22:42:57 -08002321CTL_RO_GEN(stats_arenas_i_pmuzzy, arenas_i(mib[2])->pmuzzy, size_t)
Jason Evansd8a39002013-12-19 21:40:41 -08002322CTL_RO_CGEN(config_stats, stats_arenas_i_mapped,
David Goldblattee202ef2017-03-13 16:18:40 -07002323 atomic_load_zu(&arenas_i(mib[2])->astats->astats.mapped, ATOMIC_RELAXED),
2324 size_t)
Jason Evans04c3c0f2016-05-03 22:11:35 -07002325CTL_RO_CGEN(config_stats, stats_arenas_i_retained,
David Goldblattee202ef2017-03-13 16:18:40 -07002326 atomic_load_zu(&arenas_i(mib[2])->astats->astats.retained, ATOMIC_RELAXED),
2327 size_t)
Jason Evans64e458f2017-03-08 22:42:57 -08002328
2329CTL_RO_CGEN(config_stats, stats_arenas_i_dirty_npurge,
2330 arena_stats_read_u64(&arenas_i(mib[2])->astats->astats.decay_dirty.npurge),
2331 uint64_t)
2332CTL_RO_CGEN(config_stats, stats_arenas_i_dirty_nmadvise,
2333 arena_stats_read_u64(
2334 &arenas_i(mib[2])->astats->astats.decay_dirty.nmadvise), uint64_t)
2335CTL_RO_CGEN(config_stats, stats_arenas_i_dirty_purged,
2336 arena_stats_read_u64(&arenas_i(mib[2])->astats->astats.decay_dirty.purged),
2337 uint64_t)
2338
2339CTL_RO_CGEN(config_stats, stats_arenas_i_muzzy_npurge,
2340 arena_stats_read_u64(&arenas_i(mib[2])->astats->astats.decay_muzzy.npurge),
2341 uint64_t)
2342CTL_RO_CGEN(config_stats, stats_arenas_i_muzzy_nmadvise,
2343 arena_stats_read_u64(
2344 &arenas_i(mib[2])->astats->astats.decay_muzzy.nmadvise), uint64_t)
2345CTL_RO_CGEN(config_stats, stats_arenas_i_muzzy_purged,
2346 arena_stats_read_u64(&arenas_i(mib[2])->astats->astats.decay_muzzy.purged),
2347 uint64_t)
2348
Jason Evansa0dd3a42016-12-22 16:39:10 -06002349CTL_RO_CGEN(config_stats, stats_arenas_i_base,
David Goldblattee202ef2017-03-13 16:18:40 -07002350 atomic_load_zu(&arenas_i(mib[2])->astats->astats.base, ATOMIC_RELAXED),
2351 size_t)
Jason Evansa0dd3a42016-12-22 16:39:10 -06002352CTL_RO_CGEN(config_stats, stats_arenas_i_internal,
David Goldblattee202ef2017-03-13 16:18:40 -07002353 atomic_load_zu(&arenas_i(mib[2])->astats->astats.internal, ATOMIC_RELAXED),
2354 size_t)
Jason Evans4403c9a2017-04-20 17:21:37 -07002355CTL_RO_CGEN(config_stats, stats_arenas_i_tcache_bytes,
David Goldblattee202ef2017-03-13 16:18:40 -07002356 atomic_load_zu(&arenas_i(mib[2])->astats->astats.tcache_bytes,
2357 ATOMIC_RELAXED), size_t)
Jason Evansa0dd3a42016-12-22 16:39:10 -06002358CTL_RO_CGEN(config_stats, stats_arenas_i_resident,
David Goldblattee202ef2017-03-13 16:18:40 -07002359 atomic_load_zu(&arenas_i(mib[2])->astats->astats.resident, ATOMIC_RELAXED),
2360 size_t)
Jason Evansd8a39002013-12-19 21:40:41 -08002361
Jason Evans7372b152012-02-10 20:22:09 -08002362CTL_RO_CGEN(config_stats, stats_arenas_i_small_allocated,
Jason Evans9eb1b1c2017-01-18 23:03:37 -08002363 arenas_i(mib[2])->astats->allocated_small, size_t)
Jason Evans7372b152012-02-10 20:22:09 -08002364CTL_RO_CGEN(config_stats, stats_arenas_i_small_nmalloc,
Jason Evans9eb1b1c2017-01-18 23:03:37 -08002365 arenas_i(mib[2])->astats->nmalloc_small, uint64_t)
Jason Evans7372b152012-02-10 20:22:09 -08002366CTL_RO_CGEN(config_stats, stats_arenas_i_small_ndalloc,
Jason Evans9eb1b1c2017-01-18 23:03:37 -08002367 arenas_i(mib[2])->astats->ndalloc_small, uint64_t)
Jason Evans7372b152012-02-10 20:22:09 -08002368CTL_RO_CGEN(config_stats, stats_arenas_i_small_nrequests,
Jason Evans9eb1b1c2017-01-18 23:03:37 -08002369 arenas_i(mib[2])->astats->nrequests_small, uint64_t)
Jason Evans7d63fed2016-05-31 14:50:21 -07002370CTL_RO_CGEN(config_stats, stats_arenas_i_large_allocated,
David Goldblattee202ef2017-03-13 16:18:40 -07002371 atomic_load_zu(&arenas_i(mib[2])->astats->astats.allocated_large,
2372 ATOMIC_RELAXED), size_t)
Jason Evans7d63fed2016-05-31 14:50:21 -07002373CTL_RO_CGEN(config_stats, stats_arenas_i_large_nmalloc,
David Goldblatt4fc2acf2017-03-08 15:56:31 -08002374 arena_stats_read_u64(&arenas_i(mib[2])->astats->astats.nmalloc_large),
2375 uint64_t)
Jason Evans7d63fed2016-05-31 14:50:21 -07002376CTL_RO_CGEN(config_stats, stats_arenas_i_large_ndalloc,
David Goldblatt4fc2acf2017-03-08 15:56:31 -08002377 arena_stats_read_u64(&arenas_i(mib[2])->astats->astats.ndalloc_large),
2378 uint64_t)
Jason Evans7d63fed2016-05-31 14:50:21 -07002379CTL_RO_CGEN(config_stats, stats_arenas_i_large_nrequests,
David Goldblatt4fc2acf2017-03-08 15:56:31 -08002380 arena_stats_read_u64(&arenas_i(mib[2])->astats->astats.nmalloc_large),
2381 uint64_t) /* Intentional. */
Jason Evans3c234352010-01-27 13:10:55 -08002382
Qi Wang0fb5c0e2017-03-10 12:14:05 -08002383/* Lock profiling related APIs below. */
Qi Wang64c5f5c2017-03-13 17:29:03 -07002384#define RO_MUTEX_CTL_GEN(n, l) \
Qi Wangca9074d2017-03-11 20:28:31 -08002385CTL_RO_CGEN(config_stats, stats_##n##_num_ops, \
2386 l.n_lock_ops, uint64_t) \
2387CTL_RO_CGEN(config_stats, stats_##n##_num_wait, \
2388 l.n_wait_times, uint64_t) \
2389CTL_RO_CGEN(config_stats, stats_##n##_num_spin_acq, \
2390 l.n_spin_acquired, uint64_t) \
2391CTL_RO_CGEN(config_stats, stats_##n##_num_owner_switch, \
2392 l.n_owner_switches, uint64_t) \
2393CTL_RO_CGEN(config_stats, stats_##n##_total_wait_time, \
Qi Wangf6698ec2017-03-17 17:42:10 -07002394 nstime_ns(&l.tot_wait_time), uint64_t) \
Qi Wangca9074d2017-03-11 20:28:31 -08002395CTL_RO_CGEN(config_stats, stats_##n##_max_wait_time, \
Qi Wangf6698ec2017-03-17 17:42:10 -07002396 nstime_ns(&l.max_wait_time), uint64_t) \
Qi Wangca9074d2017-03-11 20:28:31 -08002397CTL_RO_CGEN(config_stats, stats_##n##_max_num_thds, \
Qi Wangd3fde1c2017-03-21 11:56:38 -07002398 l.max_n_thds, uint32_t)
Qi Wang0fb5c0e2017-03-10 12:14:05 -08002399
Qi Wang64c5f5c2017-03-13 17:29:03 -07002400/* Global mutexes. */
Qi Wangd3fde1c2017-03-21 11:56:38 -07002401#define OP(mtx) \
2402 RO_MUTEX_CTL_GEN(mutexes_##mtx, \
2403 ctl_stats->mutex_prof_data[global_prof_mutex_##mtx])
Qi Wangca9074d2017-03-11 20:28:31 -08002404GLOBAL_PROF_MUTEXES
Qi Wangd3fde1c2017-03-21 11:56:38 -07002405#undef OP
2406
2407/* Per arena mutexes */
2408#define OP(mtx) RO_MUTEX_CTL_GEN(arenas_i_mutexes_##mtx, \
2409 arenas_i(mib[2])->astats->astats.mutex_prof_data[arena_prof_mutex_##mtx])
2410ARENA_PROF_MUTEXES
2411#undef OP
Qi Wangca9074d2017-03-11 20:28:31 -08002412
Qi Wang20b8c702017-03-15 14:00:57 -07002413/* tcache bin mutex */
Qi Wang64c5f5c2017-03-13 17:29:03 -07002414RO_MUTEX_CTL_GEN(arenas_i_bins_j_mutex,
2415 arenas_i(mib[2])->astats->bstats[mib[4]].mutex_data)
Qi Wang64c5f5c2017-03-13 17:29:03 -07002416#undef RO_MUTEX_CTL_GEN
2417
2418/* Resets all mutex stats, including global, arena and bin mutexes. */
2419static int
2420stats_mutexes_reset_ctl(tsd_t *tsd, const size_t *mib, size_t miblen,
2421 void *oldp, size_t *oldlenp, void *newp, size_t newlen) {
2422 if (!config_stats) {
2423 return ENOENT;
2424 }
2425
2426 tsdn_t *tsdn = tsd_tsdn(tsd);
2427
2428#define MUTEX_PROF_RESET(mtx) \
2429 malloc_mutex_lock(tsdn, &mtx); \
2430 malloc_mutex_prof_data_reset(tsdn, &mtx); \
2431 malloc_mutex_unlock(tsdn, &mtx);
2432
Qi Wang362e3562017-03-22 01:49:56 -07002433 /* Global mutexes: ctl and prof. */
2434 MUTEX_PROF_RESET(ctl_mtx);
Qi Wang64c5f5c2017-03-13 17:29:03 -07002435 if (config_prof && opt_prof) {
2436 MUTEX_PROF_RESET(bt2gctx_mtx);
2437 }
Qi Wang362e3562017-03-22 01:49:56 -07002438
Qi Wang64c5f5c2017-03-13 17:29:03 -07002439
2440 /* Per arena mutexes. */
2441 unsigned n = narenas_total_get();
2442
2443 for (unsigned i = 0; i < n; i++) {
2444 arena_t *arena = arena_get(tsdn, i, false);
2445 if (!arena) {
2446 continue;
2447 }
2448 MUTEX_PROF_RESET(arena->large_mtx);
Jason Evans881fbf72017-04-16 22:31:16 -07002449 MUTEX_PROF_RESET(arena->extent_avail_mtx);
Qi Wang20b8c702017-03-15 14:00:57 -07002450 MUTEX_PROF_RESET(arena->extents_dirty.mtx);
2451 MUTEX_PROF_RESET(arena->extents_muzzy.mtx);
Qi Wang64c5f5c2017-03-13 17:29:03 -07002452 MUTEX_PROF_RESET(arena->extents_retained.mtx);
Qi Wang20b8c702017-03-15 14:00:57 -07002453 MUTEX_PROF_RESET(arena->decay_dirty.mtx);
2454 MUTEX_PROF_RESET(arena->decay_muzzy.mtx);
Jason Evans4403c9a2017-04-20 17:21:37 -07002455 MUTEX_PROF_RESET(arena->tcache_ql_mtx);
Qi Wang362e3562017-03-22 01:49:56 -07002456 MUTEX_PROF_RESET(arena->base->mtx);
Qi Wang64c5f5c2017-03-13 17:29:03 -07002457
2458 for (szind_t i = 0; i < NBINS; i++) {
2459 arena_bin_t *bin = &arena->bins[i];
2460 MUTEX_PROF_RESET(bin->lock);
2461 }
2462 }
2463#undef MUTEX_PROF_RESET
2464 return 0;
2465}
Qi Wang0fb5c0e2017-03-10 12:14:05 -08002466
Jason Evans7372b152012-02-10 20:22:09 -08002467CTL_RO_CGEN(config_stats, stats_arenas_i_bins_j_nmalloc,
Jason Evans9eb1b1c2017-01-18 23:03:37 -08002468 arenas_i(mib[2])->astats->bstats[mib[4]].nmalloc, uint64_t)
Jason Evans7372b152012-02-10 20:22:09 -08002469CTL_RO_CGEN(config_stats, stats_arenas_i_bins_j_ndalloc,
Jason Evans9eb1b1c2017-01-18 23:03:37 -08002470 arenas_i(mib[2])->astats->bstats[mib[4]].ndalloc, uint64_t)
Jason Evans7372b152012-02-10 20:22:09 -08002471CTL_RO_CGEN(config_stats, stats_arenas_i_bins_j_nrequests,
Jason Evans9eb1b1c2017-01-18 23:03:37 -08002472 arenas_i(mib[2])->astats->bstats[mib[4]].nrequests, uint64_t)
Jason Evans3c4d92e2014-10-12 22:53:59 -07002473CTL_RO_CGEN(config_stats, stats_arenas_i_bins_j_curregs,
Jason Evans9eb1b1c2017-01-18 23:03:37 -08002474 arenas_i(mib[2])->astats->bstats[mib[4]].curregs, size_t)
Jason Evans4403c9a2017-04-20 17:21:37 -07002475CTL_RO_CGEN(config_stats, stats_arenas_i_bins_j_nfills,
Jason Evans9eb1b1c2017-01-18 23:03:37 -08002476 arenas_i(mib[2])->astats->bstats[mib[4]].nfills, uint64_t)
Jason Evans4403c9a2017-04-20 17:21:37 -07002477CTL_RO_CGEN(config_stats, stats_arenas_i_bins_j_nflushes,
Jason Evans9eb1b1c2017-01-18 23:03:37 -08002478 arenas_i(mib[2])->astats->bstats[mib[4]].nflushes, uint64_t)
Jason Evans498856f2016-05-29 18:34:50 -07002479CTL_RO_CGEN(config_stats, stats_arenas_i_bins_j_nslabs,
Jason Evans9eb1b1c2017-01-18 23:03:37 -08002480 arenas_i(mib[2])->astats->bstats[mib[4]].nslabs, uint64_t)
Jason Evans498856f2016-05-29 18:34:50 -07002481CTL_RO_CGEN(config_stats, stats_arenas_i_bins_j_nreslabs,
Jason Evans9eb1b1c2017-01-18 23:03:37 -08002482 arenas_i(mib[2])->astats->bstats[mib[4]].reslabs, uint64_t)
Jason Evans498856f2016-05-29 18:34:50 -07002483CTL_RO_CGEN(config_stats, stats_arenas_i_bins_j_curslabs,
Jason Evans9eb1b1c2017-01-18 23:03:37 -08002484 arenas_i(mib[2])->astats->bstats[mib[4]].curslabs, size_t)
Jason Evans3c234352010-01-27 13:10:55 -08002485
Jason Evans609ae592012-10-11 13:53:15 -07002486static const ctl_named_node_t *
Jason Evansc1e00ef2016-05-10 22:21:10 -07002487stats_arenas_i_bins_j_index(tsdn_t *tsdn, const size_t *mib, size_t miblen,
Jason Evansc4c25922017-01-15 16:56:30 -08002488 size_t j) {
2489 if (j > NBINS) {
Jason Evansf4086432017-01-19 18:15:45 -08002490 return NULL;
Jason Evansc4c25922017-01-15 16:56:30 -08002491 }
Jason Evansf4086432017-01-19 18:15:45 -08002492 return super_stats_arenas_i_bins_j_node;
Jason Evans3c234352010-01-27 13:10:55 -08002493}
2494
Jason Evans7d63fed2016-05-31 14:50:21 -07002495CTL_RO_CGEN(config_stats, stats_arenas_i_lextents_j_nmalloc,
David Goldblatt4fc2acf2017-03-08 15:56:31 -08002496 arena_stats_read_u64(&arenas_i(mib[2])->astats->lstats[mib[4]].nmalloc),
2497 uint64_t)
Jason Evans7d63fed2016-05-31 14:50:21 -07002498CTL_RO_CGEN(config_stats, stats_arenas_i_lextents_j_ndalloc,
David Goldblatt4fc2acf2017-03-08 15:56:31 -08002499 arena_stats_read_u64(&arenas_i(mib[2])->astats->lstats[mib[4]].ndalloc),
2500 uint64_t)
Jason Evans7d63fed2016-05-31 14:50:21 -07002501CTL_RO_CGEN(config_stats, stats_arenas_i_lextents_j_nrequests,
Jason Evans64e458f2017-03-08 22:42:57 -08002502 arena_stats_read_u64(&arenas_i(mib[2])->astats->lstats[mib[4]].nrequests),
2503 uint64_t)
Jason Evans7d63fed2016-05-31 14:50:21 -07002504CTL_RO_CGEN(config_stats, stats_arenas_i_lextents_j_curlextents,
Jason Evans9eb1b1c2017-01-18 23:03:37 -08002505 arenas_i(mib[2])->astats->lstats[mib[4]].curlextents, size_t)
Jason Evans3c4d92e2014-10-12 22:53:59 -07002506
2507static const ctl_named_node_t *
Jason Evans7d63fed2016-05-31 14:50:21 -07002508stats_arenas_i_lextents_j_index(tsdn_t *tsdn, const size_t *mib, size_t miblen,
Jason Evansc4c25922017-01-15 16:56:30 -08002509 size_t j) {
2510 if (j > NSIZES - NBINS) {
Jason Evansf4086432017-01-19 18:15:45 -08002511 return NULL;
Jason Evansc4c25922017-01-15 16:56:30 -08002512 }
Jason Evansf4086432017-01-19 18:15:45 -08002513 return super_stats_arenas_i_lextents_j_node;
Jason Evans3c4d92e2014-10-12 22:53:59 -07002514}
2515
Jason Evans609ae592012-10-11 13:53:15 -07002516static const ctl_named_node_t *
Jason Evansc4c25922017-01-15 16:56:30 -08002517stats_arenas_i_index(tsdn_t *tsdn, const size_t *mib, size_t miblen, size_t i) {
Jason Evans3dc4e832017-01-03 07:27:42 -08002518 const ctl_named_node_t *ret;
2519 size_t a;
Jason Evans3c234352010-01-27 13:10:55 -08002520
Jason Evansc1e00ef2016-05-10 22:21:10 -07002521 malloc_mutex_lock(tsdn, &ctl_mtx);
Jason Evans9eb1b1c2017-01-18 23:03:37 -08002522 a = arenas_i2a_impl(i, true, true);
2523 if (a == UINT_MAX || !ctl_arenas->arenas[a]->initialized) {
Jason Evansfc4dcfa2010-11-24 15:44:21 -08002524 ret = NULL;
Jason Evansa1ee7832012-04-10 15:07:44 -07002525 goto label_return;
Jason Evansfc4dcfa2010-11-24 15:44:21 -08002526 }
2527
2528 ret = super_stats_arenas_i_node;
Jason Evansa1ee7832012-04-10 15:07:44 -07002529label_return:
Jason Evansc1e00ef2016-05-10 22:21:10 -07002530 malloc_mutex_unlock(tsdn, &ctl_mtx);
Jason Evansf4086432017-01-19 18:15:45 -08002531 return ret;
Jason Evans3c234352010-01-27 13:10:55 -08002532}