blob: bc78b20558a5df5a168bef9b847ed0c68daa1887 [file] [log] [blame]
Jason Evans3c234352010-01-27 13:10:55 -08001#define JEMALLOC_CTL_C_
Jason Evans376b1522010-02-11 14:45:59 -08002#include "jemalloc/internal/jemalloc_internal.h"
Jason Evans3c234352010-01-27 13:10:55 -08003
4/******************************************************************************/
5/* Data. */
6
Jason Evansfc4dcfa2010-11-24 15:44:21 -08007/*
8 * ctl_mtx protects the following:
9 * - ctl_stats.*
Jason Evansfc4dcfa2010-11-24 15:44:21 -080010 */
Jason Evans3c234352010-01-27 13:10:55 -080011static malloc_mutex_t ctl_mtx;
12static bool ctl_initialized;
13static uint64_t ctl_epoch;
14static ctl_stats_t ctl_stats;
15
16/******************************************************************************/
Mike Hommey461ad5c2012-04-20 08:38:42 +020017/* Helpers for named and indexed nodes. */
18
Jason Evansaf1f5922014-10-30 16:38:08 -070019JEMALLOC_INLINE_C const ctl_named_node_t *
Mike Hommey461ad5c2012-04-20 08:38:42 +020020ctl_named_node(const ctl_node_t *node)
21{
22
23 return ((node->named) ? (const ctl_named_node_t *)node : NULL);
24}
25
Jason Evansaf1f5922014-10-30 16:38:08 -070026JEMALLOC_INLINE_C const ctl_named_node_t *
Jason Evans8dd51152016-02-24 11:00:40 -080027ctl_named_children(const ctl_named_node_t *node, size_t index)
Mike Hommey461ad5c2012-04-20 08:38:42 +020028{
29 const ctl_named_node_t *children = ctl_named_node(node->children);
30
31 return (children ? &children[index] : NULL);
32}
33
Jason Evansaf1f5922014-10-30 16:38:08 -070034JEMALLOC_INLINE_C const ctl_indexed_node_t *
Mike Hommey461ad5c2012-04-20 08:38:42 +020035ctl_indexed_node(const ctl_node_t *node)
36{
37
Jason Evans551ebc42014-10-03 10:16:09 -070038 return (!node->named ? (const ctl_indexed_node_t *)node : NULL);
Mike Hommey461ad5c2012-04-20 08:38:42 +020039}
40
41/******************************************************************************/
Jason Evans3c234352010-01-27 13:10:55 -080042/* Function prototypes for non-inline static functions. */
43
44#define CTL_PROTO(n) \
Jason Evansb2c0d632016-04-13 23:36:15 -070045static int n##_ctl(tsd_t *tsd, const size_t *mib, size_t miblen, \
46 void *oldp, size_t *oldlenp, void *newp, size_t newlen);
Jason Evans3c234352010-01-27 13:10:55 -080047
48#define INDEX_PROTO(n) \
Jason Evansc1e00ef2016-05-10 22:21:10 -070049static const ctl_named_node_t *n##_index(tsdn_t *tsdn, \
Jason Evansb2c0d632016-04-13 23:36:15 -070050 const size_t *mib, size_t miblen, size_t i);
Jason Evans3c234352010-01-27 13:10:55 -080051
Jason Evans3c234352010-01-27 13:10:55 -080052static bool ctl_arena_init(ctl_arena_stats_t *astats);
Jason Evans3c234352010-01-27 13:10:55 -080053static void ctl_arena_clear(ctl_arena_stats_t *astats);
Jason Evansc1e00ef2016-05-10 22:21:10 -070054static void ctl_arena_stats_amerge(tsdn_t *tsdn, ctl_arena_stats_t *cstats,
Jason Evans86815df2010-03-13 20:32:56 -080055 arena_t *arena);
56static void ctl_arena_stats_smerge(ctl_arena_stats_t *sstats,
57 ctl_arena_stats_t *astats);
Jason Evansc1e00ef2016-05-10 22:21:10 -070058static void ctl_arena_refresh(tsdn_t *tsdn, arena_t *arena, unsigned i);
59static bool ctl_grow(tsdn_t *tsdn);
60static void ctl_refresh(tsdn_t *tsdn);
61static bool ctl_init(tsdn_t *tsdn);
62static int ctl_lookup(tsdn_t *tsdn, const char *name,
Jason Evansb2c0d632016-04-13 23:36:15 -070063 ctl_node_t const **nodesp, size_t *mibp, size_t *depthp);
Jason Evans3c234352010-01-27 13:10:55 -080064
Jason Evansa40bc7a2010-03-02 13:01:16 -080065CTL_PROTO(version)
Jason Evans3c234352010-01-27 13:10:55 -080066CTL_PROTO(epoch)
Jason Evansd4be8b72012-03-26 18:54:44 -070067CTL_PROTO(thread_tcache_enabled)
Jason Evanse7b8fa12012-03-16 17:09:32 -070068CTL_PROTO(thread_tcache_flush)
Jason Evans602c8e02014-08-18 16:22:13 -070069CTL_PROTO(thread_prof_name)
70CTL_PROTO(thread_prof_active)
Jason Evansb267d0f2010-08-13 15:42:29 -070071CTL_PROTO(thread_arena)
Jason Evans93443682010-10-20 17:39:18 -070072CTL_PROTO(thread_allocated)
Jason Evansecf229a2010-12-03 15:55:47 -080073CTL_PROTO(thread_allocatedp)
Jason Evans93443682010-10-20 17:39:18 -070074CTL_PROTO(thread_deallocated)
Jason Evansecf229a2010-12-03 15:55:47 -080075CTL_PROTO(thread_deallocatedp)
Jason Evansf2bc8522015-07-17 16:38:25 -070076CTL_PROTO(config_cache_oblivious)
Jason Evans3c234352010-01-27 13:10:55 -080077CTL_PROTO(config_debug)
Jason Evans3c234352010-01-27 13:10:55 -080078CTL_PROTO(config_fill)
79CTL_PROTO(config_lazy_lock)
Jason Evansf8290092016-02-07 14:23:22 -080080CTL_PROTO(config_malloc_conf)
Jason Evans59ae2762012-04-16 17:52:27 -070081CTL_PROTO(config_munmap)
Jason Evansd34f9e72010-02-11 13:19:21 -080082CTL_PROTO(config_prof)
83CTL_PROTO(config_prof_libgcc)
84CTL_PROTO(config_prof_libunwind)
Jason Evans3c234352010-01-27 13:10:55 -080085CTL_PROTO(config_stats)
Jason Evans3c234352010-01-27 13:10:55 -080086CTL_PROTO(config_tcache)
Jason Evans3c234352010-01-27 13:10:55 -080087CTL_PROTO(config_tls)
Jason Evansb1476112012-04-05 13:36:17 -070088CTL_PROTO(config_utrace)
Jason Evans122449b2012-04-06 00:35:09 -070089CTL_PROTO(config_valgrind)
Jason Evans3c234352010-01-27 13:10:55 -080090CTL_PROTO(config_xmalloc)
91CTL_PROTO(opt_abort)
Jason Evans609ae592012-10-11 13:53:15 -070092CTL_PROTO(opt_dss)
Jason Evanse7339702010-10-23 18:37:06 -070093CTL_PROTO(opt_lg_chunk)
94CTL_PROTO(opt_narenas)
Jason Evans243f7a02016-02-19 20:09:31 -080095CTL_PROTO(opt_purge)
Jason Evanse7339702010-10-23 18:37:06 -070096CTL_PROTO(opt_lg_dirty_mult)
Jason Evans243f7a02016-02-19 20:09:31 -080097CTL_PROTO(opt_decay_time)
Jason Evanse7339702010-10-23 18:37:06 -070098CTL_PROTO(opt_stats_print)
Jason Evans3c234352010-01-27 13:10:55 -080099CTL_PROTO(opt_junk)
Jason Evanse7339702010-10-23 18:37:06 -0700100CTL_PROTO(opt_zero)
Jason Evans122449b2012-04-06 00:35:09 -0700101CTL_PROTO(opt_quarantine)
102CTL_PROTO(opt_redzone)
Jason Evansb1476112012-04-05 13:36:17 -0700103CTL_PROTO(opt_utrace)
Jason Evans3c234352010-01-27 13:10:55 -0800104CTL_PROTO(opt_xmalloc)
Jason Evans3fa9a2f2010-03-07 15:34:14 -0800105CTL_PROTO(opt_tcache)
Jason Evansf3ca7c82012-04-04 16:16:09 -0700106CTL_PROTO(opt_lg_tcache_max)
Jason Evansd34f9e72010-02-11 13:19:21 -0800107CTL_PROTO(opt_prof)
Jason Evanse7339702010-10-23 18:37:06 -0700108CTL_PROTO(opt_prof_prefix)
Jason Evansf18c9822010-03-31 18:43:24 -0700109CTL_PROTO(opt_prof_active)
Jason Evansfc12c0b2014-10-03 23:25:30 -0700110CTL_PROTO(opt_prof_thread_active_init)
Jason Evansb9477e72010-03-01 20:15:26 -0800111CTL_PROTO(opt_lg_prof_sample)
Jason Evansd34f9e72010-02-11 13:19:21 -0800112CTL_PROTO(opt_lg_prof_interval)
Jason Evanse7339702010-10-23 18:37:06 -0700113CTL_PROTO(opt_prof_gdump)
Jason Evans0b25fe72012-04-17 16:39:33 -0700114CTL_PROTO(opt_prof_final)
Jason Evansd34f9e72010-02-11 13:19:21 -0800115CTL_PROTO(opt_prof_leak)
Jason Evansa881cd22010-10-02 15:18:50 -0700116CTL_PROTO(opt_prof_accum)
Jason Evans1cb181e2015-01-29 15:30:47 -0800117CTL_PROTO(tcache_create)
118CTL_PROTO(tcache_flush)
119CTL_PROTO(tcache_destroy)
Jason Evansc1e00ef2016-05-10 22:21:10 -0700120static void arena_i_purge(tsdn_t *tsdn, unsigned arena_ind, bool all);
Jason Evans609ae592012-10-11 13:53:15 -0700121CTL_PROTO(arena_i_purge)
Jason Evans243f7a02016-02-19 20:09:31 -0800122CTL_PROTO(arena_i_decay)
Jason Evans19ff2ce2016-04-22 14:37:17 -0700123CTL_PROTO(arena_i_reset)
Jason Evans609ae592012-10-11 13:53:15 -0700124CTL_PROTO(arena_i_dss)
Jason Evans8d6a3e82015-03-18 18:55:33 -0700125CTL_PROTO(arena_i_lg_dirty_mult)
Jason Evans243f7a02016-02-19 20:09:31 -0800126CTL_PROTO(arena_i_decay_time)
Jason Evansb49a3342015-07-28 11:28:19 -0400127CTL_PROTO(arena_i_chunk_hooks)
Jason Evans609ae592012-10-11 13:53:15 -0700128INDEX_PROTO(arena_i)
Jason Evans3c234352010-01-27 13:10:55 -0800129CTL_PROTO(arenas_bin_i_size)
130CTL_PROTO(arenas_bin_i_nregs)
131CTL_PROTO(arenas_bin_i_run_size)
132INDEX_PROTO(arenas_bin_i)
133CTL_PROTO(arenas_lrun_i_size)
134INDEX_PROTO(arenas_lrun_i)
Jason Evans3c4d92e2014-10-12 22:53:59 -0700135CTL_PROTO(arenas_hchunk_i_size)
136INDEX_PROTO(arenas_hchunk_i)
Jason Evans3c234352010-01-27 13:10:55 -0800137CTL_PROTO(arenas_narenas)
138CTL_PROTO(arenas_initialized)
Jason Evans8d6a3e82015-03-18 18:55:33 -0700139CTL_PROTO(arenas_lg_dirty_mult)
Jason Evans243f7a02016-02-19 20:09:31 -0800140CTL_PROTO(arenas_decay_time)
Jason Evans3c234352010-01-27 13:10:55 -0800141CTL_PROTO(arenas_quantum)
Jason Evansae4c7b42012-04-02 07:04:34 -0700142CTL_PROTO(arenas_page)
Jason Evansdafde142010-03-17 16:27:39 -0700143CTL_PROTO(arenas_tcache_max)
Jason Evans3c234352010-01-27 13:10:55 -0800144CTL_PROTO(arenas_nbins)
Jason Evansdafde142010-03-17 16:27:39 -0700145CTL_PROTO(arenas_nhbins)
Jason Evans3c234352010-01-27 13:10:55 -0800146CTL_PROTO(arenas_nlruns)
Jason Evans3c4d92e2014-10-12 22:53:59 -0700147CTL_PROTO(arenas_nhchunks)
Jason Evans609ae592012-10-11 13:53:15 -0700148CTL_PROTO(arenas_extend)
Jason Evansfc12c0b2014-10-03 23:25:30 -0700149CTL_PROTO(prof_thread_active_init)
Jason Evansf18c9822010-03-31 18:43:24 -0700150CTL_PROTO(prof_active)
Jason Evansd34f9e72010-02-11 13:19:21 -0800151CTL_PROTO(prof_dump)
Jason Evans5b8ed5b2015-01-25 21:16:57 -0800152CTL_PROTO(prof_gdump)
Jason Evans602c8e02014-08-18 16:22:13 -0700153CTL_PROTO(prof_reset)
Jason Evansd34f9e72010-02-11 13:19:21 -0800154CTL_PROTO(prof_interval)
Jason Evans602c8e02014-08-18 16:22:13 -0700155CTL_PROTO(lg_prof_sample)
Jason Evans3c234352010-01-27 13:10:55 -0800156CTL_PROTO(stats_arenas_i_small_allocated)
157CTL_PROTO(stats_arenas_i_small_nmalloc)
158CTL_PROTO(stats_arenas_i_small_ndalloc)
Jason Evans86815df2010-03-13 20:32:56 -0800159CTL_PROTO(stats_arenas_i_small_nrequests)
Jason Evans3c234352010-01-27 13:10:55 -0800160CTL_PROTO(stats_arenas_i_large_allocated)
161CTL_PROTO(stats_arenas_i_large_nmalloc)
162CTL_PROTO(stats_arenas_i_large_ndalloc)
Jason Evansdafde142010-03-17 16:27:39 -0700163CTL_PROTO(stats_arenas_i_large_nrequests)
Jason Evanse2deab72014-05-15 22:22:27 -0700164CTL_PROTO(stats_arenas_i_huge_allocated)
165CTL_PROTO(stats_arenas_i_huge_nmalloc)
166CTL_PROTO(stats_arenas_i_huge_ndalloc)
167CTL_PROTO(stats_arenas_i_huge_nrequests)
Jason Evans86815df2010-03-13 20:32:56 -0800168CTL_PROTO(stats_arenas_i_bins_j_nmalloc)
169CTL_PROTO(stats_arenas_i_bins_j_ndalloc)
Jason Evans3c234352010-01-27 13:10:55 -0800170CTL_PROTO(stats_arenas_i_bins_j_nrequests)
Jason Evans3c4d92e2014-10-12 22:53:59 -0700171CTL_PROTO(stats_arenas_i_bins_j_curregs)
Jason Evans3c234352010-01-27 13:10:55 -0800172CTL_PROTO(stats_arenas_i_bins_j_nfills)
173CTL_PROTO(stats_arenas_i_bins_j_nflushes)
Jason Evans3c234352010-01-27 13:10:55 -0800174CTL_PROTO(stats_arenas_i_bins_j_nruns)
175CTL_PROTO(stats_arenas_i_bins_j_nreruns)
Jason Evans3c234352010-01-27 13:10:55 -0800176CTL_PROTO(stats_arenas_i_bins_j_curruns)
177INDEX_PROTO(stats_arenas_i_bins_j)
Jason Evansdafde142010-03-17 16:27:39 -0700178CTL_PROTO(stats_arenas_i_lruns_j_nmalloc)
179CTL_PROTO(stats_arenas_i_lruns_j_ndalloc)
Jason Evans3c234352010-01-27 13:10:55 -0800180CTL_PROTO(stats_arenas_i_lruns_j_nrequests)
Jason Evans3c234352010-01-27 13:10:55 -0800181CTL_PROTO(stats_arenas_i_lruns_j_curruns)
182INDEX_PROTO(stats_arenas_i_lruns_j)
Jason Evans3c4d92e2014-10-12 22:53:59 -0700183CTL_PROTO(stats_arenas_i_hchunks_j_nmalloc)
184CTL_PROTO(stats_arenas_i_hchunks_j_ndalloc)
185CTL_PROTO(stats_arenas_i_hchunks_j_nrequests)
186CTL_PROTO(stats_arenas_i_hchunks_j_curhchunks)
187INDEX_PROTO(stats_arenas_i_hchunks_j)
Jason Evans597632b2011-03-18 13:41:33 -0700188CTL_PROTO(stats_arenas_i_nthreads)
Jason Evans609ae592012-10-11 13:53:15 -0700189CTL_PROTO(stats_arenas_i_dss)
Jason Evans562d2662015-03-24 16:36:12 -0700190CTL_PROTO(stats_arenas_i_lg_dirty_mult)
Jason Evans243f7a02016-02-19 20:09:31 -0800191CTL_PROTO(stats_arenas_i_decay_time)
Jason Evans3c234352010-01-27 13:10:55 -0800192CTL_PROTO(stats_arenas_i_pactive)
193CTL_PROTO(stats_arenas_i_pdirty)
Jason Evans3c234352010-01-27 13:10:55 -0800194CTL_PROTO(stats_arenas_i_mapped)
Jason Evans04c3c0f2016-05-03 22:11:35 -0700195CTL_PROTO(stats_arenas_i_retained)
Jason Evans3c234352010-01-27 13:10:55 -0800196CTL_PROTO(stats_arenas_i_npurge)
197CTL_PROTO(stats_arenas_i_nmadvise)
198CTL_PROTO(stats_arenas_i_purged)
Jason Evans4581b972014-11-27 17:22:36 -0200199CTL_PROTO(stats_arenas_i_metadata_mapped)
200CTL_PROTO(stats_arenas_i_metadata_allocated)
Jason Evans3c234352010-01-27 13:10:55 -0800201INDEX_PROTO(stats_arenas_i)
Jason Evans0657f122011-03-18 17:56:14 -0700202CTL_PROTO(stats_cactive)
Jason Evans3c234352010-01-27 13:10:55 -0800203CTL_PROTO(stats_allocated)
204CTL_PROTO(stats_active)
Jason Evans4581b972014-11-27 17:22:36 -0200205CTL_PROTO(stats_metadata)
Jason Evans4acd75a2015-03-23 17:25:57 -0700206CTL_PROTO(stats_resident)
Jason Evans3c234352010-01-27 13:10:55 -0800207CTL_PROTO(stats_mapped)
Jason Evans04c3c0f2016-05-03 22:11:35 -0700208CTL_PROTO(stats_retained)
Jason Evans3c234352010-01-27 13:10:55 -0800209
210/******************************************************************************/
211/* mallctl tree. */
212
213/* Maximum tree depth. */
214#define CTL_MAX_DEPTH 6
215
Mike Hommey461ad5c2012-04-20 08:38:42 +0200216#define NAME(n) {true}, n
Jason Evans65f343a2012-04-23 19:31:45 -0700217#define CHILD(t, c) \
218 sizeof(c##_node) / sizeof(ctl_##t##_node_t), \
219 (ctl_node_t *)c##_node, \
220 NULL
Mike Hommey461ad5c2012-04-20 08:38:42 +0200221#define CTL(c) 0, NULL, c##_ctl
Jason Evans3c234352010-01-27 13:10:55 -0800222
223/*
224 * Only handles internal indexed nodes, since there are currently no external
225 * ones.
226 */
Mike Hommey461ad5c2012-04-20 08:38:42 +0200227#define INDEX(i) {false}, i##_index
Jason Evans3c234352010-01-27 13:10:55 -0800228
Jason Evans602c8e02014-08-18 16:22:13 -0700229static const ctl_named_node_t thread_tcache_node[] = {
Jason Evansd4be8b72012-03-26 18:54:44 -0700230 {NAME("enabled"), CTL(thread_tcache_enabled)},
Jason Evanse7b8fa12012-03-16 17:09:32 -0700231 {NAME("flush"), CTL(thread_tcache_flush)}
Jason Evans3c234352010-01-27 13:10:55 -0800232};
Jason Evans3c234352010-01-27 13:10:55 -0800233
Jason Evans602c8e02014-08-18 16:22:13 -0700234static const ctl_named_node_t thread_prof_node[] = {
235 {NAME("name"), CTL(thread_prof_name)},
236 {NAME("active"), CTL(thread_prof_active)}
237};
238
Mike Hommey461ad5c2012-04-20 08:38:42 +0200239static const ctl_named_node_t thread_node[] = {
Jason Evans7372b152012-02-10 20:22:09 -0800240 {NAME("arena"), CTL(thread_arena)},
Jason Evans93443682010-10-20 17:39:18 -0700241 {NAME("allocated"), CTL(thread_allocated)},
Jason Evansecf229a2010-12-03 15:55:47 -0800242 {NAME("allocatedp"), CTL(thread_allocatedp)},
243 {NAME("deallocated"), CTL(thread_deallocated)},
Jason Evanse7b8fa12012-03-16 17:09:32 -0700244 {NAME("deallocatedp"), CTL(thread_deallocatedp)},
Jason Evans602c8e02014-08-18 16:22:13 -0700245 {NAME("tcache"), CHILD(named, thread_tcache)},
246 {NAME("prof"), CHILD(named, thread_prof)}
Jason Evansb267d0f2010-08-13 15:42:29 -0700247};
Jason Evansb267d0f2010-08-13 15:42:29 -0700248
Mike Hommey461ad5c2012-04-20 08:38:42 +0200249static const ctl_named_node_t config_node[] = {
Jason Evansf2bc8522015-07-17 16:38:25 -0700250 {NAME("cache_oblivious"), CTL(config_cache_oblivious)},
Jason Evans3c4d92e2014-10-12 22:53:59 -0700251 {NAME("debug"), CTL(config_debug)},
252 {NAME("fill"), CTL(config_fill)},
253 {NAME("lazy_lock"), CTL(config_lazy_lock)},
Jason Evansf8290092016-02-07 14:23:22 -0800254 {NAME("malloc_conf"), CTL(config_malloc_conf)},
Jason Evans3c4d92e2014-10-12 22:53:59 -0700255 {NAME("munmap"), CTL(config_munmap)},
256 {NAME("prof"), CTL(config_prof)},
257 {NAME("prof_libgcc"), CTL(config_prof_libgcc)},
258 {NAME("prof_libunwind"), CTL(config_prof_libunwind)},
259 {NAME("stats"), CTL(config_stats)},
260 {NAME("tcache"), CTL(config_tcache)},
261 {NAME("tls"), CTL(config_tls)},
262 {NAME("utrace"), CTL(config_utrace)},
263 {NAME("valgrind"), CTL(config_valgrind)},
264 {NAME("xmalloc"), CTL(config_xmalloc)}
Jason Evans3c234352010-01-27 13:10:55 -0800265};
266
Mike Hommey461ad5c2012-04-20 08:38:42 +0200267static const ctl_named_node_t opt_node[] = {
Jason Evans3c4d92e2014-10-12 22:53:59 -0700268 {NAME("abort"), CTL(opt_abort)},
269 {NAME("dss"), CTL(opt_dss)},
270 {NAME("lg_chunk"), CTL(opt_lg_chunk)},
271 {NAME("narenas"), CTL(opt_narenas)},
Jason Evans243f7a02016-02-19 20:09:31 -0800272 {NAME("purge"), CTL(opt_purge)},
Jason Evans3c4d92e2014-10-12 22:53:59 -0700273 {NAME("lg_dirty_mult"), CTL(opt_lg_dirty_mult)},
Jason Evans243f7a02016-02-19 20:09:31 -0800274 {NAME("decay_time"), CTL(opt_decay_time)},
Jason Evans3c4d92e2014-10-12 22:53:59 -0700275 {NAME("stats_print"), CTL(opt_stats_print)},
276 {NAME("junk"), CTL(opt_junk)},
277 {NAME("zero"), CTL(opt_zero)},
278 {NAME("quarantine"), CTL(opt_quarantine)},
279 {NAME("redzone"), CTL(opt_redzone)},
280 {NAME("utrace"), CTL(opt_utrace)},
281 {NAME("xmalloc"), CTL(opt_xmalloc)},
282 {NAME("tcache"), CTL(opt_tcache)},
283 {NAME("lg_tcache_max"), CTL(opt_lg_tcache_max)},
284 {NAME("prof"), CTL(opt_prof)},
285 {NAME("prof_prefix"), CTL(opt_prof_prefix)},
286 {NAME("prof_active"), CTL(opt_prof_active)},
Jason Evansfc12c0b2014-10-03 23:25:30 -0700287 {NAME("prof_thread_active_init"), CTL(opt_prof_thread_active_init)},
Jason Evans3c4d92e2014-10-12 22:53:59 -0700288 {NAME("lg_prof_sample"), CTL(opt_lg_prof_sample)},
289 {NAME("lg_prof_interval"), CTL(opt_lg_prof_interval)},
290 {NAME("prof_gdump"), CTL(opt_prof_gdump)},
291 {NAME("prof_final"), CTL(opt_prof_final)},
292 {NAME("prof_leak"), CTL(opt_prof_leak)},
293 {NAME("prof_accum"), CTL(opt_prof_accum)}
Jason Evans3c234352010-01-27 13:10:55 -0800294};
295
Jason Evans1cb181e2015-01-29 15:30:47 -0800296static const ctl_named_node_t tcache_node[] = {
297 {NAME("create"), CTL(tcache_create)},
298 {NAME("flush"), CTL(tcache_flush)},
299 {NAME("destroy"), CTL(tcache_destroy)}
300};
301
Jason Evans609ae592012-10-11 13:53:15 -0700302static const ctl_named_node_t arena_i_node[] = {
Jason Evans3c4d92e2014-10-12 22:53:59 -0700303 {NAME("purge"), CTL(arena_i_purge)},
Jason Evans243f7a02016-02-19 20:09:31 -0800304 {NAME("decay"), CTL(arena_i_decay)},
Jason Evans19ff2ce2016-04-22 14:37:17 -0700305 {NAME("reset"), CTL(arena_i_reset)},
Jason Evans3c4d92e2014-10-12 22:53:59 -0700306 {NAME("dss"), CTL(arena_i_dss)},
Jason Evans8d6a3e82015-03-18 18:55:33 -0700307 {NAME("lg_dirty_mult"), CTL(arena_i_lg_dirty_mult)},
Jason Evans243f7a02016-02-19 20:09:31 -0800308 {NAME("decay_time"), CTL(arena_i_decay_time)},
Jason Evansb49a3342015-07-28 11:28:19 -0400309 {NAME("chunk_hooks"), CTL(arena_i_chunk_hooks)}
Jason Evans609ae592012-10-11 13:53:15 -0700310};
311static const ctl_named_node_t super_arena_i_node[] = {
Jason Evans3c4d92e2014-10-12 22:53:59 -0700312 {NAME(""), CHILD(named, arena_i)}
Jason Evans609ae592012-10-11 13:53:15 -0700313};
314
315static const ctl_indexed_node_t arena_node[] = {
316 {INDEX(arena_i)}
317};
318
Mike Hommey461ad5c2012-04-20 08:38:42 +0200319static const ctl_named_node_t arenas_bin_i_node[] = {
Jason Evans3c4d92e2014-10-12 22:53:59 -0700320 {NAME("size"), CTL(arenas_bin_i_size)},
321 {NAME("nregs"), CTL(arenas_bin_i_nregs)},
322 {NAME("run_size"), CTL(arenas_bin_i_run_size)}
Jason Evans3c234352010-01-27 13:10:55 -0800323};
Mike Hommey461ad5c2012-04-20 08:38:42 +0200324static const ctl_named_node_t super_arenas_bin_i_node[] = {
Jason Evans3c4d92e2014-10-12 22:53:59 -0700325 {NAME(""), CHILD(named, arenas_bin_i)}
Jason Evans3c234352010-01-27 13:10:55 -0800326};
327
Mike Hommey461ad5c2012-04-20 08:38:42 +0200328static const ctl_indexed_node_t arenas_bin_node[] = {
Jason Evans3c234352010-01-27 13:10:55 -0800329 {INDEX(arenas_bin_i)}
330};
331
Mike Hommey461ad5c2012-04-20 08:38:42 +0200332static const ctl_named_node_t arenas_lrun_i_node[] = {
Jason Evans3c4d92e2014-10-12 22:53:59 -0700333 {NAME("size"), CTL(arenas_lrun_i_size)}
Jason Evans3c234352010-01-27 13:10:55 -0800334};
Mike Hommey461ad5c2012-04-20 08:38:42 +0200335static const ctl_named_node_t super_arenas_lrun_i_node[] = {
Jason Evans3c4d92e2014-10-12 22:53:59 -0700336 {NAME(""), CHILD(named, arenas_lrun_i)}
Jason Evans3c234352010-01-27 13:10:55 -0800337};
338
Mike Hommey461ad5c2012-04-20 08:38:42 +0200339static const ctl_indexed_node_t arenas_lrun_node[] = {
Jason Evans3c234352010-01-27 13:10:55 -0800340 {INDEX(arenas_lrun_i)}
341};
342
Jason Evans3c4d92e2014-10-12 22:53:59 -0700343static const ctl_named_node_t arenas_hchunk_i_node[] = {
344 {NAME("size"), CTL(arenas_hchunk_i_size)}
345};
346static const ctl_named_node_t super_arenas_hchunk_i_node[] = {
347 {NAME(""), CHILD(named, arenas_hchunk_i)}
348};
349
350static const ctl_indexed_node_t arenas_hchunk_node[] = {
351 {INDEX(arenas_hchunk_i)}
352};
353
Mike Hommey461ad5c2012-04-20 08:38:42 +0200354static const ctl_named_node_t arenas_node[] = {
Jason Evans3c4d92e2014-10-12 22:53:59 -0700355 {NAME("narenas"), CTL(arenas_narenas)},
356 {NAME("initialized"), CTL(arenas_initialized)},
Jason Evans8d6a3e82015-03-18 18:55:33 -0700357 {NAME("lg_dirty_mult"), CTL(arenas_lg_dirty_mult)},
Jason Evans243f7a02016-02-19 20:09:31 -0800358 {NAME("decay_time"), CTL(arenas_decay_time)},
Jason Evans3c4d92e2014-10-12 22:53:59 -0700359 {NAME("quantum"), CTL(arenas_quantum)},
360 {NAME("page"), CTL(arenas_page)},
361 {NAME("tcache_max"), CTL(arenas_tcache_max)},
362 {NAME("nbins"), CTL(arenas_nbins)},
363 {NAME("nhbins"), CTL(arenas_nhbins)},
364 {NAME("bin"), CHILD(indexed, arenas_bin)},
365 {NAME("nlruns"), CTL(arenas_nlruns)},
366 {NAME("lrun"), CHILD(indexed, arenas_lrun)},
367 {NAME("nhchunks"), CTL(arenas_nhchunks)},
368 {NAME("hchunk"), CHILD(indexed, arenas_hchunk)},
369 {NAME("extend"), CTL(arenas_extend)}
Jason Evans3c234352010-01-27 13:10:55 -0800370};
371
Mike Hommey461ad5c2012-04-20 08:38:42 +0200372static const ctl_named_node_t prof_node[] = {
Jason Evansfc12c0b2014-10-03 23:25:30 -0700373 {NAME("thread_active_init"), CTL(prof_thread_active_init)},
Jason Evansf18c9822010-03-31 18:43:24 -0700374 {NAME("active"), CTL(prof_active)},
Jason Evansd34f9e72010-02-11 13:19:21 -0800375 {NAME("dump"), CTL(prof_dump)},
Jason Evans5b8ed5b2015-01-25 21:16:57 -0800376 {NAME("gdump"), CTL(prof_gdump)},
Jason Evans602c8e02014-08-18 16:22:13 -0700377 {NAME("reset"), CTL(prof_reset)},
378 {NAME("interval"), CTL(prof_interval)},
379 {NAME("lg_sample"), CTL(lg_prof_sample)}
Jason Evansd34f9e72010-02-11 13:19:21 -0800380};
Jason Evansd34f9e72010-02-11 13:19:21 -0800381
Jason Evans4581b972014-11-27 17:22:36 -0200382static const ctl_named_node_t stats_arenas_i_metadata_node[] = {
383 {NAME("mapped"), CTL(stats_arenas_i_metadata_mapped)},
384 {NAME("allocated"), CTL(stats_arenas_i_metadata_allocated)}
385};
386
Mike Hommey461ad5c2012-04-20 08:38:42 +0200387static const ctl_named_node_t stats_arenas_i_small_node[] = {
Jason Evans3c4d92e2014-10-12 22:53:59 -0700388 {NAME("allocated"), CTL(stats_arenas_i_small_allocated)},
389 {NAME("nmalloc"), CTL(stats_arenas_i_small_nmalloc)},
390 {NAME("ndalloc"), CTL(stats_arenas_i_small_ndalloc)},
391 {NAME("nrequests"), CTL(stats_arenas_i_small_nrequests)}
Jason Evans3c234352010-01-27 13:10:55 -0800392};
393
Mike Hommey461ad5c2012-04-20 08:38:42 +0200394static const ctl_named_node_t stats_arenas_i_large_node[] = {
Jason Evans3c4d92e2014-10-12 22:53:59 -0700395 {NAME("allocated"), CTL(stats_arenas_i_large_allocated)},
396 {NAME("nmalloc"), CTL(stats_arenas_i_large_nmalloc)},
397 {NAME("ndalloc"), CTL(stats_arenas_i_large_ndalloc)},
398 {NAME("nrequests"), CTL(stats_arenas_i_large_nrequests)}
Jason Evans3c234352010-01-27 13:10:55 -0800399};
400
Jason Evanse2deab72014-05-15 22:22:27 -0700401static const ctl_named_node_t stats_arenas_i_huge_node[] = {
Jason Evans3c4d92e2014-10-12 22:53:59 -0700402 {NAME("allocated"), CTL(stats_arenas_i_huge_allocated)},
403 {NAME("nmalloc"), CTL(stats_arenas_i_huge_nmalloc)},
404 {NAME("ndalloc"), CTL(stats_arenas_i_huge_ndalloc)},
405 {NAME("nrequests"), CTL(stats_arenas_i_huge_nrequests)}
Jason Evanse2deab72014-05-15 22:22:27 -0700406};
407
Mike Hommey461ad5c2012-04-20 08:38:42 +0200408static const ctl_named_node_t stats_arenas_i_bins_j_node[] = {
Jason Evans3c4d92e2014-10-12 22:53:59 -0700409 {NAME("nmalloc"), CTL(stats_arenas_i_bins_j_nmalloc)},
410 {NAME("ndalloc"), CTL(stats_arenas_i_bins_j_ndalloc)},
411 {NAME("nrequests"), CTL(stats_arenas_i_bins_j_nrequests)},
412 {NAME("curregs"), CTL(stats_arenas_i_bins_j_curregs)},
413 {NAME("nfills"), CTL(stats_arenas_i_bins_j_nfills)},
414 {NAME("nflushes"), CTL(stats_arenas_i_bins_j_nflushes)},
415 {NAME("nruns"), CTL(stats_arenas_i_bins_j_nruns)},
416 {NAME("nreruns"), CTL(stats_arenas_i_bins_j_nreruns)},
417 {NAME("curruns"), CTL(stats_arenas_i_bins_j_curruns)}
Jason Evans3c234352010-01-27 13:10:55 -0800418};
Mike Hommey461ad5c2012-04-20 08:38:42 +0200419static const ctl_named_node_t super_stats_arenas_i_bins_j_node[] = {
Jason Evans3c4d92e2014-10-12 22:53:59 -0700420 {NAME(""), CHILD(named, stats_arenas_i_bins_j)}
Jason Evans3c234352010-01-27 13:10:55 -0800421};
422
Mike Hommey461ad5c2012-04-20 08:38:42 +0200423static const ctl_indexed_node_t stats_arenas_i_bins_node[] = {
Jason Evans3c234352010-01-27 13:10:55 -0800424 {INDEX(stats_arenas_i_bins_j)}
425};
426
Mike Hommey461ad5c2012-04-20 08:38:42 +0200427static const ctl_named_node_t stats_arenas_i_lruns_j_node[] = {
Jason Evans3c4d92e2014-10-12 22:53:59 -0700428 {NAME("nmalloc"), CTL(stats_arenas_i_lruns_j_nmalloc)},
429 {NAME("ndalloc"), CTL(stats_arenas_i_lruns_j_ndalloc)},
430 {NAME("nrequests"), CTL(stats_arenas_i_lruns_j_nrequests)},
431 {NAME("curruns"), CTL(stats_arenas_i_lruns_j_curruns)}
Jason Evans3c234352010-01-27 13:10:55 -0800432};
Mike Hommey461ad5c2012-04-20 08:38:42 +0200433static const ctl_named_node_t super_stats_arenas_i_lruns_j_node[] = {
Jason Evans3c4d92e2014-10-12 22:53:59 -0700434 {NAME(""), CHILD(named, stats_arenas_i_lruns_j)}
Jason Evans3c234352010-01-27 13:10:55 -0800435};
436
Mike Hommey461ad5c2012-04-20 08:38:42 +0200437static const ctl_indexed_node_t stats_arenas_i_lruns_node[] = {
Jason Evans3c234352010-01-27 13:10:55 -0800438 {INDEX(stats_arenas_i_lruns_j)}
439};
Jason Evans3c234352010-01-27 13:10:55 -0800440
Jason Evans3c4d92e2014-10-12 22:53:59 -0700441static const ctl_named_node_t stats_arenas_i_hchunks_j_node[] = {
442 {NAME("nmalloc"), CTL(stats_arenas_i_hchunks_j_nmalloc)},
443 {NAME("ndalloc"), CTL(stats_arenas_i_hchunks_j_ndalloc)},
444 {NAME("nrequests"), CTL(stats_arenas_i_hchunks_j_nrequests)},
445 {NAME("curhchunks"), CTL(stats_arenas_i_hchunks_j_curhchunks)}
446};
447static const ctl_named_node_t super_stats_arenas_i_hchunks_j_node[] = {
448 {NAME(""), CHILD(named, stats_arenas_i_hchunks_j)}
449};
450
451static const ctl_indexed_node_t stats_arenas_i_hchunks_node[] = {
452 {INDEX(stats_arenas_i_hchunks_j)}
453};
454
Mike Hommey461ad5c2012-04-20 08:38:42 +0200455static const ctl_named_node_t stats_arenas_i_node[] = {
Jason Evans3c4d92e2014-10-12 22:53:59 -0700456 {NAME("nthreads"), CTL(stats_arenas_i_nthreads)},
457 {NAME("dss"), CTL(stats_arenas_i_dss)},
Jason Evans562d2662015-03-24 16:36:12 -0700458 {NAME("lg_dirty_mult"), CTL(stats_arenas_i_lg_dirty_mult)},
Jason Evans243f7a02016-02-19 20:09:31 -0800459 {NAME("decay_time"), CTL(stats_arenas_i_decay_time)},
Jason Evans3c4d92e2014-10-12 22:53:59 -0700460 {NAME("pactive"), CTL(stats_arenas_i_pactive)},
461 {NAME("pdirty"), CTL(stats_arenas_i_pdirty)},
462 {NAME("mapped"), CTL(stats_arenas_i_mapped)},
Jason Evans04c3c0f2016-05-03 22:11:35 -0700463 {NAME("retained"), CTL(stats_arenas_i_retained)},
Jason Evans3c4d92e2014-10-12 22:53:59 -0700464 {NAME("npurge"), CTL(stats_arenas_i_npurge)},
465 {NAME("nmadvise"), CTL(stats_arenas_i_nmadvise)},
466 {NAME("purged"), CTL(stats_arenas_i_purged)},
Jason Evans4581b972014-11-27 17:22:36 -0200467 {NAME("metadata"), CHILD(named, stats_arenas_i_metadata)},
Jason Evans3c4d92e2014-10-12 22:53:59 -0700468 {NAME("small"), CHILD(named, stats_arenas_i_small)},
469 {NAME("large"), CHILD(named, stats_arenas_i_large)},
470 {NAME("huge"), CHILD(named, stats_arenas_i_huge)},
471 {NAME("bins"), CHILD(indexed, stats_arenas_i_bins)},
472 {NAME("lruns"), CHILD(indexed, stats_arenas_i_lruns)},
473 {NAME("hchunks"), CHILD(indexed, stats_arenas_i_hchunks)}
Jason Evans3c234352010-01-27 13:10:55 -0800474};
Mike Hommey461ad5c2012-04-20 08:38:42 +0200475static const ctl_named_node_t super_stats_arenas_i_node[] = {
Jason Evans3c4d92e2014-10-12 22:53:59 -0700476 {NAME(""), CHILD(named, stats_arenas_i)}
Jason Evans3c234352010-01-27 13:10:55 -0800477};
478
Mike Hommey461ad5c2012-04-20 08:38:42 +0200479static const ctl_indexed_node_t stats_arenas_node[] = {
Jason Evans3c234352010-01-27 13:10:55 -0800480 {INDEX(stats_arenas_i)}
481};
482
Mike Hommey461ad5c2012-04-20 08:38:42 +0200483static const ctl_named_node_t stats_node[] = {
Jason Evans3c4d92e2014-10-12 22:53:59 -0700484 {NAME("cactive"), CTL(stats_cactive)},
485 {NAME("allocated"), CTL(stats_allocated)},
486 {NAME("active"), CTL(stats_active)},
Jason Evans4581b972014-11-27 17:22:36 -0200487 {NAME("metadata"), CTL(stats_metadata)},
Jason Evans4acd75a2015-03-23 17:25:57 -0700488 {NAME("resident"), CTL(stats_resident)},
Jason Evans3c4d92e2014-10-12 22:53:59 -0700489 {NAME("mapped"), CTL(stats_mapped)},
Jason Evans04c3c0f2016-05-03 22:11:35 -0700490 {NAME("retained"), CTL(stats_retained)},
Jason Evans3c4d92e2014-10-12 22:53:59 -0700491 {NAME("arenas"), CHILD(indexed, stats_arenas)}
Jason Evans3c234352010-01-27 13:10:55 -0800492};
493
Mike Hommey461ad5c2012-04-20 08:38:42 +0200494static const ctl_named_node_t root_node[] = {
Jason Evansa40bc7a2010-03-02 13:01:16 -0800495 {NAME("version"), CTL(version)},
Jason Evans3c234352010-01-27 13:10:55 -0800496 {NAME("epoch"), CTL(epoch)},
Jason Evans65f343a2012-04-23 19:31:45 -0700497 {NAME("thread"), CHILD(named, thread)},
498 {NAME("config"), CHILD(named, config)},
499 {NAME("opt"), CHILD(named, opt)},
Jason Evans1cb181e2015-01-29 15:30:47 -0800500 {NAME("tcache"), CHILD(named, tcache)},
Jason Evans609ae592012-10-11 13:53:15 -0700501 {NAME("arena"), CHILD(indexed, arena)},
Jason Evans65f343a2012-04-23 19:31:45 -0700502 {NAME("arenas"), CHILD(named, arenas)},
503 {NAME("prof"), CHILD(named, prof)},
504 {NAME("stats"), CHILD(named, stats)}
Jason Evans3c234352010-01-27 13:10:55 -0800505};
Mike Hommey461ad5c2012-04-20 08:38:42 +0200506static const ctl_named_node_t super_root_node[] = {
Jason Evans65f343a2012-04-23 19:31:45 -0700507 {NAME(""), CHILD(named, root)}
Jason Evans3c234352010-01-27 13:10:55 -0800508};
509
510#undef NAME
511#undef CHILD
512#undef CTL
513#undef INDEX
514
515/******************************************************************************/
516
Jason Evans3c234352010-01-27 13:10:55 -0800517static bool
518ctl_arena_init(ctl_arena_stats_t *astats)
519{
520
Jason Evans3c234352010-01-27 13:10:55 -0800521 if (astats->lstats == NULL) {
Jason Evans8bb31982014-10-07 23:14:57 -0700522 astats->lstats = (malloc_large_stats_t *)a0malloc(nlclasses *
Jason Evans4581b972014-11-27 17:22:36 -0200523 sizeof(malloc_large_stats_t));
Jason Evans3c234352010-01-27 13:10:55 -0800524 if (astats->lstats == NULL)
525 return (true);
526 }
527
Jason Evans3c4d92e2014-10-12 22:53:59 -0700528 if (astats->hstats == NULL) {
529 astats->hstats = (malloc_huge_stats_t *)a0malloc(nhclasses *
Jason Evans4581b972014-11-27 17:22:36 -0200530 sizeof(malloc_huge_stats_t));
Jason Evans3c4d92e2014-10-12 22:53:59 -0700531 if (astats->hstats == NULL)
532 return (true);
533 }
534
Jason Evans3c234352010-01-27 13:10:55 -0800535 return (false);
536}
Jason Evans3c234352010-01-27 13:10:55 -0800537
538static void
539ctl_arena_clear(ctl_arena_stats_t *astats)
540{
541
Jason Evans3c07f802016-02-27 20:40:13 -0800542 astats->nthreads = 0;
Jason Evans609ae592012-10-11 13:53:15 -0700543 astats->dss = dss_prec_names[dss_prec_limit];
Jason Evans562d2662015-03-24 16:36:12 -0700544 astats->lg_dirty_mult = -1;
Jason Evans243f7a02016-02-19 20:09:31 -0800545 astats->decay_time = -1;
Jason Evans3c234352010-01-27 13:10:55 -0800546 astats->pactive = 0;
547 astats->pdirty = 0;
Jason Evans7372b152012-02-10 20:22:09 -0800548 if (config_stats) {
549 memset(&astats->astats, 0, sizeof(arena_stats_t));
550 astats->allocated_small = 0;
551 astats->nmalloc_small = 0;
552 astats->ndalloc_small = 0;
553 astats->nrequests_small = 0;
Jason Evansb1726102012-02-28 16:50:47 -0800554 memset(astats->bstats, 0, NBINS * sizeof(malloc_bin_stats_t));
Jason Evans7372b152012-02-10 20:22:09 -0800555 memset(astats->lstats, 0, nlclasses *
556 sizeof(malloc_large_stats_t));
Jason Evans3c4d92e2014-10-12 22:53:59 -0700557 memset(astats->hstats, 0, nhclasses *
558 sizeof(malloc_huge_stats_t));
Jason Evans7372b152012-02-10 20:22:09 -0800559 }
Jason Evans3c234352010-01-27 13:10:55 -0800560}
561
Jason Evans86815df2010-03-13 20:32:56 -0800562static void
Jason Evansc1e00ef2016-05-10 22:21:10 -0700563ctl_arena_stats_amerge(tsdn_t *tsdn, ctl_arena_stats_t *cstats, arena_t *arena)
Jason Evans86815df2010-03-13 20:32:56 -0800564{
565 unsigned i;
566
Jason Evans3c07f802016-02-27 20:40:13 -0800567 if (config_stats) {
Jason Evansc1e00ef2016-05-10 22:21:10 -0700568 arena_stats_merge(tsdn, arena, &cstats->nthreads, &cstats->dss,
Jason Evans3c07f802016-02-27 20:40:13 -0800569 &cstats->lg_dirty_mult, &cstats->decay_time,
570 &cstats->pactive, &cstats->pdirty, &cstats->astats,
571 cstats->bstats, cstats->lstats, cstats->hstats);
Jason Evans86815df2010-03-13 20:32:56 -0800572
Jason Evans3c07f802016-02-27 20:40:13 -0800573 for (i = 0; i < NBINS; i++) {
574 cstats->allocated_small += cstats->bstats[i].curregs *
575 index2size(i);
576 cstats->nmalloc_small += cstats->bstats[i].nmalloc;
577 cstats->ndalloc_small += cstats->bstats[i].ndalloc;
578 cstats->nrequests_small += cstats->bstats[i].nrequests;
579 }
580 } else {
Jason Evansc1e00ef2016-05-10 22:21:10 -0700581 arena_basic_stats_merge(tsdn, arena, &cstats->nthreads,
Jason Evansb2c0d632016-04-13 23:36:15 -0700582 &cstats->dss, &cstats->lg_dirty_mult, &cstats->decay_time,
Jason Evans3c07f802016-02-27 20:40:13 -0800583 &cstats->pactive, &cstats->pdirty);
Jason Evans86815df2010-03-13 20:32:56 -0800584 }
Jason Evans86815df2010-03-13 20:32:56 -0800585}
586
587static void
588ctl_arena_stats_smerge(ctl_arena_stats_t *sstats, ctl_arena_stats_t *astats)
589{
590 unsigned i;
591
Jason Evans3c07f802016-02-27 20:40:13 -0800592 sstats->nthreads += astats->nthreads;
Jason Evans86815df2010-03-13 20:32:56 -0800593 sstats->pactive += astats->pactive;
594 sstats->pdirty += astats->pdirty;
595
Jason Evans3c07f802016-02-27 20:40:13 -0800596 if (config_stats) {
597 sstats->astats.mapped += astats->astats.mapped;
Jason Evans04c3c0f2016-05-03 22:11:35 -0700598 sstats->astats.retained += astats->astats.retained;
Jason Evans3c07f802016-02-27 20:40:13 -0800599 sstats->astats.npurge += astats->astats.npurge;
600 sstats->astats.nmadvise += astats->astats.nmadvise;
601 sstats->astats.purged += astats->astats.purged;
Jason Evans86815df2010-03-13 20:32:56 -0800602
Jason Evans3c07f802016-02-27 20:40:13 -0800603 sstats->astats.metadata_mapped +=
604 astats->astats.metadata_mapped;
605 sstats->astats.metadata_allocated +=
606 astats->astats.metadata_allocated;
Jason Evans4581b972014-11-27 17:22:36 -0200607
Jason Evans3c07f802016-02-27 20:40:13 -0800608 sstats->allocated_small += astats->allocated_small;
609 sstats->nmalloc_small += astats->nmalloc_small;
610 sstats->ndalloc_small += astats->ndalloc_small;
611 sstats->nrequests_small += astats->nrequests_small;
Jason Evans86815df2010-03-13 20:32:56 -0800612
Jason Evans3c07f802016-02-27 20:40:13 -0800613 sstats->astats.allocated_large +=
614 astats->astats.allocated_large;
615 sstats->astats.nmalloc_large += astats->astats.nmalloc_large;
616 sstats->astats.ndalloc_large += astats->astats.ndalloc_large;
617 sstats->astats.nrequests_large +=
618 astats->astats.nrequests_large;
Jason Evans86815df2010-03-13 20:32:56 -0800619
Jason Evans3c07f802016-02-27 20:40:13 -0800620 sstats->astats.allocated_huge += astats->astats.allocated_huge;
621 sstats->astats.nmalloc_huge += astats->astats.nmalloc_huge;
622 sstats->astats.ndalloc_huge += astats->astats.ndalloc_huge;
Jason Evans86815df2010-03-13 20:32:56 -0800623
Jason Evans3c07f802016-02-27 20:40:13 -0800624 for (i = 0; i < NBINS; i++) {
625 sstats->bstats[i].nmalloc += astats->bstats[i].nmalloc;
626 sstats->bstats[i].ndalloc += astats->bstats[i].ndalloc;
627 sstats->bstats[i].nrequests +=
628 astats->bstats[i].nrequests;
629 sstats->bstats[i].curregs += astats->bstats[i].curregs;
630 if (config_tcache) {
631 sstats->bstats[i].nfills +=
632 astats->bstats[i].nfills;
633 sstats->bstats[i].nflushes +=
634 astats->bstats[i].nflushes;
635 }
636 sstats->bstats[i].nruns += astats->bstats[i].nruns;
637 sstats->bstats[i].reruns += astats->bstats[i].reruns;
638 sstats->bstats[i].curruns += astats->bstats[i].curruns;
Jason Evans7372b152012-02-10 20:22:09 -0800639 }
Jason Evans3c4d92e2014-10-12 22:53:59 -0700640
Jason Evans3c07f802016-02-27 20:40:13 -0800641 for (i = 0; i < nlclasses; i++) {
642 sstats->lstats[i].nmalloc += astats->lstats[i].nmalloc;
643 sstats->lstats[i].ndalloc += astats->lstats[i].ndalloc;
644 sstats->lstats[i].nrequests +=
645 astats->lstats[i].nrequests;
646 sstats->lstats[i].curruns += astats->lstats[i].curruns;
647 }
Jason Evans3c4d92e2014-10-12 22:53:59 -0700648
Jason Evans3c07f802016-02-27 20:40:13 -0800649 for (i = 0; i < nhclasses; i++) {
650 sstats->hstats[i].nmalloc += astats->hstats[i].nmalloc;
651 sstats->hstats[i].ndalloc += astats->hstats[i].ndalloc;
652 sstats->hstats[i].curhchunks +=
653 astats->hstats[i].curhchunks;
654 }
Jason Evans3c4d92e2014-10-12 22:53:59 -0700655 }
Jason Evans86815df2010-03-13 20:32:56 -0800656}
Jason Evans86815df2010-03-13 20:32:56 -0800657
Jason Evans3c234352010-01-27 13:10:55 -0800658static void
Jason Evansc1e00ef2016-05-10 22:21:10 -0700659ctl_arena_refresh(tsdn_t *tsdn, arena_t *arena, unsigned i)
Jason Evans3c234352010-01-27 13:10:55 -0800660{
661 ctl_arena_stats_t *astats = &ctl_stats.arenas[i];
Jason Evans609ae592012-10-11 13:53:15 -0700662 ctl_arena_stats_t *sstats = &ctl_stats.arenas[ctl_stats.narenas];
Jason Evans3c234352010-01-27 13:10:55 -0800663
664 ctl_arena_clear(astats);
Jason Evansc1e00ef2016-05-10 22:21:10 -0700665 ctl_arena_stats_amerge(tsdn, astats, arena);
Jason Evans3c07f802016-02-27 20:40:13 -0800666 /* Merge into sum stats as well. */
667 ctl_arena_stats_smerge(sstats, astats);
Jason Evans3c234352010-01-27 13:10:55 -0800668}
669
Jason Evans609ae592012-10-11 13:53:15 -0700670static bool
Jason Evansc1e00ef2016-05-10 22:21:10 -0700671ctl_grow(tsdn_t *tsdn)
Jason Evans609ae592012-10-11 13:53:15 -0700672{
Jason Evans609ae592012-10-11 13:53:15 -0700673 ctl_arena_stats_t *astats;
Jason Evans609ae592012-10-11 13:53:15 -0700674
Jason Evans8bb31982014-10-07 23:14:57 -0700675 /* Initialize new arena. */
Jason Evansc1e00ef2016-05-10 22:21:10 -0700676 if (arena_init(tsdn, ctl_stats.narenas) == NULL)
Jason Evans8bb31982014-10-07 23:14:57 -0700677 return (true);
Jason Evans5460aa62014-09-22 21:09:23 -0700678
Jason Evans8bb31982014-10-07 23:14:57 -0700679 /* Allocate extended arena stats. */
680 astats = (ctl_arena_stats_t *)a0malloc((ctl_stats.narenas + 2) *
Jason Evans4581b972014-11-27 17:22:36 -0200681 sizeof(ctl_arena_stats_t));
Jason Evans7b651802013-10-20 14:09:54 -0700682 if (astats == NULL)
Jason Evans609ae592012-10-11 13:53:15 -0700683 return (true);
Jason Evans7b651802013-10-20 14:09:54 -0700684
685 /* Initialize the new astats element. */
686 memcpy(astats, ctl_stats.arenas, (ctl_stats.narenas + 1) *
687 sizeof(ctl_arena_stats_t));
688 memset(&astats[ctl_stats.narenas + 1], 0, sizeof(ctl_arena_stats_t));
689 if (ctl_arena_init(&astats[ctl_stats.narenas + 1])) {
Jason Evans10aff3f2015-01-20 15:37:51 -0800690 a0dalloc(astats);
Jason Evans7b651802013-10-20 14:09:54 -0700691 return (true);
692 }
Jason Evans609ae592012-10-11 13:53:15 -0700693 /* Swap merged stats to their new location. */
694 {
695 ctl_arena_stats_t tstats;
696 memcpy(&tstats, &astats[ctl_stats.narenas],
697 sizeof(ctl_arena_stats_t));
698 memcpy(&astats[ctl_stats.narenas],
699 &astats[ctl_stats.narenas + 1], sizeof(ctl_arena_stats_t));
700 memcpy(&astats[ctl_stats.narenas + 1], &tstats,
701 sizeof(ctl_arena_stats_t));
702 }
Jason Evans10aff3f2015-01-20 15:37:51 -0800703 a0dalloc(ctl_stats.arenas);
Jason Evans609ae592012-10-11 13:53:15 -0700704 ctl_stats.arenas = astats;
705 ctl_stats.narenas++;
Jason Evans609ae592012-10-11 13:53:15 -0700706
707 return (false);
708}
709
Jason Evans3c234352010-01-27 13:10:55 -0800710static void
Jason Evansc1e00ef2016-05-10 22:21:10 -0700711ctl_refresh(tsdn_t *tsdn)
Jason Evans3c234352010-01-27 13:10:55 -0800712{
713 unsigned i;
Jason Evans609ae592012-10-11 13:53:15 -0700714 VARIABLE_ARRAY(arena_t *, tarenas, ctl_stats.narenas);
Jason Evans3c234352010-01-27 13:10:55 -0800715
Jason Evans3c234352010-01-27 13:10:55 -0800716 /*
Jason Evans13668262010-01-31 03:57:29 -0800717 * Clear sum stats, since they will be merged into by
Jason Evans3c234352010-01-27 13:10:55 -0800718 * ctl_arena_refresh().
719 */
Jason Evans609ae592012-10-11 13:53:15 -0700720 ctl_arena_clear(&ctl_stats.arenas[ctl_stats.narenas]);
Jason Evans3c234352010-01-27 13:10:55 -0800721
Jason Evans767d8502016-02-24 23:58:10 -0800722 for (i = 0; i < ctl_stats.narenas; i++)
Jason Evansc1e00ef2016-05-10 22:21:10 -0700723 tarenas[i] = arena_get(tsdn, i, false);
Jason Evans8bb31982014-10-07 23:14:57 -0700724
Jason Evans609ae592012-10-11 13:53:15 -0700725 for (i = 0; i < ctl_stats.narenas; i++) {
Jason Evans3c234352010-01-27 13:10:55 -0800726 bool initialized = (tarenas[i] != NULL);
727
728 ctl_stats.arenas[i].initialized = initialized;
729 if (initialized)
Jason Evansc1e00ef2016-05-10 22:21:10 -0700730 ctl_arena_refresh(tsdn, tarenas[i], i);
Jason Evans3c234352010-01-27 13:10:55 -0800731 }
732
Jason Evans7372b152012-02-10 20:22:09 -0800733 if (config_stats) {
Jason Evans4acd75a2015-03-23 17:25:57 -0700734 size_t base_allocated, base_resident, base_mapped;
Jason Evansc1e00ef2016-05-10 22:21:10 -0700735 base_stats_get(tsdn, &base_allocated, &base_resident,
Jason Evansb2c0d632016-04-13 23:36:15 -0700736 &base_mapped);
Jason Evans609ae592012-10-11 13:53:15 -0700737 ctl_stats.allocated =
Jason Evans4acd75a2015-03-23 17:25:57 -0700738 ctl_stats.arenas[ctl_stats.narenas].allocated_small +
739 ctl_stats.arenas[ctl_stats.narenas].astats.allocated_large +
740 ctl_stats.arenas[ctl_stats.narenas].astats.allocated_huge;
Jason Evans609ae592012-10-11 13:53:15 -0700741 ctl_stats.active =
Jason Evanse2deab72014-05-15 22:22:27 -0700742 (ctl_stats.arenas[ctl_stats.narenas].pactive << LG_PAGE);
Jason Evans4acd75a2015-03-23 17:25:57 -0700743 ctl_stats.metadata = base_allocated +
744 ctl_stats.arenas[ctl_stats.narenas].astats.metadata_mapped +
745 ctl_stats.arenas[ctl_stats.narenas].astats
Jason Evans4581b972014-11-27 17:22:36 -0200746 .metadata_allocated;
Jason Evans4acd75a2015-03-23 17:25:57 -0700747 ctl_stats.resident = base_resident +
748 ctl_stats.arenas[ctl_stats.narenas].astats.metadata_mapped +
749 ((ctl_stats.arenas[ctl_stats.narenas].pactive +
750 ctl_stats.arenas[ctl_stats.narenas].pdirty) << LG_PAGE);
751 ctl_stats.mapped = base_mapped +
Jason Evanscbf3a6d2015-02-11 12:24:27 -0800752 ctl_stats.arenas[ctl_stats.narenas].astats.mapped;
Jason Evans04c3c0f2016-05-03 22:11:35 -0700753 ctl_stats.retained =
754 ctl_stats.arenas[ctl_stats.narenas].astats.retained;
Jason Evans7372b152012-02-10 20:22:09 -0800755 }
Jason Evans3c234352010-01-27 13:10:55 -0800756
757 ctl_epoch++;
758}
759
760static bool
Jason Evansc1e00ef2016-05-10 22:21:10 -0700761ctl_init(tsdn_t *tsdn)
Jason Evans3c234352010-01-27 13:10:55 -0800762{
Jason Evansfc4dcfa2010-11-24 15:44:21 -0800763 bool ret;
Jason Evans3c234352010-01-27 13:10:55 -0800764
Jason Evansc1e00ef2016-05-10 22:21:10 -0700765 malloc_mutex_lock(tsdn, &ctl_mtx);
Jason Evans551ebc42014-10-03 10:16:09 -0700766 if (!ctl_initialized) {
Jason Evans3c234352010-01-27 13:10:55 -0800767 /*
768 * Allocate space for one extra arena stats element, which
769 * contains summed stats across all arenas.
770 */
Jason Evans8bb31982014-10-07 23:14:57 -0700771 ctl_stats.narenas = narenas_total_get();
772 ctl_stats.arenas = (ctl_arena_stats_t *)a0malloc(
Jason Evans4581b972014-11-27 17:22:36 -0200773 (ctl_stats.narenas + 1) * sizeof(ctl_arena_stats_t));
Jason Evansfc4dcfa2010-11-24 15:44:21 -0800774 if (ctl_stats.arenas == NULL) {
775 ret = true;
Jason Evansa1ee7832012-04-10 15:07:44 -0700776 goto label_return;
Jason Evansfc4dcfa2010-11-24 15:44:21 -0800777 }
Jason Evans609ae592012-10-11 13:53:15 -0700778 memset(ctl_stats.arenas, 0, (ctl_stats.narenas + 1) *
Jason Evans3c234352010-01-27 13:10:55 -0800779 sizeof(ctl_arena_stats_t));
780
781 /*
782 * Initialize all stats structures, regardless of whether they
783 * ever get used. Lazy initialization would allow errors to
784 * cause inconsistent state to be viewable by the application.
785 */
Jason Evans7372b152012-02-10 20:22:09 -0800786 if (config_stats) {
787 unsigned i;
Jason Evans609ae592012-10-11 13:53:15 -0700788 for (i = 0; i <= ctl_stats.narenas; i++) {
Jason Evans7372b152012-02-10 20:22:09 -0800789 if (ctl_arena_init(&ctl_stats.arenas[i])) {
Jason Evans8bb31982014-10-07 23:14:57 -0700790 unsigned j;
791 for (j = 0; j < i; j++) {
Jason Evans10aff3f2015-01-20 15:37:51 -0800792 a0dalloc(
Jason Evans8bb31982014-10-07 23:14:57 -0700793 ctl_stats.arenas[j].lstats);
Jason Evans10aff3f2015-01-20 15:37:51 -0800794 a0dalloc(
Jason Evans3c4d92e2014-10-12 22:53:59 -0700795 ctl_stats.arenas[j].hstats);
Jason Evans8bb31982014-10-07 23:14:57 -0700796 }
Jason Evans10aff3f2015-01-20 15:37:51 -0800797 a0dalloc(ctl_stats.arenas);
Jason Evans8bb31982014-10-07 23:14:57 -0700798 ctl_stats.arenas = NULL;
Jason Evans7372b152012-02-10 20:22:09 -0800799 ret = true;
Jason Evansa1ee7832012-04-10 15:07:44 -0700800 goto label_return;
Jason Evans7372b152012-02-10 20:22:09 -0800801 }
Jason Evansfc4dcfa2010-11-24 15:44:21 -0800802 }
Jason Evans3c234352010-01-27 13:10:55 -0800803 }
Jason Evans609ae592012-10-11 13:53:15 -0700804 ctl_stats.arenas[ctl_stats.narenas].initialized = true;
Jason Evans3c234352010-01-27 13:10:55 -0800805
806 ctl_epoch = 0;
Jason Evansc1e00ef2016-05-10 22:21:10 -0700807 ctl_refresh(tsdn);
Jason Evans3c234352010-01-27 13:10:55 -0800808 ctl_initialized = true;
809 }
810
Jason Evansfc4dcfa2010-11-24 15:44:21 -0800811 ret = false;
Jason Evansa1ee7832012-04-10 15:07:44 -0700812label_return:
Jason Evansc1e00ef2016-05-10 22:21:10 -0700813 malloc_mutex_unlock(tsdn, &ctl_mtx);
Jason Evansfc4dcfa2010-11-24 15:44:21 -0800814 return (ret);
Jason Evans3c234352010-01-27 13:10:55 -0800815}
816
817static int
Jason Evansc1e00ef2016-05-10 22:21:10 -0700818ctl_lookup(tsdn_t *tsdn, const char *name, ctl_node_t const **nodesp,
Jason Evansb2c0d632016-04-13 23:36:15 -0700819 size_t *mibp, size_t *depthp)
Jason Evans3c234352010-01-27 13:10:55 -0800820{
821 int ret;
822 const char *elm, *tdot, *dot;
823 size_t elen, i, j;
Mike Hommey461ad5c2012-04-20 08:38:42 +0200824 const ctl_named_node_t *node;
Jason Evans3c234352010-01-27 13:10:55 -0800825
826 elm = name;
827 /* Equivalent to strchrnul(). */
828 dot = ((tdot = strchr(elm, '.')) != NULL) ? tdot : strchr(elm, '\0');
829 elen = (size_t)((uintptr_t)dot - (uintptr_t)elm);
830 if (elen == 0) {
831 ret = ENOENT;
Jason Evansa1ee7832012-04-10 15:07:44 -0700832 goto label_return;
Jason Evans3c234352010-01-27 13:10:55 -0800833 }
834 node = super_root_node;
835 for (i = 0; i < *depthp; i++) {
Mike Hommey461ad5c2012-04-20 08:38:42 +0200836 assert(node);
837 assert(node->nchildren > 0);
838 if (ctl_named_node(node->children) != NULL) {
839 const ctl_named_node_t *pnode = node;
Jason Evans3c234352010-01-27 13:10:55 -0800840
841 /* Children are named. */
Mike Hommey461ad5c2012-04-20 08:38:42 +0200842 for (j = 0; j < node->nchildren; j++) {
843 const ctl_named_node_t *child =
844 ctl_named_children(node, j);
845 if (strlen(child->name) == elen &&
846 strncmp(elm, child->name, elen) == 0) {
Jason Evans3c234352010-01-27 13:10:55 -0800847 node = child;
848 if (nodesp != NULL)
Mike Hommey461ad5c2012-04-20 08:38:42 +0200849 nodesp[i] =
850 (const ctl_node_t *)node;
Jason Evans3c234352010-01-27 13:10:55 -0800851 mibp[i] = j;
852 break;
853 }
854 }
855 if (node == pnode) {
856 ret = ENOENT;
Jason Evansa1ee7832012-04-10 15:07:44 -0700857 goto label_return;
Jason Evans3c234352010-01-27 13:10:55 -0800858 }
859 } else {
Jason Evans41b6afb2012-02-02 22:04:57 -0800860 uintmax_t index;
Mike Hommey461ad5c2012-04-20 08:38:42 +0200861 const ctl_indexed_node_t *inode;
Jason Evans3c234352010-01-27 13:10:55 -0800862
863 /* Children are indexed. */
Jason Evans41b6afb2012-02-02 22:04:57 -0800864 index = malloc_strtoumax(elm, NULL, 10);
865 if (index == UINTMAX_MAX || index > SIZE_T_MAX) {
Jason Evans3c234352010-01-27 13:10:55 -0800866 ret = ENOENT;
Jason Evansa1ee7832012-04-10 15:07:44 -0700867 goto label_return;
Jason Evans3c234352010-01-27 13:10:55 -0800868 }
869
Mike Hommey461ad5c2012-04-20 08:38:42 +0200870 inode = ctl_indexed_node(node->children);
Jason Evansc1e00ef2016-05-10 22:21:10 -0700871 node = inode->index(tsdn, mibp, *depthp, (size_t)index);
Jason Evans3c234352010-01-27 13:10:55 -0800872 if (node == NULL) {
873 ret = ENOENT;
Jason Evansa1ee7832012-04-10 15:07:44 -0700874 goto label_return;
Jason Evans3c234352010-01-27 13:10:55 -0800875 }
876
877 if (nodesp != NULL)
Mike Hommey461ad5c2012-04-20 08:38:42 +0200878 nodesp[i] = (const ctl_node_t *)node;
Jason Evans3c234352010-01-27 13:10:55 -0800879 mibp[i] = (size_t)index;
880 }
881
882 if (node->ctl != NULL) {
883 /* Terminal node. */
884 if (*dot != '\0') {
885 /*
886 * The name contains more elements than are
887 * in this path through the tree.
888 */
889 ret = ENOENT;
Jason Evansa1ee7832012-04-10 15:07:44 -0700890 goto label_return;
Jason Evans3c234352010-01-27 13:10:55 -0800891 }
892 /* Complete lookup successful. */
893 *depthp = i + 1;
894 break;
895 }
896
897 /* Update elm. */
898 if (*dot == '\0') {
899 /* No more elements. */
900 ret = ENOENT;
Jason Evansa1ee7832012-04-10 15:07:44 -0700901 goto label_return;
Jason Evans3c234352010-01-27 13:10:55 -0800902 }
903 elm = &dot[1];
904 dot = ((tdot = strchr(elm, '.')) != NULL) ? tdot :
905 strchr(elm, '\0');
906 elen = (size_t)((uintptr_t)dot - (uintptr_t)elm);
907 }
908
909 ret = 0;
Jason Evansa1ee7832012-04-10 15:07:44 -0700910label_return:
Jason Evans3c234352010-01-27 13:10:55 -0800911 return (ret);
912}
913
914int
Jason Evansb2c0d632016-04-13 23:36:15 -0700915ctl_byname(tsd_t *tsd, const char *name, void *oldp, size_t *oldlenp,
916 void *newp, size_t newlen)
Jason Evans3c234352010-01-27 13:10:55 -0800917{
918 int ret;
919 size_t depth;
920 ctl_node_t const *nodes[CTL_MAX_DEPTH];
921 size_t mib[CTL_MAX_DEPTH];
Mike Hommey461ad5c2012-04-20 08:38:42 +0200922 const ctl_named_node_t *node;
Jason Evans3c234352010-01-27 13:10:55 -0800923
Jason Evansc1e00ef2016-05-10 22:21:10 -0700924 if (!ctl_initialized && ctl_init(tsd_tsdn(tsd))) {
Jason Evans3c234352010-01-27 13:10:55 -0800925 ret = EAGAIN;
Jason Evansa1ee7832012-04-10 15:07:44 -0700926 goto label_return;
Jason Evans3c234352010-01-27 13:10:55 -0800927 }
928
929 depth = CTL_MAX_DEPTH;
Jason Evansc1e00ef2016-05-10 22:21:10 -0700930 ret = ctl_lookup(tsd_tsdn(tsd), name, nodes, mib, &depth);
Jason Evans3c234352010-01-27 13:10:55 -0800931 if (ret != 0)
Jason Evansa1ee7832012-04-10 15:07:44 -0700932 goto label_return;
Jason Evans3c234352010-01-27 13:10:55 -0800933
Mike Hommey461ad5c2012-04-20 08:38:42 +0200934 node = ctl_named_node(nodes[depth-1]);
935 if (node != NULL && node->ctl)
Jason Evansb2c0d632016-04-13 23:36:15 -0700936 ret = node->ctl(tsd, mib, depth, oldp, oldlenp, newp, newlen);
Mike Hommey461ad5c2012-04-20 08:38:42 +0200937 else {
Jason Evans3c234352010-01-27 13:10:55 -0800938 /* The name refers to a partial path through the ctl tree. */
939 ret = ENOENT;
Jason Evans3c234352010-01-27 13:10:55 -0800940 }
Jason Evans3c234352010-01-27 13:10:55 -0800941
Jason Evansa1ee7832012-04-10 15:07:44 -0700942label_return:
Jason Evans3c234352010-01-27 13:10:55 -0800943 return(ret);
944}
945
946int
Jason Evansc1e00ef2016-05-10 22:21:10 -0700947ctl_nametomib(tsdn_t *tsdn, const char *name, size_t *mibp, size_t *miblenp)
Jason Evans3c234352010-01-27 13:10:55 -0800948{
949 int ret;
950
Jason Evansc1e00ef2016-05-10 22:21:10 -0700951 if (!ctl_initialized && ctl_init(tsdn)) {
Jason Evans3c234352010-01-27 13:10:55 -0800952 ret = EAGAIN;
Jason Evansa1ee7832012-04-10 15:07:44 -0700953 goto label_return;
Jason Evans3c234352010-01-27 13:10:55 -0800954 }
955
Jason Evansc1e00ef2016-05-10 22:21:10 -0700956 ret = ctl_lookup(tsdn, name, NULL, mibp, miblenp);
Jason Evansa1ee7832012-04-10 15:07:44 -0700957label_return:
Jason Evans3c234352010-01-27 13:10:55 -0800958 return(ret);
959}
960
961int
Jason Evansb2c0d632016-04-13 23:36:15 -0700962ctl_bymib(tsd_t *tsd, const size_t *mib, size_t miblen, void *oldp,
963 size_t *oldlenp, void *newp, size_t newlen)
Jason Evans3c234352010-01-27 13:10:55 -0800964{
965 int ret;
Mike Hommey461ad5c2012-04-20 08:38:42 +0200966 const ctl_named_node_t *node;
Jason Evans3c234352010-01-27 13:10:55 -0800967 size_t i;
968
Jason Evansc1e00ef2016-05-10 22:21:10 -0700969 if (!ctl_initialized && ctl_init(tsd_tsdn(tsd))) {
Jason Evans3c234352010-01-27 13:10:55 -0800970 ret = EAGAIN;
Jason Evansa1ee7832012-04-10 15:07:44 -0700971 goto label_return;
Jason Evans3c234352010-01-27 13:10:55 -0800972 }
973
974 /* Iterate down the tree. */
975 node = super_root_node;
976 for (i = 0; i < miblen; i++) {
Mike Hommey461ad5c2012-04-20 08:38:42 +0200977 assert(node);
978 assert(node->nchildren > 0);
979 if (ctl_named_node(node->children) != NULL) {
Jason Evans3c234352010-01-27 13:10:55 -0800980 /* Children are named. */
Jason Evans8dd51152016-02-24 11:00:40 -0800981 if (node->nchildren <= (unsigned)mib[i]) {
Jason Evans3c234352010-01-27 13:10:55 -0800982 ret = ENOENT;
Jason Evansa1ee7832012-04-10 15:07:44 -0700983 goto label_return;
Jason Evans3c234352010-01-27 13:10:55 -0800984 }
Mike Hommey461ad5c2012-04-20 08:38:42 +0200985 node = ctl_named_children(node, mib[i]);
Jason Evans3c234352010-01-27 13:10:55 -0800986 } else {
Mike Hommey461ad5c2012-04-20 08:38:42 +0200987 const ctl_indexed_node_t *inode;
Jason Evans3c234352010-01-27 13:10:55 -0800988
989 /* Indexed element. */
Mike Hommey461ad5c2012-04-20 08:38:42 +0200990 inode = ctl_indexed_node(node->children);
Jason Evansc1e00ef2016-05-10 22:21:10 -0700991 node = inode->index(tsd_tsdn(tsd), mib, miblen, mib[i]);
Jason Evans3c234352010-01-27 13:10:55 -0800992 if (node == NULL) {
993 ret = ENOENT;
Jason Evansa1ee7832012-04-10 15:07:44 -0700994 goto label_return;
Jason Evans3c234352010-01-27 13:10:55 -0800995 }
996 }
997 }
998
999 /* Call the ctl function. */
Mike Hommey461ad5c2012-04-20 08:38:42 +02001000 if (node && node->ctl)
Jason Evansb2c0d632016-04-13 23:36:15 -07001001 ret = node->ctl(tsd, mib, miblen, oldp, oldlenp, newp, newlen);
Mike Hommey461ad5c2012-04-20 08:38:42 +02001002 else {
Jason Evans3c234352010-01-27 13:10:55 -08001003 /* Partial MIB. */
1004 ret = ENOENT;
Jason Evans3c234352010-01-27 13:10:55 -08001005 }
Jason Evans3c234352010-01-27 13:10:55 -08001006
Jason Evansa1ee7832012-04-10 15:07:44 -07001007label_return:
Jason Evans3c234352010-01-27 13:10:55 -08001008 return(ret);
1009}
1010
1011bool
1012ctl_boot(void)
1013{
1014
Jason Evansb2c0d632016-04-13 23:36:15 -07001015 if (malloc_mutex_init(&ctl_mtx, "ctl", WITNESS_RANK_CTL))
Jason Evans3c234352010-01-27 13:10:55 -08001016 return (true);
1017
1018 ctl_initialized = false;
1019
1020 return (false);
1021}
1022
Jason Evans20f1fc92012-10-09 14:46:22 -07001023void
Jason Evansc1e00ef2016-05-10 22:21:10 -07001024ctl_prefork(tsdn_t *tsdn)
Jason Evans20f1fc92012-10-09 14:46:22 -07001025{
1026
Jason Evansc1e00ef2016-05-10 22:21:10 -07001027 malloc_mutex_prefork(tsdn, &ctl_mtx);
Jason Evans20f1fc92012-10-09 14:46:22 -07001028}
1029
1030void
Jason Evansc1e00ef2016-05-10 22:21:10 -07001031ctl_postfork_parent(tsdn_t *tsdn)
Jason Evans20f1fc92012-10-09 14:46:22 -07001032{
1033
Jason Evansc1e00ef2016-05-10 22:21:10 -07001034 malloc_mutex_postfork_parent(tsdn, &ctl_mtx);
Jason Evans20f1fc92012-10-09 14:46:22 -07001035}
1036
1037void
Jason Evansc1e00ef2016-05-10 22:21:10 -07001038ctl_postfork_child(tsdn_t *tsdn)
Jason Evans20f1fc92012-10-09 14:46:22 -07001039{
1040
Jason Evansc1e00ef2016-05-10 22:21:10 -07001041 malloc_mutex_postfork_child(tsdn, &ctl_mtx);
Jason Evans20f1fc92012-10-09 14:46:22 -07001042}
1043
Jason Evans3c234352010-01-27 13:10:55 -08001044/******************************************************************************/
1045/* *_ctl() functions. */
1046
1047#define READONLY() do { \
1048 if (newp != NULL || newlen != 0) { \
1049 ret = EPERM; \
Jason Evans6b9ed672012-04-25 13:12:46 -07001050 goto label_return; \
Jason Evans3c234352010-01-27 13:10:55 -08001051 } \
1052} while (0)
1053
Jason Evans22ca8552010-03-02 11:57:30 -08001054#define WRITEONLY() do { \
Jason Evans3c234352010-01-27 13:10:55 -08001055 if (oldp != NULL || oldlenp != NULL) { \
1056 ret = EPERM; \
Jason Evans6b9ed672012-04-25 13:12:46 -07001057 goto label_return; \
Jason Evans3c234352010-01-27 13:10:55 -08001058 } \
1059} while (0)
1060
Jason Evansfc12c0b2014-10-03 23:25:30 -07001061#define READ_XOR_WRITE() do { \
1062 if ((oldp != NULL && oldlenp != NULL) && (newp != NULL || \
1063 newlen != 0)) { \
1064 ret = EPERM; \
1065 goto label_return; \
1066 } \
1067} while (0)
1068
Jason Evans3c234352010-01-27 13:10:55 -08001069#define READ(v, t) do { \
1070 if (oldp != NULL && oldlenp != NULL) { \
1071 if (*oldlenp != sizeof(t)) { \
1072 size_t copylen = (sizeof(t) <= *oldlenp) \
1073 ? sizeof(t) : *oldlenp; \
Jason Evans6eb84fb2012-11-29 22:13:04 -08001074 memcpy(oldp, (void *)&(v), copylen); \
Jason Evans3c234352010-01-27 13:10:55 -08001075 ret = EINVAL; \
Jason Evans6b9ed672012-04-25 13:12:46 -07001076 goto label_return; \
Jason Evansb49a3342015-07-28 11:28:19 -04001077 } \
1078 *(t *)oldp = (v); \
Jason Evans3c234352010-01-27 13:10:55 -08001079 } \
1080} while (0)
1081
1082#define WRITE(v, t) do { \
1083 if (newp != NULL) { \
1084 if (newlen != sizeof(t)) { \
1085 ret = EINVAL; \
Jason Evans6b9ed672012-04-25 13:12:46 -07001086 goto label_return; \
Jason Evans3c234352010-01-27 13:10:55 -08001087 } \
Jason Evans6eb84fb2012-11-29 22:13:04 -08001088 (v) = *(t *)newp; \
Jason Evans3c234352010-01-27 13:10:55 -08001089 } \
1090} while (0)
1091
Jason Evans7372b152012-02-10 20:22:09 -08001092/*
1093 * There's a lot of code duplication in the following macros due to limitations
1094 * in how nested cpp macros are expanded.
1095 */
1096#define CTL_RO_CLGEN(c, l, n, v, t) \
1097static int \
Jason Evansb2c0d632016-04-13 23:36:15 -07001098n##_ctl(tsd_t *tsd, const size_t *mib, size_t miblen, void *oldp, \
1099 size_t *oldlenp, void *newp, size_t newlen) \
Jason Evans7372b152012-02-10 20:22:09 -08001100{ \
1101 int ret; \
1102 t oldval; \
1103 \
Jason Evans551ebc42014-10-03 10:16:09 -07001104 if (!(c)) \
Jason Evans7372b152012-02-10 20:22:09 -08001105 return (ENOENT); \
1106 if (l) \
Jason Evansc1e00ef2016-05-10 22:21:10 -07001107 malloc_mutex_lock(tsd_tsdn(tsd), &ctl_mtx); \
Jason Evans7372b152012-02-10 20:22:09 -08001108 READONLY(); \
Jason Evans6eb84fb2012-11-29 22:13:04 -08001109 oldval = (v); \
Jason Evans7372b152012-02-10 20:22:09 -08001110 READ(oldval, t); \
1111 \
1112 ret = 0; \
Jason Evans6b9ed672012-04-25 13:12:46 -07001113label_return: \
Jason Evans7372b152012-02-10 20:22:09 -08001114 if (l) \
Jason Evansc1e00ef2016-05-10 22:21:10 -07001115 malloc_mutex_unlock(tsd_tsdn(tsd), &ctl_mtx); \
Jason Evans7372b152012-02-10 20:22:09 -08001116 return (ret); \
1117}
1118
1119#define CTL_RO_CGEN(c, n, v, t) \
1120static int \
Jason Evansb2c0d632016-04-13 23:36:15 -07001121n##_ctl(tsd_t *tsd, const size_t *mib, size_t miblen, void *oldp, \
1122 size_t *oldlenp, void *newp, size_t newlen) \
Jason Evans7372b152012-02-10 20:22:09 -08001123{ \
1124 int ret; \
1125 t oldval; \
1126 \
Jason Evans551ebc42014-10-03 10:16:09 -07001127 if (!(c)) \
Jason Evans7372b152012-02-10 20:22:09 -08001128 return (ENOENT); \
Jason Evansc1e00ef2016-05-10 22:21:10 -07001129 malloc_mutex_lock(tsd_tsdn(tsd), &ctl_mtx); \
Jason Evans7372b152012-02-10 20:22:09 -08001130 READONLY(); \
Jason Evans6eb84fb2012-11-29 22:13:04 -08001131 oldval = (v); \
Jason Evans7372b152012-02-10 20:22:09 -08001132 READ(oldval, t); \
1133 \
1134 ret = 0; \
Jason Evans6b9ed672012-04-25 13:12:46 -07001135label_return: \
Jason Evansc1e00ef2016-05-10 22:21:10 -07001136 malloc_mutex_unlock(tsd_tsdn(tsd), &ctl_mtx); \
Jason Evans7372b152012-02-10 20:22:09 -08001137 return (ret); \
1138}
1139
Jason Evans3c234352010-01-27 13:10:55 -08001140#define CTL_RO_GEN(n, v, t) \
1141static int \
Jason Evansb2c0d632016-04-13 23:36:15 -07001142n##_ctl(tsd_t *tsd, const size_t *mib, size_t miblen, void *oldp, \
1143 size_t *oldlenp, void *newp, size_t newlen) \
Jason Evans3c234352010-01-27 13:10:55 -08001144{ \
1145 int ret; \
1146 t oldval; \
1147 \
Jason Evansc1e00ef2016-05-10 22:21:10 -07001148 malloc_mutex_lock(tsd_tsdn(tsd), &ctl_mtx); \
Jason Evansfc4dcfa2010-11-24 15:44:21 -08001149 READONLY(); \
Jason Evans6eb84fb2012-11-29 22:13:04 -08001150 oldval = (v); \
Jason Evansfc4dcfa2010-11-24 15:44:21 -08001151 READ(oldval, t); \
1152 \
1153 ret = 0; \
Jason Evans6b9ed672012-04-25 13:12:46 -07001154label_return: \
Jason Evansc1e00ef2016-05-10 22:21:10 -07001155 malloc_mutex_unlock(tsd_tsdn(tsd), &ctl_mtx); \
Jason Evansfc4dcfa2010-11-24 15:44:21 -08001156 return (ret); \
1157}
1158
1159/*
1160 * ctl_mtx is not acquired, under the assumption that no pertinent data will
1161 * mutate during the call.
1162 */
Jason Evans7372b152012-02-10 20:22:09 -08001163#define CTL_RO_NL_CGEN(c, n, v, t) \
1164static int \
Jason Evansb2c0d632016-04-13 23:36:15 -07001165n##_ctl(tsd_t *tsd, const size_t *mib, size_t miblen, void *oldp, \
1166 size_t *oldlenp, void *newp, size_t newlen) \
Jason Evans7372b152012-02-10 20:22:09 -08001167{ \
1168 int ret; \
1169 t oldval; \
1170 \
Jason Evans551ebc42014-10-03 10:16:09 -07001171 if (!(c)) \
Jason Evans7372b152012-02-10 20:22:09 -08001172 return (ENOENT); \
1173 READONLY(); \
Jason Evans6eb84fb2012-11-29 22:13:04 -08001174 oldval = (v); \
Jason Evans7372b152012-02-10 20:22:09 -08001175 READ(oldval, t); \
1176 \
1177 ret = 0; \
Jason Evans6b9ed672012-04-25 13:12:46 -07001178label_return: \
Jason Evans7372b152012-02-10 20:22:09 -08001179 return (ret); \
1180}
1181
1182#define CTL_RO_NL_GEN(n, v, t) \
Jason Evansfc4dcfa2010-11-24 15:44:21 -08001183static int \
Jason Evansb2c0d632016-04-13 23:36:15 -07001184n##_ctl(tsd_t *tsd, const size_t *mib, size_t miblen, void *oldp, \
1185 size_t *oldlenp, void *newp, size_t newlen) \
Jason Evansfc4dcfa2010-11-24 15:44:21 -08001186{ \
1187 int ret; \
1188 t oldval; \
1189 \
Jason Evans3c234352010-01-27 13:10:55 -08001190 READONLY(); \
Jason Evans6eb84fb2012-11-29 22:13:04 -08001191 oldval = (v); \
Jason Evans3c234352010-01-27 13:10:55 -08001192 READ(oldval, t); \
1193 \
1194 ret = 0; \
Jason Evans6b9ed672012-04-25 13:12:46 -07001195label_return: \
Jason Evans3c234352010-01-27 13:10:55 -08001196 return (ret); \
1197}
1198
Jason Evans5460aa62014-09-22 21:09:23 -07001199#define CTL_TSD_RO_NL_CGEN(c, n, m, t) \
1200static int \
Jason Evansb2c0d632016-04-13 23:36:15 -07001201n##_ctl(tsd_t *tsd, const size_t *mib, size_t miblen, void *oldp, \
1202 size_t *oldlenp, void *newp, size_t newlen) \
Jason Evans5460aa62014-09-22 21:09:23 -07001203{ \
1204 int ret; \
1205 t oldval; \
Jason Evans5460aa62014-09-22 21:09:23 -07001206 \
Jason Evans551ebc42014-10-03 10:16:09 -07001207 if (!(c)) \
Jason Evans5460aa62014-09-22 21:09:23 -07001208 return (ENOENT); \
1209 READONLY(); \
Jason Evans5460aa62014-09-22 21:09:23 -07001210 oldval = (m(tsd)); \
1211 READ(oldval, t); \
1212 \
1213 ret = 0; \
1214label_return: \
1215 return (ret); \
1216}
1217
Jason Evansf8290092016-02-07 14:23:22 -08001218#define CTL_RO_CONFIG_GEN(n, t) \
Jason Evans3c234352010-01-27 13:10:55 -08001219static int \
Jason Evansb2c0d632016-04-13 23:36:15 -07001220n##_ctl(tsd_t *tsd, const size_t *mib, size_t miblen, void *oldp, \
1221 size_t *oldlenp, void *newp, size_t newlen) \
Jason Evans3c234352010-01-27 13:10:55 -08001222{ \
1223 int ret; \
Jason Evansf8290092016-02-07 14:23:22 -08001224 t oldval; \
Jason Evans3c234352010-01-27 13:10:55 -08001225 \
1226 READONLY(); \
Jason Evans7372b152012-02-10 20:22:09 -08001227 oldval = n; \
Jason Evansf8290092016-02-07 14:23:22 -08001228 READ(oldval, t); \
Jason Evans3c234352010-01-27 13:10:55 -08001229 \
1230 ret = 0; \
Jason Evans6b9ed672012-04-25 13:12:46 -07001231label_return: \
Jason Evans3c234352010-01-27 13:10:55 -08001232 return (ret); \
1233}
1234
Jason Evansd8a39002013-12-19 21:40:41 -08001235/******************************************************************************/
1236
Jason Evansfc4dcfa2010-11-24 15:44:21 -08001237CTL_RO_NL_GEN(version, JEMALLOC_VERSION, const char *)
Jason Evansa40bc7a2010-03-02 13:01:16 -08001238
Jason Evans3c234352010-01-27 13:10:55 -08001239static int
Jason Evansb2c0d632016-04-13 23:36:15 -07001240epoch_ctl(tsd_t *tsd, const size_t *mib, size_t miblen, void *oldp,
1241 size_t *oldlenp, void *newp, size_t newlen)
Jason Evans3c234352010-01-27 13:10:55 -08001242{
1243 int ret;
Jason Evans3ab682d2013-10-19 17:19:49 -07001244 UNUSED uint64_t newval;
Jason Evans3c234352010-01-27 13:10:55 -08001245
Jason Evansc1e00ef2016-05-10 22:21:10 -07001246 malloc_mutex_lock(tsd_tsdn(tsd), &ctl_mtx);
Jason Evans3c234352010-01-27 13:10:55 -08001247 WRITE(newval, uint64_t);
Jason Evans6b9ed672012-04-25 13:12:46 -07001248 if (newp != NULL)
Jason Evansc1e00ef2016-05-10 22:21:10 -07001249 ctl_refresh(tsd_tsdn(tsd));
Jason Evans3c234352010-01-27 13:10:55 -08001250 READ(ctl_epoch, uint64_t);
1251
1252 ret = 0;
Jason Evansa1ee7832012-04-10 15:07:44 -07001253label_return:
Jason Evansc1e00ef2016-05-10 22:21:10 -07001254 malloc_mutex_unlock(tsd_tsdn(tsd), &ctl_mtx);
Jason Evans3c234352010-01-27 13:10:55 -08001255 return (ret);
1256}
1257
Jason Evansd8a39002013-12-19 21:40:41 -08001258/******************************************************************************/
Jason Evansd4be8b72012-03-26 18:54:44 -07001259
Jason Evansf8290092016-02-07 14:23:22 -08001260CTL_RO_CONFIG_GEN(config_cache_oblivious, bool)
1261CTL_RO_CONFIG_GEN(config_debug, bool)
1262CTL_RO_CONFIG_GEN(config_fill, bool)
1263CTL_RO_CONFIG_GEN(config_lazy_lock, bool)
1264CTL_RO_CONFIG_GEN(config_malloc_conf, const char *)
1265CTL_RO_CONFIG_GEN(config_munmap, bool)
1266CTL_RO_CONFIG_GEN(config_prof, bool)
1267CTL_RO_CONFIG_GEN(config_prof_libgcc, bool)
1268CTL_RO_CONFIG_GEN(config_prof_libunwind, bool)
1269CTL_RO_CONFIG_GEN(config_stats, bool)
1270CTL_RO_CONFIG_GEN(config_tcache, bool)
1271CTL_RO_CONFIG_GEN(config_tls, bool)
1272CTL_RO_CONFIG_GEN(config_utrace, bool)
1273CTL_RO_CONFIG_GEN(config_valgrind, bool)
1274CTL_RO_CONFIG_GEN(config_xmalloc, bool)
Jason Evansd4be8b72012-03-26 18:54:44 -07001275
Jason Evansd8a39002013-12-19 21:40:41 -08001276/******************************************************************************/
Jason Evansd4be8b72012-03-26 18:54:44 -07001277
Jason Evansd8a39002013-12-19 21:40:41 -08001278CTL_RO_NL_GEN(opt_abort, opt_abort, bool)
1279CTL_RO_NL_GEN(opt_dss, opt_dss, const char *)
1280CTL_RO_NL_GEN(opt_lg_chunk, opt_lg_chunk, size_t)
Jason Evans8f683b92016-02-24 11:03:40 -08001281CTL_RO_NL_GEN(opt_narenas, opt_narenas, unsigned)
Jason Evans243f7a02016-02-19 20:09:31 -08001282CTL_RO_NL_GEN(opt_purge, purge_mode_names[opt_purge], const char *)
Jason Evansd8a39002013-12-19 21:40:41 -08001283CTL_RO_NL_GEN(opt_lg_dirty_mult, opt_lg_dirty_mult, ssize_t)
Jason Evans243f7a02016-02-19 20:09:31 -08001284CTL_RO_NL_GEN(opt_decay_time, opt_decay_time, ssize_t)
Jason Evansd8a39002013-12-19 21:40:41 -08001285CTL_RO_NL_GEN(opt_stats_print, opt_stats_print, bool)
Guilherme Goncalves2c5cb612014-12-08 19:12:41 -02001286CTL_RO_NL_CGEN(config_fill, opt_junk, opt_junk, const char *)
Jason Evansd8a39002013-12-19 21:40:41 -08001287CTL_RO_NL_CGEN(config_fill, opt_quarantine, opt_quarantine, size_t)
1288CTL_RO_NL_CGEN(config_fill, opt_redzone, opt_redzone, bool)
1289CTL_RO_NL_CGEN(config_fill, opt_zero, opt_zero, bool)
1290CTL_RO_NL_CGEN(config_utrace, opt_utrace, opt_utrace, bool)
Jason Evansd8a39002013-12-19 21:40:41 -08001291CTL_RO_NL_CGEN(config_xmalloc, opt_xmalloc, opt_xmalloc, bool)
1292CTL_RO_NL_CGEN(config_tcache, opt_tcache, opt_tcache, bool)
1293CTL_RO_NL_CGEN(config_tcache, opt_lg_tcache_max, opt_lg_tcache_max, ssize_t)
1294CTL_RO_NL_CGEN(config_prof, opt_prof, opt_prof, bool)
1295CTL_RO_NL_CGEN(config_prof, opt_prof_prefix, opt_prof_prefix, const char *)
Jason Evansfc12c0b2014-10-03 23:25:30 -07001296CTL_RO_NL_CGEN(config_prof, opt_prof_active, opt_prof_active, bool)
1297CTL_RO_NL_CGEN(config_prof, opt_prof_thread_active_init,
1298 opt_prof_thread_active_init, bool)
Jason Evansd8a39002013-12-19 21:40:41 -08001299CTL_RO_NL_CGEN(config_prof, opt_lg_prof_sample, opt_lg_prof_sample, size_t)
1300CTL_RO_NL_CGEN(config_prof, opt_prof_accum, opt_prof_accum, bool)
1301CTL_RO_NL_CGEN(config_prof, opt_lg_prof_interval, opt_lg_prof_interval, ssize_t)
1302CTL_RO_NL_CGEN(config_prof, opt_prof_gdump, opt_prof_gdump, bool)
1303CTL_RO_NL_CGEN(config_prof, opt_prof_final, opt_prof_final, bool)
1304CTL_RO_NL_CGEN(config_prof, opt_prof_leak, opt_prof_leak, bool)
Jason Evansd4be8b72012-03-26 18:54:44 -07001305
Jason Evansd8a39002013-12-19 21:40:41 -08001306/******************************************************************************/
Jason Evans3c234352010-01-27 13:10:55 -08001307
Jason Evansb267d0f2010-08-13 15:42:29 -07001308static int
Jason Evansb2c0d632016-04-13 23:36:15 -07001309thread_arena_ctl(tsd_t *tsd, const size_t *mib, size_t miblen, void *oldp,
1310 size_t *oldlenp, void *newp, size_t newlen)
Jason Evansb267d0f2010-08-13 15:42:29 -07001311{
1312 int ret;
Jason Evans1cb181e2015-01-29 15:30:47 -08001313 arena_t *oldarena;
Jason Evansb267d0f2010-08-13 15:42:29 -07001314 unsigned newind, oldind;
1315
Jason Evans90827a32016-05-03 15:00:42 -07001316 oldarena = arena_choose(tsd, NULL);
Jason Evans1cb181e2015-01-29 15:30:47 -08001317 if (oldarena == NULL)
Jason Evans8bb31982014-10-07 23:14:57 -07001318 return (EAGAIN);
Jason Evans5460aa62014-09-22 21:09:23 -07001319
Jason Evansc1e00ef2016-05-10 22:21:10 -07001320 malloc_mutex_lock(tsd_tsdn(tsd), &ctl_mtx);
Jason Evans1cb181e2015-01-29 15:30:47 -08001321 newind = oldind = oldarena->ind;
Jason Evansa7153a02011-03-14 11:39:49 -07001322 WRITE(newind, unsigned);
1323 READ(oldind, unsigned);
Jason Evansb267d0f2010-08-13 15:42:29 -07001324 if (newind != oldind) {
Jason Evans1cb181e2015-01-29 15:30:47 -08001325 arena_t *newarena;
1326
Jason Evans609ae592012-10-11 13:53:15 -07001327 if (newind >= ctl_stats.narenas) {
Jason Evansb267d0f2010-08-13 15:42:29 -07001328 /* New arena index is out of range. */
1329 ret = EFAULT;
Jason Evansa1ee7832012-04-10 15:07:44 -07001330 goto label_return;
Jason Evansb267d0f2010-08-13 15:42:29 -07001331 }
1332
1333 /* Initialize arena if necessary. */
Jason Evansc1e00ef2016-05-10 22:21:10 -07001334 newarena = arena_get(tsd_tsdn(tsd), newind, true);
Jason Evans1cb181e2015-01-29 15:30:47 -08001335 if (newarena == NULL) {
Jason Evansb267d0f2010-08-13 15:42:29 -07001336 ret = EAGAIN;
Jason Evansa1ee7832012-04-10 15:07:44 -07001337 goto label_return;
Jason Evansb267d0f2010-08-13 15:42:29 -07001338 }
Jason Evans8bb31982014-10-07 23:14:57 -07001339 /* Set new arena/tcache associations. */
1340 arena_migrate(tsd, oldind, newind);
Jason Evans7372b152012-02-10 20:22:09 -08001341 if (config_tcache) {
Jason Evans5460aa62014-09-22 21:09:23 -07001342 tcache_t *tcache = tsd_tcache_get(tsd);
Jason Evans1cb181e2015-01-29 15:30:47 -08001343 if (tcache != NULL) {
Jason Evansc1e00ef2016-05-10 22:21:10 -07001344 tcache_arena_reassociate(tsd_tsdn(tsd), tcache,
1345 oldarena, newarena);
Jason Evans1cb181e2015-01-29 15:30:47 -08001346 }
Jason Evans624f2f32010-12-29 12:21:05 -08001347 }
Jason Evansb267d0f2010-08-13 15:42:29 -07001348 }
1349
1350 ret = 0;
Jason Evansa1ee7832012-04-10 15:07:44 -07001351label_return:
Jason Evansc1e00ef2016-05-10 22:21:10 -07001352 malloc_mutex_unlock(tsd_tsdn(tsd), &ctl_mtx);
Jason Evansb267d0f2010-08-13 15:42:29 -07001353 return (ret);
1354}
Jason Evansb267d0f2010-08-13 15:42:29 -07001355
Jason Evans5460aa62014-09-22 21:09:23 -07001356CTL_TSD_RO_NL_CGEN(config_stats, thread_allocated, tsd_thread_allocated_get,
1357 uint64_t)
1358CTL_TSD_RO_NL_CGEN(config_stats, thread_allocatedp, tsd_thread_allocatedp_get,
1359 uint64_t *)
1360CTL_TSD_RO_NL_CGEN(config_stats, thread_deallocated, tsd_thread_deallocated_get,
1361 uint64_t)
1362CTL_TSD_RO_NL_CGEN(config_stats, thread_deallocatedp,
1363 tsd_thread_deallocatedp_get, uint64_t *)
Jason Evans93443682010-10-20 17:39:18 -07001364
Jason Evansd8a39002013-12-19 21:40:41 -08001365static int
Jason Evansb2c0d632016-04-13 23:36:15 -07001366thread_tcache_enabled_ctl(tsd_t *tsd, const size_t *mib, size_t miblen,
1367 void *oldp, size_t *oldlenp, void *newp, size_t newlen)
Jason Evansd8a39002013-12-19 21:40:41 -08001368{
1369 int ret;
1370 bool oldval;
Jason Evans3c234352010-01-27 13:10:55 -08001371
Jason Evans551ebc42014-10-03 10:16:09 -07001372 if (!config_tcache)
Jason Evansd8a39002013-12-19 21:40:41 -08001373 return (ENOENT);
Jason Evans3c234352010-01-27 13:10:55 -08001374
Jason Evansd8a39002013-12-19 21:40:41 -08001375 oldval = tcache_enabled_get();
1376 if (newp != NULL) {
1377 if (newlen != sizeof(bool)) {
1378 ret = EINVAL;
1379 goto label_return;
1380 }
1381 tcache_enabled_set(*(bool *)newp);
1382 }
1383 READ(oldval, bool);
Jason Evans3c234352010-01-27 13:10:55 -08001384
Jason Evansd8a39002013-12-19 21:40:41 -08001385 ret = 0;
1386label_return:
1387 return (ret);
1388}
1389
1390static int
Jason Evansb2c0d632016-04-13 23:36:15 -07001391thread_tcache_flush_ctl(tsd_t *tsd, const size_t *mib, size_t miblen,
1392 void *oldp, size_t *oldlenp, void *newp, size_t newlen)
Jason Evansd8a39002013-12-19 21:40:41 -08001393{
1394 int ret;
1395
Jason Evans551ebc42014-10-03 10:16:09 -07001396 if (!config_tcache)
Jason Evansd8a39002013-12-19 21:40:41 -08001397 return (ENOENT);
1398
1399 READONLY();
1400 WRITEONLY();
1401
1402 tcache_flush();
1403
1404 ret = 0;
1405label_return:
1406 return (ret);
1407}
Jason Evans3c234352010-01-27 13:10:55 -08001408
Jason Evans602c8e02014-08-18 16:22:13 -07001409static int
Jason Evansb2c0d632016-04-13 23:36:15 -07001410thread_prof_name_ctl(tsd_t *tsd, const size_t *mib, size_t miblen, void *oldp,
Jason Evans602c8e02014-08-18 16:22:13 -07001411 size_t *oldlenp, void *newp, size_t newlen)
1412{
1413 int ret;
Jason Evans602c8e02014-08-18 16:22:13 -07001414
Jason Evans551ebc42014-10-03 10:16:09 -07001415 if (!config_prof)
Jason Evans602c8e02014-08-18 16:22:13 -07001416 return (ENOENT);
1417
Jason Evansfc12c0b2014-10-03 23:25:30 -07001418 READ_XOR_WRITE();
1419
Jason Evans602c8e02014-08-18 16:22:13 -07001420 if (newp != NULL) {
1421 if (newlen != sizeof(const char *)) {
1422 ret = EINVAL;
1423 goto label_return;
1424 }
Jason Evans5460aa62014-09-22 21:09:23 -07001425
Jason Evansfc12c0b2014-10-03 23:25:30 -07001426 if ((ret = prof_thread_name_set(tsd, *(const char **)newp)) !=
1427 0)
Jason Evans602c8e02014-08-18 16:22:13 -07001428 goto label_return;
Jason Evansfc12c0b2014-10-03 23:25:30 -07001429 } else {
Jason Evansb2c0d632016-04-13 23:36:15 -07001430 const char *oldname = prof_thread_name_get(tsd);
Jason Evansfc12c0b2014-10-03 23:25:30 -07001431 READ(oldname, const char *);
Jason Evans602c8e02014-08-18 16:22:13 -07001432 }
Jason Evans602c8e02014-08-18 16:22:13 -07001433
1434 ret = 0;
1435label_return:
1436 return (ret);
1437}
1438
1439static int
Jason Evansb2c0d632016-04-13 23:36:15 -07001440thread_prof_active_ctl(tsd_t *tsd, const size_t *mib, size_t miblen, void *oldp,
Jason Evans602c8e02014-08-18 16:22:13 -07001441 size_t *oldlenp, void *newp, size_t newlen)
1442{
1443 int ret;
1444 bool oldval;
1445
Jason Evans551ebc42014-10-03 10:16:09 -07001446 if (!config_prof)
Jason Evans602c8e02014-08-18 16:22:13 -07001447 return (ENOENT);
1448
Jason Evansb2c0d632016-04-13 23:36:15 -07001449 oldval = prof_thread_active_get(tsd);
Jason Evans602c8e02014-08-18 16:22:13 -07001450 if (newp != NULL) {
1451 if (newlen != sizeof(bool)) {
1452 ret = EINVAL;
1453 goto label_return;
1454 }
Jason Evansb2c0d632016-04-13 23:36:15 -07001455 if (prof_thread_active_set(tsd, *(bool *)newp)) {
Jason Evans602c8e02014-08-18 16:22:13 -07001456 ret = EAGAIN;
1457 goto label_return;
1458 }
1459 }
1460 READ(oldval, bool);
1461
1462 ret = 0;
1463label_return:
1464 return (ret);
1465}
1466
Jason Evans3c234352010-01-27 13:10:55 -08001467/******************************************************************************/
1468
Jason Evans1cb181e2015-01-29 15:30:47 -08001469static int
Jason Evansb2c0d632016-04-13 23:36:15 -07001470tcache_create_ctl(tsd_t *tsd, const size_t *mib, size_t miblen, void *oldp,
1471 size_t *oldlenp, void *newp, size_t newlen)
Jason Evans1cb181e2015-01-29 15:30:47 -08001472{
1473 int ret;
Jason Evans1cb181e2015-01-29 15:30:47 -08001474 unsigned tcache_ind;
1475
1476 if (!config_tcache)
1477 return (ENOENT);
1478
Jason Evansc1e00ef2016-05-10 22:21:10 -07001479 malloc_mutex_lock(tsd_tsdn(tsd), &ctl_mtx);
Jason Evans1cb181e2015-01-29 15:30:47 -08001480 READONLY();
Jason Evans962a2972016-10-20 23:59:12 -07001481 if (tcaches_create(tsd, &tcache_ind)) {
Jason Evans1cb181e2015-01-29 15:30:47 -08001482 ret = EFAULT;
1483 goto label_return;
1484 }
1485 READ(tcache_ind, unsigned);
1486
1487 ret = 0;
1488label_return:
Jason Evansc1e00ef2016-05-10 22:21:10 -07001489 malloc_mutex_unlock(tsd_tsdn(tsd), &ctl_mtx);
Jason Evans1cb181e2015-01-29 15:30:47 -08001490 return (ret);
1491}
1492
1493static int
Jason Evansb2c0d632016-04-13 23:36:15 -07001494tcache_flush_ctl(tsd_t *tsd, const size_t *mib, size_t miblen, void *oldp,
1495 size_t *oldlenp, void *newp, size_t newlen)
Jason Evans1cb181e2015-01-29 15:30:47 -08001496{
1497 int ret;
Jason Evans1cb181e2015-01-29 15:30:47 -08001498 unsigned tcache_ind;
1499
1500 if (!config_tcache)
1501 return (ENOENT);
1502
Jason Evans1cb181e2015-01-29 15:30:47 -08001503 WRITEONLY();
1504 tcache_ind = UINT_MAX;
1505 WRITE(tcache_ind, unsigned);
1506 if (tcache_ind == UINT_MAX) {
1507 ret = EFAULT;
1508 goto label_return;
1509 }
1510 tcaches_flush(tsd, tcache_ind);
1511
1512 ret = 0;
1513label_return:
1514 return (ret);
1515}
1516
1517static int
Jason Evansb2c0d632016-04-13 23:36:15 -07001518tcache_destroy_ctl(tsd_t *tsd, const size_t *mib, size_t miblen, void *oldp,
Jason Evans1cb181e2015-01-29 15:30:47 -08001519 size_t *oldlenp, void *newp, size_t newlen)
1520{
1521 int ret;
Jason Evans1cb181e2015-01-29 15:30:47 -08001522 unsigned tcache_ind;
1523
1524 if (!config_tcache)
1525 return (ENOENT);
1526
Jason Evans1cb181e2015-01-29 15:30:47 -08001527 WRITEONLY();
1528 tcache_ind = UINT_MAX;
1529 WRITE(tcache_ind, unsigned);
1530 if (tcache_ind == UINT_MAX) {
1531 ret = EFAULT;
1532 goto label_return;
1533 }
1534 tcaches_destroy(tsd, tcache_ind);
1535
1536 ret = 0;
1537label_return:
1538 return (ret);
1539}
1540
1541/******************************************************************************/
1542
Jason Evans34457f52012-11-03 21:18:28 -07001543static void
Jason Evansc1e00ef2016-05-10 22:21:10 -07001544arena_i_purge(tsdn_t *tsdn, unsigned arena_ind, bool all)
Jason Evans609ae592012-10-11 13:53:15 -07001545{
Jason Evans609ae592012-10-11 13:53:15 -07001546
Jason Evansc1e00ef2016-05-10 22:21:10 -07001547 malloc_mutex_lock(tsdn, &ctl_mtx);
Jason Evans243f7a02016-02-19 20:09:31 -08001548 {
Jason Evans243f7a02016-02-19 20:09:31 -08001549 unsigned narenas = ctl_stats.narenas;
Jason Evans609ae592012-10-11 13:53:15 -07001550
Jason Evans243f7a02016-02-19 20:09:31 -08001551 if (arena_ind == narenas) {
1552 unsigned i;
Jason Evans243f7a02016-02-19 20:09:31 -08001553 VARIABLE_ARRAY(arena_t *, tarenas, narenas);
1554
Jason Evans767d8502016-02-24 23:58:10 -08001555 for (i = 0; i < narenas; i++)
Jason Evansc1e00ef2016-05-10 22:21:10 -07001556 tarenas[i] = arena_get(tsdn, i, false);
Jason Evans243f7a02016-02-19 20:09:31 -08001557
1558 /*
1559 * No further need to hold ctl_mtx, since narenas and
1560 * tarenas contain everything needed below.
1561 */
Jason Evansc1e00ef2016-05-10 22:21:10 -07001562 malloc_mutex_unlock(tsdn, &ctl_mtx);
Jason Evans243f7a02016-02-19 20:09:31 -08001563
1564 for (i = 0; i < narenas; i++) {
1565 if (tarenas[i] != NULL)
Jason Evansc1e00ef2016-05-10 22:21:10 -07001566 arena_purge(tsdn, tarenas[i], all);
Jason Evans243f7a02016-02-19 20:09:31 -08001567 }
1568 } else {
1569 arena_t *tarena;
1570
1571 assert(arena_ind < narenas);
1572
Jason Evansc1e00ef2016-05-10 22:21:10 -07001573 tarena = arena_get(tsdn, arena_ind, false);
Jason Evans243f7a02016-02-19 20:09:31 -08001574
1575 /* No further need to hold ctl_mtx. */
Jason Evansc1e00ef2016-05-10 22:21:10 -07001576 malloc_mutex_unlock(tsdn, &ctl_mtx);
Jason Evans243f7a02016-02-19 20:09:31 -08001577
1578 if (tarena != NULL)
Jason Evansc1e00ef2016-05-10 22:21:10 -07001579 arena_purge(tsdn, tarena, all);
Jason Evans609ae592012-10-11 13:53:15 -07001580 }
1581 }
Jason Evans609ae592012-10-11 13:53:15 -07001582}
1583
1584static int
Jason Evansb2c0d632016-04-13 23:36:15 -07001585arena_i_purge_ctl(tsd_t *tsd, const size_t *mib, size_t miblen, void *oldp,
1586 size_t *oldlenp, void *newp, size_t newlen)
Jason Evans609ae592012-10-11 13:53:15 -07001587{
1588 int ret;
1589
1590 READONLY();
1591 WRITEONLY();
Jason Evansc1e00ef2016-05-10 22:21:10 -07001592 arena_i_purge(tsd_tsdn(tsd), (unsigned)mib[1], true);
Jason Evans243f7a02016-02-19 20:09:31 -08001593
1594 ret = 0;
1595label_return:
1596 return (ret);
1597}
1598
1599static int
Jason Evansb2c0d632016-04-13 23:36:15 -07001600arena_i_decay_ctl(tsd_t *tsd, const size_t *mib, size_t miblen, void *oldp,
1601 size_t *oldlenp, void *newp, size_t newlen)
Jason Evans243f7a02016-02-19 20:09:31 -08001602{
1603 int ret;
1604
1605 READONLY();
1606 WRITEONLY();
Jason Evansc1e00ef2016-05-10 22:21:10 -07001607 arena_i_purge(tsd_tsdn(tsd), (unsigned)mib[1], false);
Jason Evans609ae592012-10-11 13:53:15 -07001608
Jason Evans34457f52012-11-03 21:18:28 -07001609 ret = 0;
Jason Evans609ae592012-10-11 13:53:15 -07001610label_return:
1611 return (ret);
1612}
1613
1614static int
Jason Evans19ff2ce2016-04-22 14:37:17 -07001615arena_i_reset_ctl(tsd_t *tsd, const size_t *mib, size_t miblen, void *oldp,
1616 size_t *oldlenp, void *newp, size_t newlen)
1617{
1618 int ret;
1619 unsigned arena_ind;
1620 arena_t *arena;
1621
1622 READONLY();
1623 WRITEONLY();
1624
1625 if ((config_valgrind && unlikely(in_valgrind)) || (config_fill &&
1626 unlikely(opt_quarantine))) {
1627 ret = EFAULT;
1628 goto label_return;
1629 }
1630
1631 arena_ind = (unsigned)mib[1];
1632 if (config_debug) {
Jason Evansc1e00ef2016-05-10 22:21:10 -07001633 malloc_mutex_lock(tsd_tsdn(tsd), &ctl_mtx);
Jason Evans19ff2ce2016-04-22 14:37:17 -07001634 assert(arena_ind < ctl_stats.narenas);
Jason Evansc1e00ef2016-05-10 22:21:10 -07001635 malloc_mutex_unlock(tsd_tsdn(tsd), &ctl_mtx);
Jason Evans19ff2ce2016-04-22 14:37:17 -07001636 }
1637 assert(arena_ind >= opt_narenas);
1638
Jason Evansc1e00ef2016-05-10 22:21:10 -07001639 arena = arena_get(tsd_tsdn(tsd), arena_ind, false);
Jason Evans19ff2ce2016-04-22 14:37:17 -07001640
1641 arena_reset(tsd, arena);
1642
1643 ret = 0;
1644label_return:
1645 return (ret);
1646}
1647
1648static int
Jason Evansb2c0d632016-04-13 23:36:15 -07001649arena_i_dss_ctl(tsd_t *tsd, const size_t *mib, size_t miblen, void *oldp,
1650 size_t *oldlenp, void *newp, size_t newlen)
Jason Evans609ae592012-10-11 13:53:15 -07001651{
Jason Evans586c8ed2014-08-15 12:20:20 -07001652 int ret;
1653 const char *dss = NULL;
Jason Evans8dd51152016-02-24 11:00:40 -08001654 unsigned arena_ind = (unsigned)mib[1];
Jason Evans609ae592012-10-11 13:53:15 -07001655 dss_prec_t dss_prec_old = dss_prec_limit;
1656 dss_prec_t dss_prec = dss_prec_limit;
1657
Jason Evansc1e00ef2016-05-10 22:21:10 -07001658 malloc_mutex_lock(tsd_tsdn(tsd), &ctl_mtx);
Jason Evans609ae592012-10-11 13:53:15 -07001659 WRITE(dss, const char *);
Jason Evans586c8ed2014-08-15 12:20:20 -07001660 if (dss != NULL) {
1661 int i;
1662 bool match = false;
1663
1664 for (i = 0; i < dss_prec_limit; i++) {
1665 if (strcmp(dss_prec_names[i], dss) == 0) {
1666 dss_prec = i;
1667 match = true;
1668 break;
1669 }
Jason Evans609ae592012-10-11 13:53:15 -07001670 }
Jason Evans586c8ed2014-08-15 12:20:20 -07001671
Jason Evans551ebc42014-10-03 10:16:09 -07001672 if (!match) {
Jason Evans586c8ed2014-08-15 12:20:20 -07001673 ret = EINVAL;
1674 goto label_return;
1675 }
Jason Evans609ae592012-10-11 13:53:15 -07001676 }
1677
1678 if (arena_ind < ctl_stats.narenas) {
Jason Evansc1e00ef2016-05-10 22:21:10 -07001679 arena_t *arena = arena_get(tsd_tsdn(tsd), arena_ind, false);
Jason Evans586c8ed2014-08-15 12:20:20 -07001680 if (arena == NULL || (dss_prec != dss_prec_limit &&
Jason Evansc1e00ef2016-05-10 22:21:10 -07001681 arena_dss_prec_set(tsd_tsdn(tsd), arena, dss_prec))) {
Jason Evans586c8ed2014-08-15 12:20:20 -07001682 ret = EFAULT;
1683 goto label_return;
1684 }
Jason Evansc1e00ef2016-05-10 22:21:10 -07001685 dss_prec_old = arena_dss_prec_get(tsd_tsdn(tsd), arena);
Jason Evans609ae592012-10-11 13:53:15 -07001686 } else {
Jason Evans586c8ed2014-08-15 12:20:20 -07001687 if (dss_prec != dss_prec_limit &&
Jason Evanse2bcf032016-10-13 12:18:38 -07001688 chunk_dss_prec_set(dss_prec)) {
Jason Evans586c8ed2014-08-15 12:20:20 -07001689 ret = EFAULT;
1690 goto label_return;
1691 }
Jason Evanse2bcf032016-10-13 12:18:38 -07001692 dss_prec_old = chunk_dss_prec_get();
Jason Evans609ae592012-10-11 13:53:15 -07001693 }
Jason Evans586c8ed2014-08-15 12:20:20 -07001694
Jason Evans609ae592012-10-11 13:53:15 -07001695 dss = dss_prec_names[dss_prec_old];
1696 READ(dss, const char *);
Jason Evans609ae592012-10-11 13:53:15 -07001697
1698 ret = 0;
1699label_return:
Jason Evansc1e00ef2016-05-10 22:21:10 -07001700 malloc_mutex_unlock(tsd_tsdn(tsd), &ctl_mtx);
Jason Evans609ae592012-10-11 13:53:15 -07001701 return (ret);
1702}
1703
aravindfb7fe502014-05-05 15:16:56 -07001704static int
Jason Evansb2c0d632016-04-13 23:36:15 -07001705arena_i_lg_dirty_mult_ctl(tsd_t *tsd, const size_t *mib, size_t miblen,
1706 void *oldp, size_t *oldlenp, void *newp, size_t newlen)
aravindfb7fe502014-05-05 15:16:56 -07001707{
1708 int ret;
Jason Evans8dd51152016-02-24 11:00:40 -08001709 unsigned arena_ind = (unsigned)mib[1];
aravindfb7fe502014-05-05 15:16:56 -07001710 arena_t *arena;
1711
Jason Evansc1e00ef2016-05-10 22:21:10 -07001712 arena = arena_get(tsd_tsdn(tsd), arena_ind, false);
Jason Evans8d6a3e82015-03-18 18:55:33 -07001713 if (arena == NULL) {
aravindfb7fe502014-05-05 15:16:56 -07001714 ret = EFAULT;
Jason Evans8d6a3e82015-03-18 18:55:33 -07001715 goto label_return;
aravindfb7fe502014-05-05 15:16:56 -07001716 }
Jason Evans8d6a3e82015-03-18 18:55:33 -07001717
1718 if (oldp != NULL && oldlenp != NULL) {
Jason Evansc1e00ef2016-05-10 22:21:10 -07001719 size_t oldval = arena_lg_dirty_mult_get(tsd_tsdn(tsd), arena);
Jason Evans8d6a3e82015-03-18 18:55:33 -07001720 READ(oldval, ssize_t);
1721 }
1722 if (newp != NULL) {
1723 if (newlen != sizeof(ssize_t)) {
1724 ret = EINVAL;
1725 goto label_return;
1726 }
Jason Evansc1e00ef2016-05-10 22:21:10 -07001727 if (arena_lg_dirty_mult_set(tsd_tsdn(tsd), arena,
1728 *(ssize_t *)newp)) {
Jason Evans8d6a3e82015-03-18 18:55:33 -07001729 ret = EFAULT;
1730 goto label_return;
1731 }
1732 }
1733
aravindfb7fe502014-05-05 15:16:56 -07001734 ret = 0;
1735label_return:
aravindfb7fe502014-05-05 15:16:56 -07001736 return (ret);
1737}
1738
Jason Evansb49a3342015-07-28 11:28:19 -04001739static int
Jason Evansb2c0d632016-04-13 23:36:15 -07001740arena_i_decay_time_ctl(tsd_t *tsd, const size_t *mib, size_t miblen, void *oldp,
Jason Evans243f7a02016-02-19 20:09:31 -08001741 size_t *oldlenp, void *newp, size_t newlen)
1742{
1743 int ret;
Jason Evans8dd51152016-02-24 11:00:40 -08001744 unsigned arena_ind = (unsigned)mib[1];
Jason Evans243f7a02016-02-19 20:09:31 -08001745 arena_t *arena;
1746
Jason Evansc1e00ef2016-05-10 22:21:10 -07001747 arena = arena_get(tsd_tsdn(tsd), arena_ind, false);
Jason Evans243f7a02016-02-19 20:09:31 -08001748 if (arena == NULL) {
1749 ret = EFAULT;
1750 goto label_return;
1751 }
1752
1753 if (oldp != NULL && oldlenp != NULL) {
Jason Evansc1e00ef2016-05-10 22:21:10 -07001754 size_t oldval = arena_decay_time_get(tsd_tsdn(tsd), arena);
Jason Evans243f7a02016-02-19 20:09:31 -08001755 READ(oldval, ssize_t);
1756 }
1757 if (newp != NULL) {
1758 if (newlen != sizeof(ssize_t)) {
1759 ret = EINVAL;
1760 goto label_return;
1761 }
Jason Evansc1e00ef2016-05-10 22:21:10 -07001762 if (arena_decay_time_set(tsd_tsdn(tsd), arena,
1763 *(ssize_t *)newp)) {
Jason Evans243f7a02016-02-19 20:09:31 -08001764 ret = EFAULT;
1765 goto label_return;
1766 }
1767 }
1768
1769 ret = 0;
1770label_return:
1771 return (ret);
1772}
1773
1774static int
Jason Evansb2c0d632016-04-13 23:36:15 -07001775arena_i_chunk_hooks_ctl(tsd_t *tsd, const size_t *mib, size_t miblen,
1776 void *oldp, size_t *oldlenp, void *newp, size_t newlen)
Jason Evansb49a3342015-07-28 11:28:19 -04001777{
1778 int ret;
Jason Evans8dd51152016-02-24 11:00:40 -08001779 unsigned arena_ind = (unsigned)mib[1];
Jason Evansb49a3342015-07-28 11:28:19 -04001780 arena_t *arena;
1781
Jason Evansc1e00ef2016-05-10 22:21:10 -07001782 malloc_mutex_lock(tsd_tsdn(tsd), &ctl_mtx);
Jason Evansb49a3342015-07-28 11:28:19 -04001783 if (arena_ind < narenas_total_get() && (arena =
Jason Evansc1e00ef2016-05-10 22:21:10 -07001784 arena_get(tsd_tsdn(tsd), arena_ind, false)) != NULL) {
Jason Evansb49a3342015-07-28 11:28:19 -04001785 if (newp != NULL) {
1786 chunk_hooks_t old_chunk_hooks, new_chunk_hooks;
1787 WRITE(new_chunk_hooks, chunk_hooks_t);
Jason Evansc1e00ef2016-05-10 22:21:10 -07001788 old_chunk_hooks = chunk_hooks_set(tsd_tsdn(tsd), arena,
Jason Evansb49a3342015-07-28 11:28:19 -04001789 &new_chunk_hooks);
1790 READ(old_chunk_hooks, chunk_hooks_t);
1791 } else {
Jason Evansc1e00ef2016-05-10 22:21:10 -07001792 chunk_hooks_t old_chunk_hooks =
1793 chunk_hooks_get(tsd_tsdn(tsd), arena);
Jason Evansb49a3342015-07-28 11:28:19 -04001794 READ(old_chunk_hooks, chunk_hooks_t);
1795 }
1796 } else {
1797 ret = EFAULT;
1798 goto label_return;
1799 }
1800 ret = 0;
1801label_return:
Jason Evansc1e00ef2016-05-10 22:21:10 -07001802 malloc_mutex_unlock(tsd_tsdn(tsd), &ctl_mtx);
Jason Evansb49a3342015-07-28 11:28:19 -04001803 return (ret);
aravindfb7fe502014-05-05 15:16:56 -07001804}
1805
Jason Evans609ae592012-10-11 13:53:15 -07001806static const ctl_named_node_t *
Jason Evansc1e00ef2016-05-10 22:21:10 -07001807arena_i_index(tsdn_t *tsdn, const size_t *mib, size_t miblen, size_t i)
Jason Evans609ae592012-10-11 13:53:15 -07001808{
Jason Evansb2c0d632016-04-13 23:36:15 -07001809 const ctl_named_node_t *ret;
Jason Evans609ae592012-10-11 13:53:15 -07001810
Jason Evansc1e00ef2016-05-10 22:21:10 -07001811 malloc_mutex_lock(tsdn, &ctl_mtx);
Jason Evans609ae592012-10-11 13:53:15 -07001812 if (i > ctl_stats.narenas) {
1813 ret = NULL;
1814 goto label_return;
1815 }
1816
1817 ret = super_arena_i_node;
1818label_return:
Jason Evansc1e00ef2016-05-10 22:21:10 -07001819 malloc_mutex_unlock(tsdn, &ctl_mtx);
Jason Evans609ae592012-10-11 13:53:15 -07001820 return (ret);
1821}
1822
Jason Evans609ae592012-10-11 13:53:15 -07001823/******************************************************************************/
1824
Jason Evans609ae592012-10-11 13:53:15 -07001825static int
Jason Evansb2c0d632016-04-13 23:36:15 -07001826arenas_narenas_ctl(tsd_t *tsd, const size_t *mib, size_t miblen, void *oldp,
Jason Evans609ae592012-10-11 13:53:15 -07001827 size_t *oldlenp, void *newp, size_t newlen)
1828{
1829 int ret;
1830 unsigned narenas;
1831
Jason Evansc1e00ef2016-05-10 22:21:10 -07001832 malloc_mutex_lock(tsd_tsdn(tsd), &ctl_mtx);
Jason Evans609ae592012-10-11 13:53:15 -07001833 READONLY();
1834 if (*oldlenp != sizeof(unsigned)) {
1835 ret = EINVAL;
1836 goto label_return;
1837 }
1838 narenas = ctl_stats.narenas;
1839 READ(narenas, unsigned);
1840
1841 ret = 0;
1842label_return:
Jason Evansc1e00ef2016-05-10 22:21:10 -07001843 malloc_mutex_unlock(tsd_tsdn(tsd), &ctl_mtx);
Jason Evans609ae592012-10-11 13:53:15 -07001844 return (ret);
1845}
Jason Evans3c234352010-01-27 13:10:55 -08001846
1847static int
Jason Evansb2c0d632016-04-13 23:36:15 -07001848arenas_initialized_ctl(tsd_t *tsd, const size_t *mib, size_t miblen, void *oldp,
Jason Evans3c234352010-01-27 13:10:55 -08001849 size_t *oldlenp, void *newp, size_t newlen)
1850{
1851 int ret;
1852 unsigned nread, i;
1853
Jason Evansc1e00ef2016-05-10 22:21:10 -07001854 malloc_mutex_lock(tsd_tsdn(tsd), &ctl_mtx);
Jason Evans3c234352010-01-27 13:10:55 -08001855 READONLY();
Jason Evans609ae592012-10-11 13:53:15 -07001856 if (*oldlenp != ctl_stats.narenas * sizeof(bool)) {
Jason Evans3c234352010-01-27 13:10:55 -08001857 ret = EINVAL;
Jason Evans609ae592012-10-11 13:53:15 -07001858 nread = (*oldlenp < ctl_stats.narenas * sizeof(bool))
Jason Evans8dd51152016-02-24 11:00:40 -08001859 ? (unsigned)(*oldlenp / sizeof(bool)) : ctl_stats.narenas;
Jason Evans3c234352010-01-27 13:10:55 -08001860 } else {
1861 ret = 0;
Jason Evans609ae592012-10-11 13:53:15 -07001862 nread = ctl_stats.narenas;
Jason Evans3c234352010-01-27 13:10:55 -08001863 }
1864
1865 for (i = 0; i < nread; i++)
1866 ((bool *)oldp)[i] = ctl_stats.arenas[i].initialized;
1867
Jason Evansa1ee7832012-04-10 15:07:44 -07001868label_return:
Jason Evansc1e00ef2016-05-10 22:21:10 -07001869 malloc_mutex_unlock(tsd_tsdn(tsd), &ctl_mtx);
Jason Evans3c234352010-01-27 13:10:55 -08001870 return (ret);
1871}
1872
Jason Evans8d6a3e82015-03-18 18:55:33 -07001873static int
Jason Evansb2c0d632016-04-13 23:36:15 -07001874arenas_lg_dirty_mult_ctl(tsd_t *tsd, const size_t *mib, size_t miblen,
1875 void *oldp, size_t *oldlenp, void *newp, size_t newlen)
Jason Evans8d6a3e82015-03-18 18:55:33 -07001876{
1877 int ret;
1878
1879 if (oldp != NULL && oldlenp != NULL) {
1880 size_t oldval = arena_lg_dirty_mult_default_get();
1881 READ(oldval, ssize_t);
1882 }
1883 if (newp != NULL) {
1884 if (newlen != sizeof(ssize_t)) {
1885 ret = EINVAL;
1886 goto label_return;
1887 }
1888 if (arena_lg_dirty_mult_default_set(*(ssize_t *)newp)) {
1889 ret = EFAULT;
1890 goto label_return;
1891 }
1892 }
1893
1894 ret = 0;
1895label_return:
1896 return (ret);
1897}
1898
Jason Evans243f7a02016-02-19 20:09:31 -08001899static int
Jason Evansb2c0d632016-04-13 23:36:15 -07001900arenas_decay_time_ctl(tsd_t *tsd, const size_t *mib, size_t miblen, void *oldp,
Jason Evans243f7a02016-02-19 20:09:31 -08001901 size_t *oldlenp, void *newp, size_t newlen)
1902{
1903 int ret;
1904
1905 if (oldp != NULL && oldlenp != NULL) {
1906 size_t oldval = arena_decay_time_default_get();
1907 READ(oldval, ssize_t);
1908 }
1909 if (newp != NULL) {
1910 if (newlen != sizeof(ssize_t)) {
1911 ret = EINVAL;
1912 goto label_return;
1913 }
1914 if (arena_decay_time_default_set(*(ssize_t *)newp)) {
1915 ret = EFAULT;
1916 goto label_return;
1917 }
1918 }
1919
1920 ret = 0;
1921label_return:
1922 return (ret);
1923}
1924
Jason Evansfc4dcfa2010-11-24 15:44:21 -08001925CTL_RO_NL_GEN(arenas_quantum, QUANTUM, size_t)
Jason Evansae4c7b42012-04-02 07:04:34 -07001926CTL_RO_NL_GEN(arenas_page, PAGE, size_t)
Jason Evans7372b152012-02-10 20:22:09 -08001927CTL_RO_NL_CGEN(config_tcache, arenas_tcache_max, tcache_maxclass, size_t)
Jason Evansb1726102012-02-28 16:50:47 -08001928CTL_RO_NL_GEN(arenas_nbins, NBINS, unsigned)
Jason Evans7372b152012-02-10 20:22:09 -08001929CTL_RO_NL_CGEN(config_tcache, arenas_nhbins, nhbins, unsigned)
Jason Evansd8a39002013-12-19 21:40:41 -08001930CTL_RO_NL_GEN(arenas_bin_i_size, arena_bin_info[mib[2]].reg_size, size_t)
1931CTL_RO_NL_GEN(arenas_bin_i_nregs, arena_bin_info[mib[2]].nregs, uint32_t)
1932CTL_RO_NL_GEN(arenas_bin_i_run_size, arena_bin_info[mib[2]].run_size, size_t)
1933static const ctl_named_node_t *
Jason Evansc1e00ef2016-05-10 22:21:10 -07001934arenas_bin_i_index(tsdn_t *tsdn, const size_t *mib, size_t miblen, size_t i)
Jason Evansd8a39002013-12-19 21:40:41 -08001935{
1936
1937 if (i > NBINS)
1938 return (NULL);
1939 return (super_arenas_bin_i_node);
1940}
1941
Jason Evans3c4d92e2014-10-12 22:53:59 -07001942CTL_RO_NL_GEN(arenas_nlruns, nlclasses, unsigned)
Jason Evans9e1810c2016-02-24 12:42:23 -08001943CTL_RO_NL_GEN(arenas_lrun_i_size, index2size(NBINS+(szind_t)mib[2]), size_t)
Jason Evansd8a39002013-12-19 21:40:41 -08001944static const ctl_named_node_t *
Jason Evansc1e00ef2016-05-10 22:21:10 -07001945arenas_lrun_i_index(tsdn_t *tsdn, const size_t *mib, size_t miblen, size_t i)
Jason Evansd8a39002013-12-19 21:40:41 -08001946{
1947
1948 if (i > nlclasses)
1949 return (NULL);
1950 return (super_arenas_lrun_i_node);
1951}
Jason Evans3c234352010-01-27 13:10:55 -08001952
Jason Evans3c4d92e2014-10-12 22:53:59 -07001953CTL_RO_NL_GEN(arenas_nhchunks, nhclasses, unsigned)
Jason Evans9e1810c2016-02-24 12:42:23 -08001954CTL_RO_NL_GEN(arenas_hchunk_i_size, index2size(NBINS+nlclasses+(szind_t)mib[2]),
1955 size_t)
Jason Evans3c4d92e2014-10-12 22:53:59 -07001956static const ctl_named_node_t *
Jason Evansc1e00ef2016-05-10 22:21:10 -07001957arenas_hchunk_i_index(tsdn_t *tsdn, const size_t *mib, size_t miblen, size_t i)
Jason Evans3c4d92e2014-10-12 22:53:59 -07001958{
1959
1960 if (i > nhclasses)
1961 return (NULL);
1962 return (super_arenas_hchunk_i_node);
1963}
1964
Jason Evans6005f072010-09-30 16:55:08 -07001965static int
Jason Evansb2c0d632016-04-13 23:36:15 -07001966arenas_extend_ctl(tsd_t *tsd, const size_t *mib, size_t miblen, void *oldp,
1967 size_t *oldlenp, void *newp, size_t newlen)
Jason Evans609ae592012-10-11 13:53:15 -07001968{
1969 int ret;
Jason Evans6eb84fb2012-11-29 22:13:04 -08001970 unsigned narenas;
Jason Evans609ae592012-10-11 13:53:15 -07001971
Jason Evansc1e00ef2016-05-10 22:21:10 -07001972 malloc_mutex_lock(tsd_tsdn(tsd), &ctl_mtx);
Jason Evans609ae592012-10-11 13:53:15 -07001973 READONLY();
Jason Evansc1e00ef2016-05-10 22:21:10 -07001974 if (ctl_grow(tsd_tsdn(tsd))) {
Jason Evans609ae592012-10-11 13:53:15 -07001975 ret = EAGAIN;
1976 goto label_return;
1977 }
Jason Evans6eb84fb2012-11-29 22:13:04 -08001978 narenas = ctl_stats.narenas - 1;
1979 READ(narenas, unsigned);
Jason Evans609ae592012-10-11 13:53:15 -07001980
Jason Evans6005f072010-09-30 16:55:08 -07001981 ret = 0;
Jason Evansa1ee7832012-04-10 15:07:44 -07001982label_return:
Jason Evansc1e00ef2016-05-10 22:21:10 -07001983 malloc_mutex_unlock(tsd_tsdn(tsd), &ctl_mtx);
Jason Evans6005f072010-09-30 16:55:08 -07001984 return (ret);
1985}
1986
Jason Evans3c234352010-01-27 13:10:55 -08001987/******************************************************************************/
1988
Jason Evansd34f9e72010-02-11 13:19:21 -08001989static int
Jason Evansb2c0d632016-04-13 23:36:15 -07001990prof_thread_active_init_ctl(tsd_t *tsd, const size_t *mib, size_t miblen,
1991 void *oldp, size_t *oldlenp, void *newp, size_t newlen)
1992{
1993 int ret;
1994 bool oldval;
1995
1996 if (!config_prof)
1997 return (ENOENT);
1998
1999 if (newp != NULL) {
2000 if (newlen != sizeof(bool)) {
2001 ret = EINVAL;
2002 goto label_return;
2003 }
Jason Evansc1e00ef2016-05-10 22:21:10 -07002004 oldval = prof_thread_active_init_set(tsd_tsdn(tsd),
2005 *(bool *)newp);
Jason Evansb2c0d632016-04-13 23:36:15 -07002006 } else
Jason Evansc1e00ef2016-05-10 22:21:10 -07002007 oldval = prof_thread_active_init_get(tsd_tsdn(tsd));
Jason Evansb2c0d632016-04-13 23:36:15 -07002008 READ(oldval, bool);
2009
2010 ret = 0;
2011label_return:
2012 return (ret);
2013}
2014
2015static int
2016prof_active_ctl(tsd_t *tsd, const size_t *mib, size_t miblen, void *oldp,
Jason Evansfc12c0b2014-10-03 23:25:30 -07002017 size_t *oldlenp, void *newp, size_t newlen)
2018{
2019 int ret;
2020 bool oldval;
2021
2022 if (!config_prof)
2023 return (ENOENT);
2024
2025 if (newp != NULL) {
2026 if (newlen != sizeof(bool)) {
2027 ret = EINVAL;
2028 goto label_return;
2029 }
Jason Evansc1e00ef2016-05-10 22:21:10 -07002030 oldval = prof_active_set(tsd_tsdn(tsd), *(bool *)newp);
Jason Evansfc12c0b2014-10-03 23:25:30 -07002031 } else
Jason Evansc1e00ef2016-05-10 22:21:10 -07002032 oldval = prof_active_get(tsd_tsdn(tsd));
Jason Evansfc12c0b2014-10-03 23:25:30 -07002033 READ(oldval, bool);
2034
2035 ret = 0;
2036label_return:
2037 return (ret);
2038}
2039
2040static int
Jason Evansb2c0d632016-04-13 23:36:15 -07002041prof_dump_ctl(tsd_t *tsd, const size_t *mib, size_t miblen, void *oldp,
2042 size_t *oldlenp, void *newp, size_t newlen)
Jason Evansd34f9e72010-02-11 13:19:21 -08002043{
2044 int ret;
Jason Evans22ca8552010-03-02 11:57:30 -08002045 const char *filename = NULL;
Jason Evansd34f9e72010-02-11 13:19:21 -08002046
Jason Evans551ebc42014-10-03 10:16:09 -07002047 if (!config_prof)
Jason Evans7372b152012-02-10 20:22:09 -08002048 return (ENOENT);
2049
Jason Evans22ca8552010-03-02 11:57:30 -08002050 WRITEONLY();
2051 WRITE(filename, const char *);
Jason Evansd34f9e72010-02-11 13:19:21 -08002052
Jason Evansb2c0d632016-04-13 23:36:15 -07002053 if (prof_mdump(tsd, filename)) {
Jason Evans22ca8552010-03-02 11:57:30 -08002054 ret = EFAULT;
Jason Evansa1ee7832012-04-10 15:07:44 -07002055 goto label_return;
Jason Evans22ca8552010-03-02 11:57:30 -08002056 }
Jason Evansd34f9e72010-02-11 13:19:21 -08002057
2058 ret = 0;
Jason Evansa1ee7832012-04-10 15:07:44 -07002059label_return:
Jason Evansd34f9e72010-02-11 13:19:21 -08002060 return (ret);
2061}
2062
Jason Evans602c8e02014-08-18 16:22:13 -07002063static int
Jason Evansb2c0d632016-04-13 23:36:15 -07002064prof_gdump_ctl(tsd_t *tsd, const size_t *mib, size_t miblen, void *oldp,
2065 size_t *oldlenp, void *newp, size_t newlen)
Jason Evans5b8ed5b2015-01-25 21:16:57 -08002066{
2067 int ret;
2068 bool oldval;
2069
2070 if (!config_prof)
2071 return (ENOENT);
2072
2073 if (newp != NULL) {
2074 if (newlen != sizeof(bool)) {
2075 ret = EINVAL;
2076 goto label_return;
2077 }
Jason Evansc1e00ef2016-05-10 22:21:10 -07002078 oldval = prof_gdump_set(tsd_tsdn(tsd), *(bool *)newp);
Jason Evans5b8ed5b2015-01-25 21:16:57 -08002079 } else
Jason Evansc1e00ef2016-05-10 22:21:10 -07002080 oldval = prof_gdump_get(tsd_tsdn(tsd));
Jason Evans5b8ed5b2015-01-25 21:16:57 -08002081 READ(oldval, bool);
2082
2083 ret = 0;
2084label_return:
2085 return (ret);
2086}
2087
2088static int
Jason Evansb2c0d632016-04-13 23:36:15 -07002089prof_reset_ctl(tsd_t *tsd, const size_t *mib, size_t miblen, void *oldp,
2090 size_t *oldlenp, void *newp, size_t newlen)
Jason Evans602c8e02014-08-18 16:22:13 -07002091{
2092 int ret;
2093 size_t lg_sample = lg_prof_sample;
2094
Jason Evans551ebc42014-10-03 10:16:09 -07002095 if (!config_prof)
Jason Evans602c8e02014-08-18 16:22:13 -07002096 return (ENOENT);
2097
2098 WRITEONLY();
2099 WRITE(lg_sample, size_t);
2100 if (lg_sample >= (sizeof(uint64_t) << 3))
2101 lg_sample = (sizeof(uint64_t) << 3) - 1;
2102
Jason Evans962a2972016-10-20 23:59:12 -07002103 prof_reset(tsd, lg_sample);
Jason Evans602c8e02014-08-18 16:22:13 -07002104
2105 ret = 0;
2106label_return:
2107 return (ret);
2108}
2109
Jason Evans7372b152012-02-10 20:22:09 -08002110CTL_RO_NL_CGEN(config_prof, prof_interval, prof_interval, uint64_t)
Jason Evans602c8e02014-08-18 16:22:13 -07002111CTL_RO_NL_CGEN(config_prof, lg_prof_sample, lg_prof_sample, size_t)
Jason Evansd34f9e72010-02-11 13:19:21 -08002112
2113/******************************************************************************/
2114
Jason Evansd8a39002013-12-19 21:40:41 -08002115CTL_RO_CGEN(config_stats, stats_cactive, &stats_cactive, size_t *)
2116CTL_RO_CGEN(config_stats, stats_allocated, ctl_stats.allocated, size_t)
2117CTL_RO_CGEN(config_stats, stats_active, ctl_stats.active, size_t)
Jason Evans4581b972014-11-27 17:22:36 -02002118CTL_RO_CGEN(config_stats, stats_metadata, ctl_stats.metadata, size_t)
Jason Evans4acd75a2015-03-23 17:25:57 -07002119CTL_RO_CGEN(config_stats, stats_resident, ctl_stats.resident, size_t)
Jason Evansd8a39002013-12-19 21:40:41 -08002120CTL_RO_CGEN(config_stats, stats_mapped, ctl_stats.mapped, size_t)
Jason Evans04c3c0f2016-05-03 22:11:35 -07002121CTL_RO_CGEN(config_stats, stats_retained, ctl_stats.retained, size_t)
Jason Evansd8a39002013-12-19 21:40:41 -08002122
Jason Evansd8a39002013-12-19 21:40:41 -08002123CTL_RO_GEN(stats_arenas_i_dss, ctl_stats.arenas[mib[2]].dss, const char *)
Jason Evans562d2662015-03-24 16:36:12 -07002124CTL_RO_GEN(stats_arenas_i_lg_dirty_mult, ctl_stats.arenas[mib[2]].lg_dirty_mult,
2125 ssize_t)
Jason Evans243f7a02016-02-19 20:09:31 -08002126CTL_RO_GEN(stats_arenas_i_decay_time, ctl_stats.arenas[mib[2]].decay_time,
2127 ssize_t)
Jason Evansd8a39002013-12-19 21:40:41 -08002128CTL_RO_GEN(stats_arenas_i_nthreads, ctl_stats.arenas[mib[2]].nthreads, unsigned)
2129CTL_RO_GEN(stats_arenas_i_pactive, ctl_stats.arenas[mib[2]].pactive, size_t)
2130CTL_RO_GEN(stats_arenas_i_pdirty, ctl_stats.arenas[mib[2]].pdirty, size_t)
2131CTL_RO_CGEN(config_stats, stats_arenas_i_mapped,
2132 ctl_stats.arenas[mib[2]].astats.mapped, size_t)
Jason Evans04c3c0f2016-05-03 22:11:35 -07002133CTL_RO_CGEN(config_stats, stats_arenas_i_retained,
2134 ctl_stats.arenas[mib[2]].astats.retained, size_t)
Jason Evansd8a39002013-12-19 21:40:41 -08002135CTL_RO_CGEN(config_stats, stats_arenas_i_npurge,
2136 ctl_stats.arenas[mib[2]].astats.npurge, uint64_t)
2137CTL_RO_CGEN(config_stats, stats_arenas_i_nmadvise,
2138 ctl_stats.arenas[mib[2]].astats.nmadvise, uint64_t)
2139CTL_RO_CGEN(config_stats, stats_arenas_i_purged,
2140 ctl_stats.arenas[mib[2]].astats.purged, uint64_t)
Jason Evans4581b972014-11-27 17:22:36 -02002141CTL_RO_CGEN(config_stats, stats_arenas_i_metadata_mapped,
2142 ctl_stats.arenas[mib[2]].astats.metadata_mapped, size_t)
2143CTL_RO_CGEN(config_stats, stats_arenas_i_metadata_allocated,
2144 ctl_stats.arenas[mib[2]].astats.metadata_allocated, size_t)
Jason Evansd8a39002013-12-19 21:40:41 -08002145
Jason Evans7372b152012-02-10 20:22:09 -08002146CTL_RO_CGEN(config_stats, stats_arenas_i_small_allocated,
Jason Evans86815df2010-03-13 20:32:56 -08002147 ctl_stats.arenas[mib[2]].allocated_small, size_t)
Jason Evans7372b152012-02-10 20:22:09 -08002148CTL_RO_CGEN(config_stats, stats_arenas_i_small_nmalloc,
Jason Evans86815df2010-03-13 20:32:56 -08002149 ctl_stats.arenas[mib[2]].nmalloc_small, uint64_t)
Jason Evans7372b152012-02-10 20:22:09 -08002150CTL_RO_CGEN(config_stats, stats_arenas_i_small_ndalloc,
Jason Evans86815df2010-03-13 20:32:56 -08002151 ctl_stats.arenas[mib[2]].ndalloc_small, uint64_t)
Jason Evans7372b152012-02-10 20:22:09 -08002152CTL_RO_CGEN(config_stats, stats_arenas_i_small_nrequests,
Jason Evans86815df2010-03-13 20:32:56 -08002153 ctl_stats.arenas[mib[2]].nrequests_small, uint64_t)
Jason Evans7372b152012-02-10 20:22:09 -08002154CTL_RO_CGEN(config_stats, stats_arenas_i_large_allocated,
Jason Evans3c234352010-01-27 13:10:55 -08002155 ctl_stats.arenas[mib[2]].astats.allocated_large, size_t)
Jason Evans7372b152012-02-10 20:22:09 -08002156CTL_RO_CGEN(config_stats, stats_arenas_i_large_nmalloc,
Jason Evans3c234352010-01-27 13:10:55 -08002157 ctl_stats.arenas[mib[2]].astats.nmalloc_large, uint64_t)
Jason Evans7372b152012-02-10 20:22:09 -08002158CTL_RO_CGEN(config_stats, stats_arenas_i_large_ndalloc,
Jason Evans3c234352010-01-27 13:10:55 -08002159 ctl_stats.arenas[mib[2]].astats.ndalloc_large, uint64_t)
Jason Evans7372b152012-02-10 20:22:09 -08002160CTL_RO_CGEN(config_stats, stats_arenas_i_large_nrequests,
Jason Evansdafde142010-03-17 16:27:39 -07002161 ctl_stats.arenas[mib[2]].astats.nrequests_large, uint64_t)
Jason Evanse2deab72014-05-15 22:22:27 -07002162CTL_RO_CGEN(config_stats, stats_arenas_i_huge_allocated,
2163 ctl_stats.arenas[mib[2]].astats.allocated_huge, size_t)
2164CTL_RO_CGEN(config_stats, stats_arenas_i_huge_nmalloc,
2165 ctl_stats.arenas[mib[2]].astats.nmalloc_huge, uint64_t)
2166CTL_RO_CGEN(config_stats, stats_arenas_i_huge_ndalloc,
2167 ctl_stats.arenas[mib[2]].astats.ndalloc_huge, uint64_t)
2168CTL_RO_CGEN(config_stats, stats_arenas_i_huge_nrequests,
Jason Evans3c4d92e2014-10-12 22:53:59 -07002169 ctl_stats.arenas[mib[2]].astats.nmalloc_huge, uint64_t) /* Intentional. */
Jason Evans3c234352010-01-27 13:10:55 -08002170
Jason Evans7372b152012-02-10 20:22:09 -08002171CTL_RO_CGEN(config_stats, stats_arenas_i_bins_j_nmalloc,
Jason Evans86815df2010-03-13 20:32:56 -08002172 ctl_stats.arenas[mib[2]].bstats[mib[4]].nmalloc, uint64_t)
Jason Evans7372b152012-02-10 20:22:09 -08002173CTL_RO_CGEN(config_stats, stats_arenas_i_bins_j_ndalloc,
Jason Evans86815df2010-03-13 20:32:56 -08002174 ctl_stats.arenas[mib[2]].bstats[mib[4]].ndalloc, uint64_t)
Jason Evans7372b152012-02-10 20:22:09 -08002175CTL_RO_CGEN(config_stats, stats_arenas_i_bins_j_nrequests,
Jason Evans3c234352010-01-27 13:10:55 -08002176 ctl_stats.arenas[mib[2]].bstats[mib[4]].nrequests, uint64_t)
Jason Evans3c4d92e2014-10-12 22:53:59 -07002177CTL_RO_CGEN(config_stats, stats_arenas_i_bins_j_curregs,
2178 ctl_stats.arenas[mib[2]].bstats[mib[4]].curregs, size_t)
Jason Evans7372b152012-02-10 20:22:09 -08002179CTL_RO_CGEN(config_stats && config_tcache, stats_arenas_i_bins_j_nfills,
Jason Evans3c234352010-01-27 13:10:55 -08002180 ctl_stats.arenas[mib[2]].bstats[mib[4]].nfills, uint64_t)
Jason Evans7372b152012-02-10 20:22:09 -08002181CTL_RO_CGEN(config_stats && config_tcache, stats_arenas_i_bins_j_nflushes,
Jason Evans3c234352010-01-27 13:10:55 -08002182 ctl_stats.arenas[mib[2]].bstats[mib[4]].nflushes, uint64_t)
Jason Evans7372b152012-02-10 20:22:09 -08002183CTL_RO_CGEN(config_stats, stats_arenas_i_bins_j_nruns,
Jason Evans3c234352010-01-27 13:10:55 -08002184 ctl_stats.arenas[mib[2]].bstats[mib[4]].nruns, uint64_t)
Jason Evans7372b152012-02-10 20:22:09 -08002185CTL_RO_CGEN(config_stats, stats_arenas_i_bins_j_nreruns,
Jason Evans3c234352010-01-27 13:10:55 -08002186 ctl_stats.arenas[mib[2]].bstats[mib[4]].reruns, uint64_t)
Jason Evans7372b152012-02-10 20:22:09 -08002187CTL_RO_CGEN(config_stats, stats_arenas_i_bins_j_curruns,
Jason Evans3c234352010-01-27 13:10:55 -08002188 ctl_stats.arenas[mib[2]].bstats[mib[4]].curruns, size_t)
2189
Jason Evans609ae592012-10-11 13:53:15 -07002190static const ctl_named_node_t *
Jason Evansc1e00ef2016-05-10 22:21:10 -07002191stats_arenas_i_bins_j_index(tsdn_t *tsdn, const size_t *mib, size_t miblen,
Jason Evansb2c0d632016-04-13 23:36:15 -07002192 size_t j)
Jason Evans3c234352010-01-27 13:10:55 -08002193{
2194
Jason Evansb1726102012-02-28 16:50:47 -08002195 if (j > NBINS)
Jason Evans3c234352010-01-27 13:10:55 -08002196 return (NULL);
2197 return (super_stats_arenas_i_bins_j_node);
2198}
2199
Jason Evans7372b152012-02-10 20:22:09 -08002200CTL_RO_CGEN(config_stats, stats_arenas_i_lruns_j_nmalloc,
Jason Evansdafde142010-03-17 16:27:39 -07002201 ctl_stats.arenas[mib[2]].lstats[mib[4]].nmalloc, uint64_t)
Jason Evans7372b152012-02-10 20:22:09 -08002202CTL_RO_CGEN(config_stats, stats_arenas_i_lruns_j_ndalloc,
Jason Evansdafde142010-03-17 16:27:39 -07002203 ctl_stats.arenas[mib[2]].lstats[mib[4]].ndalloc, uint64_t)
Jason Evans7372b152012-02-10 20:22:09 -08002204CTL_RO_CGEN(config_stats, stats_arenas_i_lruns_j_nrequests,
Jason Evans3c234352010-01-27 13:10:55 -08002205 ctl_stats.arenas[mib[2]].lstats[mib[4]].nrequests, uint64_t)
Jason Evans7372b152012-02-10 20:22:09 -08002206CTL_RO_CGEN(config_stats, stats_arenas_i_lruns_j_curruns,
Jason Evans3c234352010-01-27 13:10:55 -08002207 ctl_stats.arenas[mib[2]].lstats[mib[4]].curruns, size_t)
Jason Evans3c234352010-01-27 13:10:55 -08002208
Jason Evans609ae592012-10-11 13:53:15 -07002209static const ctl_named_node_t *
Jason Evansc1e00ef2016-05-10 22:21:10 -07002210stats_arenas_i_lruns_j_index(tsdn_t *tsdn, const size_t *mib, size_t miblen,
Jason Evansb2c0d632016-04-13 23:36:15 -07002211 size_t j)
Jason Evans3c234352010-01-27 13:10:55 -08002212{
2213
2214 if (j > nlclasses)
2215 return (NULL);
2216 return (super_stats_arenas_i_lruns_j_node);
2217}
2218
Jason Evans3c4d92e2014-10-12 22:53:59 -07002219CTL_RO_CGEN(config_stats, stats_arenas_i_hchunks_j_nmalloc,
2220 ctl_stats.arenas[mib[2]].hstats[mib[4]].nmalloc, uint64_t)
2221CTL_RO_CGEN(config_stats, stats_arenas_i_hchunks_j_ndalloc,
2222 ctl_stats.arenas[mib[2]].hstats[mib[4]].ndalloc, uint64_t)
2223CTL_RO_CGEN(config_stats, stats_arenas_i_hchunks_j_nrequests,
2224 ctl_stats.arenas[mib[2]].hstats[mib[4]].nmalloc, /* Intentional. */
2225 uint64_t)
2226CTL_RO_CGEN(config_stats, stats_arenas_i_hchunks_j_curhchunks,
2227 ctl_stats.arenas[mib[2]].hstats[mib[4]].curhchunks, size_t)
2228
2229static const ctl_named_node_t *
Jason Evansc1e00ef2016-05-10 22:21:10 -07002230stats_arenas_i_hchunks_j_index(tsdn_t *tsdn, const size_t *mib, size_t miblen,
Jason Evansb2c0d632016-04-13 23:36:15 -07002231 size_t j)
Jason Evans3c4d92e2014-10-12 22:53:59 -07002232{
2233
2234 if (j > nhclasses)
2235 return (NULL);
2236 return (super_stats_arenas_i_hchunks_j_node);
2237}
2238
Jason Evans609ae592012-10-11 13:53:15 -07002239static const ctl_named_node_t *
Jason Evansc1e00ef2016-05-10 22:21:10 -07002240stats_arenas_i_index(tsdn_t *tsdn, const size_t *mib, size_t miblen, size_t i)
Jason Evans3c234352010-01-27 13:10:55 -08002241{
Mike Hommey461ad5c2012-04-20 08:38:42 +02002242 const ctl_named_node_t * ret;
Jason Evans3c234352010-01-27 13:10:55 -08002243
Jason Evansc1e00ef2016-05-10 22:21:10 -07002244 malloc_mutex_lock(tsdn, &ctl_mtx);
Jason Evans551ebc42014-10-03 10:16:09 -07002245 if (i > ctl_stats.narenas || !ctl_stats.arenas[i].initialized) {
Jason Evansfc4dcfa2010-11-24 15:44:21 -08002246 ret = NULL;
Jason Evansa1ee7832012-04-10 15:07:44 -07002247 goto label_return;
Jason Evansfc4dcfa2010-11-24 15:44:21 -08002248 }
2249
2250 ret = super_stats_arenas_i_node;
Jason Evansa1ee7832012-04-10 15:07:44 -07002251label_return:
Jason Evansc1e00ef2016-05-10 22:21:10 -07002252 malloc_mutex_unlock(tsdn, &ctl_mtx);
Jason Evansfc4dcfa2010-11-24 15:44:21 -08002253 return (ret);
Jason Evans3c234352010-01-27 13:10:55 -08002254}