blob: 232fbd71c47db7d15a72a50b3d64b9be32721a1d [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:
Jason Evansd778dd22017-01-03 12:40:54 -08009 * - ctl_stats->*
Jason Evansfc4dcfa2010-11-24 15:44:21 -080010 */
Jason Evans3c234352010-01-27 13:10:55 -080011static malloc_mutex_t ctl_mtx;
12static bool ctl_initialized;
Jason Evansd778dd22017-01-03 12:40:54 -080013static ctl_stats_t *ctl_stats;
Jason Evans9eb1b1c2017-01-18 23:03:37 -080014static ctl_arenas_t *ctl_arenas;
Jason Evans3c234352010-01-27 13:10:55 -080015
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 *
Jason Evansc4c25922017-01-15 16:56:30 -080020ctl_named_node(const ctl_node_t *node) {
Mike Hommey461ad5c2012-04-20 08:38:42 +020021 return ((node->named) ? (const ctl_named_node_t *)node : NULL);
22}
23
Jason Evansaf1f5922014-10-30 16:38:08 -070024JEMALLOC_INLINE_C const ctl_named_node_t *
Jason Evansc4c25922017-01-15 16:56:30 -080025ctl_named_children(const ctl_named_node_t *node, size_t index) {
Mike Hommey461ad5c2012-04-20 08:38:42 +020026 const ctl_named_node_t *children = ctl_named_node(node->children);
27
28 return (children ? &children[index] : NULL);
29}
30
Jason Evansaf1f5922014-10-30 16:38:08 -070031JEMALLOC_INLINE_C const ctl_indexed_node_t *
Jason Evansc4c25922017-01-15 16:56:30 -080032ctl_indexed_node(const ctl_node_t *node) {
Jason Evans551ebc42014-10-03 10:16:09 -070033 return (!node->named ? (const ctl_indexed_node_t *)node : NULL);
Mike Hommey461ad5c2012-04-20 08:38:42 +020034}
35
36/******************************************************************************/
Jason Evans3c234352010-01-27 13:10:55 -080037/* Function prototypes for non-inline static functions. */
38
39#define CTL_PROTO(n) \
Jason Evansb2c0d632016-04-13 23:36:15 -070040static int n##_ctl(tsd_t *tsd, const size_t *mib, size_t miblen, \
41 void *oldp, size_t *oldlenp, void *newp, size_t newlen);
Jason Evans3c234352010-01-27 13:10:55 -080042
43#define INDEX_PROTO(n) \
Jason Evansc1e00ef2016-05-10 22:21:10 -070044static const ctl_named_node_t *n##_index(tsdn_t *tsdn, \
Jason Evansb2c0d632016-04-13 23:36:15 -070045 const size_t *mib, size_t miblen, size_t i);
Jason Evans3c234352010-01-27 13:10:55 -080046
Jason Evansa40bc7a2010-03-02 13:01:16 -080047CTL_PROTO(version)
Jason Evans3c234352010-01-27 13:10:55 -080048CTL_PROTO(epoch)
Jason Evansd4be8b72012-03-26 18:54:44 -070049CTL_PROTO(thread_tcache_enabled)
Jason Evanse7b8fa12012-03-16 17:09:32 -070050CTL_PROTO(thread_tcache_flush)
Jason Evans602c8e02014-08-18 16:22:13 -070051CTL_PROTO(thread_prof_name)
52CTL_PROTO(thread_prof_active)
Jason Evansb267d0f2010-08-13 15:42:29 -070053CTL_PROTO(thread_arena)
Jason Evans93443682010-10-20 17:39:18 -070054CTL_PROTO(thread_allocated)
Jason Evansecf229a2010-12-03 15:55:47 -080055CTL_PROTO(thread_allocatedp)
Jason Evans93443682010-10-20 17:39:18 -070056CTL_PROTO(thread_deallocated)
Jason Evansecf229a2010-12-03 15:55:47 -080057CTL_PROTO(thread_deallocatedp)
Jason Evansf2bc8522015-07-17 16:38:25 -070058CTL_PROTO(config_cache_oblivious)
Jason Evans3c234352010-01-27 13:10:55 -080059CTL_PROTO(config_debug)
Jason Evans3c234352010-01-27 13:10:55 -080060CTL_PROTO(config_fill)
61CTL_PROTO(config_lazy_lock)
Jason Evansf8290092016-02-07 14:23:22 -080062CTL_PROTO(config_malloc_conf)
Jason Evans59ae2762012-04-16 17:52:27 -070063CTL_PROTO(config_munmap)
Jason Evansd34f9e72010-02-11 13:19:21 -080064CTL_PROTO(config_prof)
65CTL_PROTO(config_prof_libgcc)
66CTL_PROTO(config_prof_libunwind)
Jason Evans3c234352010-01-27 13:10:55 -080067CTL_PROTO(config_stats)
Jason Evans3c234352010-01-27 13:10:55 -080068CTL_PROTO(config_tcache)
Jason Evans3c234352010-01-27 13:10:55 -080069CTL_PROTO(config_tls)
Jason Evansb1476112012-04-05 13:36:17 -070070CTL_PROTO(config_utrace)
Jason Evans3c234352010-01-27 13:10:55 -080071CTL_PROTO(config_xmalloc)
72CTL_PROTO(opt_abort)
Jason Evans609ae592012-10-11 13:53:15 -070073CTL_PROTO(opt_dss)
Jason Evanse7339702010-10-23 18:37:06 -070074CTL_PROTO(opt_narenas)
Jason Evans243f7a02016-02-19 20:09:31 -080075CTL_PROTO(opt_decay_time)
Jason Evanse7339702010-10-23 18:37:06 -070076CTL_PROTO(opt_stats_print)
Jason Evans3c234352010-01-27 13:10:55 -080077CTL_PROTO(opt_junk)
Jason Evanse7339702010-10-23 18:37:06 -070078CTL_PROTO(opt_zero)
Jason Evansb1476112012-04-05 13:36:17 -070079CTL_PROTO(opt_utrace)
Jason Evans3c234352010-01-27 13:10:55 -080080CTL_PROTO(opt_xmalloc)
Jason Evans3fa9a2f2010-03-07 15:34:14 -080081CTL_PROTO(opt_tcache)
Jason Evansf3ca7c82012-04-04 16:16:09 -070082CTL_PROTO(opt_lg_tcache_max)
Jason Evansd34f9e72010-02-11 13:19:21 -080083CTL_PROTO(opt_prof)
Jason Evanse7339702010-10-23 18:37:06 -070084CTL_PROTO(opt_prof_prefix)
Jason Evansf18c9822010-03-31 18:43:24 -070085CTL_PROTO(opt_prof_active)
Jason Evansfc12c0b2014-10-03 23:25:30 -070086CTL_PROTO(opt_prof_thread_active_init)
Jason Evansb9477e72010-03-01 20:15:26 -080087CTL_PROTO(opt_lg_prof_sample)
Jason Evansd34f9e72010-02-11 13:19:21 -080088CTL_PROTO(opt_lg_prof_interval)
Jason Evanse7339702010-10-23 18:37:06 -070089CTL_PROTO(opt_prof_gdump)
Jason Evans0b25fe72012-04-17 16:39:33 -070090CTL_PROTO(opt_prof_final)
Jason Evansd34f9e72010-02-11 13:19:21 -080091CTL_PROTO(opt_prof_leak)
Jason Evansa881cd22010-10-02 15:18:50 -070092CTL_PROTO(opt_prof_accum)
Jason Evans1cb181e2015-01-29 15:30:47 -080093CTL_PROTO(tcache_create)
94CTL_PROTO(tcache_flush)
95CTL_PROTO(tcache_destroy)
Jason Evansdc2125c2017-01-04 10:21:53 -080096CTL_PROTO(arena_i_initialized)
Jason Evans609ae592012-10-11 13:53:15 -070097CTL_PROTO(arena_i_purge)
Jason Evans243f7a02016-02-19 20:09:31 -080098CTL_PROTO(arena_i_decay)
Jason Evans19ff2ce2016-04-22 14:37:17 -070099CTL_PROTO(arena_i_reset)
Jason Evansedf1baf2017-01-03 17:21:59 -0800100CTL_PROTO(arena_i_destroy)
Jason Evans609ae592012-10-11 13:53:15 -0700101CTL_PROTO(arena_i_dss)
Jason Evans243f7a02016-02-19 20:09:31 -0800102CTL_PROTO(arena_i_decay_time)
Jason Evans9c305c92016-05-31 15:03:51 -0700103CTL_PROTO(arena_i_extent_hooks)
Jason Evans609ae592012-10-11 13:53:15 -0700104INDEX_PROTO(arena_i)
Jason Evans3c234352010-01-27 13:10:55 -0800105CTL_PROTO(arenas_bin_i_size)
106CTL_PROTO(arenas_bin_i_nregs)
Jason Evans498856f2016-05-29 18:34:50 -0700107CTL_PROTO(arenas_bin_i_slab_size)
Jason Evans3c234352010-01-27 13:10:55 -0800108INDEX_PROTO(arenas_bin_i)
Jason Evans7d63fed2016-05-31 14:50:21 -0700109CTL_PROTO(arenas_lextent_i_size)
110INDEX_PROTO(arenas_lextent_i)
Jason Evans3c234352010-01-27 13:10:55 -0800111CTL_PROTO(arenas_narenas)
Jason Evans243f7a02016-02-19 20:09:31 -0800112CTL_PROTO(arenas_decay_time)
Jason Evans3c234352010-01-27 13:10:55 -0800113CTL_PROTO(arenas_quantum)
Jason Evansae4c7b42012-04-02 07:04:34 -0700114CTL_PROTO(arenas_page)
Jason Evansdafde142010-03-17 16:27:39 -0700115CTL_PROTO(arenas_tcache_max)
Jason Evans3c234352010-01-27 13:10:55 -0800116CTL_PROTO(arenas_nbins)
Jason Evansdafde142010-03-17 16:27:39 -0700117CTL_PROTO(arenas_nhbins)
Jason Evans7d63fed2016-05-31 14:50:21 -0700118CTL_PROTO(arenas_nlextents)
Jason Evans0f04bb12017-01-03 08:21:29 -0800119CTL_PROTO(arenas_create)
Jason Evansfc12c0b2014-10-03 23:25:30 -0700120CTL_PROTO(prof_thread_active_init)
Jason Evansf18c9822010-03-31 18:43:24 -0700121CTL_PROTO(prof_active)
Jason Evansd34f9e72010-02-11 13:19:21 -0800122CTL_PROTO(prof_dump)
Jason Evans5b8ed5b2015-01-25 21:16:57 -0800123CTL_PROTO(prof_gdump)
Jason Evans602c8e02014-08-18 16:22:13 -0700124CTL_PROTO(prof_reset)
Jason Evansd34f9e72010-02-11 13:19:21 -0800125CTL_PROTO(prof_interval)
Jason Evans602c8e02014-08-18 16:22:13 -0700126CTL_PROTO(lg_prof_sample)
Jason Evans3c234352010-01-27 13:10:55 -0800127CTL_PROTO(stats_arenas_i_small_allocated)
128CTL_PROTO(stats_arenas_i_small_nmalloc)
129CTL_PROTO(stats_arenas_i_small_ndalloc)
Jason Evans86815df2010-03-13 20:32:56 -0800130CTL_PROTO(stats_arenas_i_small_nrequests)
Jason Evans7d63fed2016-05-31 14:50:21 -0700131CTL_PROTO(stats_arenas_i_large_allocated)
132CTL_PROTO(stats_arenas_i_large_nmalloc)
133CTL_PROTO(stats_arenas_i_large_ndalloc)
134CTL_PROTO(stats_arenas_i_large_nrequests)
Jason Evans86815df2010-03-13 20:32:56 -0800135CTL_PROTO(stats_arenas_i_bins_j_nmalloc)
136CTL_PROTO(stats_arenas_i_bins_j_ndalloc)
Jason Evans3c234352010-01-27 13:10:55 -0800137CTL_PROTO(stats_arenas_i_bins_j_nrequests)
Jason Evans3c4d92e2014-10-12 22:53:59 -0700138CTL_PROTO(stats_arenas_i_bins_j_curregs)
Jason Evans3c234352010-01-27 13:10:55 -0800139CTL_PROTO(stats_arenas_i_bins_j_nfills)
140CTL_PROTO(stats_arenas_i_bins_j_nflushes)
Jason Evans498856f2016-05-29 18:34:50 -0700141CTL_PROTO(stats_arenas_i_bins_j_nslabs)
142CTL_PROTO(stats_arenas_i_bins_j_nreslabs)
143CTL_PROTO(stats_arenas_i_bins_j_curslabs)
Jason Evans3c234352010-01-27 13:10:55 -0800144INDEX_PROTO(stats_arenas_i_bins_j)
Jason Evans7d63fed2016-05-31 14:50:21 -0700145CTL_PROTO(stats_arenas_i_lextents_j_nmalloc)
146CTL_PROTO(stats_arenas_i_lextents_j_ndalloc)
147CTL_PROTO(stats_arenas_i_lextents_j_nrequests)
148CTL_PROTO(stats_arenas_i_lextents_j_curlextents)
149INDEX_PROTO(stats_arenas_i_lextents_j)
Jason Evans597632b2011-03-18 13:41:33 -0700150CTL_PROTO(stats_arenas_i_nthreads)
Jason Evans609ae592012-10-11 13:53:15 -0700151CTL_PROTO(stats_arenas_i_dss)
Jason Evans243f7a02016-02-19 20:09:31 -0800152CTL_PROTO(stats_arenas_i_decay_time)
Jason Evans3c234352010-01-27 13:10:55 -0800153CTL_PROTO(stats_arenas_i_pactive)
154CTL_PROTO(stats_arenas_i_pdirty)
Jason Evans3c234352010-01-27 13:10:55 -0800155CTL_PROTO(stats_arenas_i_mapped)
Jason Evans04c3c0f2016-05-03 22:11:35 -0700156CTL_PROTO(stats_arenas_i_retained)
Jason Evans3c234352010-01-27 13:10:55 -0800157CTL_PROTO(stats_arenas_i_npurge)
158CTL_PROTO(stats_arenas_i_nmadvise)
159CTL_PROTO(stats_arenas_i_purged)
Jason Evansa0dd3a42016-12-22 16:39:10 -0600160CTL_PROTO(stats_arenas_i_base)
161CTL_PROTO(stats_arenas_i_internal)
Qi Wang58424e62016-04-22 18:37:44 -0700162CTL_PROTO(stats_arenas_i_tcache_bytes)
Jason Evansa0dd3a42016-12-22 16:39:10 -0600163CTL_PROTO(stats_arenas_i_resident)
Jason Evans3c234352010-01-27 13:10:55 -0800164INDEX_PROTO(stats_arenas_i)
Jason Evans3c234352010-01-27 13:10:55 -0800165CTL_PROTO(stats_allocated)
166CTL_PROTO(stats_active)
Jason Evans4581b972014-11-27 17:22:36 -0200167CTL_PROTO(stats_metadata)
Jason Evans4acd75a2015-03-23 17:25:57 -0700168CTL_PROTO(stats_resident)
Jason Evans3c234352010-01-27 13:10:55 -0800169CTL_PROTO(stats_mapped)
Jason Evans04c3c0f2016-05-03 22:11:35 -0700170CTL_PROTO(stats_retained)
Jason Evans3c234352010-01-27 13:10:55 -0800171
172/******************************************************************************/
173/* mallctl tree. */
174
175/* Maximum tree depth. */
176#define CTL_MAX_DEPTH 6
177
Mike Hommey461ad5c2012-04-20 08:38:42 +0200178#define NAME(n) {true}, n
Jason Evans65f343a2012-04-23 19:31:45 -0700179#define CHILD(t, c) \
180 sizeof(c##_node) / sizeof(ctl_##t##_node_t), \
181 (ctl_node_t *)c##_node, \
182 NULL
Mike Hommey461ad5c2012-04-20 08:38:42 +0200183#define CTL(c) 0, NULL, c##_ctl
Jason Evans3c234352010-01-27 13:10:55 -0800184
185/*
186 * Only handles internal indexed nodes, since there are currently no external
187 * ones.
188 */
Mike Hommey461ad5c2012-04-20 08:38:42 +0200189#define INDEX(i) {false}, i##_index
Jason Evans3c234352010-01-27 13:10:55 -0800190
Jason Evans602c8e02014-08-18 16:22:13 -0700191static const ctl_named_node_t thread_tcache_node[] = {
Jason Evansd4be8b72012-03-26 18:54:44 -0700192 {NAME("enabled"), CTL(thread_tcache_enabled)},
Jason Evanse7b8fa12012-03-16 17:09:32 -0700193 {NAME("flush"), CTL(thread_tcache_flush)}
Jason Evans3c234352010-01-27 13:10:55 -0800194};
Jason Evans3c234352010-01-27 13:10:55 -0800195
Jason Evans602c8e02014-08-18 16:22:13 -0700196static const ctl_named_node_t thread_prof_node[] = {
197 {NAME("name"), CTL(thread_prof_name)},
198 {NAME("active"), CTL(thread_prof_active)}
199};
200
Mike Hommey461ad5c2012-04-20 08:38:42 +0200201static const ctl_named_node_t thread_node[] = {
Jason Evans7372b152012-02-10 20:22:09 -0800202 {NAME("arena"), CTL(thread_arena)},
Jason Evans93443682010-10-20 17:39:18 -0700203 {NAME("allocated"), CTL(thread_allocated)},
Jason Evansecf229a2010-12-03 15:55:47 -0800204 {NAME("allocatedp"), CTL(thread_allocatedp)},
205 {NAME("deallocated"), CTL(thread_deallocated)},
Jason Evanse7b8fa12012-03-16 17:09:32 -0700206 {NAME("deallocatedp"), CTL(thread_deallocatedp)},
Jason Evans602c8e02014-08-18 16:22:13 -0700207 {NAME("tcache"), CHILD(named, thread_tcache)},
208 {NAME("prof"), CHILD(named, thread_prof)}
Jason Evansb267d0f2010-08-13 15:42:29 -0700209};
Jason Evansb267d0f2010-08-13 15:42:29 -0700210
Mike Hommey461ad5c2012-04-20 08:38:42 +0200211static const ctl_named_node_t config_node[] = {
Jason Evansf2bc8522015-07-17 16:38:25 -0700212 {NAME("cache_oblivious"), CTL(config_cache_oblivious)},
Jason Evans3c4d92e2014-10-12 22:53:59 -0700213 {NAME("debug"), CTL(config_debug)},
214 {NAME("fill"), CTL(config_fill)},
215 {NAME("lazy_lock"), CTL(config_lazy_lock)},
Jason Evansf8290092016-02-07 14:23:22 -0800216 {NAME("malloc_conf"), CTL(config_malloc_conf)},
Jason Evans3c4d92e2014-10-12 22:53:59 -0700217 {NAME("munmap"), CTL(config_munmap)},
218 {NAME("prof"), CTL(config_prof)},
219 {NAME("prof_libgcc"), CTL(config_prof_libgcc)},
220 {NAME("prof_libunwind"), CTL(config_prof_libunwind)},
221 {NAME("stats"), CTL(config_stats)},
222 {NAME("tcache"), CTL(config_tcache)},
223 {NAME("tls"), CTL(config_tls)},
224 {NAME("utrace"), CTL(config_utrace)},
Jason Evans3c4d92e2014-10-12 22:53:59 -0700225 {NAME("xmalloc"), CTL(config_xmalloc)}
Jason Evans3c234352010-01-27 13:10:55 -0800226};
227
Mike Hommey461ad5c2012-04-20 08:38:42 +0200228static const ctl_named_node_t opt_node[] = {
Jason Evans3c4d92e2014-10-12 22:53:59 -0700229 {NAME("abort"), CTL(opt_abort)},
230 {NAME("dss"), CTL(opt_dss)},
Jason Evans3c4d92e2014-10-12 22:53:59 -0700231 {NAME("narenas"), CTL(opt_narenas)},
Jason Evans243f7a02016-02-19 20:09:31 -0800232 {NAME("decay_time"), CTL(opt_decay_time)},
Jason Evans3c4d92e2014-10-12 22:53:59 -0700233 {NAME("stats_print"), CTL(opt_stats_print)},
234 {NAME("junk"), CTL(opt_junk)},
235 {NAME("zero"), CTL(opt_zero)},
Jason Evans3c4d92e2014-10-12 22:53:59 -0700236 {NAME("utrace"), CTL(opt_utrace)},
237 {NAME("xmalloc"), CTL(opt_xmalloc)},
238 {NAME("tcache"), CTL(opt_tcache)},
239 {NAME("lg_tcache_max"), CTL(opt_lg_tcache_max)},
240 {NAME("prof"), CTL(opt_prof)},
241 {NAME("prof_prefix"), CTL(opt_prof_prefix)},
242 {NAME("prof_active"), CTL(opt_prof_active)},
Jason Evansfc12c0b2014-10-03 23:25:30 -0700243 {NAME("prof_thread_active_init"), CTL(opt_prof_thread_active_init)},
Jason Evans3c4d92e2014-10-12 22:53:59 -0700244 {NAME("lg_prof_sample"), CTL(opt_lg_prof_sample)},
245 {NAME("lg_prof_interval"), CTL(opt_lg_prof_interval)},
246 {NAME("prof_gdump"), CTL(opt_prof_gdump)},
247 {NAME("prof_final"), CTL(opt_prof_final)},
248 {NAME("prof_leak"), CTL(opt_prof_leak)},
249 {NAME("prof_accum"), CTL(opt_prof_accum)}
Jason Evans3c234352010-01-27 13:10:55 -0800250};
251
Jason Evans1cb181e2015-01-29 15:30:47 -0800252static const ctl_named_node_t tcache_node[] = {
253 {NAME("create"), CTL(tcache_create)},
254 {NAME("flush"), CTL(tcache_flush)},
255 {NAME("destroy"), CTL(tcache_destroy)}
256};
257
Jason Evans609ae592012-10-11 13:53:15 -0700258static const ctl_named_node_t arena_i_node[] = {
Jason Evansdc2125c2017-01-04 10:21:53 -0800259 {NAME("initialized"), CTL(arena_i_initialized)},
Jason Evans3c4d92e2014-10-12 22:53:59 -0700260 {NAME("purge"), CTL(arena_i_purge)},
Jason Evans243f7a02016-02-19 20:09:31 -0800261 {NAME("decay"), CTL(arena_i_decay)},
Jason Evans19ff2ce2016-04-22 14:37:17 -0700262 {NAME("reset"), CTL(arena_i_reset)},
Jason Evansedf1baf2017-01-03 17:21:59 -0800263 {NAME("destroy"), CTL(arena_i_destroy)},
Jason Evans3c4d92e2014-10-12 22:53:59 -0700264 {NAME("dss"), CTL(arena_i_dss)},
Jason Evans243f7a02016-02-19 20:09:31 -0800265 {NAME("decay_time"), CTL(arena_i_decay_time)},
Jason Evans9c305c92016-05-31 15:03:51 -0700266 {NAME("extent_hooks"), CTL(arena_i_extent_hooks)}
Jason Evans609ae592012-10-11 13:53:15 -0700267};
268static const ctl_named_node_t super_arena_i_node[] = {
Jason Evans3c4d92e2014-10-12 22:53:59 -0700269 {NAME(""), CHILD(named, arena_i)}
Jason Evans609ae592012-10-11 13:53:15 -0700270};
271
272static const ctl_indexed_node_t arena_node[] = {
273 {INDEX(arena_i)}
274};
275
Mike Hommey461ad5c2012-04-20 08:38:42 +0200276static const ctl_named_node_t arenas_bin_i_node[] = {
Jason Evans3c4d92e2014-10-12 22:53:59 -0700277 {NAME("size"), CTL(arenas_bin_i_size)},
278 {NAME("nregs"), CTL(arenas_bin_i_nregs)},
Jason Evans498856f2016-05-29 18:34:50 -0700279 {NAME("slab_size"), CTL(arenas_bin_i_slab_size)}
Jason Evans3c234352010-01-27 13:10:55 -0800280};
Mike Hommey461ad5c2012-04-20 08:38:42 +0200281static const ctl_named_node_t super_arenas_bin_i_node[] = {
Jason Evans3c4d92e2014-10-12 22:53:59 -0700282 {NAME(""), CHILD(named, arenas_bin_i)}
Jason Evans3c234352010-01-27 13:10:55 -0800283};
284
Mike Hommey461ad5c2012-04-20 08:38:42 +0200285static const ctl_indexed_node_t arenas_bin_node[] = {
Jason Evans3c234352010-01-27 13:10:55 -0800286 {INDEX(arenas_bin_i)}
287};
288
Jason Evans7d63fed2016-05-31 14:50:21 -0700289static const ctl_named_node_t arenas_lextent_i_node[] = {
290 {NAME("size"), CTL(arenas_lextent_i_size)}
Jason Evans3c4d92e2014-10-12 22:53:59 -0700291};
Jason Evans7d63fed2016-05-31 14:50:21 -0700292static const ctl_named_node_t super_arenas_lextent_i_node[] = {
293 {NAME(""), CHILD(named, arenas_lextent_i)}
Jason Evans3c4d92e2014-10-12 22:53:59 -0700294};
295
Jason Evans7d63fed2016-05-31 14:50:21 -0700296static const ctl_indexed_node_t arenas_lextent_node[] = {
297 {INDEX(arenas_lextent_i)}
Jason Evans3c4d92e2014-10-12 22:53:59 -0700298};
299
Mike Hommey461ad5c2012-04-20 08:38:42 +0200300static const ctl_named_node_t arenas_node[] = {
Jason Evans3c4d92e2014-10-12 22:53:59 -0700301 {NAME("narenas"), CTL(arenas_narenas)},
Jason Evans243f7a02016-02-19 20:09:31 -0800302 {NAME("decay_time"), CTL(arenas_decay_time)},
Jason Evans3c4d92e2014-10-12 22:53:59 -0700303 {NAME("quantum"), CTL(arenas_quantum)},
304 {NAME("page"), CTL(arenas_page)},
305 {NAME("tcache_max"), CTL(arenas_tcache_max)},
306 {NAME("nbins"), CTL(arenas_nbins)},
307 {NAME("nhbins"), CTL(arenas_nhbins)},
308 {NAME("bin"), CHILD(indexed, arenas_bin)},
Jason Evans7d63fed2016-05-31 14:50:21 -0700309 {NAME("nlextents"), CTL(arenas_nlextents)},
310 {NAME("lextent"), CHILD(indexed, arenas_lextent)},
Jason Evans0f04bb12017-01-03 08:21:29 -0800311 {NAME("create"), CTL(arenas_create)}
Jason Evans3c234352010-01-27 13:10:55 -0800312};
313
Mike Hommey461ad5c2012-04-20 08:38:42 +0200314static const ctl_named_node_t prof_node[] = {
Jason Evansfc12c0b2014-10-03 23:25:30 -0700315 {NAME("thread_active_init"), CTL(prof_thread_active_init)},
Jason Evansf18c9822010-03-31 18:43:24 -0700316 {NAME("active"), CTL(prof_active)},
Jason Evansd34f9e72010-02-11 13:19:21 -0800317 {NAME("dump"), CTL(prof_dump)},
Jason Evans5b8ed5b2015-01-25 21:16:57 -0800318 {NAME("gdump"), CTL(prof_gdump)},
Jason Evans602c8e02014-08-18 16:22:13 -0700319 {NAME("reset"), CTL(prof_reset)},
320 {NAME("interval"), CTL(prof_interval)},
321 {NAME("lg_sample"), CTL(lg_prof_sample)}
Jason Evansd34f9e72010-02-11 13:19:21 -0800322};
Jason Evansd34f9e72010-02-11 13:19:21 -0800323
Mike Hommey461ad5c2012-04-20 08:38:42 +0200324static const ctl_named_node_t stats_arenas_i_small_node[] = {
Jason Evans3c4d92e2014-10-12 22:53:59 -0700325 {NAME("allocated"), CTL(stats_arenas_i_small_allocated)},
326 {NAME("nmalloc"), CTL(stats_arenas_i_small_nmalloc)},
327 {NAME("ndalloc"), CTL(stats_arenas_i_small_ndalloc)},
328 {NAME("nrequests"), CTL(stats_arenas_i_small_nrequests)}
Jason Evans3c234352010-01-27 13:10:55 -0800329};
330
Jason Evans7d63fed2016-05-31 14:50:21 -0700331static const ctl_named_node_t stats_arenas_i_large_node[] = {
332 {NAME("allocated"), CTL(stats_arenas_i_large_allocated)},
333 {NAME("nmalloc"), CTL(stats_arenas_i_large_nmalloc)},
334 {NAME("ndalloc"), CTL(stats_arenas_i_large_ndalloc)},
335 {NAME("nrequests"), CTL(stats_arenas_i_large_nrequests)}
Jason Evanse2deab72014-05-15 22:22:27 -0700336};
337
Mike Hommey461ad5c2012-04-20 08:38:42 +0200338static const ctl_named_node_t stats_arenas_i_bins_j_node[] = {
Jason Evans3c4d92e2014-10-12 22:53:59 -0700339 {NAME("nmalloc"), CTL(stats_arenas_i_bins_j_nmalloc)},
340 {NAME("ndalloc"), CTL(stats_arenas_i_bins_j_ndalloc)},
341 {NAME("nrequests"), CTL(stats_arenas_i_bins_j_nrequests)},
342 {NAME("curregs"), CTL(stats_arenas_i_bins_j_curregs)},
343 {NAME("nfills"), CTL(stats_arenas_i_bins_j_nfills)},
344 {NAME("nflushes"), CTL(stats_arenas_i_bins_j_nflushes)},
Jason Evans498856f2016-05-29 18:34:50 -0700345 {NAME("nslabs"), CTL(stats_arenas_i_bins_j_nslabs)},
346 {NAME("nreslabs"), CTL(stats_arenas_i_bins_j_nreslabs)},
347 {NAME("curslabs"), CTL(stats_arenas_i_bins_j_curslabs)}
Jason Evans3c234352010-01-27 13:10:55 -0800348};
Mike Hommey461ad5c2012-04-20 08:38:42 +0200349static const ctl_named_node_t super_stats_arenas_i_bins_j_node[] = {
Jason Evans3c4d92e2014-10-12 22:53:59 -0700350 {NAME(""), CHILD(named, stats_arenas_i_bins_j)}
Jason Evans3c234352010-01-27 13:10:55 -0800351};
352
Mike Hommey461ad5c2012-04-20 08:38:42 +0200353static const ctl_indexed_node_t stats_arenas_i_bins_node[] = {
Jason Evans3c234352010-01-27 13:10:55 -0800354 {INDEX(stats_arenas_i_bins_j)}
355};
356
Jason Evans7d63fed2016-05-31 14:50:21 -0700357static const ctl_named_node_t stats_arenas_i_lextents_j_node[] = {
358 {NAME("nmalloc"), CTL(stats_arenas_i_lextents_j_nmalloc)},
359 {NAME("ndalloc"), CTL(stats_arenas_i_lextents_j_ndalloc)},
360 {NAME("nrequests"), CTL(stats_arenas_i_lextents_j_nrequests)},
361 {NAME("curlextents"), CTL(stats_arenas_i_lextents_j_curlextents)}
Jason Evans3c4d92e2014-10-12 22:53:59 -0700362};
Jason Evans7d63fed2016-05-31 14:50:21 -0700363static const ctl_named_node_t super_stats_arenas_i_lextents_j_node[] = {
364 {NAME(""), CHILD(named, stats_arenas_i_lextents_j)}
Jason Evans3c4d92e2014-10-12 22:53:59 -0700365};
366
Jason Evans7d63fed2016-05-31 14:50:21 -0700367static const ctl_indexed_node_t stats_arenas_i_lextents_node[] = {
368 {INDEX(stats_arenas_i_lextents_j)}
Jason Evans3c4d92e2014-10-12 22:53:59 -0700369};
370
Mike Hommey461ad5c2012-04-20 08:38:42 +0200371static const ctl_named_node_t stats_arenas_i_node[] = {
Jason Evans3c4d92e2014-10-12 22:53:59 -0700372 {NAME("nthreads"), CTL(stats_arenas_i_nthreads)},
373 {NAME("dss"), CTL(stats_arenas_i_dss)},
Jason Evans243f7a02016-02-19 20:09:31 -0800374 {NAME("decay_time"), CTL(stats_arenas_i_decay_time)},
Jason Evans3c4d92e2014-10-12 22:53:59 -0700375 {NAME("pactive"), CTL(stats_arenas_i_pactive)},
376 {NAME("pdirty"), CTL(stats_arenas_i_pdirty)},
377 {NAME("mapped"), CTL(stats_arenas_i_mapped)},
Jason Evans04c3c0f2016-05-03 22:11:35 -0700378 {NAME("retained"), CTL(stats_arenas_i_retained)},
Jason Evans3c4d92e2014-10-12 22:53:59 -0700379 {NAME("npurge"), CTL(stats_arenas_i_npurge)},
380 {NAME("nmadvise"), CTL(stats_arenas_i_nmadvise)},
381 {NAME("purged"), CTL(stats_arenas_i_purged)},
Jason Evansa0dd3a42016-12-22 16:39:10 -0600382 {NAME("base"), CTL(stats_arenas_i_base)},
383 {NAME("internal"), CTL(stats_arenas_i_internal)},
Qi Wang58424e62016-04-22 18:37:44 -0700384 {NAME("tcache_bytes"), CTL(stats_arenas_i_tcache_bytes)},
Jason Evansa0dd3a42016-12-22 16:39:10 -0600385 {NAME("resident"), CTL(stats_arenas_i_resident)},
Jason Evans3c4d92e2014-10-12 22:53:59 -0700386 {NAME("small"), CHILD(named, stats_arenas_i_small)},
Jason Evans7d63fed2016-05-31 14:50:21 -0700387 {NAME("large"), CHILD(named, stats_arenas_i_large)},
Jason Evans3c4d92e2014-10-12 22:53:59 -0700388 {NAME("bins"), CHILD(indexed, stats_arenas_i_bins)},
Jason Evans7d63fed2016-05-31 14:50:21 -0700389 {NAME("lextents"), CHILD(indexed, stats_arenas_i_lextents)}
Jason Evans3c234352010-01-27 13:10:55 -0800390};
Mike Hommey461ad5c2012-04-20 08:38:42 +0200391static const ctl_named_node_t super_stats_arenas_i_node[] = {
Jason Evans3c4d92e2014-10-12 22:53:59 -0700392 {NAME(""), CHILD(named, stats_arenas_i)}
Jason Evans3c234352010-01-27 13:10:55 -0800393};
394
Mike Hommey461ad5c2012-04-20 08:38:42 +0200395static const ctl_indexed_node_t stats_arenas_node[] = {
Jason Evans3c234352010-01-27 13:10:55 -0800396 {INDEX(stats_arenas_i)}
397};
398
Mike Hommey461ad5c2012-04-20 08:38:42 +0200399static const ctl_named_node_t stats_node[] = {
Jason Evans3c4d92e2014-10-12 22:53:59 -0700400 {NAME("allocated"), CTL(stats_allocated)},
401 {NAME("active"), CTL(stats_active)},
Jason Evans4581b972014-11-27 17:22:36 -0200402 {NAME("metadata"), CTL(stats_metadata)},
Jason Evans4acd75a2015-03-23 17:25:57 -0700403 {NAME("resident"), CTL(stats_resident)},
Jason Evans3c4d92e2014-10-12 22:53:59 -0700404 {NAME("mapped"), CTL(stats_mapped)},
Jason Evans04c3c0f2016-05-03 22:11:35 -0700405 {NAME("retained"), CTL(stats_retained)},
Jason Evans3c4d92e2014-10-12 22:53:59 -0700406 {NAME("arenas"), CHILD(indexed, stats_arenas)}
Jason Evans3c234352010-01-27 13:10:55 -0800407};
408
Mike Hommey461ad5c2012-04-20 08:38:42 +0200409static const ctl_named_node_t root_node[] = {
Jason Evansa40bc7a2010-03-02 13:01:16 -0800410 {NAME("version"), CTL(version)},
Jason Evans3c234352010-01-27 13:10:55 -0800411 {NAME("epoch"), CTL(epoch)},
Jason Evans65f343a2012-04-23 19:31:45 -0700412 {NAME("thread"), CHILD(named, thread)},
413 {NAME("config"), CHILD(named, config)},
414 {NAME("opt"), CHILD(named, opt)},
Jason Evans1cb181e2015-01-29 15:30:47 -0800415 {NAME("tcache"), CHILD(named, tcache)},
Jason Evans609ae592012-10-11 13:53:15 -0700416 {NAME("arena"), CHILD(indexed, arena)},
Jason Evans65f343a2012-04-23 19:31:45 -0700417 {NAME("arenas"), CHILD(named, arenas)},
418 {NAME("prof"), CHILD(named, prof)},
419 {NAME("stats"), CHILD(named, stats)}
Jason Evans3c234352010-01-27 13:10:55 -0800420};
Mike Hommey461ad5c2012-04-20 08:38:42 +0200421static const ctl_named_node_t super_root_node[] = {
Jason Evans65f343a2012-04-23 19:31:45 -0700422 {NAME(""), CHILD(named, root)}
Jason Evans3c234352010-01-27 13:10:55 -0800423};
424
425#undef NAME
426#undef CHILD
427#undef CTL
428#undef INDEX
429
430/******************************************************************************/
431
Jason Evans3dc4e832017-01-03 07:27:42 -0800432static unsigned
Jason Evansc4c25922017-01-15 16:56:30 -0800433arenas_i2a_impl(size_t i, bool compat, bool validate) {
Jason Evans3dc4e832017-01-03 07:27:42 -0800434 unsigned a;
435
Jason Evans3dc4e832017-01-03 07:27:42 -0800436 switch (i) {
437 case MALLCTL_ARENAS_ALL:
438 a = 0;
439 break;
Jason Evansedf1baf2017-01-03 17:21:59 -0800440 case MALLCTL_ARENAS_DESTROYED:
441 a = 1;
442 break;
Jason Evans3dc4e832017-01-03 07:27:42 -0800443 default:
Jason Evans9eb1b1c2017-01-18 23:03:37 -0800444 if (compat && i == ctl_arenas->narenas) {
Jason Evans3dc4e832017-01-03 07:27:42 -0800445 /*
446 * Provide deprecated backward compatibility for
447 * accessing the merged stats at index narenas rather
448 * than via MALLCTL_ARENAS_ALL. This is scheduled for
449 * removal in 6.0.0.
450 */
451 a = 0;
Jason Evansc4c25922017-01-15 16:56:30 -0800452 } else if (validate && i >= ctl_arenas->narenas) {
Jason Evans3dc4e832017-01-03 07:27:42 -0800453 a = UINT_MAX;
Jason Evansc4c25922017-01-15 16:56:30 -0800454 } else {
Jason Evans3dc4e832017-01-03 07:27:42 -0800455 /*
456 * This function should never be called for an index
457 * more than one past the range of indices that have
Jason Evans9eb1b1c2017-01-18 23:03:37 -0800458 * initialized ctl data.
Jason Evans3dc4e832017-01-03 07:27:42 -0800459 */
Jason Evans9eb1b1c2017-01-18 23:03:37 -0800460 assert(i < ctl_arenas->narenas || (!validate && i ==
461 ctl_arenas->narenas));
Jason Evansedf1baf2017-01-03 17:21:59 -0800462 a = (unsigned)i + 2;
Jason Evans3dc4e832017-01-03 07:27:42 -0800463 }
464 break;
465 }
466
Jason Evansf4086432017-01-19 18:15:45 -0800467 return a;
Jason Evans3dc4e832017-01-03 07:27:42 -0800468}
469
Jason Evansedf1baf2017-01-03 17:21:59 -0800470static unsigned
Jason Evansc4c25922017-01-15 16:56:30 -0800471arenas_i2a(size_t i) {
Jason Evansf4086432017-01-19 18:15:45 -0800472 return arenas_i2a_impl(i, true, false);
Jason Evansedf1baf2017-01-03 17:21:59 -0800473}
474
Jason Evans9eb1b1c2017-01-18 23:03:37 -0800475static ctl_arena_t *
Jason Evansc4c25922017-01-15 16:56:30 -0800476arenas_i_impl(tsdn_t *tsdn, size_t i, bool compat, bool init) {
Jason Evans9eb1b1c2017-01-18 23:03:37 -0800477 ctl_arena_t *ret;
Jason Evansd778dd22017-01-03 12:40:54 -0800478
479 assert(!compat || !init);
480
Jason Evans9eb1b1c2017-01-18 23:03:37 -0800481 ret = ctl_arenas->arenas[arenas_i2a_impl(i, compat, false)];
Jason Evansd778dd22017-01-03 12:40:54 -0800482 if (init && ret == NULL) {
Jason Evans9eb1b1c2017-01-18 23:03:37 -0800483 if (config_stats) {
484 struct container_s {
485 ctl_arena_t ctl_arena;
486 ctl_arena_stats_t astats;
487 };
488 struct container_s *cont =
489 (struct container_s *)base_alloc(tsdn, b0get(),
490 sizeof(struct container_s), QUANTUM);
491 if (cont == NULL) {
492 return NULL;
493 }
494 ret = &cont->ctl_arena;
495 ret->astats = &cont->astats;
496 } else {
497 ret = (ctl_arena_t *)base_alloc(tsdn, b0get(),
498 sizeof(ctl_arena_t), QUANTUM);
499 if (ret == NULL) {
500 return NULL;
501 }
502 }
Jason Evansedf1baf2017-01-03 17:21:59 -0800503 ret->arena_ind = (unsigned)i;
Jason Evans9eb1b1c2017-01-18 23:03:37 -0800504 ctl_arenas->arenas[arenas_i2a_impl(i, compat, false)] = ret;
Jason Evansd778dd22017-01-03 12:40:54 -0800505 }
506
Jason Evans9eb1b1c2017-01-18 23:03:37 -0800507 assert(ret == NULL || arenas_i2a(ret->arena_ind) == arenas_i2a(i));
Jason Evansf4086432017-01-19 18:15:45 -0800508 return ret;
Jason Evansd778dd22017-01-03 12:40:54 -0800509}
510
Jason Evans9eb1b1c2017-01-18 23:03:37 -0800511static ctl_arena_t *
Jason Evansc4c25922017-01-15 16:56:30 -0800512arenas_i(size_t i) {
Jason Evans9eb1b1c2017-01-18 23:03:37 -0800513 ctl_arena_t *ret = arenas_i_impl(TSDN_NULL, i, true, false);
Jason Evansd778dd22017-01-03 12:40:54 -0800514 assert(ret != NULL);
Jason Evansf4086432017-01-19 18:15:45 -0800515 return ret;
Jason Evans3dc4e832017-01-03 07:27:42 -0800516}
517
Jason Evans3c234352010-01-27 13:10:55 -0800518static void
Jason Evansc4c25922017-01-15 16:56:30 -0800519ctl_arena_clear(ctl_arena_t *ctl_arena) {
Jason Evans9eb1b1c2017-01-18 23:03:37 -0800520 ctl_arena->nthreads = 0;
521 ctl_arena->dss = dss_prec_names[dss_prec_limit];
522 ctl_arena->decay_time = -1;
523 ctl_arena->pactive = 0;
524 ctl_arena->pdirty = 0;
Jason Evans7372b152012-02-10 20:22:09 -0800525 if (config_stats) {
Jason Evans9eb1b1c2017-01-18 23:03:37 -0800526 memset(&ctl_arena->astats->astats, 0, sizeof(arena_stats_t));
527 ctl_arena->astats->allocated_small = 0;
528 ctl_arena->astats->nmalloc_small = 0;
529 ctl_arena->astats->ndalloc_small = 0;
530 ctl_arena->astats->nrequests_small = 0;
531 memset(ctl_arena->astats->bstats, 0, NBINS *
532 sizeof(malloc_bin_stats_t));
533 memset(ctl_arena->astats->lstats, 0, (NSIZES - NBINS) *
Jason Evans7d63fed2016-05-31 14:50:21 -0700534 sizeof(malloc_large_stats_t));
Jason Evans7372b152012-02-10 20:22:09 -0800535 }
Jason Evans3c234352010-01-27 13:10:55 -0800536}
537
Jason Evans86815df2010-03-13 20:32:56 -0800538static void
Jason Evansc4c25922017-01-15 16:56:30 -0800539ctl_arena_stats_amerge(tsdn_t *tsdn, ctl_arena_t *ctl_arena, arena_t *arena) {
Jason Evans86815df2010-03-13 20:32:56 -0800540 unsigned i;
541
Jason Evans3c07f802016-02-27 20:40:13 -0800542 if (config_stats) {
Jason Evans9eb1b1c2017-01-18 23:03:37 -0800543 arena_stats_merge(tsdn, arena, &ctl_arena->nthreads,
544 &ctl_arena->dss, &ctl_arena->decay_time,
545 &ctl_arena->pactive, &ctl_arena->pdirty,
546 &ctl_arena->astats->astats, ctl_arena->astats->bstats,
547 ctl_arena->astats->lstats);
Jason Evans86815df2010-03-13 20:32:56 -0800548
Jason Evans3c07f802016-02-27 20:40:13 -0800549 for (i = 0; i < NBINS; i++) {
Jason Evans9eb1b1c2017-01-18 23:03:37 -0800550 ctl_arena->astats->allocated_small +=
551 ctl_arena->astats->bstats[i].curregs *
Jason Evans3c07f802016-02-27 20:40:13 -0800552 index2size(i);
Jason Evans9eb1b1c2017-01-18 23:03:37 -0800553 ctl_arena->astats->nmalloc_small +=
554 ctl_arena->astats->bstats[i].nmalloc;
555 ctl_arena->astats->ndalloc_small +=
556 ctl_arena->astats->bstats[i].ndalloc;
557 ctl_arena->astats->nrequests_small +=
558 ctl_arena->astats->bstats[i].nrequests;
Jason Evans3c07f802016-02-27 20:40:13 -0800559 }
560 } else {
Jason Evans9eb1b1c2017-01-18 23:03:37 -0800561 arena_basic_stats_merge(tsdn, arena, &ctl_arena->nthreads,
562 &ctl_arena->dss, &ctl_arena->decay_time,
563 &ctl_arena->pactive, &ctl_arena->pdirty);
Jason Evans86815df2010-03-13 20:32:56 -0800564 }
Jason Evans86815df2010-03-13 20:32:56 -0800565}
566
567static void
Jason Evans9eb1b1c2017-01-18 23:03:37 -0800568ctl_arena_stats_sdmerge(ctl_arena_t *ctl_sdarena, ctl_arena_t *ctl_arena,
Jason Evansc4c25922017-01-15 16:56:30 -0800569 bool destroyed) {
Jason Evans86815df2010-03-13 20:32:56 -0800570 unsigned i;
571
Jason Evansedf1baf2017-01-03 17:21:59 -0800572 if (!destroyed) {
Jason Evans9eb1b1c2017-01-18 23:03:37 -0800573 ctl_sdarena->nthreads += ctl_arena->nthreads;
574 ctl_sdarena->pactive += ctl_arena->pactive;
575 ctl_sdarena->pdirty += ctl_arena->pdirty;
Jason Evansedf1baf2017-01-03 17:21:59 -0800576 } else {
Jason Evans9eb1b1c2017-01-18 23:03:37 -0800577 assert(ctl_arena->nthreads == 0);
578 assert(ctl_arena->pactive == 0);
579 assert(ctl_arena->pdirty == 0);
Jason Evansedf1baf2017-01-03 17:21:59 -0800580 }
Jason Evans86815df2010-03-13 20:32:56 -0800581
Jason Evans3c07f802016-02-27 20:40:13 -0800582 if (config_stats) {
Jason Evans9eb1b1c2017-01-18 23:03:37 -0800583 ctl_arena_stats_t *sdstats = ctl_sdarena->astats;
584 ctl_arena_stats_t *astats = ctl_arena->astats;
585
Jason Evansedf1baf2017-01-03 17:21:59 -0800586 if (!destroyed) {
587 sdstats->astats.mapped += astats->astats.mapped;
588 sdstats->astats.retained += astats->astats.retained;
589 }
590 sdstats->astats.npurge += astats->astats.npurge;
591 sdstats->astats.nmadvise += astats->astats.nmadvise;
592 sdstats->astats.purged += astats->astats.purged;
Jason Evans86815df2010-03-13 20:32:56 -0800593
Jason Evansedf1baf2017-01-03 17:21:59 -0800594 if (!destroyed) {
595 sdstats->astats.base += astats->astats.base;
596 sdstats->astats.internal += astats->astats.internal;
597 sdstats->astats.resident += astats->astats.resident;
Jason Evansc4c25922017-01-15 16:56:30 -0800598 } else {
Jason Evansedf1baf2017-01-03 17:21:59 -0800599 assert(astats->astats.internal == 0);
Jason Evansc4c25922017-01-15 16:56:30 -0800600 }
Jason Evans4581b972014-11-27 17:22:36 -0200601
Jason Evansc4c25922017-01-15 16:56:30 -0800602 if (!destroyed) {
Jason Evansedf1baf2017-01-03 17:21:59 -0800603 sdstats->allocated_small += astats->allocated_small;
Jason Evansc4c25922017-01-15 16:56:30 -0800604 } else {
Jason Evansedf1baf2017-01-03 17:21:59 -0800605 assert(astats->allocated_small == 0);
Jason Evansc4c25922017-01-15 16:56:30 -0800606 }
Jason Evansedf1baf2017-01-03 17:21:59 -0800607 sdstats->nmalloc_small += astats->nmalloc_small;
608 sdstats->ndalloc_small += astats->ndalloc_small;
609 sdstats->nrequests_small += astats->nrequests_small;
Jason Evans86815df2010-03-13 20:32:56 -0800610
Jason Evansedf1baf2017-01-03 17:21:59 -0800611 if (!destroyed) {
612 sdstats->astats.allocated_large +=
613 astats->astats.allocated_large;
Jason Evansc4c25922017-01-15 16:56:30 -0800614 } else {
Jason Evansedf1baf2017-01-03 17:21:59 -0800615 assert(astats->astats.allocated_large == 0);
Jason Evansc4c25922017-01-15 16:56:30 -0800616 }
Jason Evansedf1baf2017-01-03 17:21:59 -0800617 sdstats->astats.nmalloc_large += astats->astats.nmalloc_large;
618 sdstats->astats.ndalloc_large += astats->astats.ndalloc_large;
619 sdstats->astats.nrequests_large +=
Jason Evans7d63fed2016-05-31 14:50:21 -0700620 astats->astats.nrequests_large;
Jason Evans86815df2010-03-13 20:32:56 -0800621
Qi Wang58424e62016-04-22 18:37:44 -0700622 if (config_tcache) {
623 sdstats->astats.tcache_bytes +=
624 astats->astats.tcache_bytes;
625 }
626
Jason Evans3c07f802016-02-27 20:40:13 -0800627 for (i = 0; i < NBINS; i++) {
Jason Evansedf1baf2017-01-03 17:21:59 -0800628 sdstats->bstats[i].nmalloc += astats->bstats[i].nmalloc;
629 sdstats->bstats[i].ndalloc += astats->bstats[i].ndalloc;
630 sdstats->bstats[i].nrequests +=
Jason Evans3c07f802016-02-27 20:40:13 -0800631 astats->bstats[i].nrequests;
Jason Evansedf1baf2017-01-03 17:21:59 -0800632 if (!destroyed) {
633 sdstats->bstats[i].curregs +=
634 astats->bstats[i].curregs;
Jason Evansc4c25922017-01-15 16:56:30 -0800635 } else {
Jason Evansedf1baf2017-01-03 17:21:59 -0800636 assert(astats->bstats[i].curregs == 0);
Jason Evansc4c25922017-01-15 16:56:30 -0800637 }
Jason Evans3c07f802016-02-27 20:40:13 -0800638 if (config_tcache) {
Jason Evansedf1baf2017-01-03 17:21:59 -0800639 sdstats->bstats[i].nfills +=
Jason Evans3c07f802016-02-27 20:40:13 -0800640 astats->bstats[i].nfills;
Jason Evansedf1baf2017-01-03 17:21:59 -0800641 sdstats->bstats[i].nflushes +=
Jason Evans3c07f802016-02-27 20:40:13 -0800642 astats->bstats[i].nflushes;
643 }
Jason Evansedf1baf2017-01-03 17:21:59 -0800644 sdstats->bstats[i].nslabs += astats->bstats[i].nslabs;
645 sdstats->bstats[i].reslabs += astats->bstats[i].reslabs;
646 if (!destroyed) {
647 sdstats->bstats[i].curslabs +=
648 astats->bstats[i].curslabs;
Jason Evansc4c25922017-01-15 16:56:30 -0800649 } else {
Jason Evansedf1baf2017-01-03 17:21:59 -0800650 assert(astats->bstats[i].curslabs == 0);
Jason Evansc4c25922017-01-15 16:56:30 -0800651 }
Jason Evans7372b152012-02-10 20:22:09 -0800652 }
Jason Evans3c4d92e2014-10-12 22:53:59 -0700653
Jason Evansed2c2422016-05-28 00:17:28 -0700654 for (i = 0; i < NSIZES - NBINS; i++) {
Jason Evansedf1baf2017-01-03 17:21:59 -0800655 sdstats->lstats[i].nmalloc += astats->lstats[i].nmalloc;
656 sdstats->lstats[i].ndalloc += astats->lstats[i].ndalloc;
657 sdstats->lstats[i].nrequests +=
Jason Evans7d63fed2016-05-31 14:50:21 -0700658 astats->lstats[i].nrequests;
Jason Evansedf1baf2017-01-03 17:21:59 -0800659 if (!destroyed) {
660 sdstats->lstats[i].curlextents +=
661 astats->lstats[i].curlextents;
Jason Evansc4c25922017-01-15 16:56:30 -0800662 } else {
Jason Evansedf1baf2017-01-03 17:21:59 -0800663 assert(astats->lstats[i].curlextents == 0);
Jason Evansc4c25922017-01-15 16:56:30 -0800664 }
Jason Evans3c07f802016-02-27 20:40:13 -0800665 }
Jason Evans3c4d92e2014-10-12 22:53:59 -0700666 }
Jason Evans86815df2010-03-13 20:32:56 -0800667}
Jason Evans86815df2010-03-13 20:32:56 -0800668
Jason Evans3c234352010-01-27 13:10:55 -0800669static void
Jason Evans9eb1b1c2017-01-18 23:03:37 -0800670ctl_arena_refresh(tsdn_t *tsdn, arena_t *arena, ctl_arena_t *ctl_sdarena,
Jason Evansc4c25922017-01-15 16:56:30 -0800671 unsigned i, bool destroyed) {
Jason Evans9eb1b1c2017-01-18 23:03:37 -0800672 ctl_arena_t *ctl_arena = arenas_i(i);
Jason Evans3c234352010-01-27 13:10:55 -0800673
Jason Evans9eb1b1c2017-01-18 23:03:37 -0800674 ctl_arena_clear(ctl_arena);
675 ctl_arena_stats_amerge(tsdn, ctl_arena, arena);
Jason Evans3c07f802016-02-27 20:40:13 -0800676 /* Merge into sum stats as well. */
Jason Evans9eb1b1c2017-01-18 23:03:37 -0800677 ctl_arena_stats_sdmerge(ctl_sdarena, ctl_arena, destroyed);
Jason Evans3c234352010-01-27 13:10:55 -0800678}
679
Jason Evansedf1baf2017-01-03 17:21:59 -0800680static unsigned
Jason Evansc4c25922017-01-15 16:56:30 -0800681ctl_arena_init(tsdn_t *tsdn, extent_hooks_t *extent_hooks) {
Jason Evansedf1baf2017-01-03 17:21:59 -0800682 unsigned arena_ind;
Jason Evans9eb1b1c2017-01-18 23:03:37 -0800683 ctl_arena_t *ctl_arena;
Jason Evansedf1baf2017-01-03 17:21:59 -0800684
Jason Evans9eb1b1c2017-01-18 23:03:37 -0800685 if ((ctl_arena = ql_last(&ctl_arenas->destroyed, destroyed_link)) !=
686 NULL) {
687 ql_remove(&ctl_arenas->destroyed, ctl_arena, destroyed_link);
688 arena_ind = ctl_arena->arena_ind;
Jason Evansc4c25922017-01-15 16:56:30 -0800689 } else {
Jason Evans9eb1b1c2017-01-18 23:03:37 -0800690 arena_ind = ctl_arenas->narenas;
Jason Evansc4c25922017-01-15 16:56:30 -0800691 }
Jason Evansd778dd22017-01-03 12:40:54 -0800692
693 /* Trigger stats allocation. */
Jason Evansc4c25922017-01-15 16:56:30 -0800694 if (arenas_i_impl(tsdn, arena_ind, false, true) == NULL) {
Jason Evansf4086432017-01-19 18:15:45 -0800695 return UINT_MAX;
Jason Evansc4c25922017-01-15 16:56:30 -0800696 }
Jason Evans609ae592012-10-11 13:53:15 -0700697
Jason Evans8bb31982014-10-07 23:14:57 -0700698 /* Initialize new arena. */
Jason Evansc4c25922017-01-15 16:56:30 -0800699 if (arena_init(tsdn, arena_ind, extent_hooks) == NULL) {
Jason Evansf4086432017-01-19 18:15:45 -0800700 return UINT_MAX;
Jason Evansc4c25922017-01-15 16:56:30 -0800701 }
Jason Evans609ae592012-10-11 13:53:15 -0700702
Jason Evansc4c25922017-01-15 16:56:30 -0800703 if (arena_ind == ctl_arenas->narenas) {
Jason Evans9eb1b1c2017-01-18 23:03:37 -0800704 ctl_arenas->narenas++;
Jason Evansc4c25922017-01-15 16:56:30 -0800705 }
Jason Evansedf1baf2017-01-03 17:21:59 -0800706
Jason Evansf4086432017-01-19 18:15:45 -0800707 return arena_ind;
Jason Evans609ae592012-10-11 13:53:15 -0700708}
709
Jason Evans3c234352010-01-27 13:10:55 -0800710static void
Jason Evansc4c25922017-01-15 16:56:30 -0800711ctl_refresh(tsdn_t *tsdn) {
Jason Evans3c234352010-01-27 13:10:55 -0800712 unsigned i;
Jason Evans9eb1b1c2017-01-18 23:03:37 -0800713 ctl_arena_t *ctl_sarena = arenas_i(MALLCTL_ARENAS_ALL);
714 VARIABLE_ARRAY(arena_t *, tarenas, ctl_arenas->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 Evans9eb1b1c2017-01-18 23:03:37 -0800720 ctl_arena_clear(ctl_sarena);
Jason Evans3c234352010-01-27 13:10:55 -0800721
Jason Evans9eb1b1c2017-01-18 23:03:37 -0800722 for (i = 0; i < ctl_arenas->narenas; i++) {
Jason Evansc1e00ef2016-05-10 22:21:10 -0700723 tarenas[i] = arena_get(tsdn, i, false);
Jason Evans9eb1b1c2017-01-18 23:03:37 -0800724 }
Jason Evans8bb31982014-10-07 23:14:57 -0700725
Jason Evans9eb1b1c2017-01-18 23:03:37 -0800726 for (i = 0; i < ctl_arenas->narenas; i++) {
727 ctl_arena_t *ctl_arena = arenas_i(i);
Jason Evans3c234352010-01-27 13:10:55 -0800728 bool initialized = (tarenas[i] != NULL);
729
Jason Evans9eb1b1c2017-01-18 23:03:37 -0800730 ctl_arena->initialized = initialized;
731 if (initialized) {
732 ctl_arena_refresh(tsdn, tarenas[i], ctl_sarena, i,
733 false);
734 }
Jason Evans3c234352010-01-27 13:10:55 -0800735 }
736
Jason Evans7372b152012-02-10 20:22:09 -0800737 if (config_stats) {
Jason Evans9eb1b1c2017-01-18 23:03:37 -0800738 ctl_stats->allocated = ctl_sarena->astats->allocated_small +
739 ctl_sarena->astats->astats.allocated_large;
740 ctl_stats->active = (ctl_sarena->pactive << LG_PAGE);
741 ctl_stats->metadata = ctl_sarena->astats->astats.base +
742 ctl_sarena->astats->astats.internal;
743 ctl_stats->resident = ctl_sarena->astats->astats.resident;
744 ctl_stats->mapped = ctl_sarena->astats->astats.mapped;
745 ctl_stats->retained = ctl_sarena->astats->astats.retained;
Jason Evans7372b152012-02-10 20:22:09 -0800746 }
Jason Evans9eb1b1c2017-01-18 23:03:37 -0800747 ctl_arenas->epoch++;
Jason Evans3c234352010-01-27 13:10:55 -0800748}
749
750static bool
Jason Evansc4c25922017-01-15 16:56:30 -0800751ctl_init(tsdn_t *tsdn) {
Jason Evansfc4dcfa2010-11-24 15:44:21 -0800752 bool ret;
Jason Evans3c234352010-01-27 13:10:55 -0800753
Jason Evansc1e00ef2016-05-10 22:21:10 -0700754 malloc_mutex_lock(tsdn, &ctl_mtx);
Jason Evans551ebc42014-10-03 10:16:09 -0700755 if (!ctl_initialized) {
Jason Evans9eb1b1c2017-01-18 23:03:37 -0800756 ctl_arena_t *ctl_sarena, *ctl_darena;
Jason Evansd778dd22017-01-03 12:40:54 -0800757 unsigned i;
758
Jason Evans3c234352010-01-27 13:10:55 -0800759 /*
Jason Evans9eb1b1c2017-01-18 23:03:37 -0800760 * Allocate demand-zeroed space for pointers to the full
761 * range of supported arena indices.
Jason Evans3c234352010-01-27 13:10:55 -0800762 */
Jason Evans9eb1b1c2017-01-18 23:03:37 -0800763 if (ctl_arenas == NULL) {
764 ctl_arenas = (ctl_arenas_t *)base_alloc(tsdn,
765 b0get(), sizeof(ctl_arenas_t), QUANTUM);
766 if (ctl_arenas == NULL) {
767 ret = true;
768 goto label_return;
769 }
770 }
771
772 if (config_stats && ctl_stats == NULL) {
Jason Evansd778dd22017-01-03 12:40:54 -0800773 ctl_stats = (ctl_stats_t *)base_alloc(tsdn, b0get(),
774 sizeof(ctl_stats_t), QUANTUM);
775 if (ctl_stats == NULL) {
776 ret = true;
777 goto label_return;
778 }
779 }
780
781 /*
Jason Evans9eb1b1c2017-01-18 23:03:37 -0800782 * Allocate space for the current full range of arenas
783 * here rather than doing it lazily elsewhere, in order
784 * to limit when OOM-caused errors can occur.
Jason Evansd778dd22017-01-03 12:40:54 -0800785 */
Jason Evans9eb1b1c2017-01-18 23:03:37 -0800786 if ((ctl_sarena = arenas_i_impl(tsdn, MALLCTL_ARENAS_ALL, false,
787 true)) == NULL) {
788 ret = true;
789 goto label_return;
790 }
791 ctl_sarena->initialized = true;
792
793 if ((ctl_darena = arenas_i_impl(tsdn, MALLCTL_ARENAS_DESTROYED,
Jason Evansd778dd22017-01-03 12:40:54 -0800794 false, true)) == NULL) {
Jason Evansfc4dcfa2010-11-24 15:44:21 -0800795 ret = true;
Jason Evansa1ee7832012-04-10 15:07:44 -0700796 goto label_return;
Jason Evansfc4dcfa2010-11-24 15:44:21 -0800797 }
Jason Evans9eb1b1c2017-01-18 23:03:37 -0800798 ctl_arena_clear(ctl_darena);
Jason Evansedf1baf2017-01-03 17:21:59 -0800799 /*
Jason Evans9eb1b1c2017-01-18 23:03:37 -0800800 * Don't toggle ctl_darena to initialized until an arena is
801 * actually destroyed, so that arena.<i>.initialized can be used
802 * to query whether the stats are relevant.
Jason Evansedf1baf2017-01-03 17:21:59 -0800803 */
804
Jason Evans9eb1b1c2017-01-18 23:03:37 -0800805 ctl_arenas->narenas = narenas_total_get();
806 for (i = 0; i < ctl_arenas->narenas; i++) {
807 if (arenas_i_impl(tsdn, i, false, true) == NULL) {
Jason Evansd778dd22017-01-03 12:40:54 -0800808 ret = true;
809 goto label_return;
810 }
811 }
Jason Evans3c234352010-01-27 13:10:55 -0800812
Jason Evans9eb1b1c2017-01-18 23:03:37 -0800813 ql_new(&ctl_arenas->destroyed);
Jason Evansc1e00ef2016-05-10 22:21:10 -0700814 ctl_refresh(tsdn);
Jason Evans9eb1b1c2017-01-18 23:03:37 -0800815
Jason Evans3c234352010-01-27 13:10:55 -0800816 ctl_initialized = true;
817 }
818
Jason Evansfc4dcfa2010-11-24 15:44:21 -0800819 ret = false;
Jason Evansa1ee7832012-04-10 15:07:44 -0700820label_return:
Jason Evansc1e00ef2016-05-10 22:21:10 -0700821 malloc_mutex_unlock(tsdn, &ctl_mtx);
Jason Evansf4086432017-01-19 18:15:45 -0800822 return ret;
Jason Evans3c234352010-01-27 13:10:55 -0800823}
824
825static int
Jason Evansc1e00ef2016-05-10 22:21:10 -0700826ctl_lookup(tsdn_t *tsdn, const char *name, ctl_node_t const **nodesp,
Jason Evansc4c25922017-01-15 16:56:30 -0800827 size_t *mibp, size_t *depthp) {
Jason Evans3c234352010-01-27 13:10:55 -0800828 int ret;
829 const char *elm, *tdot, *dot;
830 size_t elen, i, j;
Mike Hommey461ad5c2012-04-20 08:38:42 +0200831 const ctl_named_node_t *node;
Jason Evans3c234352010-01-27 13:10:55 -0800832
833 elm = name;
834 /* Equivalent to strchrnul(). */
835 dot = ((tdot = strchr(elm, '.')) != NULL) ? tdot : strchr(elm, '\0');
836 elen = (size_t)((uintptr_t)dot - (uintptr_t)elm);
837 if (elen == 0) {
838 ret = ENOENT;
Jason Evansa1ee7832012-04-10 15:07:44 -0700839 goto label_return;
Jason Evans3c234352010-01-27 13:10:55 -0800840 }
841 node = super_root_node;
842 for (i = 0; i < *depthp; i++) {
Mike Hommey461ad5c2012-04-20 08:38:42 +0200843 assert(node);
844 assert(node->nchildren > 0);
845 if (ctl_named_node(node->children) != NULL) {
846 const ctl_named_node_t *pnode = node;
Jason Evans3c234352010-01-27 13:10:55 -0800847
848 /* Children are named. */
Mike Hommey461ad5c2012-04-20 08:38:42 +0200849 for (j = 0; j < node->nchildren; j++) {
850 const ctl_named_node_t *child =
851 ctl_named_children(node, j);
852 if (strlen(child->name) == elen &&
853 strncmp(elm, child->name, elen) == 0) {
Jason Evans3c234352010-01-27 13:10:55 -0800854 node = child;
Jason Evansc4c25922017-01-15 16:56:30 -0800855 if (nodesp != NULL) {
Mike Hommey461ad5c2012-04-20 08:38:42 +0200856 nodesp[i] =
857 (const ctl_node_t *)node;
Jason Evansc4c25922017-01-15 16:56:30 -0800858 }
Jason Evans3c234352010-01-27 13:10:55 -0800859 mibp[i] = j;
860 break;
861 }
862 }
863 if (node == pnode) {
864 ret = ENOENT;
Jason Evansa1ee7832012-04-10 15:07:44 -0700865 goto label_return;
Jason Evans3c234352010-01-27 13:10:55 -0800866 }
867 } else {
Jason Evans41b6afb2012-02-02 22:04:57 -0800868 uintmax_t index;
Mike Hommey461ad5c2012-04-20 08:38:42 +0200869 const ctl_indexed_node_t *inode;
Jason Evans3c234352010-01-27 13:10:55 -0800870
871 /* Children are indexed. */
Jason Evans41b6afb2012-02-02 22:04:57 -0800872 index = malloc_strtoumax(elm, NULL, 10);
873 if (index == UINTMAX_MAX || index > SIZE_T_MAX) {
Jason Evans3c234352010-01-27 13:10:55 -0800874 ret = ENOENT;
Jason Evansa1ee7832012-04-10 15:07:44 -0700875 goto label_return;
Jason Evans3c234352010-01-27 13:10:55 -0800876 }
877
Mike Hommey461ad5c2012-04-20 08:38:42 +0200878 inode = ctl_indexed_node(node->children);
Jason Evansc1e00ef2016-05-10 22:21:10 -0700879 node = inode->index(tsdn, mibp, *depthp, (size_t)index);
Jason Evans3c234352010-01-27 13:10:55 -0800880 if (node == NULL) {
881 ret = ENOENT;
Jason Evansa1ee7832012-04-10 15:07:44 -0700882 goto label_return;
Jason Evans3c234352010-01-27 13:10:55 -0800883 }
884
Jason Evansc4c25922017-01-15 16:56:30 -0800885 if (nodesp != NULL) {
Mike Hommey461ad5c2012-04-20 08:38:42 +0200886 nodesp[i] = (const ctl_node_t *)node;
Jason Evansc4c25922017-01-15 16:56:30 -0800887 }
Jason Evans3c234352010-01-27 13:10:55 -0800888 mibp[i] = (size_t)index;
889 }
890
891 if (node->ctl != NULL) {
892 /* Terminal node. */
893 if (*dot != '\0') {
894 /*
895 * The name contains more elements than are
896 * in this path through the tree.
897 */
898 ret = ENOENT;
Jason Evansa1ee7832012-04-10 15:07:44 -0700899 goto label_return;
Jason Evans3c234352010-01-27 13:10:55 -0800900 }
901 /* Complete lookup successful. */
902 *depthp = i + 1;
903 break;
904 }
905
906 /* Update elm. */
907 if (*dot == '\0') {
908 /* No more elements. */
909 ret = ENOENT;
Jason Evansa1ee7832012-04-10 15:07:44 -0700910 goto label_return;
Jason Evans3c234352010-01-27 13:10:55 -0800911 }
912 elm = &dot[1];
913 dot = ((tdot = strchr(elm, '.')) != NULL) ? tdot :
914 strchr(elm, '\0');
915 elen = (size_t)((uintptr_t)dot - (uintptr_t)elm);
916 }
917
918 ret = 0;
Jason Evansa1ee7832012-04-10 15:07:44 -0700919label_return:
Jason Evansf4086432017-01-19 18:15:45 -0800920 return ret;
Jason Evans3c234352010-01-27 13:10:55 -0800921}
922
923int
Jason Evansb2c0d632016-04-13 23:36:15 -0700924ctl_byname(tsd_t *tsd, const char *name, void *oldp, size_t *oldlenp,
Jason Evansc4c25922017-01-15 16:56:30 -0800925 void *newp, size_t newlen) {
Jason Evans3c234352010-01-27 13:10:55 -0800926 int ret;
927 size_t depth;
928 ctl_node_t const *nodes[CTL_MAX_DEPTH];
929 size_t mib[CTL_MAX_DEPTH];
Mike Hommey461ad5c2012-04-20 08:38:42 +0200930 const ctl_named_node_t *node;
Jason Evans3c234352010-01-27 13:10:55 -0800931
Jason Evansc1e00ef2016-05-10 22:21:10 -0700932 if (!ctl_initialized && ctl_init(tsd_tsdn(tsd))) {
Jason Evans3c234352010-01-27 13:10:55 -0800933 ret = EAGAIN;
Jason Evansa1ee7832012-04-10 15:07:44 -0700934 goto label_return;
Jason Evans3c234352010-01-27 13:10:55 -0800935 }
936
937 depth = CTL_MAX_DEPTH;
Jason Evansc1e00ef2016-05-10 22:21:10 -0700938 ret = ctl_lookup(tsd_tsdn(tsd), name, nodes, mib, &depth);
Jason Evansc4c25922017-01-15 16:56:30 -0800939 if (ret != 0) {
Jason Evansa1ee7832012-04-10 15:07:44 -0700940 goto label_return;
Jason Evansc4c25922017-01-15 16:56:30 -0800941 }
Jason Evans3c234352010-01-27 13:10:55 -0800942
Mike Hommey461ad5c2012-04-20 08:38:42 +0200943 node = ctl_named_node(nodes[depth-1]);
Jason Evansc4c25922017-01-15 16:56:30 -0800944 if (node != NULL && node->ctl) {
Jason Evansb2c0d632016-04-13 23:36:15 -0700945 ret = node->ctl(tsd, mib, depth, oldp, oldlenp, newp, newlen);
Jason Evansc4c25922017-01-15 16:56:30 -0800946 }
Mike Hommey461ad5c2012-04-20 08:38:42 +0200947 else {
Jason Evans3c234352010-01-27 13:10:55 -0800948 /* The name refers to a partial path through the ctl tree. */
949 ret = ENOENT;
Jason Evans3c234352010-01-27 13:10:55 -0800950 }
Jason Evans3c234352010-01-27 13:10:55 -0800951
Jason Evansa1ee7832012-04-10 15:07:44 -0700952label_return:
Jason Evans3c234352010-01-27 13:10:55 -0800953 return(ret);
954}
955
956int
Jason Evansc4c25922017-01-15 16:56:30 -0800957ctl_nametomib(tsdn_t *tsdn, const char *name, size_t *mibp, size_t *miblenp) {
Jason Evans3c234352010-01-27 13:10:55 -0800958 int ret;
959
Jason Evansc1e00ef2016-05-10 22:21:10 -0700960 if (!ctl_initialized && ctl_init(tsdn)) {
Jason Evans3c234352010-01-27 13:10:55 -0800961 ret = EAGAIN;
Jason Evansa1ee7832012-04-10 15:07:44 -0700962 goto label_return;
Jason Evans3c234352010-01-27 13:10:55 -0800963 }
964
Jason Evansc1e00ef2016-05-10 22:21:10 -0700965 ret = ctl_lookup(tsdn, name, NULL, mibp, miblenp);
Jason Evansa1ee7832012-04-10 15:07:44 -0700966label_return:
Jason Evans3c234352010-01-27 13:10:55 -0800967 return(ret);
968}
969
970int
Jason Evansb2c0d632016-04-13 23:36:15 -0700971ctl_bymib(tsd_t *tsd, const size_t *mib, size_t miblen, void *oldp,
Jason Evansc4c25922017-01-15 16:56:30 -0800972 size_t *oldlenp, void *newp, size_t newlen) {
Jason Evans3c234352010-01-27 13:10:55 -0800973 int ret;
Mike Hommey461ad5c2012-04-20 08:38:42 +0200974 const ctl_named_node_t *node;
Jason Evans3c234352010-01-27 13:10:55 -0800975 size_t i;
976
Jason Evansc1e00ef2016-05-10 22:21:10 -0700977 if (!ctl_initialized && ctl_init(tsd_tsdn(tsd))) {
Jason Evans3c234352010-01-27 13:10:55 -0800978 ret = EAGAIN;
Jason Evansa1ee7832012-04-10 15:07:44 -0700979 goto label_return;
Jason Evans3c234352010-01-27 13:10:55 -0800980 }
981
982 /* Iterate down the tree. */
983 node = super_root_node;
984 for (i = 0; i < miblen; i++) {
Mike Hommey461ad5c2012-04-20 08:38:42 +0200985 assert(node);
986 assert(node->nchildren > 0);
987 if (ctl_named_node(node->children) != NULL) {
Jason Evans3c234352010-01-27 13:10:55 -0800988 /* Children are named. */
Jason Evans6edbedd2017-01-04 07:51:49 -0800989 if (node->nchildren <= mib[i]) {
Jason Evans3c234352010-01-27 13:10:55 -0800990 ret = ENOENT;
Jason Evansa1ee7832012-04-10 15:07:44 -0700991 goto label_return;
Jason Evans3c234352010-01-27 13:10:55 -0800992 }
Mike Hommey461ad5c2012-04-20 08:38:42 +0200993 node = ctl_named_children(node, mib[i]);
Jason Evans3c234352010-01-27 13:10:55 -0800994 } else {
Mike Hommey461ad5c2012-04-20 08:38:42 +0200995 const ctl_indexed_node_t *inode;
Jason Evans3c234352010-01-27 13:10:55 -0800996
997 /* Indexed element. */
Mike Hommey461ad5c2012-04-20 08:38:42 +0200998 inode = ctl_indexed_node(node->children);
Jason Evansc1e00ef2016-05-10 22:21:10 -0700999 node = inode->index(tsd_tsdn(tsd), mib, miblen, mib[i]);
Jason Evans3c234352010-01-27 13:10:55 -08001000 if (node == NULL) {
1001 ret = ENOENT;
Jason Evansa1ee7832012-04-10 15:07:44 -07001002 goto label_return;
Jason Evans3c234352010-01-27 13:10:55 -08001003 }
1004 }
1005 }
1006
1007 /* Call the ctl function. */
Jason Evansc4c25922017-01-15 16:56:30 -08001008 if (node && node->ctl) {
Jason Evansb2c0d632016-04-13 23:36:15 -07001009 ret = node->ctl(tsd, mib, miblen, oldp, oldlenp, newp, newlen);
Jason Evansc4c25922017-01-15 16:56:30 -08001010 } else {
Jason Evans3c234352010-01-27 13:10:55 -08001011 /* Partial MIB. */
1012 ret = ENOENT;
Jason Evans3c234352010-01-27 13:10:55 -08001013 }
Jason Evans3c234352010-01-27 13:10:55 -08001014
Jason Evansa1ee7832012-04-10 15:07:44 -07001015label_return:
Jason Evans3c234352010-01-27 13:10:55 -08001016 return(ret);
1017}
1018
1019bool
Jason Evansc4c25922017-01-15 16:56:30 -08001020ctl_boot(void) {
1021 if (malloc_mutex_init(&ctl_mtx, "ctl", WITNESS_RANK_CTL)) {
Jason Evansf4086432017-01-19 18:15:45 -08001022 return true;
Jason Evansc4c25922017-01-15 16:56:30 -08001023 }
Jason Evans3c234352010-01-27 13:10:55 -08001024
1025 ctl_initialized = false;
1026
Jason Evansf4086432017-01-19 18:15:45 -08001027 return false;
Jason Evans3c234352010-01-27 13:10:55 -08001028}
1029
Jason Evans20f1fc92012-10-09 14:46:22 -07001030void
Jason Evansc4c25922017-01-15 16:56:30 -08001031ctl_prefork(tsdn_t *tsdn) {
Jason Evansc1e00ef2016-05-10 22:21:10 -07001032 malloc_mutex_prefork(tsdn, &ctl_mtx);
Jason Evans20f1fc92012-10-09 14:46:22 -07001033}
1034
1035void
Jason Evansc4c25922017-01-15 16:56:30 -08001036ctl_postfork_parent(tsdn_t *tsdn) {
Jason Evansc1e00ef2016-05-10 22:21:10 -07001037 malloc_mutex_postfork_parent(tsdn, &ctl_mtx);
Jason Evans20f1fc92012-10-09 14:46:22 -07001038}
1039
1040void
Jason Evansc4c25922017-01-15 16:56:30 -08001041ctl_postfork_child(tsdn_t *tsdn) {
Jason Evansc1e00ef2016-05-10 22:21:10 -07001042 malloc_mutex_postfork_child(tsdn, &ctl_mtx);
Jason Evans20f1fc92012-10-09 14:46:22 -07001043}
1044
Jason Evans3c234352010-01-27 13:10:55 -08001045/******************************************************************************/
1046/* *_ctl() functions. */
1047
1048#define READONLY() do { \
1049 if (newp != NULL || newlen != 0) { \
1050 ret = EPERM; \
Jason Evans6b9ed672012-04-25 13:12:46 -07001051 goto label_return; \
Jason Evans3c234352010-01-27 13:10:55 -08001052 } \
1053} while (0)
1054
Jason Evans22ca8552010-03-02 11:57:30 -08001055#define WRITEONLY() do { \
Jason Evans3c234352010-01-27 13:10:55 -08001056 if (oldp != NULL || oldlenp != NULL) { \
1057 ret = EPERM; \
Jason Evans6b9ed672012-04-25 13:12:46 -07001058 goto label_return; \
Jason Evans3c234352010-01-27 13:10:55 -08001059 } \
1060} while (0)
1061
Jason Evansfc12c0b2014-10-03 23:25:30 -07001062#define READ_XOR_WRITE() do { \
1063 if ((oldp != NULL && oldlenp != NULL) && (newp != NULL || \
1064 newlen != 0)) { \
1065 ret = EPERM; \
1066 goto label_return; \
1067 } \
1068} while (0)
1069
Jason Evans3c234352010-01-27 13:10:55 -08001070#define READ(v, t) do { \
1071 if (oldp != NULL && oldlenp != NULL) { \
1072 if (*oldlenp != sizeof(t)) { \
1073 size_t copylen = (sizeof(t) <= *oldlenp) \
1074 ? sizeof(t) : *oldlenp; \
Jason Evans6eb84fb2012-11-29 22:13:04 -08001075 memcpy(oldp, (void *)&(v), copylen); \
Jason Evans3c234352010-01-27 13:10:55 -08001076 ret = EINVAL; \
Jason Evans6b9ed672012-04-25 13:12:46 -07001077 goto label_return; \
Jason Evansb49a3342015-07-28 11:28:19 -04001078 } \
1079 *(t *)oldp = (v); \
Jason Evans3c234352010-01-27 13:10:55 -08001080 } \
1081} while (0)
1082
1083#define WRITE(v, t) do { \
1084 if (newp != NULL) { \
1085 if (newlen != sizeof(t)) { \
1086 ret = EINVAL; \
Jason Evans6b9ed672012-04-25 13:12:46 -07001087 goto label_return; \
Jason Evans3c234352010-01-27 13:10:55 -08001088 } \
Jason Evans6eb84fb2012-11-29 22:13:04 -08001089 (v) = *(t *)newp; \
Jason Evans3c234352010-01-27 13:10:55 -08001090 } \
1091} while (0)
1092
Jason Evans6edbedd2017-01-04 07:51:49 -08001093#define MIB_UNSIGNED(v, i) do { \
1094 if (mib[i] > UINT_MAX) { \
1095 ret = EFAULT; \
1096 goto label_return; \
1097 } \
1098 v = (unsigned)mib[i]; \
1099} while (0)
1100
Jason Evans7372b152012-02-10 20:22:09 -08001101/*
1102 * There's a lot of code duplication in the following macros due to limitations
1103 * in how nested cpp macros are expanded.
1104 */
1105#define CTL_RO_CLGEN(c, l, n, v, t) \
1106static int \
Jason Evansb2c0d632016-04-13 23:36:15 -07001107n##_ctl(tsd_t *tsd, const size_t *mib, size_t miblen, void *oldp, \
Jason Evansc4c25922017-01-15 16:56:30 -08001108 size_t *oldlenp, void *newp, size_t newlen) { \
Jason Evans7372b152012-02-10 20:22:09 -08001109 int ret; \
1110 t oldval; \
1111 \
Jason Evansc4c25922017-01-15 16:56:30 -08001112 if (!(c)) { \
Jason Evansf4086432017-01-19 18:15:45 -08001113 return ENOENT; \
Jason Evansc4c25922017-01-15 16:56:30 -08001114 } \
1115 if (l) { \
Jason Evansc1e00ef2016-05-10 22:21:10 -07001116 malloc_mutex_lock(tsd_tsdn(tsd), &ctl_mtx); \
Jason Evansc4c25922017-01-15 16:56:30 -08001117 } \
Jason Evans7372b152012-02-10 20:22:09 -08001118 READONLY(); \
Jason Evans6eb84fb2012-11-29 22:13:04 -08001119 oldval = (v); \
Jason Evans7372b152012-02-10 20:22:09 -08001120 READ(oldval, t); \
1121 \
1122 ret = 0; \
Jason Evans6b9ed672012-04-25 13:12:46 -07001123label_return: \
Jason Evansc4c25922017-01-15 16:56:30 -08001124 if (l) { \
Jason Evansc1e00ef2016-05-10 22:21:10 -07001125 malloc_mutex_unlock(tsd_tsdn(tsd), &ctl_mtx); \
Jason Evansc4c25922017-01-15 16:56:30 -08001126 } \
Jason Evansf4086432017-01-19 18:15:45 -08001127 return ret; \
Jason Evans7372b152012-02-10 20:22:09 -08001128}
1129
1130#define CTL_RO_CGEN(c, n, v, t) \
1131static int \
Jason Evansb2c0d632016-04-13 23:36:15 -07001132n##_ctl(tsd_t *tsd, const size_t *mib, size_t miblen, void *oldp, \
Jason Evansc4c25922017-01-15 16:56:30 -08001133 size_t *oldlenp, void *newp, size_t newlen) { \
Jason Evans7372b152012-02-10 20:22:09 -08001134 int ret; \
1135 t oldval; \
1136 \
Jason Evansc4c25922017-01-15 16:56:30 -08001137 if (!(c)) { \
Jason Evansf4086432017-01-19 18:15:45 -08001138 return ENOENT; \
Jason Evansc4c25922017-01-15 16:56:30 -08001139 } \
Jason Evansc1e00ef2016-05-10 22:21:10 -07001140 malloc_mutex_lock(tsd_tsdn(tsd), &ctl_mtx); \
Jason Evans7372b152012-02-10 20:22:09 -08001141 READONLY(); \
Jason Evans6eb84fb2012-11-29 22:13:04 -08001142 oldval = (v); \
Jason Evans7372b152012-02-10 20:22:09 -08001143 READ(oldval, t); \
1144 \
1145 ret = 0; \
Jason Evans6b9ed672012-04-25 13:12:46 -07001146label_return: \
Jason Evansc1e00ef2016-05-10 22:21:10 -07001147 malloc_mutex_unlock(tsd_tsdn(tsd), &ctl_mtx); \
Jason Evansf4086432017-01-19 18:15:45 -08001148 return ret; \
Jason Evans7372b152012-02-10 20:22:09 -08001149}
1150
Jason Evans3c234352010-01-27 13:10:55 -08001151#define CTL_RO_GEN(n, v, t) \
1152static int \
Jason Evansb2c0d632016-04-13 23:36:15 -07001153n##_ctl(tsd_t *tsd, const size_t *mib, size_t miblen, void *oldp, \
Jason Evansc4c25922017-01-15 16:56:30 -08001154 size_t *oldlenp, void *newp, size_t newlen) { \
Jason Evans3c234352010-01-27 13:10:55 -08001155 int ret; \
1156 t oldval; \
1157 \
Jason Evansc1e00ef2016-05-10 22:21:10 -07001158 malloc_mutex_lock(tsd_tsdn(tsd), &ctl_mtx); \
Jason Evansfc4dcfa2010-11-24 15:44:21 -08001159 READONLY(); \
Jason Evans6eb84fb2012-11-29 22:13:04 -08001160 oldval = (v); \
Jason Evansfc4dcfa2010-11-24 15:44:21 -08001161 READ(oldval, t); \
1162 \
1163 ret = 0; \
Jason Evans6b9ed672012-04-25 13:12:46 -07001164label_return: \
Jason Evansc1e00ef2016-05-10 22:21:10 -07001165 malloc_mutex_unlock(tsd_tsdn(tsd), &ctl_mtx); \
Jason Evansf4086432017-01-19 18:15:45 -08001166 return ret; \
Jason Evansfc4dcfa2010-11-24 15:44:21 -08001167}
1168
1169/*
1170 * ctl_mtx is not acquired, under the assumption that no pertinent data will
1171 * mutate during the call.
1172 */
Jason Evans7372b152012-02-10 20:22:09 -08001173#define CTL_RO_NL_CGEN(c, n, v, t) \
1174static int \
Jason Evansb2c0d632016-04-13 23:36:15 -07001175n##_ctl(tsd_t *tsd, const size_t *mib, size_t miblen, void *oldp, \
Jason Evansc4c25922017-01-15 16:56:30 -08001176 size_t *oldlenp, void *newp, size_t newlen) { \
Jason Evans7372b152012-02-10 20:22:09 -08001177 int ret; \
1178 t oldval; \
1179 \
Jason Evansc4c25922017-01-15 16:56:30 -08001180 if (!(c)) { \
Jason Evansf4086432017-01-19 18:15:45 -08001181 return ENOENT; \
Jason Evansc4c25922017-01-15 16:56:30 -08001182 } \
Jason Evans7372b152012-02-10 20:22:09 -08001183 READONLY(); \
Jason Evans6eb84fb2012-11-29 22:13:04 -08001184 oldval = (v); \
Jason Evans7372b152012-02-10 20:22:09 -08001185 READ(oldval, t); \
1186 \
1187 ret = 0; \
Jason Evans6b9ed672012-04-25 13:12:46 -07001188label_return: \
Jason Evansf4086432017-01-19 18:15:45 -08001189 return ret; \
Jason Evans7372b152012-02-10 20:22:09 -08001190}
1191
1192#define CTL_RO_NL_GEN(n, v, t) \
Jason Evansfc4dcfa2010-11-24 15:44:21 -08001193static int \
Jason Evansb2c0d632016-04-13 23:36:15 -07001194n##_ctl(tsd_t *tsd, const size_t *mib, size_t miblen, void *oldp, \
Jason Evansc4c25922017-01-15 16:56:30 -08001195 size_t *oldlenp, void *newp, size_t newlen) { \
Jason Evansfc4dcfa2010-11-24 15:44:21 -08001196 int ret; \
1197 t oldval; \
1198 \
Jason Evans3c234352010-01-27 13:10:55 -08001199 READONLY(); \
Jason Evans6eb84fb2012-11-29 22:13:04 -08001200 oldval = (v); \
Jason Evans3c234352010-01-27 13:10:55 -08001201 READ(oldval, t); \
1202 \
1203 ret = 0; \
Jason Evans6b9ed672012-04-25 13:12:46 -07001204label_return: \
Jason Evansf4086432017-01-19 18:15:45 -08001205 return ret; \
Jason Evans3c234352010-01-27 13:10:55 -08001206}
1207
Jason Evans5460aa62014-09-22 21:09:23 -07001208#define CTL_TSD_RO_NL_CGEN(c, n, m, t) \
1209static int \
Jason Evansb2c0d632016-04-13 23:36:15 -07001210n##_ctl(tsd_t *tsd, const size_t *mib, size_t miblen, void *oldp, \
Jason Evansc4c25922017-01-15 16:56:30 -08001211 size_t *oldlenp, void *newp, size_t newlen) { \
Jason Evans5460aa62014-09-22 21:09:23 -07001212 int ret; \
1213 t oldval; \
Jason Evans5460aa62014-09-22 21:09:23 -07001214 \
Jason Evansc4c25922017-01-15 16:56:30 -08001215 if (!(c)) { \
Jason Evansf4086432017-01-19 18:15:45 -08001216 return ENOENT; \
Jason Evansc4c25922017-01-15 16:56:30 -08001217 } \
Jason Evans5460aa62014-09-22 21:09:23 -07001218 READONLY(); \
Jason Evans5460aa62014-09-22 21:09:23 -07001219 oldval = (m(tsd)); \
1220 READ(oldval, t); \
1221 \
1222 ret = 0; \
1223label_return: \
Jason Evansf4086432017-01-19 18:15:45 -08001224 return ret; \
Jason Evans5460aa62014-09-22 21:09:23 -07001225}
1226
Jason Evansf8290092016-02-07 14:23:22 -08001227#define CTL_RO_CONFIG_GEN(n, t) \
Jason Evans3c234352010-01-27 13:10:55 -08001228static int \
Jason Evansb2c0d632016-04-13 23:36:15 -07001229n##_ctl(tsd_t *tsd, const size_t *mib, size_t miblen, void *oldp, \
Jason Evansc4c25922017-01-15 16:56:30 -08001230 size_t *oldlenp, void *newp, size_t newlen) { \
Jason Evans3c234352010-01-27 13:10:55 -08001231 int ret; \
Jason Evansf8290092016-02-07 14:23:22 -08001232 t oldval; \
Jason Evans3c234352010-01-27 13:10:55 -08001233 \
1234 READONLY(); \
Jason Evans7372b152012-02-10 20:22:09 -08001235 oldval = n; \
Jason Evansf8290092016-02-07 14:23:22 -08001236 READ(oldval, t); \
Jason Evans3c234352010-01-27 13:10:55 -08001237 \
1238 ret = 0; \
Jason Evans6b9ed672012-04-25 13:12:46 -07001239label_return: \
Jason Evansf4086432017-01-19 18:15:45 -08001240 return ret; \
Jason Evans3c234352010-01-27 13:10:55 -08001241}
1242
Jason Evansd8a39002013-12-19 21:40:41 -08001243/******************************************************************************/
1244
Jason Evansfc4dcfa2010-11-24 15:44:21 -08001245CTL_RO_NL_GEN(version, JEMALLOC_VERSION, const char *)
Jason Evansa40bc7a2010-03-02 13:01:16 -08001246
Jason Evans3c234352010-01-27 13:10:55 -08001247static int
Jason Evansb2c0d632016-04-13 23:36:15 -07001248epoch_ctl(tsd_t *tsd, const size_t *mib, size_t miblen, void *oldp,
Jason Evansc4c25922017-01-15 16:56:30 -08001249 size_t *oldlenp, void *newp, size_t newlen) {
Jason Evans3c234352010-01-27 13:10:55 -08001250 int ret;
Jason Evans3ab682d2013-10-19 17:19:49 -07001251 UNUSED uint64_t newval;
Jason Evans3c234352010-01-27 13:10:55 -08001252
Jason Evansc1e00ef2016-05-10 22:21:10 -07001253 malloc_mutex_lock(tsd_tsdn(tsd), &ctl_mtx);
Jason Evans3c234352010-01-27 13:10:55 -08001254 WRITE(newval, uint64_t);
Jason Evansc4c25922017-01-15 16:56:30 -08001255 if (newp != NULL) {
Jason Evansc1e00ef2016-05-10 22:21:10 -07001256 ctl_refresh(tsd_tsdn(tsd));
Jason Evansc4c25922017-01-15 16:56:30 -08001257 }
Jason Evans9eb1b1c2017-01-18 23:03:37 -08001258 READ(ctl_arenas->epoch, uint64_t);
Jason Evans3c234352010-01-27 13:10:55 -08001259
1260 ret = 0;
Jason Evansa1ee7832012-04-10 15:07:44 -07001261label_return:
Jason Evansc1e00ef2016-05-10 22:21:10 -07001262 malloc_mutex_unlock(tsd_tsdn(tsd), &ctl_mtx);
Jason Evansf4086432017-01-19 18:15:45 -08001263 return ret;
Jason Evans3c234352010-01-27 13:10:55 -08001264}
1265
Jason Evansd8a39002013-12-19 21:40:41 -08001266/******************************************************************************/
Jason Evansd4be8b72012-03-26 18:54:44 -07001267
Jason Evansf8290092016-02-07 14:23:22 -08001268CTL_RO_CONFIG_GEN(config_cache_oblivious, bool)
1269CTL_RO_CONFIG_GEN(config_debug, bool)
1270CTL_RO_CONFIG_GEN(config_fill, bool)
1271CTL_RO_CONFIG_GEN(config_lazy_lock, bool)
1272CTL_RO_CONFIG_GEN(config_malloc_conf, const char *)
1273CTL_RO_CONFIG_GEN(config_munmap, bool)
1274CTL_RO_CONFIG_GEN(config_prof, bool)
1275CTL_RO_CONFIG_GEN(config_prof_libgcc, bool)
1276CTL_RO_CONFIG_GEN(config_prof_libunwind, bool)
1277CTL_RO_CONFIG_GEN(config_stats, bool)
1278CTL_RO_CONFIG_GEN(config_tcache, bool)
1279CTL_RO_CONFIG_GEN(config_tls, bool)
1280CTL_RO_CONFIG_GEN(config_utrace, bool)
Jason Evansf8290092016-02-07 14:23:22 -08001281CTL_RO_CONFIG_GEN(config_xmalloc, bool)
Jason Evansd4be8b72012-03-26 18:54:44 -07001282
Jason Evansd8a39002013-12-19 21:40:41 -08001283/******************************************************************************/
Jason Evansd4be8b72012-03-26 18:54:44 -07001284
Jason Evansd8a39002013-12-19 21:40:41 -08001285CTL_RO_NL_GEN(opt_abort, opt_abort, bool)
1286CTL_RO_NL_GEN(opt_dss, opt_dss, const char *)
Jason Evans8f683b92016-02-24 11:03:40 -08001287CTL_RO_NL_GEN(opt_narenas, opt_narenas, unsigned)
Jason Evans243f7a02016-02-19 20:09:31 -08001288CTL_RO_NL_GEN(opt_decay_time, opt_decay_time, ssize_t)
Jason Evansd8a39002013-12-19 21:40:41 -08001289CTL_RO_NL_GEN(opt_stats_print, opt_stats_print, bool)
Guilherme Goncalves2c5cb612014-12-08 19:12:41 -02001290CTL_RO_NL_CGEN(config_fill, opt_junk, opt_junk, const char *)
Jason Evansd8a39002013-12-19 21:40:41 -08001291CTL_RO_NL_CGEN(config_fill, opt_zero, opt_zero, bool)
1292CTL_RO_NL_CGEN(config_utrace, opt_utrace, opt_utrace, bool)
Jason Evansd8a39002013-12-19 21:40:41 -08001293CTL_RO_NL_CGEN(config_xmalloc, opt_xmalloc, opt_xmalloc, bool)
1294CTL_RO_NL_CGEN(config_tcache, opt_tcache, opt_tcache, bool)
1295CTL_RO_NL_CGEN(config_tcache, opt_lg_tcache_max, opt_lg_tcache_max, ssize_t)
1296CTL_RO_NL_CGEN(config_prof, opt_prof, opt_prof, bool)
1297CTL_RO_NL_CGEN(config_prof, opt_prof_prefix, opt_prof_prefix, const char *)
Jason Evansfc12c0b2014-10-03 23:25:30 -07001298CTL_RO_NL_CGEN(config_prof, opt_prof_active, opt_prof_active, bool)
1299CTL_RO_NL_CGEN(config_prof, opt_prof_thread_active_init,
1300 opt_prof_thread_active_init, bool)
Jason Evansd8a39002013-12-19 21:40:41 -08001301CTL_RO_NL_CGEN(config_prof, opt_lg_prof_sample, opt_lg_prof_sample, size_t)
1302CTL_RO_NL_CGEN(config_prof, opt_prof_accum, opt_prof_accum, bool)
1303CTL_RO_NL_CGEN(config_prof, opt_lg_prof_interval, opt_lg_prof_interval, ssize_t)
1304CTL_RO_NL_CGEN(config_prof, opt_prof_gdump, opt_prof_gdump, bool)
1305CTL_RO_NL_CGEN(config_prof, opt_prof_final, opt_prof_final, bool)
1306CTL_RO_NL_CGEN(config_prof, opt_prof_leak, opt_prof_leak, bool)
Jason Evansd4be8b72012-03-26 18:54:44 -07001307
Jason Evansd8a39002013-12-19 21:40:41 -08001308/******************************************************************************/
Jason Evans3c234352010-01-27 13:10:55 -08001309
Jason Evansb267d0f2010-08-13 15:42:29 -07001310static int
Jason Evansb2c0d632016-04-13 23:36:15 -07001311thread_arena_ctl(tsd_t *tsd, const size_t *mib, size_t miblen, void *oldp,
Jason Evansc4c25922017-01-15 16:56:30 -08001312 size_t *oldlenp, void *newp, size_t newlen) {
Jason Evansb267d0f2010-08-13 15:42:29 -07001313 int ret;
Jason Evans1cb181e2015-01-29 15:30:47 -08001314 arena_t *oldarena;
Jason Evansb267d0f2010-08-13 15:42:29 -07001315 unsigned newind, oldind;
1316
Jason Evans90827a32016-05-03 15:00:42 -07001317 oldarena = arena_choose(tsd, NULL);
Jason Evansc4c25922017-01-15 16:56:30 -08001318 if (oldarena == NULL) {
Jason Evansf4086432017-01-19 18:15:45 -08001319 return EAGAIN;
Jason Evansc4c25922017-01-15 16:56:30 -08001320 }
Jason Evans5460aa62014-09-22 21:09:23 -07001321
Jason Evansa0dd3a42016-12-22 16:39:10 -06001322 newind = oldind = arena_ind_get(oldarena);
Jason Evansa7153a02011-03-14 11:39:49 -07001323 WRITE(newind, unsigned);
1324 READ(oldind, unsigned);
Jason Evansb267d0f2010-08-13 15:42:29 -07001325 if (newind != oldind) {
Jason Evans1cb181e2015-01-29 15:30:47 -08001326 arena_t *newarena;
1327
Jason Evansb6c08672016-10-03 10:37:12 -07001328 if (newind >= narenas_total_get()) {
Jason Evansb267d0f2010-08-13 15:42:29 -07001329 /* New arena index is out of range. */
1330 ret = EFAULT;
Jason Evansa1ee7832012-04-10 15:07:44 -07001331 goto label_return;
Jason Evansb267d0f2010-08-13 15:42:29 -07001332 }
1333
1334 /* Initialize arena if necessary. */
Jason Evansc1e00ef2016-05-10 22:21:10 -07001335 newarena = arena_get(tsd_tsdn(tsd), newind, true);
Jason Evans1cb181e2015-01-29 15:30:47 -08001336 if (newarena == NULL) {
Jason Evansb267d0f2010-08-13 15:42:29 -07001337 ret = EAGAIN;
Jason Evansa1ee7832012-04-10 15:07:44 -07001338 goto label_return;
Jason Evansb267d0f2010-08-13 15:42:29 -07001339 }
Jason Evans8bb31982014-10-07 23:14:57 -07001340 /* Set new arena/tcache associations. */
1341 arena_migrate(tsd, oldind, newind);
Jason Evans7372b152012-02-10 20:22:09 -08001342 if (config_tcache) {
Jason Evans5460aa62014-09-22 21:09:23 -07001343 tcache_t *tcache = tsd_tcache_get(tsd);
Jason Evans1cb181e2015-01-29 15:30:47 -08001344 if (tcache != NULL) {
Jason Evansc1e00ef2016-05-10 22:21:10 -07001345 tcache_arena_reassociate(tsd_tsdn(tsd), tcache,
1346 oldarena, newarena);
Jason Evans1cb181e2015-01-29 15:30:47 -08001347 }
Jason Evans624f2f32010-12-29 12:21:05 -08001348 }
Jason Evansb267d0f2010-08-13 15:42:29 -07001349 }
1350
1351 ret = 0;
Jason Evansa1ee7832012-04-10 15:07:44 -07001352label_return:
Jason Evansf4086432017-01-19 18:15:45 -08001353 return ret;
Jason Evansb267d0f2010-08-13 15:42:29 -07001354}
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,
Jason Evansc4c25922017-01-15 16:56:30 -08001367 void *oldp, size_t *oldlenp, void *newp, size_t newlen) {
Jason Evansd8a39002013-12-19 21:40:41 -08001368 int ret;
1369 bool oldval;
Jason Evans3c234352010-01-27 13:10:55 -08001370
Jason Evansc4c25922017-01-15 16:56:30 -08001371 if (!config_tcache) {
Jason Evansf4086432017-01-19 18:15:45 -08001372 return ENOENT;
Jason Evansc4c25922017-01-15 16:56:30 -08001373 }
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:
Jason Evansf4086432017-01-19 18:15:45 -08001387 return ret;
Jason Evansd8a39002013-12-19 21:40:41 -08001388}
1389
1390static int
Jason Evansb2c0d632016-04-13 23:36:15 -07001391thread_tcache_flush_ctl(tsd_t *tsd, const size_t *mib, size_t miblen,
Jason Evansc4c25922017-01-15 16:56:30 -08001392 void *oldp, size_t *oldlenp, void *newp, size_t newlen) {
Jason Evansd8a39002013-12-19 21:40:41 -08001393 int ret;
1394
Jason Evansc4c25922017-01-15 16:56:30 -08001395 if (!config_tcache) {
Jason Evansf4086432017-01-19 18:15:45 -08001396 return ENOENT;
Jason Evansc4c25922017-01-15 16:56:30 -08001397 }
Jason Evansd8a39002013-12-19 21:40:41 -08001398
1399 READONLY();
1400 WRITEONLY();
1401
1402 tcache_flush();
1403
1404 ret = 0;
1405label_return:
Jason Evansf4086432017-01-19 18:15:45 -08001406 return ret;
Jason Evansd8a39002013-12-19 21:40:41 -08001407}
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 Evansc4c25922017-01-15 16:56:30 -08001411 size_t *oldlenp, void *newp, size_t newlen) {
Jason Evans602c8e02014-08-18 16:22:13 -07001412 int ret;
Jason Evans602c8e02014-08-18 16:22:13 -07001413
Jason Evansc4c25922017-01-15 16:56:30 -08001414 if (!config_prof) {
Jason Evansf4086432017-01-19 18:15:45 -08001415 return ENOENT;
Jason Evansc4c25922017-01-15 16:56:30 -08001416 }
Jason Evans602c8e02014-08-18 16:22:13 -07001417
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)) !=
Jason Evansc4c25922017-01-15 16:56:30 -08001427 0) {
Jason Evans602c8e02014-08-18 16:22:13 -07001428 goto label_return;
Jason Evansc4c25922017-01-15 16:56:30 -08001429 }
Jason Evansfc12c0b2014-10-03 23:25:30 -07001430 } else {
Jason Evansb2c0d632016-04-13 23:36:15 -07001431 const char *oldname = prof_thread_name_get(tsd);
Jason Evansfc12c0b2014-10-03 23:25:30 -07001432 READ(oldname, const char *);
Jason Evans602c8e02014-08-18 16:22:13 -07001433 }
Jason Evans602c8e02014-08-18 16:22:13 -07001434
1435 ret = 0;
1436label_return:
Jason Evansf4086432017-01-19 18:15:45 -08001437 return ret;
Jason Evans602c8e02014-08-18 16:22:13 -07001438}
1439
1440static int
Jason Evansb2c0d632016-04-13 23:36:15 -07001441thread_prof_active_ctl(tsd_t *tsd, const size_t *mib, size_t miblen, void *oldp,
Jason Evansc4c25922017-01-15 16:56:30 -08001442 size_t *oldlenp, void *newp, size_t newlen) {
Jason Evans602c8e02014-08-18 16:22:13 -07001443 int ret;
1444 bool oldval;
1445
Jason Evansc4c25922017-01-15 16:56:30 -08001446 if (!config_prof) {
Jason Evansf4086432017-01-19 18:15:45 -08001447 return ENOENT;
Jason Evansc4c25922017-01-15 16:56:30 -08001448 }
Jason Evans602c8e02014-08-18 16:22:13 -07001449
Jason Evansb2c0d632016-04-13 23:36:15 -07001450 oldval = prof_thread_active_get(tsd);
Jason Evans602c8e02014-08-18 16:22:13 -07001451 if (newp != NULL) {
1452 if (newlen != sizeof(bool)) {
1453 ret = EINVAL;
1454 goto label_return;
1455 }
Jason Evansb2c0d632016-04-13 23:36:15 -07001456 if (prof_thread_active_set(tsd, *(bool *)newp)) {
Jason Evans602c8e02014-08-18 16:22:13 -07001457 ret = EAGAIN;
1458 goto label_return;
1459 }
1460 }
1461 READ(oldval, bool);
1462
1463 ret = 0;
1464label_return:
Jason Evansf4086432017-01-19 18:15:45 -08001465 return ret;
Jason Evans602c8e02014-08-18 16:22:13 -07001466}
1467
Jason Evans3c234352010-01-27 13:10:55 -08001468/******************************************************************************/
1469
Jason Evans1cb181e2015-01-29 15:30:47 -08001470static int
Jason Evansb2c0d632016-04-13 23:36:15 -07001471tcache_create_ctl(tsd_t *tsd, const size_t *mib, size_t miblen, void *oldp,
Jason Evansc4c25922017-01-15 16:56:30 -08001472 size_t *oldlenp, void *newp, size_t newlen) {
Jason Evans1cb181e2015-01-29 15:30:47 -08001473 int ret;
Jason Evans1cb181e2015-01-29 15:30:47 -08001474 unsigned tcache_ind;
1475
Jason Evansc4c25922017-01-15 16:56:30 -08001476 if (!config_tcache) {
Jason Evansf4086432017-01-19 18:15:45 -08001477 return ENOENT;
Jason Evansc4c25922017-01-15 16:56:30 -08001478 }
Jason Evans1cb181e2015-01-29 15:30:47 -08001479
Jason Evansc1e00ef2016-05-10 22:21:10 -07001480 malloc_mutex_lock(tsd_tsdn(tsd), &ctl_mtx);
Jason Evans1cb181e2015-01-29 15:30:47 -08001481 READONLY();
Jason Evansb54d1602016-10-20 23:59:12 -07001482 if (tcaches_create(tsd, &tcache_ind)) {
Jason Evans1cb181e2015-01-29 15:30:47 -08001483 ret = EFAULT;
1484 goto label_return;
1485 }
1486 READ(tcache_ind, unsigned);
1487
1488 ret = 0;
1489label_return:
Jason Evansc1e00ef2016-05-10 22:21:10 -07001490 malloc_mutex_unlock(tsd_tsdn(tsd), &ctl_mtx);
Jason Evansf4086432017-01-19 18:15:45 -08001491 return ret;
Jason Evans1cb181e2015-01-29 15:30:47 -08001492}
1493
1494static int
Jason Evansb2c0d632016-04-13 23:36:15 -07001495tcache_flush_ctl(tsd_t *tsd, const size_t *mib, size_t miblen, void *oldp,
Jason Evansc4c25922017-01-15 16:56:30 -08001496 size_t *oldlenp, void *newp, size_t newlen) {
Jason Evans1cb181e2015-01-29 15:30:47 -08001497 int ret;
Jason Evans1cb181e2015-01-29 15:30:47 -08001498 unsigned tcache_ind;
1499
Jason Evansc4c25922017-01-15 16:56:30 -08001500 if (!config_tcache) {
Jason Evansf4086432017-01-19 18:15:45 -08001501 return ENOENT;
Jason Evansc4c25922017-01-15 16:56:30 -08001502 }
Jason Evans1cb181e2015-01-29 15:30:47 -08001503
Jason Evans1cb181e2015-01-29 15:30:47 -08001504 WRITEONLY();
1505 tcache_ind = UINT_MAX;
1506 WRITE(tcache_ind, unsigned);
1507 if (tcache_ind == UINT_MAX) {
1508 ret = EFAULT;
1509 goto label_return;
1510 }
1511 tcaches_flush(tsd, tcache_ind);
1512
1513 ret = 0;
1514label_return:
Jason Evansf4086432017-01-19 18:15:45 -08001515 return ret;
Jason Evans1cb181e2015-01-29 15:30:47 -08001516}
1517
1518static int
Jason Evansb2c0d632016-04-13 23:36:15 -07001519tcache_destroy_ctl(tsd_t *tsd, const size_t *mib, size_t miblen, void *oldp,
Jason Evansc4c25922017-01-15 16:56:30 -08001520 size_t *oldlenp, void *newp, size_t newlen) {
Jason Evans1cb181e2015-01-29 15:30:47 -08001521 int ret;
Jason Evans1cb181e2015-01-29 15:30:47 -08001522 unsigned tcache_ind;
1523
Jason Evansc4c25922017-01-15 16:56:30 -08001524 if (!config_tcache) {
Jason Evansf4086432017-01-19 18:15:45 -08001525 return ENOENT;
Jason Evansc4c25922017-01-15 16:56:30 -08001526 }
Jason Evans1cb181e2015-01-29 15:30:47 -08001527
Jason Evans1cb181e2015-01-29 15:30:47 -08001528 WRITEONLY();
1529 tcache_ind = UINT_MAX;
1530 WRITE(tcache_ind, unsigned);
1531 if (tcache_ind == UINT_MAX) {
1532 ret = EFAULT;
1533 goto label_return;
1534 }
1535 tcaches_destroy(tsd, tcache_ind);
1536
1537 ret = 0;
1538label_return:
Jason Evansf4086432017-01-19 18:15:45 -08001539 return ret;
Jason Evans1cb181e2015-01-29 15:30:47 -08001540}
1541
1542/******************************************************************************/
1543
Jason Evansdc2125c2017-01-04 10:21:53 -08001544static int
1545arena_i_initialized_ctl(tsd_t *tsd, const size_t *mib, size_t miblen,
Jason Evansc4c25922017-01-15 16:56:30 -08001546 void *oldp, size_t *oldlenp, void *newp, size_t newlen) {
Jason Evansdc2125c2017-01-04 10:21:53 -08001547 int ret;
1548 tsdn_t *tsdn = tsd_tsdn(tsd);
1549 unsigned arena_ind;
1550 bool initialized;
1551
1552 READONLY();
1553 MIB_UNSIGNED(arena_ind, 1);
1554
1555 malloc_mutex_lock(tsdn, &ctl_mtx);
Jason Evans9eb1b1c2017-01-18 23:03:37 -08001556 initialized = arenas_i(arena_ind)->initialized;
Jason Evansdc2125c2017-01-04 10:21:53 -08001557 malloc_mutex_unlock(tsdn, &ctl_mtx);
1558
1559 READ(initialized, bool);
1560
1561 ret = 0;
1562label_return:
Jason Evansf4086432017-01-19 18:15:45 -08001563 return ret;
Jason Evansdc2125c2017-01-04 10:21:53 -08001564}
1565
Jason Evans34457f52012-11-03 21:18:28 -07001566static void
Jason Evansc4c25922017-01-15 16:56:30 -08001567arena_i_purge(tsdn_t *tsdn, unsigned arena_ind, bool all) {
Jason Evansc1e00ef2016-05-10 22:21:10 -07001568 malloc_mutex_lock(tsdn, &ctl_mtx);
Jason Evans243f7a02016-02-19 20:09:31 -08001569 {
Jason Evans9eb1b1c2017-01-18 23:03:37 -08001570 unsigned narenas = ctl_arenas->narenas;
Jason Evans609ae592012-10-11 13:53:15 -07001571
Jason Evans3dc4e832017-01-03 07:27:42 -08001572 /*
1573 * Access via index narenas is deprecated, and scheduled for
1574 * removal in 6.0.0.
1575 */
1576 if (arena_ind == MALLCTL_ARENAS_ALL || arena_ind == narenas) {
Jason Evans243f7a02016-02-19 20:09:31 -08001577 unsigned i;
Jason Evans243f7a02016-02-19 20:09:31 -08001578 VARIABLE_ARRAY(arena_t *, tarenas, narenas);
1579
Jason Evansc4c25922017-01-15 16:56:30 -08001580 for (i = 0; i < narenas; i++) {
Jason Evansc1e00ef2016-05-10 22:21:10 -07001581 tarenas[i] = arena_get(tsdn, i, false);
Jason Evansc4c25922017-01-15 16:56:30 -08001582 }
Jason Evans243f7a02016-02-19 20:09:31 -08001583
1584 /*
1585 * No further need to hold ctl_mtx, since narenas and
1586 * tarenas contain everything needed below.
1587 */
Jason Evansc1e00ef2016-05-10 22:21:10 -07001588 malloc_mutex_unlock(tsdn, &ctl_mtx);
Jason Evans243f7a02016-02-19 20:09:31 -08001589
1590 for (i = 0; i < narenas; i++) {
Jason Evansc4c25922017-01-15 16:56:30 -08001591 if (tarenas[i] != NULL) {
Jason Evansc1e00ef2016-05-10 22:21:10 -07001592 arena_purge(tsdn, tarenas[i], all);
Jason Evansc4c25922017-01-15 16:56:30 -08001593 }
Jason Evans243f7a02016-02-19 20:09:31 -08001594 }
1595 } else {
1596 arena_t *tarena;
1597
1598 assert(arena_ind < narenas);
1599
Jason Evansc1e00ef2016-05-10 22:21:10 -07001600 tarena = arena_get(tsdn, arena_ind, false);
Jason Evans243f7a02016-02-19 20:09:31 -08001601
1602 /* No further need to hold ctl_mtx. */
Jason Evansc1e00ef2016-05-10 22:21:10 -07001603 malloc_mutex_unlock(tsdn, &ctl_mtx);
Jason Evans243f7a02016-02-19 20:09:31 -08001604
Jason Evansc4c25922017-01-15 16:56:30 -08001605 if (tarena != NULL) {
Jason Evansc1e00ef2016-05-10 22:21:10 -07001606 arena_purge(tsdn, tarena, all);
Jason Evansc4c25922017-01-15 16:56:30 -08001607 }
Jason Evans609ae592012-10-11 13:53:15 -07001608 }
1609 }
Jason Evans609ae592012-10-11 13:53:15 -07001610}
1611
1612static int
Jason Evansb2c0d632016-04-13 23:36:15 -07001613arena_i_purge_ctl(tsd_t *tsd, const size_t *mib, size_t miblen, void *oldp,
Jason Evansc4c25922017-01-15 16:56:30 -08001614 size_t *oldlenp, void *newp, size_t newlen) {
Jason Evans609ae592012-10-11 13:53:15 -07001615 int ret;
Jason Evans6edbedd2017-01-04 07:51:49 -08001616 unsigned arena_ind;
Jason Evans609ae592012-10-11 13:53:15 -07001617
1618 READONLY();
1619 WRITEONLY();
Jason Evans6edbedd2017-01-04 07:51:49 -08001620 MIB_UNSIGNED(arena_ind, 1);
1621 arena_i_purge(tsd_tsdn(tsd), arena_ind, true);
Jason Evans243f7a02016-02-19 20:09:31 -08001622
1623 ret = 0;
1624label_return:
Jason Evansf4086432017-01-19 18:15:45 -08001625 return ret;
Jason Evans243f7a02016-02-19 20:09:31 -08001626}
1627
1628static int
Jason Evansb2c0d632016-04-13 23:36:15 -07001629arena_i_decay_ctl(tsd_t *tsd, const size_t *mib, size_t miblen, void *oldp,
Jason Evansc4c25922017-01-15 16:56:30 -08001630 size_t *oldlenp, void *newp, size_t newlen) {
Jason Evans243f7a02016-02-19 20:09:31 -08001631 int ret;
Jason Evans6edbedd2017-01-04 07:51:49 -08001632 unsigned arena_ind;
Jason Evans243f7a02016-02-19 20:09:31 -08001633
1634 READONLY();
1635 WRITEONLY();
Jason Evans6edbedd2017-01-04 07:51:49 -08001636 MIB_UNSIGNED(arena_ind, 1);
1637 arena_i_purge(tsd_tsdn(tsd), arena_ind, false);
Jason Evans609ae592012-10-11 13:53:15 -07001638
Jason Evans34457f52012-11-03 21:18:28 -07001639 ret = 0;
Jason Evans609ae592012-10-11 13:53:15 -07001640label_return:
Jason Evansf4086432017-01-19 18:15:45 -08001641 return ret;
Jason Evans609ae592012-10-11 13:53:15 -07001642}
1643
1644static int
Jason Evansedf1baf2017-01-03 17:21:59 -08001645arena_i_reset_destroy_helper(tsd_t *tsd, const size_t *mib, size_t miblen,
1646 void *oldp, size_t *oldlenp, void *newp, size_t newlen, unsigned *arena_ind,
Jason Evansc4c25922017-01-15 16:56:30 -08001647 arena_t **arena) {
Jason Evansedf1baf2017-01-03 17:21:59 -08001648 int ret;
1649
1650 READONLY();
1651 WRITEONLY();
1652 MIB_UNSIGNED(*arena_ind, 1);
1653
1654 if (*arena_ind < narenas_auto) {
1655 ret = EFAULT;
1656 goto label_return;
1657 }
1658
1659 *arena = arena_get(tsd_tsdn(tsd), *arena_ind, false);
1660 if (*arena == NULL) {
1661 ret = EFAULT;
1662 goto label_return;
1663 }
1664
1665 ret = 0;
1666label_return:
Jason Evansf4086432017-01-19 18:15:45 -08001667 return ret;
Jason Evansedf1baf2017-01-03 17:21:59 -08001668}
1669
1670static int
Jason Evans19ff2ce2016-04-22 14:37:17 -07001671arena_i_reset_ctl(tsd_t *tsd, const size_t *mib, size_t miblen, void *oldp,
Jason Evansc4c25922017-01-15 16:56:30 -08001672 size_t *oldlenp, void *newp, size_t newlen) {
Jason Evans19ff2ce2016-04-22 14:37:17 -07001673 int ret;
1674 unsigned arena_ind;
1675 arena_t *arena;
1676
Jason Evansedf1baf2017-01-03 17:21:59 -08001677 ret = arena_i_reset_destroy_helper(tsd, mib, miblen, oldp, oldlenp,
1678 newp, newlen, &arena_ind, &arena);
Jason Evansc4c25922017-01-15 16:56:30 -08001679 if (ret != 0) {
Jason Evansf4086432017-01-19 18:15:45 -08001680 return ret;
Jason Evansc4c25922017-01-15 16:56:30 -08001681 }
Jason Evans19ff2ce2016-04-22 14:37:17 -07001682
Jason Evansedf1baf2017-01-03 17:21:59 -08001683 arena_reset(tsd, arena);
Jason Evans19ff2ce2016-04-22 14:37:17 -07001684
Jason Evansf4086432017-01-19 18:15:45 -08001685 return ret;
Jason Evansedf1baf2017-01-03 17:21:59 -08001686}
1687
1688static int
1689arena_i_destroy_ctl(tsd_t *tsd, const size_t *mib, size_t miblen, void *oldp,
Jason Evansc4c25922017-01-15 16:56:30 -08001690 size_t *oldlenp, void *newp, size_t newlen) {
Jason Evansedf1baf2017-01-03 17:21:59 -08001691 int ret;
1692 unsigned arena_ind;
1693 arena_t *arena;
Jason Evans9eb1b1c2017-01-18 23:03:37 -08001694 ctl_arena_t *ctl_darena, *ctl_arena;
Jason Evansedf1baf2017-01-03 17:21:59 -08001695
1696 ret = arena_i_reset_destroy_helper(tsd, mib, miblen, oldp, oldlenp,
1697 newp, newlen, &arena_ind, &arena);
Jason Evansc4c25922017-01-15 16:56:30 -08001698 if (ret != 0) {
Jason Evansedf1baf2017-01-03 17:21:59 -08001699 goto label_return;
Jason Evansc4c25922017-01-15 16:56:30 -08001700 }
Jason Evansedf1baf2017-01-03 17:21:59 -08001701
1702 if (arena_nthreads_get(arena, false) != 0 || arena_nthreads_get(arena,
1703 true) != 0) {
Jason Evans3dc4e832017-01-03 07:27:42 -08001704 ret = EFAULT;
1705 goto label_return;
1706 }
Jason Evans19ff2ce2016-04-22 14:37:17 -07001707
Jason Evansedf1baf2017-01-03 17:21:59 -08001708 /* Merge stats after resetting and purging arena. */
Jason Evans19ff2ce2016-04-22 14:37:17 -07001709 arena_reset(tsd, arena);
Jason Evansedf1baf2017-01-03 17:21:59 -08001710 arena_purge(tsd_tsdn(tsd), arena, true);
Jason Evans9eb1b1c2017-01-18 23:03:37 -08001711 ctl_darena = arenas_i(MALLCTL_ARENAS_DESTROYED);
1712 ctl_darena->initialized = true;
1713 ctl_arena_refresh(tsd_tsdn(tsd), arena, ctl_darena, arena_ind, true);
Jason Evansedf1baf2017-01-03 17:21:59 -08001714 /* Destroy arena. */
1715 arena_destroy(tsd, arena);
Jason Evans9eb1b1c2017-01-18 23:03:37 -08001716 ctl_arena = arenas_i(arena_ind);
1717 ctl_arena->initialized = false;
Jason Evansedf1baf2017-01-03 17:21:59 -08001718 /* Record arena index for later recycling via arenas.create. */
Jason Evans9eb1b1c2017-01-18 23:03:37 -08001719 ql_elm_new(ctl_arena, destroyed_link);
1720 ql_tail_insert(&ctl_arenas->destroyed, ctl_arena, destroyed_link);
Jason Evans19ff2ce2016-04-22 14:37:17 -07001721
Jason Evansedf1baf2017-01-03 17:21:59 -08001722 assert(ret == 0);
Jason Evans19ff2ce2016-04-22 14:37:17 -07001723label_return:
Jason Evansf4086432017-01-19 18:15:45 -08001724 return ret;
Jason Evans19ff2ce2016-04-22 14:37:17 -07001725}
1726
1727static int
Jason Evansb2c0d632016-04-13 23:36:15 -07001728arena_i_dss_ctl(tsd_t *tsd, const size_t *mib, size_t miblen, void *oldp,
Jason Evansc4c25922017-01-15 16:56:30 -08001729 size_t *oldlenp, void *newp, size_t newlen) {
Jason Evans586c8ed2014-08-15 12:20:20 -07001730 int ret;
1731 const char *dss = NULL;
Jason Evans6edbedd2017-01-04 07:51:49 -08001732 unsigned arena_ind;
Jason Evans609ae592012-10-11 13:53:15 -07001733 dss_prec_t dss_prec_old = dss_prec_limit;
1734 dss_prec_t dss_prec = dss_prec_limit;
1735
Jason Evansc1e00ef2016-05-10 22:21:10 -07001736 malloc_mutex_lock(tsd_tsdn(tsd), &ctl_mtx);
Jason Evans609ae592012-10-11 13:53:15 -07001737 WRITE(dss, const char *);
Jason Evans6edbedd2017-01-04 07:51:49 -08001738 MIB_UNSIGNED(arena_ind, 1);
Jason Evans586c8ed2014-08-15 12:20:20 -07001739 if (dss != NULL) {
1740 int i;
1741 bool match = false;
1742
1743 for (i = 0; i < dss_prec_limit; i++) {
1744 if (strcmp(dss_prec_names[i], dss) == 0) {
1745 dss_prec = i;
1746 match = true;
1747 break;
1748 }
Jason Evans609ae592012-10-11 13:53:15 -07001749 }
Jason Evans586c8ed2014-08-15 12:20:20 -07001750
Jason Evans551ebc42014-10-03 10:16:09 -07001751 if (!match) {
Jason Evans586c8ed2014-08-15 12:20:20 -07001752 ret = EINVAL;
1753 goto label_return;
1754 }
Jason Evans609ae592012-10-11 13:53:15 -07001755 }
1756
Jason Evans3dc4e832017-01-03 07:27:42 -08001757 /*
1758 * Access via index narenas is deprecated, and scheduled for removal in
1759 * 6.0.0.
1760 */
Jason Evansd778dd22017-01-03 12:40:54 -08001761 if (arena_ind == MALLCTL_ARENAS_ALL || arena_ind ==
Jason Evans9eb1b1c2017-01-18 23:03:37 -08001762 ctl_arenas->narenas) {
Jason Evans3dc4e832017-01-03 07:27:42 -08001763 if (dss_prec != dss_prec_limit &&
1764 extent_dss_prec_set(dss_prec)) {
1765 ret = EFAULT;
1766 goto label_return;
1767 }
1768 dss_prec_old = extent_dss_prec_get();
1769 } else {
Jason Evansc1e00ef2016-05-10 22:21:10 -07001770 arena_t *arena = arena_get(tsd_tsdn(tsd), arena_ind, false);
Jason Evans586c8ed2014-08-15 12:20:20 -07001771 if (arena == NULL || (dss_prec != dss_prec_limit &&
Jason Evansc1e00ef2016-05-10 22:21:10 -07001772 arena_dss_prec_set(tsd_tsdn(tsd), arena, dss_prec))) {
Jason Evans586c8ed2014-08-15 12:20:20 -07001773 ret = EFAULT;
1774 goto label_return;
1775 }
Jason Evansc1e00ef2016-05-10 22:21:10 -07001776 dss_prec_old = arena_dss_prec_get(tsd_tsdn(tsd), arena);
Jason Evans609ae592012-10-11 13:53:15 -07001777 }
Jason Evans586c8ed2014-08-15 12:20:20 -07001778
Jason Evans609ae592012-10-11 13:53:15 -07001779 dss = dss_prec_names[dss_prec_old];
1780 READ(dss, const char *);
Jason Evans609ae592012-10-11 13:53:15 -07001781
1782 ret = 0;
1783label_return:
Jason Evansc1e00ef2016-05-10 22:21:10 -07001784 malloc_mutex_unlock(tsd_tsdn(tsd), &ctl_mtx);
Jason Evansf4086432017-01-19 18:15:45 -08001785 return ret;
Jason Evans609ae592012-10-11 13:53:15 -07001786}
1787
aravindfb7fe502014-05-05 15:16:56 -07001788static int
Jason Evansb2c0d632016-04-13 23:36:15 -07001789arena_i_decay_time_ctl(tsd_t *tsd, const size_t *mib, size_t miblen, void *oldp,
Jason Evansc4c25922017-01-15 16:56:30 -08001790 size_t *oldlenp, void *newp, size_t newlen) {
Jason Evans243f7a02016-02-19 20:09:31 -08001791 int ret;
Jason Evans6edbedd2017-01-04 07:51:49 -08001792 unsigned arena_ind;
Jason Evans243f7a02016-02-19 20:09:31 -08001793 arena_t *arena;
1794
Jason Evans6edbedd2017-01-04 07:51:49 -08001795 MIB_UNSIGNED(arena_ind, 1);
Jason Evansc1e00ef2016-05-10 22:21:10 -07001796 arena = arena_get(tsd_tsdn(tsd), arena_ind, false);
Jason Evans243f7a02016-02-19 20:09:31 -08001797 if (arena == NULL) {
1798 ret = EFAULT;
1799 goto label_return;
1800 }
1801
1802 if (oldp != NULL && oldlenp != NULL) {
Jason Evansc1e00ef2016-05-10 22:21:10 -07001803 size_t oldval = arena_decay_time_get(tsd_tsdn(tsd), arena);
Jason Evans243f7a02016-02-19 20:09:31 -08001804 READ(oldval, ssize_t);
1805 }
1806 if (newp != NULL) {
1807 if (newlen != sizeof(ssize_t)) {
1808 ret = EINVAL;
1809 goto label_return;
1810 }
Jason Evansc1e00ef2016-05-10 22:21:10 -07001811 if (arena_decay_time_set(tsd_tsdn(tsd), arena,
1812 *(ssize_t *)newp)) {
Jason Evans243f7a02016-02-19 20:09:31 -08001813 ret = EFAULT;
1814 goto label_return;
1815 }
1816 }
1817
1818 ret = 0;
1819label_return:
Jason Evansf4086432017-01-19 18:15:45 -08001820 return ret;
Jason Evans243f7a02016-02-19 20:09:31 -08001821}
1822
1823static int
Jason Evans9c305c92016-05-31 15:03:51 -07001824arena_i_extent_hooks_ctl(tsd_t *tsd, const size_t *mib, size_t miblen,
Jason Evansc4c25922017-01-15 16:56:30 -08001825 void *oldp, size_t *oldlenp, void *newp, size_t newlen) {
Jason Evansb49a3342015-07-28 11:28:19 -04001826 int ret;
Jason Evans6edbedd2017-01-04 07:51:49 -08001827 unsigned arena_ind;
Jason Evansb49a3342015-07-28 11:28:19 -04001828 arena_t *arena;
1829
Jason Evansc1e00ef2016-05-10 22:21:10 -07001830 malloc_mutex_lock(tsd_tsdn(tsd), &ctl_mtx);
Jason Evans6edbedd2017-01-04 07:51:49 -08001831 MIB_UNSIGNED(arena_ind, 1);
Jason Evansb49a3342015-07-28 11:28:19 -04001832 if (arena_ind < narenas_total_get() && (arena =
Jason Evansc1e00ef2016-05-10 22:21:10 -07001833 arena_get(tsd_tsdn(tsd), arena_ind, false)) != NULL) {
Jason Evansb49a3342015-07-28 11:28:19 -04001834 if (newp != NULL) {
Jason Evansf02fec82016-06-03 19:39:14 -07001835 extent_hooks_t *old_extent_hooks;
1836 extent_hooks_t *new_extent_hooks
1837 JEMALLOC_CC_SILENCE_INIT(NULL);
Jason Evansf8f05422016-06-03 12:05:53 -07001838 WRITE(new_extent_hooks, extent_hooks_t *);
1839 old_extent_hooks = extent_hooks_set(arena,
1840 new_extent_hooks);
1841 READ(old_extent_hooks, extent_hooks_t *);
Jason Evansb49a3342015-07-28 11:28:19 -04001842 } else {
Jason Evansf8f05422016-06-03 12:05:53 -07001843 extent_hooks_t *old_extent_hooks =
1844 extent_hooks_get(arena);
1845 READ(old_extent_hooks, extent_hooks_t *);
Jason Evansb49a3342015-07-28 11:28:19 -04001846 }
1847 } else {
1848 ret = EFAULT;
1849 goto label_return;
1850 }
1851 ret = 0;
1852label_return:
Jason Evansc1e00ef2016-05-10 22:21:10 -07001853 malloc_mutex_unlock(tsd_tsdn(tsd), &ctl_mtx);
Jason Evansf4086432017-01-19 18:15:45 -08001854 return ret;
aravindfb7fe502014-05-05 15:16:56 -07001855}
1856
Jason Evans609ae592012-10-11 13:53:15 -07001857static const ctl_named_node_t *
Jason Evansc4c25922017-01-15 16:56:30 -08001858arena_i_index(tsdn_t *tsdn, const size_t *mib, size_t miblen, size_t i) {
Jason Evansb2c0d632016-04-13 23:36:15 -07001859 const ctl_named_node_t *ret;
Jason Evans609ae592012-10-11 13:53:15 -07001860
Jason Evansc1e00ef2016-05-10 22:21:10 -07001861 malloc_mutex_lock(tsdn, &ctl_mtx);
Jason Evansedf1baf2017-01-03 17:21:59 -08001862 switch (i) {
1863 case MALLCTL_ARENAS_ALL:
1864 case MALLCTL_ARENAS_DESTROYED:
1865 break;
1866 default:
Jason Evans9eb1b1c2017-01-18 23:03:37 -08001867 if (i > ctl_arenas->narenas) {
Jason Evansedf1baf2017-01-03 17:21:59 -08001868 ret = NULL;
1869 goto label_return;
1870 }
1871 break;
Jason Evans609ae592012-10-11 13:53:15 -07001872 }
1873
1874 ret = super_arena_i_node;
1875label_return:
Jason Evansc1e00ef2016-05-10 22:21:10 -07001876 malloc_mutex_unlock(tsdn, &ctl_mtx);
Jason Evansf4086432017-01-19 18:15:45 -08001877 return ret;
Jason Evans609ae592012-10-11 13:53:15 -07001878}
1879
Jason Evans609ae592012-10-11 13:53:15 -07001880/******************************************************************************/
1881
Jason Evans609ae592012-10-11 13:53:15 -07001882static int
Jason Evansb2c0d632016-04-13 23:36:15 -07001883arenas_narenas_ctl(tsd_t *tsd, const size_t *mib, size_t miblen, void *oldp,
Jason Evansc4c25922017-01-15 16:56:30 -08001884 size_t *oldlenp, void *newp, size_t newlen) {
Jason Evans609ae592012-10-11 13:53:15 -07001885 int ret;
1886 unsigned narenas;
1887
Jason Evansc1e00ef2016-05-10 22:21:10 -07001888 malloc_mutex_lock(tsd_tsdn(tsd), &ctl_mtx);
Jason Evans609ae592012-10-11 13:53:15 -07001889 READONLY();
1890 if (*oldlenp != sizeof(unsigned)) {
1891 ret = EINVAL;
1892 goto label_return;
1893 }
Jason Evans9eb1b1c2017-01-18 23:03:37 -08001894 narenas = ctl_arenas->narenas;
Jason Evans609ae592012-10-11 13:53:15 -07001895 READ(narenas, unsigned);
1896
1897 ret = 0;
1898label_return:
Jason Evansc1e00ef2016-05-10 22:21:10 -07001899 malloc_mutex_unlock(tsd_tsdn(tsd), &ctl_mtx);
Jason Evansf4086432017-01-19 18:15:45 -08001900 return ret;
Jason Evans609ae592012-10-11 13:53:15 -07001901}
Jason Evans3c234352010-01-27 13:10:55 -08001902
1903static int
Jason Evansb2c0d632016-04-13 23:36:15 -07001904arenas_decay_time_ctl(tsd_t *tsd, const size_t *mib, size_t miblen, void *oldp,
Jason Evansc4c25922017-01-15 16:56:30 -08001905 size_t *oldlenp, void *newp, size_t newlen) {
Jason Evans243f7a02016-02-19 20:09:31 -08001906 int ret;
1907
1908 if (oldp != NULL && oldlenp != NULL) {
1909 size_t oldval = arena_decay_time_default_get();
1910 READ(oldval, ssize_t);
1911 }
1912 if (newp != NULL) {
1913 if (newlen != sizeof(ssize_t)) {
1914 ret = EINVAL;
1915 goto label_return;
1916 }
1917 if (arena_decay_time_default_set(*(ssize_t *)newp)) {
1918 ret = EFAULT;
1919 goto label_return;
1920 }
1921 }
1922
1923 ret = 0;
1924label_return:
Jason Evansf4086432017-01-19 18:15:45 -08001925 return ret;
Jason Evans243f7a02016-02-19 20:09:31 -08001926}
1927
Jason Evansfc4dcfa2010-11-24 15:44:21 -08001928CTL_RO_NL_GEN(arenas_quantum, QUANTUM, size_t)
Jason Evansae4c7b42012-04-02 07:04:34 -07001929CTL_RO_NL_GEN(arenas_page, PAGE, size_t)
Jason Evans7372b152012-02-10 20:22:09 -08001930CTL_RO_NL_CGEN(config_tcache, arenas_tcache_max, tcache_maxclass, size_t)
Jason Evansb1726102012-02-28 16:50:47 -08001931CTL_RO_NL_GEN(arenas_nbins, NBINS, unsigned)
Jason Evans7372b152012-02-10 20:22:09 -08001932CTL_RO_NL_CGEN(config_tcache, arenas_nhbins, nhbins, unsigned)
Jason Evansd8a39002013-12-19 21:40:41 -08001933CTL_RO_NL_GEN(arenas_bin_i_size, arena_bin_info[mib[2]].reg_size, size_t)
1934CTL_RO_NL_GEN(arenas_bin_i_nregs, arena_bin_info[mib[2]].nregs, uint32_t)
Jason Evans498856f2016-05-29 18:34:50 -07001935CTL_RO_NL_GEN(arenas_bin_i_slab_size, arena_bin_info[mib[2]].slab_size, size_t)
Jason Evansd8a39002013-12-19 21:40:41 -08001936static const ctl_named_node_t *
Jason Evansc4c25922017-01-15 16:56:30 -08001937arenas_bin_i_index(tsdn_t *tsdn, const size_t *mib, size_t miblen, size_t i) {
1938 if (i > NBINS) {
Jason Evansf4086432017-01-19 18:15:45 -08001939 return NULL;
Jason Evansc4c25922017-01-15 16:56:30 -08001940 }
Jason Evansf4086432017-01-19 18:15:45 -08001941 return super_arenas_bin_i_node;
Jason Evansd8a39002013-12-19 21:40:41 -08001942}
1943
Jason Evans7d63fed2016-05-31 14:50:21 -07001944CTL_RO_NL_GEN(arenas_nlextents, NSIZES - NBINS, unsigned)
1945CTL_RO_NL_GEN(arenas_lextent_i_size, index2size(NBINS+(szind_t)mib[2]), size_t)
Jason Evans3c4d92e2014-10-12 22:53:59 -07001946static const ctl_named_node_t *
Jason Evansc4c25922017-01-15 16:56:30 -08001947arenas_lextent_i_index(tsdn_t *tsdn, const size_t *mib, size_t miblen,
1948 size_t i) {
1949 if (i > NSIZES - NBINS) {
Jason Evansf4086432017-01-19 18:15:45 -08001950 return NULL;
Jason Evansc4c25922017-01-15 16:56:30 -08001951 }
Jason Evansf4086432017-01-19 18:15:45 -08001952 return super_arenas_lextent_i_node;
Jason Evans3c4d92e2014-10-12 22:53:59 -07001953}
1954
Jason Evans6005f072010-09-30 16:55:08 -07001955static int
Jason Evans0f04bb12017-01-03 08:21:29 -08001956arenas_create_ctl(tsd_t *tsd, const size_t *mib, size_t miblen, void *oldp,
Jason Evansc4c25922017-01-15 16:56:30 -08001957 size_t *oldlenp, void *newp, size_t newlen) {
Jason Evans609ae592012-10-11 13:53:15 -07001958 int ret;
Jason Evansa0dd3a42016-12-22 16:39:10 -06001959 extent_hooks_t *extent_hooks;
Jason Evansedf1baf2017-01-03 17:21:59 -08001960 unsigned arena_ind;
Jason Evans609ae592012-10-11 13:53:15 -07001961
Jason Evansc1e00ef2016-05-10 22:21:10 -07001962 malloc_mutex_lock(tsd_tsdn(tsd), &ctl_mtx);
Jason Evansa0dd3a42016-12-22 16:39:10 -06001963
1964 extent_hooks = (extent_hooks_t *)&extent_hooks_default;
1965 WRITE(extent_hooks, extent_hooks_t *);
Jason Evansedf1baf2017-01-03 17:21:59 -08001966 if ((arena_ind = ctl_arena_init(tsd_tsdn(tsd), extent_hooks)) ==
1967 UINT_MAX) {
Jason Evans609ae592012-10-11 13:53:15 -07001968 ret = EAGAIN;
1969 goto label_return;
1970 }
Jason Evansedf1baf2017-01-03 17:21:59 -08001971 READ(arena_ind, unsigned);
Jason Evans609ae592012-10-11 13:53:15 -07001972
Jason Evans6005f072010-09-30 16:55:08 -07001973 ret = 0;
Jason Evansa1ee7832012-04-10 15:07:44 -07001974label_return:
Jason Evansc1e00ef2016-05-10 22:21:10 -07001975 malloc_mutex_unlock(tsd_tsdn(tsd), &ctl_mtx);
Jason Evansf4086432017-01-19 18:15:45 -08001976 return ret;
Jason Evans6005f072010-09-30 16:55:08 -07001977}
1978
Jason Evans3c234352010-01-27 13:10:55 -08001979/******************************************************************************/
1980
Jason Evansd34f9e72010-02-11 13:19:21 -08001981static int
Jason Evansb2c0d632016-04-13 23:36:15 -07001982prof_thread_active_init_ctl(tsd_t *tsd, const size_t *mib, size_t miblen,
Jason Evansc4c25922017-01-15 16:56:30 -08001983 void *oldp, size_t *oldlenp, void *newp, size_t newlen) {
Jason Evansb2c0d632016-04-13 23:36:15 -07001984 int ret;
1985 bool oldval;
1986
Jason Evansc4c25922017-01-15 16:56:30 -08001987 if (!config_prof) {
Jason Evansf4086432017-01-19 18:15:45 -08001988 return ENOENT;
Jason Evansc4c25922017-01-15 16:56:30 -08001989 }
Jason Evansb2c0d632016-04-13 23:36:15 -07001990
1991 if (newp != NULL) {
1992 if (newlen != sizeof(bool)) {
1993 ret = EINVAL;
1994 goto label_return;
1995 }
Jason Evansc1e00ef2016-05-10 22:21:10 -07001996 oldval = prof_thread_active_init_set(tsd_tsdn(tsd),
1997 *(bool *)newp);
Jason Evansc4c25922017-01-15 16:56:30 -08001998 } else {
Jason Evansc1e00ef2016-05-10 22:21:10 -07001999 oldval = prof_thread_active_init_get(tsd_tsdn(tsd));
Jason Evansc4c25922017-01-15 16:56:30 -08002000 }
Jason Evansb2c0d632016-04-13 23:36:15 -07002001 READ(oldval, bool);
2002
2003 ret = 0;
2004label_return:
Jason Evansf4086432017-01-19 18:15:45 -08002005 return ret;
Jason Evansb2c0d632016-04-13 23:36:15 -07002006}
2007
2008static int
2009prof_active_ctl(tsd_t *tsd, const size_t *mib, size_t miblen, void *oldp,
Jason Evansc4c25922017-01-15 16:56:30 -08002010 size_t *oldlenp, void *newp, size_t newlen) {
Jason Evansfc12c0b2014-10-03 23:25:30 -07002011 int ret;
2012 bool oldval;
2013
Jason Evansc4c25922017-01-15 16:56:30 -08002014 if (!config_prof) {
Jason Evansf4086432017-01-19 18:15:45 -08002015 return ENOENT;
Jason Evansc4c25922017-01-15 16:56:30 -08002016 }
Jason Evansfc12c0b2014-10-03 23:25:30 -07002017
2018 if (newp != NULL) {
2019 if (newlen != sizeof(bool)) {
2020 ret = EINVAL;
2021 goto label_return;
2022 }
Jason Evansc1e00ef2016-05-10 22:21:10 -07002023 oldval = prof_active_set(tsd_tsdn(tsd), *(bool *)newp);
Jason Evansc4c25922017-01-15 16:56:30 -08002024 } else {
Jason Evansc1e00ef2016-05-10 22:21:10 -07002025 oldval = prof_active_get(tsd_tsdn(tsd));
Jason Evansc4c25922017-01-15 16:56:30 -08002026 }
Jason Evansfc12c0b2014-10-03 23:25:30 -07002027 READ(oldval, bool);
2028
2029 ret = 0;
2030label_return:
Jason Evansf4086432017-01-19 18:15:45 -08002031 return ret;
Jason Evansfc12c0b2014-10-03 23:25:30 -07002032}
2033
2034static int
Jason Evansb2c0d632016-04-13 23:36:15 -07002035prof_dump_ctl(tsd_t *tsd, const size_t *mib, size_t miblen, void *oldp,
Jason Evansc4c25922017-01-15 16:56:30 -08002036 size_t *oldlenp, void *newp, size_t newlen) {
Jason Evansd34f9e72010-02-11 13:19:21 -08002037 int ret;
Jason Evans22ca8552010-03-02 11:57:30 -08002038 const char *filename = NULL;
Jason Evansd34f9e72010-02-11 13:19:21 -08002039
Jason Evansc4c25922017-01-15 16:56:30 -08002040 if (!config_prof) {
Jason Evansf4086432017-01-19 18:15:45 -08002041 return ENOENT;
Jason Evansc4c25922017-01-15 16:56:30 -08002042 }
Jason Evans7372b152012-02-10 20:22:09 -08002043
Jason Evans22ca8552010-03-02 11:57:30 -08002044 WRITEONLY();
2045 WRITE(filename, const char *);
Jason Evansd34f9e72010-02-11 13:19:21 -08002046
Jason Evansb2c0d632016-04-13 23:36:15 -07002047 if (prof_mdump(tsd, filename)) {
Jason Evans22ca8552010-03-02 11:57:30 -08002048 ret = EFAULT;
Jason Evansa1ee7832012-04-10 15:07:44 -07002049 goto label_return;
Jason Evans22ca8552010-03-02 11:57:30 -08002050 }
Jason Evansd34f9e72010-02-11 13:19:21 -08002051
2052 ret = 0;
Jason Evansa1ee7832012-04-10 15:07:44 -07002053label_return:
Jason Evansf4086432017-01-19 18:15:45 -08002054 return ret;
Jason Evansd34f9e72010-02-11 13:19:21 -08002055}
2056
Jason Evans602c8e02014-08-18 16:22:13 -07002057static int
Jason Evansb2c0d632016-04-13 23:36:15 -07002058prof_gdump_ctl(tsd_t *tsd, const size_t *mib, size_t miblen, void *oldp,
Jason Evansc4c25922017-01-15 16:56:30 -08002059 size_t *oldlenp, void *newp, size_t newlen) {
Jason Evans5b8ed5b2015-01-25 21:16:57 -08002060 int ret;
2061 bool oldval;
2062
Jason Evansc4c25922017-01-15 16:56:30 -08002063 if (!config_prof) {
Jason Evansf4086432017-01-19 18:15:45 -08002064 return ENOENT;
Jason Evansc4c25922017-01-15 16:56:30 -08002065 }
Jason Evans5b8ed5b2015-01-25 21:16:57 -08002066
2067 if (newp != NULL) {
2068 if (newlen != sizeof(bool)) {
2069 ret = EINVAL;
2070 goto label_return;
2071 }
Jason Evansc1e00ef2016-05-10 22:21:10 -07002072 oldval = prof_gdump_set(tsd_tsdn(tsd), *(bool *)newp);
Jason Evansc4c25922017-01-15 16:56:30 -08002073 } else {
Jason Evansc1e00ef2016-05-10 22:21:10 -07002074 oldval = prof_gdump_get(tsd_tsdn(tsd));
Jason Evansc4c25922017-01-15 16:56:30 -08002075 }
Jason Evans5b8ed5b2015-01-25 21:16:57 -08002076 READ(oldval, bool);
2077
2078 ret = 0;
2079label_return:
Jason Evansf4086432017-01-19 18:15:45 -08002080 return ret;
Jason Evans5b8ed5b2015-01-25 21:16:57 -08002081}
2082
2083static int
Jason Evansb2c0d632016-04-13 23:36:15 -07002084prof_reset_ctl(tsd_t *tsd, const size_t *mib, size_t miblen, void *oldp,
Jason Evansc4c25922017-01-15 16:56:30 -08002085 size_t *oldlenp, void *newp, size_t newlen) {
Jason Evans602c8e02014-08-18 16:22:13 -07002086 int ret;
2087 size_t lg_sample = lg_prof_sample;
2088
Jason Evansc4c25922017-01-15 16:56:30 -08002089 if (!config_prof) {
Jason Evansf4086432017-01-19 18:15:45 -08002090 return ENOENT;
Jason Evansc4c25922017-01-15 16:56:30 -08002091 }
Jason Evans602c8e02014-08-18 16:22:13 -07002092
2093 WRITEONLY();
2094 WRITE(lg_sample, size_t);
Jason Evansc4c25922017-01-15 16:56:30 -08002095 if (lg_sample >= (sizeof(uint64_t) << 3)) {
Jason Evans602c8e02014-08-18 16:22:13 -07002096 lg_sample = (sizeof(uint64_t) << 3) - 1;
Jason Evansc4c25922017-01-15 16:56:30 -08002097 }
Jason Evans602c8e02014-08-18 16:22:13 -07002098
Jason Evansb54d1602016-10-20 23:59:12 -07002099 prof_reset(tsd, lg_sample);
Jason Evans602c8e02014-08-18 16:22:13 -07002100
2101 ret = 0;
2102label_return:
Jason Evansf4086432017-01-19 18:15:45 -08002103 return ret;
Jason Evans602c8e02014-08-18 16:22:13 -07002104}
2105
Jason Evans7372b152012-02-10 20:22:09 -08002106CTL_RO_NL_CGEN(config_prof, prof_interval, prof_interval, uint64_t)
Jason Evans602c8e02014-08-18 16:22:13 -07002107CTL_RO_NL_CGEN(config_prof, lg_prof_sample, lg_prof_sample, size_t)
Jason Evansd34f9e72010-02-11 13:19:21 -08002108
2109/******************************************************************************/
2110
Jason Evansd778dd22017-01-03 12:40:54 -08002111CTL_RO_CGEN(config_stats, stats_allocated, ctl_stats->allocated, size_t)
2112CTL_RO_CGEN(config_stats, stats_active, ctl_stats->active, size_t)
2113CTL_RO_CGEN(config_stats, stats_metadata, ctl_stats->metadata, size_t)
2114CTL_RO_CGEN(config_stats, stats_resident, ctl_stats->resident, size_t)
2115CTL_RO_CGEN(config_stats, stats_mapped, ctl_stats->mapped, size_t)
2116CTL_RO_CGEN(config_stats, stats_retained, ctl_stats->retained, size_t)
Jason Evansd8a39002013-12-19 21:40:41 -08002117
Jason Evans9eb1b1c2017-01-18 23:03:37 -08002118CTL_RO_GEN(stats_arenas_i_dss, arenas_i(mib[2])->dss, const char *)
2119CTL_RO_GEN(stats_arenas_i_decay_time, arenas_i(mib[2])->decay_time,
Jason Evans243f7a02016-02-19 20:09:31 -08002120 ssize_t)
Jason Evans9eb1b1c2017-01-18 23:03:37 -08002121CTL_RO_GEN(stats_arenas_i_nthreads, arenas_i(mib[2])->nthreads, unsigned)
2122CTL_RO_GEN(stats_arenas_i_pactive, arenas_i(mib[2])->pactive, size_t)
2123CTL_RO_GEN(stats_arenas_i_pdirty, arenas_i(mib[2])->pdirty, size_t)
Jason Evansd8a39002013-12-19 21:40:41 -08002124CTL_RO_CGEN(config_stats, stats_arenas_i_mapped,
Jason Evans9eb1b1c2017-01-18 23:03:37 -08002125 arenas_i(mib[2])->astats->astats.mapped, size_t)
Jason Evans04c3c0f2016-05-03 22:11:35 -07002126CTL_RO_CGEN(config_stats, stats_arenas_i_retained,
Jason Evans9eb1b1c2017-01-18 23:03:37 -08002127 arenas_i(mib[2])->astats->astats.retained, size_t)
Jason Evansd8a39002013-12-19 21:40:41 -08002128CTL_RO_CGEN(config_stats, stats_arenas_i_npurge,
Jason Evans9eb1b1c2017-01-18 23:03:37 -08002129 arenas_i(mib[2])->astats->astats.npurge, uint64_t)
Jason Evansd8a39002013-12-19 21:40:41 -08002130CTL_RO_CGEN(config_stats, stats_arenas_i_nmadvise,
Jason Evans9eb1b1c2017-01-18 23:03:37 -08002131 arenas_i(mib[2])->astats->astats.nmadvise, uint64_t)
Jason Evansd8a39002013-12-19 21:40:41 -08002132CTL_RO_CGEN(config_stats, stats_arenas_i_purged,
Jason Evans9eb1b1c2017-01-18 23:03:37 -08002133 arenas_i(mib[2])->astats->astats.purged, uint64_t)
Jason Evansa0dd3a42016-12-22 16:39:10 -06002134CTL_RO_CGEN(config_stats, stats_arenas_i_base,
Jason Evans9eb1b1c2017-01-18 23:03:37 -08002135 arenas_i(mib[2])->astats->astats.base, size_t)
Jason Evansa0dd3a42016-12-22 16:39:10 -06002136CTL_RO_CGEN(config_stats, stats_arenas_i_internal,
Jason Evans9eb1b1c2017-01-18 23:03:37 -08002137 arenas_i(mib[2])->astats->astats.internal, size_t)
Qi Wang58424e62016-04-22 18:37:44 -07002138CTL_RO_CGEN(config_stats && config_tcache, stats_arenas_i_tcache_bytes,
Jason Evans9eb1b1c2017-01-18 23:03:37 -08002139 arenas_i(mib[2])->astats->astats.tcache_bytes, size_t)
Jason Evansa0dd3a42016-12-22 16:39:10 -06002140CTL_RO_CGEN(config_stats, stats_arenas_i_resident,
Jason Evans9eb1b1c2017-01-18 23:03:37 -08002141 arenas_i(mib[2])->astats->astats.resident, size_t)
Jason Evansd8a39002013-12-19 21:40:41 -08002142
Jason Evans7372b152012-02-10 20:22:09 -08002143CTL_RO_CGEN(config_stats, stats_arenas_i_small_allocated,
Jason Evans9eb1b1c2017-01-18 23:03:37 -08002144 arenas_i(mib[2])->astats->allocated_small, size_t)
Jason Evans7372b152012-02-10 20:22:09 -08002145CTL_RO_CGEN(config_stats, stats_arenas_i_small_nmalloc,
Jason Evans9eb1b1c2017-01-18 23:03:37 -08002146 arenas_i(mib[2])->astats->nmalloc_small, uint64_t)
Jason Evans7372b152012-02-10 20:22:09 -08002147CTL_RO_CGEN(config_stats, stats_arenas_i_small_ndalloc,
Jason Evans9eb1b1c2017-01-18 23:03:37 -08002148 arenas_i(mib[2])->astats->ndalloc_small, uint64_t)
Jason Evans7372b152012-02-10 20:22:09 -08002149CTL_RO_CGEN(config_stats, stats_arenas_i_small_nrequests,
Jason Evans9eb1b1c2017-01-18 23:03:37 -08002150 arenas_i(mib[2])->astats->nrequests_small, uint64_t)
Jason Evans7d63fed2016-05-31 14:50:21 -07002151CTL_RO_CGEN(config_stats, stats_arenas_i_large_allocated,
Jason Evans9eb1b1c2017-01-18 23:03:37 -08002152 arenas_i(mib[2])->astats->astats.allocated_large, size_t)
Jason Evans7d63fed2016-05-31 14:50:21 -07002153CTL_RO_CGEN(config_stats, stats_arenas_i_large_nmalloc,
Jason Evans9eb1b1c2017-01-18 23:03:37 -08002154 arenas_i(mib[2])->astats->astats.nmalloc_large, uint64_t)
Jason Evans7d63fed2016-05-31 14:50:21 -07002155CTL_RO_CGEN(config_stats, stats_arenas_i_large_ndalloc,
Jason Evans9eb1b1c2017-01-18 23:03:37 -08002156 arenas_i(mib[2])->astats->astats.ndalloc_large, uint64_t)
Jason Evans7d63fed2016-05-31 14:50:21 -07002157CTL_RO_CGEN(config_stats, stats_arenas_i_large_nrequests,
Jason Evans9eb1b1c2017-01-18 23:03:37 -08002158 arenas_i(mib[2])->astats->astats.nmalloc_large, uint64_t) /* Intentional. */
Jason Evans3c234352010-01-27 13:10:55 -08002159
Jason Evans7372b152012-02-10 20:22:09 -08002160CTL_RO_CGEN(config_stats, stats_arenas_i_bins_j_nmalloc,
Jason Evans9eb1b1c2017-01-18 23:03:37 -08002161 arenas_i(mib[2])->astats->bstats[mib[4]].nmalloc, uint64_t)
Jason Evans7372b152012-02-10 20:22:09 -08002162CTL_RO_CGEN(config_stats, stats_arenas_i_bins_j_ndalloc,
Jason Evans9eb1b1c2017-01-18 23:03:37 -08002163 arenas_i(mib[2])->astats->bstats[mib[4]].ndalloc, uint64_t)
Jason Evans7372b152012-02-10 20:22:09 -08002164CTL_RO_CGEN(config_stats, stats_arenas_i_bins_j_nrequests,
Jason Evans9eb1b1c2017-01-18 23:03:37 -08002165 arenas_i(mib[2])->astats->bstats[mib[4]].nrequests, uint64_t)
Jason Evans3c4d92e2014-10-12 22:53:59 -07002166CTL_RO_CGEN(config_stats, stats_arenas_i_bins_j_curregs,
Jason Evans9eb1b1c2017-01-18 23:03:37 -08002167 arenas_i(mib[2])->astats->bstats[mib[4]].curregs, size_t)
Jason Evans7372b152012-02-10 20:22:09 -08002168CTL_RO_CGEN(config_stats && config_tcache, stats_arenas_i_bins_j_nfills,
Jason Evans9eb1b1c2017-01-18 23:03:37 -08002169 arenas_i(mib[2])->astats->bstats[mib[4]].nfills, uint64_t)
Jason Evans7372b152012-02-10 20:22:09 -08002170CTL_RO_CGEN(config_stats && config_tcache, stats_arenas_i_bins_j_nflushes,
Jason Evans9eb1b1c2017-01-18 23:03:37 -08002171 arenas_i(mib[2])->astats->bstats[mib[4]].nflushes, uint64_t)
Jason Evans498856f2016-05-29 18:34:50 -07002172CTL_RO_CGEN(config_stats, stats_arenas_i_bins_j_nslabs,
Jason Evans9eb1b1c2017-01-18 23:03:37 -08002173 arenas_i(mib[2])->astats->bstats[mib[4]].nslabs, uint64_t)
Jason Evans498856f2016-05-29 18:34:50 -07002174CTL_RO_CGEN(config_stats, stats_arenas_i_bins_j_nreslabs,
Jason Evans9eb1b1c2017-01-18 23:03:37 -08002175 arenas_i(mib[2])->astats->bstats[mib[4]].reslabs, uint64_t)
Jason Evans498856f2016-05-29 18:34:50 -07002176CTL_RO_CGEN(config_stats, stats_arenas_i_bins_j_curslabs,
Jason Evans9eb1b1c2017-01-18 23:03:37 -08002177 arenas_i(mib[2])->astats->bstats[mib[4]].curslabs, size_t)
Jason Evans3c234352010-01-27 13:10:55 -08002178
Jason Evans609ae592012-10-11 13:53:15 -07002179static const ctl_named_node_t *
Jason Evansc1e00ef2016-05-10 22:21:10 -07002180stats_arenas_i_bins_j_index(tsdn_t *tsdn, const size_t *mib, size_t miblen,
Jason Evansc4c25922017-01-15 16:56:30 -08002181 size_t j) {
2182 if (j > NBINS) {
Jason Evansf4086432017-01-19 18:15:45 -08002183 return NULL;
Jason Evansc4c25922017-01-15 16:56:30 -08002184 }
Jason Evansf4086432017-01-19 18:15:45 -08002185 return super_stats_arenas_i_bins_j_node;
Jason Evans3c234352010-01-27 13:10:55 -08002186}
2187
Jason Evans7d63fed2016-05-31 14:50:21 -07002188CTL_RO_CGEN(config_stats, stats_arenas_i_lextents_j_nmalloc,
Jason Evans9eb1b1c2017-01-18 23:03:37 -08002189 arenas_i(mib[2])->astats->lstats[mib[4]].nmalloc, uint64_t)
Jason Evans7d63fed2016-05-31 14:50:21 -07002190CTL_RO_CGEN(config_stats, stats_arenas_i_lextents_j_ndalloc,
Jason Evans9eb1b1c2017-01-18 23:03:37 -08002191 arenas_i(mib[2])->astats->lstats[mib[4]].ndalloc, uint64_t)
Jason Evans7d63fed2016-05-31 14:50:21 -07002192CTL_RO_CGEN(config_stats, stats_arenas_i_lextents_j_nrequests,
Jason Evans9eb1b1c2017-01-18 23:03:37 -08002193 arenas_i(mib[2])->astats->lstats[mib[4]].nrequests, uint64_t)
Jason Evans7d63fed2016-05-31 14:50:21 -07002194CTL_RO_CGEN(config_stats, stats_arenas_i_lextents_j_curlextents,
Jason Evans9eb1b1c2017-01-18 23:03:37 -08002195 arenas_i(mib[2])->astats->lstats[mib[4]].curlextents, size_t)
Jason Evans3c4d92e2014-10-12 22:53:59 -07002196
2197static const ctl_named_node_t *
Jason Evans7d63fed2016-05-31 14:50:21 -07002198stats_arenas_i_lextents_j_index(tsdn_t *tsdn, const size_t *mib, size_t miblen,
Jason Evansc4c25922017-01-15 16:56:30 -08002199 size_t j) {
2200 if (j > NSIZES - NBINS) {
Jason Evansf4086432017-01-19 18:15:45 -08002201 return NULL;
Jason Evansc4c25922017-01-15 16:56:30 -08002202 }
Jason Evansf4086432017-01-19 18:15:45 -08002203 return super_stats_arenas_i_lextents_j_node;
Jason Evans3c4d92e2014-10-12 22:53:59 -07002204}
2205
Jason Evans609ae592012-10-11 13:53:15 -07002206static const ctl_named_node_t *
Jason Evansc4c25922017-01-15 16:56:30 -08002207stats_arenas_i_index(tsdn_t *tsdn, const size_t *mib, size_t miblen, size_t i) {
Jason Evans3dc4e832017-01-03 07:27:42 -08002208 const ctl_named_node_t *ret;
2209 size_t a;
Jason Evans3c234352010-01-27 13:10:55 -08002210
Jason Evansc1e00ef2016-05-10 22:21:10 -07002211 malloc_mutex_lock(tsdn, &ctl_mtx);
Jason Evans9eb1b1c2017-01-18 23:03:37 -08002212 a = arenas_i2a_impl(i, true, true);
2213 if (a == UINT_MAX || !ctl_arenas->arenas[a]->initialized) {
Jason Evansfc4dcfa2010-11-24 15:44:21 -08002214 ret = NULL;
Jason Evansa1ee7832012-04-10 15:07:44 -07002215 goto label_return;
Jason Evansfc4dcfa2010-11-24 15:44:21 -08002216 }
2217
2218 ret = super_stats_arenas_i_node;
Jason Evansa1ee7832012-04-10 15:07:44 -07002219label_return:
Jason Evansc1e00ef2016-05-10 22:21:10 -07002220 malloc_mutex_unlock(tsdn, &ctl_mtx);
Jason Evansf4086432017-01-19 18:15:45 -08002221 return ret;
Jason Evans3c234352010-01-27 13:10:55 -08002222}