blob: 47b4768bcdd1a7ca106c63c5ed081cf3310c8e15 [file] [log] [blame]
Jason Evans3c234352010-01-27 13:10:55 -08001#define JEMALLOC_CTL_C_
Jason Evans376b1522010-02-11 14:45:59 -08002#include "jemalloc/internal/jemalloc_internal.h"
Jason Evans3c234352010-01-27 13:10:55 -08003
4/******************************************************************************/
5/* Data. */
6
Jason Evansfc4dcfa2010-11-24 15:44:21 -08007/*
8 * ctl_mtx protects the following:
9 * - ctl_stats.*
Jason Evansfc4dcfa2010-11-24 15:44:21 -080010 */
Jason Evans3c234352010-01-27 13:10:55 -080011static malloc_mutex_t ctl_mtx;
12static bool ctl_initialized;
13static uint64_t ctl_epoch;
14static ctl_stats_t ctl_stats;
15
16/******************************************************************************/
Mike Hommey461ad5c2012-04-20 08:38:42 +020017/* Helpers for named and indexed nodes. */
18
Jason Evansaf1f5922014-10-30 16:38:08 -070019JEMALLOC_INLINE_C const ctl_named_node_t *
Mike Hommey461ad5c2012-04-20 08:38:42 +020020ctl_named_node(const ctl_node_t *node)
21{
22
23 return ((node->named) ? (const ctl_named_node_t *)node : NULL);
24}
25
Jason Evansaf1f5922014-10-30 16:38:08 -070026JEMALLOC_INLINE_C const ctl_named_node_t *
Jason Evans8dd51152016-02-24 11:00:40 -080027ctl_named_children(const ctl_named_node_t *node, size_t index)
Mike Hommey461ad5c2012-04-20 08:38:42 +020028{
29 const ctl_named_node_t *children = ctl_named_node(node->children);
30
31 return (children ? &children[index] : NULL);
32}
33
Jason Evansaf1f5922014-10-30 16:38:08 -070034JEMALLOC_INLINE_C const ctl_indexed_node_t *
Mike Hommey461ad5c2012-04-20 08:38:42 +020035ctl_indexed_node(const ctl_node_t *node)
36{
37
Jason Evans551ebc42014-10-03 10:16:09 -070038 return (!node->named ? (const ctl_indexed_node_t *)node : NULL);
Mike Hommey461ad5c2012-04-20 08:38:42 +020039}
40
41/******************************************************************************/
Jason Evans3c234352010-01-27 13:10:55 -080042/* Function prototypes for non-inline static functions. */
43
44#define CTL_PROTO(n) \
Jason Evansb2c0d632016-04-13 23:36:15 -070045static int n##_ctl(tsd_t *tsd, const size_t *mib, size_t miblen, \
46 void *oldp, size_t *oldlenp, void *newp, size_t newlen);
Jason Evans3c234352010-01-27 13:10:55 -080047
48#define INDEX_PROTO(n) \
Jason Evansc1e00ef2016-05-10 22:21:10 -070049static const ctl_named_node_t *n##_index(tsdn_t *tsdn, \
Jason Evansb2c0d632016-04-13 23:36:15 -070050 const size_t *mib, size_t miblen, size_t i);
Jason Evans3c234352010-01-27 13:10:55 -080051
Jason Evans3c234352010-01-27 13:10:55 -080052static void ctl_arena_clear(ctl_arena_stats_t *astats);
Jason Evansc1e00ef2016-05-10 22:21:10 -070053static void ctl_arena_stats_amerge(tsdn_t *tsdn, ctl_arena_stats_t *cstats,
Jason Evans86815df2010-03-13 20:32:56 -080054 arena_t *arena);
55static void ctl_arena_stats_smerge(ctl_arena_stats_t *sstats,
56 ctl_arena_stats_t *astats);
Jason Evansc1e00ef2016-05-10 22:21:10 -070057static void ctl_arena_refresh(tsdn_t *tsdn, arena_t *arena, unsigned i);
58static bool ctl_grow(tsdn_t *tsdn);
59static void ctl_refresh(tsdn_t *tsdn);
60static bool ctl_init(tsdn_t *tsdn);
61static int ctl_lookup(tsdn_t *tsdn, const char *name,
Jason Evansb2c0d632016-04-13 23:36:15 -070062 ctl_node_t const **nodesp, size_t *mibp, size_t *depthp);
Jason Evans3c234352010-01-27 13:10:55 -080063
Jason Evansa40bc7a2010-03-02 13:01:16 -080064CTL_PROTO(version)
Jason Evans3c234352010-01-27 13:10:55 -080065CTL_PROTO(epoch)
Jason Evansd4be8b72012-03-26 18:54:44 -070066CTL_PROTO(thread_tcache_enabled)
Jason Evanse7b8fa12012-03-16 17:09:32 -070067CTL_PROTO(thread_tcache_flush)
Jason Evans602c8e02014-08-18 16:22:13 -070068CTL_PROTO(thread_prof_name)
69CTL_PROTO(thread_prof_active)
Jason Evansb267d0f2010-08-13 15:42:29 -070070CTL_PROTO(thread_arena)
Jason Evans93443682010-10-20 17:39:18 -070071CTL_PROTO(thread_allocated)
Jason Evansecf229a2010-12-03 15:55:47 -080072CTL_PROTO(thread_allocatedp)
Jason Evans93443682010-10-20 17:39:18 -070073CTL_PROTO(thread_deallocated)
Jason Evansecf229a2010-12-03 15:55:47 -080074CTL_PROTO(thread_deallocatedp)
Jason Evansf2bc8522015-07-17 16:38:25 -070075CTL_PROTO(config_cache_oblivious)
Jason Evans3c234352010-01-27 13:10:55 -080076CTL_PROTO(config_debug)
Jason Evans3c234352010-01-27 13:10:55 -080077CTL_PROTO(config_fill)
78CTL_PROTO(config_lazy_lock)
Jason Evansf8290092016-02-07 14:23:22 -080079CTL_PROTO(config_malloc_conf)
Jason Evans59ae2762012-04-16 17:52:27 -070080CTL_PROTO(config_munmap)
Jason Evansd34f9e72010-02-11 13:19:21 -080081CTL_PROTO(config_prof)
82CTL_PROTO(config_prof_libgcc)
83CTL_PROTO(config_prof_libunwind)
Jason Evans3c234352010-01-27 13:10:55 -080084CTL_PROTO(config_stats)
Jason Evans3c234352010-01-27 13:10:55 -080085CTL_PROTO(config_tcache)
Jason Evans3c234352010-01-27 13:10:55 -080086CTL_PROTO(config_tls)
Jason Evansb1476112012-04-05 13:36:17 -070087CTL_PROTO(config_utrace)
Jason Evans3c234352010-01-27 13:10:55 -080088CTL_PROTO(config_xmalloc)
89CTL_PROTO(opt_abort)
Jason Evans609ae592012-10-11 13:53:15 -070090CTL_PROTO(opt_dss)
Jason Evanse7339702010-10-23 18:37:06 -070091CTL_PROTO(opt_narenas)
Jason Evans243f7a02016-02-19 20:09:31 -080092CTL_PROTO(opt_decay_time)
Jason Evanse7339702010-10-23 18:37:06 -070093CTL_PROTO(opt_stats_print)
Jason Evans3c234352010-01-27 13:10:55 -080094CTL_PROTO(opt_junk)
Jason Evanse7339702010-10-23 18:37:06 -070095CTL_PROTO(opt_zero)
Jason Evansb1476112012-04-05 13:36:17 -070096CTL_PROTO(opt_utrace)
Jason Evans3c234352010-01-27 13:10:55 -080097CTL_PROTO(opt_xmalloc)
Jason Evans3fa9a2f2010-03-07 15:34:14 -080098CTL_PROTO(opt_tcache)
Jason Evansf3ca7c82012-04-04 16:16:09 -070099CTL_PROTO(opt_lg_tcache_max)
Jason Evansd34f9e72010-02-11 13:19:21 -0800100CTL_PROTO(opt_prof)
Jason Evanse7339702010-10-23 18:37:06 -0700101CTL_PROTO(opt_prof_prefix)
Jason Evansf18c9822010-03-31 18:43:24 -0700102CTL_PROTO(opt_prof_active)
Jason Evansfc12c0b2014-10-03 23:25:30 -0700103CTL_PROTO(opt_prof_thread_active_init)
Jason Evansb9477e72010-03-01 20:15:26 -0800104CTL_PROTO(opt_lg_prof_sample)
Jason Evansd34f9e72010-02-11 13:19:21 -0800105CTL_PROTO(opt_lg_prof_interval)
Jason Evanse7339702010-10-23 18:37:06 -0700106CTL_PROTO(opt_prof_gdump)
Jason Evans0b25fe72012-04-17 16:39:33 -0700107CTL_PROTO(opt_prof_final)
Jason Evansd34f9e72010-02-11 13:19:21 -0800108CTL_PROTO(opt_prof_leak)
Jason Evansa881cd22010-10-02 15:18:50 -0700109CTL_PROTO(opt_prof_accum)
Jason Evans1cb181e2015-01-29 15:30:47 -0800110CTL_PROTO(tcache_create)
111CTL_PROTO(tcache_flush)
112CTL_PROTO(tcache_destroy)
Jason Evansc1e00ef2016-05-10 22:21:10 -0700113static void arena_i_purge(tsdn_t *tsdn, unsigned arena_ind, bool all);
Jason Evans609ae592012-10-11 13:53:15 -0700114CTL_PROTO(arena_i_purge)
Jason Evans243f7a02016-02-19 20:09:31 -0800115CTL_PROTO(arena_i_decay)
Jason Evans19ff2ce2016-04-22 14:37:17 -0700116CTL_PROTO(arena_i_reset)
Jason Evans609ae592012-10-11 13:53:15 -0700117CTL_PROTO(arena_i_dss)
Jason Evans243f7a02016-02-19 20:09:31 -0800118CTL_PROTO(arena_i_decay_time)
Jason Evans9c305c92016-05-31 15:03:51 -0700119CTL_PROTO(arena_i_extent_hooks)
Jason Evans609ae592012-10-11 13:53:15 -0700120INDEX_PROTO(arena_i)
Jason Evans3c234352010-01-27 13:10:55 -0800121CTL_PROTO(arenas_bin_i_size)
122CTL_PROTO(arenas_bin_i_nregs)
Jason Evans498856f2016-05-29 18:34:50 -0700123CTL_PROTO(arenas_bin_i_slab_size)
Jason Evans3c234352010-01-27 13:10:55 -0800124INDEX_PROTO(arenas_bin_i)
Jason Evans7d63fed2016-05-31 14:50:21 -0700125CTL_PROTO(arenas_lextent_i_size)
126INDEX_PROTO(arenas_lextent_i)
Jason Evans3c234352010-01-27 13:10:55 -0800127CTL_PROTO(arenas_narenas)
128CTL_PROTO(arenas_initialized)
Jason Evans243f7a02016-02-19 20:09:31 -0800129CTL_PROTO(arenas_decay_time)
Jason Evans3c234352010-01-27 13:10:55 -0800130CTL_PROTO(arenas_quantum)
Jason Evansae4c7b42012-04-02 07:04:34 -0700131CTL_PROTO(arenas_page)
Jason Evansdafde142010-03-17 16:27:39 -0700132CTL_PROTO(arenas_tcache_max)
Jason Evans3c234352010-01-27 13:10:55 -0800133CTL_PROTO(arenas_nbins)
Jason Evansdafde142010-03-17 16:27:39 -0700134CTL_PROTO(arenas_nhbins)
Jason Evans7d63fed2016-05-31 14:50:21 -0700135CTL_PROTO(arenas_nlextents)
Jason Evans609ae592012-10-11 13:53:15 -0700136CTL_PROTO(arenas_extend)
Jason Evansfc12c0b2014-10-03 23:25:30 -0700137CTL_PROTO(prof_thread_active_init)
Jason Evansf18c9822010-03-31 18:43:24 -0700138CTL_PROTO(prof_active)
Jason Evansd34f9e72010-02-11 13:19:21 -0800139CTL_PROTO(prof_dump)
Jason Evans5b8ed5b2015-01-25 21:16:57 -0800140CTL_PROTO(prof_gdump)
Jason Evans602c8e02014-08-18 16:22:13 -0700141CTL_PROTO(prof_reset)
Jason Evansd34f9e72010-02-11 13:19:21 -0800142CTL_PROTO(prof_interval)
Jason Evans602c8e02014-08-18 16:22:13 -0700143CTL_PROTO(lg_prof_sample)
Jason Evans3c234352010-01-27 13:10:55 -0800144CTL_PROTO(stats_arenas_i_small_allocated)
145CTL_PROTO(stats_arenas_i_small_nmalloc)
146CTL_PROTO(stats_arenas_i_small_ndalloc)
Jason Evans86815df2010-03-13 20:32:56 -0800147CTL_PROTO(stats_arenas_i_small_nrequests)
Jason Evans7d63fed2016-05-31 14:50:21 -0700148CTL_PROTO(stats_arenas_i_large_allocated)
149CTL_PROTO(stats_arenas_i_large_nmalloc)
150CTL_PROTO(stats_arenas_i_large_ndalloc)
151CTL_PROTO(stats_arenas_i_large_nrequests)
Jason Evans86815df2010-03-13 20:32:56 -0800152CTL_PROTO(stats_arenas_i_bins_j_nmalloc)
153CTL_PROTO(stats_arenas_i_bins_j_ndalloc)
Jason Evans3c234352010-01-27 13:10:55 -0800154CTL_PROTO(stats_arenas_i_bins_j_nrequests)
Jason Evans3c4d92e2014-10-12 22:53:59 -0700155CTL_PROTO(stats_arenas_i_bins_j_curregs)
Jason Evans3c234352010-01-27 13:10:55 -0800156CTL_PROTO(stats_arenas_i_bins_j_nfills)
157CTL_PROTO(stats_arenas_i_bins_j_nflushes)
Jason Evans498856f2016-05-29 18:34:50 -0700158CTL_PROTO(stats_arenas_i_bins_j_nslabs)
159CTL_PROTO(stats_arenas_i_bins_j_nreslabs)
160CTL_PROTO(stats_arenas_i_bins_j_curslabs)
Jason Evans3c234352010-01-27 13:10:55 -0800161INDEX_PROTO(stats_arenas_i_bins_j)
Jason Evans7d63fed2016-05-31 14:50:21 -0700162CTL_PROTO(stats_arenas_i_lextents_j_nmalloc)
163CTL_PROTO(stats_arenas_i_lextents_j_ndalloc)
164CTL_PROTO(stats_arenas_i_lextents_j_nrequests)
165CTL_PROTO(stats_arenas_i_lextents_j_curlextents)
166INDEX_PROTO(stats_arenas_i_lextents_j)
Jason Evans597632b2011-03-18 13:41:33 -0700167CTL_PROTO(stats_arenas_i_nthreads)
Jason Evans609ae592012-10-11 13:53:15 -0700168CTL_PROTO(stats_arenas_i_dss)
Jason Evans243f7a02016-02-19 20:09:31 -0800169CTL_PROTO(stats_arenas_i_decay_time)
Jason Evans3c234352010-01-27 13:10:55 -0800170CTL_PROTO(stats_arenas_i_pactive)
171CTL_PROTO(stats_arenas_i_pdirty)
Jason Evans3c234352010-01-27 13:10:55 -0800172CTL_PROTO(stats_arenas_i_mapped)
Jason Evans04c3c0f2016-05-03 22:11:35 -0700173CTL_PROTO(stats_arenas_i_retained)
Jason Evans3c234352010-01-27 13:10:55 -0800174CTL_PROTO(stats_arenas_i_npurge)
175CTL_PROTO(stats_arenas_i_nmadvise)
176CTL_PROTO(stats_arenas_i_purged)
Jason Evans751f2c32016-06-01 13:40:48 -0700177CTL_PROTO(stats_arenas_i_metadata)
Jason Evans3c234352010-01-27 13:10:55 -0800178INDEX_PROTO(stats_arenas_i)
Jason Evans3c234352010-01-27 13:10:55 -0800179CTL_PROTO(stats_allocated)
180CTL_PROTO(stats_active)
Jason Evans4581b972014-11-27 17:22:36 -0200181CTL_PROTO(stats_metadata)
Jason Evans4acd75a2015-03-23 17:25:57 -0700182CTL_PROTO(stats_resident)
Jason Evans3c234352010-01-27 13:10:55 -0800183CTL_PROTO(stats_mapped)
Jason Evans04c3c0f2016-05-03 22:11:35 -0700184CTL_PROTO(stats_retained)
Jason Evans3c234352010-01-27 13:10:55 -0800185
186/******************************************************************************/
187/* mallctl tree. */
188
189/* Maximum tree depth. */
190#define CTL_MAX_DEPTH 6
191
Mike Hommey461ad5c2012-04-20 08:38:42 +0200192#define NAME(n) {true}, n
Jason Evans65f343a2012-04-23 19:31:45 -0700193#define CHILD(t, c) \
194 sizeof(c##_node) / sizeof(ctl_##t##_node_t), \
195 (ctl_node_t *)c##_node, \
196 NULL
Mike Hommey461ad5c2012-04-20 08:38:42 +0200197#define CTL(c) 0, NULL, c##_ctl
Jason Evans3c234352010-01-27 13:10:55 -0800198
199/*
200 * Only handles internal indexed nodes, since there are currently no external
201 * ones.
202 */
Mike Hommey461ad5c2012-04-20 08:38:42 +0200203#define INDEX(i) {false}, i##_index
Jason Evans3c234352010-01-27 13:10:55 -0800204
Jason Evans602c8e02014-08-18 16:22:13 -0700205static const ctl_named_node_t thread_tcache_node[] = {
Jason Evansd4be8b72012-03-26 18:54:44 -0700206 {NAME("enabled"), CTL(thread_tcache_enabled)},
Jason Evanse7b8fa12012-03-16 17:09:32 -0700207 {NAME("flush"), CTL(thread_tcache_flush)}
Jason Evans3c234352010-01-27 13:10:55 -0800208};
Jason Evans3c234352010-01-27 13:10:55 -0800209
Jason Evans602c8e02014-08-18 16:22:13 -0700210static const ctl_named_node_t thread_prof_node[] = {
211 {NAME("name"), CTL(thread_prof_name)},
212 {NAME("active"), CTL(thread_prof_active)}
213};
214
Mike Hommey461ad5c2012-04-20 08:38:42 +0200215static const ctl_named_node_t thread_node[] = {
Jason Evans7372b152012-02-10 20:22:09 -0800216 {NAME("arena"), CTL(thread_arena)},
Jason Evans93443682010-10-20 17:39:18 -0700217 {NAME("allocated"), CTL(thread_allocated)},
Jason Evansecf229a2010-12-03 15:55:47 -0800218 {NAME("allocatedp"), CTL(thread_allocatedp)},
219 {NAME("deallocated"), CTL(thread_deallocated)},
Jason Evanse7b8fa12012-03-16 17:09:32 -0700220 {NAME("deallocatedp"), CTL(thread_deallocatedp)},
Jason Evans602c8e02014-08-18 16:22:13 -0700221 {NAME("tcache"), CHILD(named, thread_tcache)},
222 {NAME("prof"), CHILD(named, thread_prof)}
Jason Evansb267d0f2010-08-13 15:42:29 -0700223};
Jason Evansb267d0f2010-08-13 15:42:29 -0700224
Mike Hommey461ad5c2012-04-20 08:38:42 +0200225static const ctl_named_node_t config_node[] = {
Jason Evansf2bc8522015-07-17 16:38:25 -0700226 {NAME("cache_oblivious"), CTL(config_cache_oblivious)},
Jason Evans3c4d92e2014-10-12 22:53:59 -0700227 {NAME("debug"), CTL(config_debug)},
228 {NAME("fill"), CTL(config_fill)},
229 {NAME("lazy_lock"), CTL(config_lazy_lock)},
Jason Evansf8290092016-02-07 14:23:22 -0800230 {NAME("malloc_conf"), CTL(config_malloc_conf)},
Jason Evans3c4d92e2014-10-12 22:53:59 -0700231 {NAME("munmap"), CTL(config_munmap)},
232 {NAME("prof"), CTL(config_prof)},
233 {NAME("prof_libgcc"), CTL(config_prof_libgcc)},
234 {NAME("prof_libunwind"), CTL(config_prof_libunwind)},
235 {NAME("stats"), CTL(config_stats)},
236 {NAME("tcache"), CTL(config_tcache)},
237 {NAME("tls"), CTL(config_tls)},
238 {NAME("utrace"), CTL(config_utrace)},
Jason Evans3c4d92e2014-10-12 22:53:59 -0700239 {NAME("xmalloc"), CTL(config_xmalloc)}
Jason Evans3c234352010-01-27 13:10:55 -0800240};
241
Mike Hommey461ad5c2012-04-20 08:38:42 +0200242static const ctl_named_node_t opt_node[] = {
Jason Evans3c4d92e2014-10-12 22:53:59 -0700243 {NAME("abort"), CTL(opt_abort)},
244 {NAME("dss"), CTL(opt_dss)},
Jason Evans3c4d92e2014-10-12 22:53:59 -0700245 {NAME("narenas"), CTL(opt_narenas)},
Jason Evans243f7a02016-02-19 20:09:31 -0800246 {NAME("decay_time"), CTL(opt_decay_time)},
Jason Evans3c4d92e2014-10-12 22:53:59 -0700247 {NAME("stats_print"), CTL(opt_stats_print)},
248 {NAME("junk"), CTL(opt_junk)},
249 {NAME("zero"), CTL(opt_zero)},
Jason Evans3c4d92e2014-10-12 22:53:59 -0700250 {NAME("utrace"), CTL(opt_utrace)},
251 {NAME("xmalloc"), CTL(opt_xmalloc)},
252 {NAME("tcache"), CTL(opt_tcache)},
253 {NAME("lg_tcache_max"), CTL(opt_lg_tcache_max)},
254 {NAME("prof"), CTL(opt_prof)},
255 {NAME("prof_prefix"), CTL(opt_prof_prefix)},
256 {NAME("prof_active"), CTL(opt_prof_active)},
Jason Evansfc12c0b2014-10-03 23:25:30 -0700257 {NAME("prof_thread_active_init"), CTL(opt_prof_thread_active_init)},
Jason Evans3c4d92e2014-10-12 22:53:59 -0700258 {NAME("lg_prof_sample"), CTL(opt_lg_prof_sample)},
259 {NAME("lg_prof_interval"), CTL(opt_lg_prof_interval)},
260 {NAME("prof_gdump"), CTL(opt_prof_gdump)},
261 {NAME("prof_final"), CTL(opt_prof_final)},
262 {NAME("prof_leak"), CTL(opt_prof_leak)},
263 {NAME("prof_accum"), CTL(opt_prof_accum)}
Jason Evans3c234352010-01-27 13:10:55 -0800264};
265
Jason Evans1cb181e2015-01-29 15:30:47 -0800266static const ctl_named_node_t tcache_node[] = {
267 {NAME("create"), CTL(tcache_create)},
268 {NAME("flush"), CTL(tcache_flush)},
269 {NAME("destroy"), CTL(tcache_destroy)}
270};
271
Jason Evans609ae592012-10-11 13:53:15 -0700272static const ctl_named_node_t arena_i_node[] = {
Jason Evans3c4d92e2014-10-12 22:53:59 -0700273 {NAME("purge"), CTL(arena_i_purge)},
Jason Evans243f7a02016-02-19 20:09:31 -0800274 {NAME("decay"), CTL(arena_i_decay)},
Jason Evans19ff2ce2016-04-22 14:37:17 -0700275 {NAME("reset"), CTL(arena_i_reset)},
Jason Evans3c4d92e2014-10-12 22:53:59 -0700276 {NAME("dss"), CTL(arena_i_dss)},
Jason Evans243f7a02016-02-19 20:09:31 -0800277 {NAME("decay_time"), CTL(arena_i_decay_time)},
Jason Evans9c305c92016-05-31 15:03:51 -0700278 {NAME("extent_hooks"), CTL(arena_i_extent_hooks)}
Jason Evans609ae592012-10-11 13:53:15 -0700279};
280static const ctl_named_node_t super_arena_i_node[] = {
Jason Evans3c4d92e2014-10-12 22:53:59 -0700281 {NAME(""), CHILD(named, arena_i)}
Jason Evans609ae592012-10-11 13:53:15 -0700282};
283
284static const ctl_indexed_node_t arena_node[] = {
285 {INDEX(arena_i)}
286};
287
Mike Hommey461ad5c2012-04-20 08:38:42 +0200288static const ctl_named_node_t arenas_bin_i_node[] = {
Jason Evans3c4d92e2014-10-12 22:53:59 -0700289 {NAME("size"), CTL(arenas_bin_i_size)},
290 {NAME("nregs"), CTL(arenas_bin_i_nregs)},
Jason Evans498856f2016-05-29 18:34:50 -0700291 {NAME("slab_size"), CTL(arenas_bin_i_slab_size)}
Jason Evans3c234352010-01-27 13:10:55 -0800292};
Mike Hommey461ad5c2012-04-20 08:38:42 +0200293static const ctl_named_node_t super_arenas_bin_i_node[] = {
Jason Evans3c4d92e2014-10-12 22:53:59 -0700294 {NAME(""), CHILD(named, arenas_bin_i)}
Jason Evans3c234352010-01-27 13:10:55 -0800295};
296
Mike Hommey461ad5c2012-04-20 08:38:42 +0200297static const ctl_indexed_node_t arenas_bin_node[] = {
Jason Evans3c234352010-01-27 13:10:55 -0800298 {INDEX(arenas_bin_i)}
299};
300
Jason Evans7d63fed2016-05-31 14:50:21 -0700301static const ctl_named_node_t arenas_lextent_i_node[] = {
302 {NAME("size"), CTL(arenas_lextent_i_size)}
Jason Evans3c4d92e2014-10-12 22:53:59 -0700303};
Jason Evans7d63fed2016-05-31 14:50:21 -0700304static const ctl_named_node_t super_arenas_lextent_i_node[] = {
305 {NAME(""), CHILD(named, arenas_lextent_i)}
Jason Evans3c4d92e2014-10-12 22:53:59 -0700306};
307
Jason Evans7d63fed2016-05-31 14:50:21 -0700308static const ctl_indexed_node_t arenas_lextent_node[] = {
309 {INDEX(arenas_lextent_i)}
Jason Evans3c4d92e2014-10-12 22:53:59 -0700310};
311
Mike Hommey461ad5c2012-04-20 08:38:42 +0200312static const ctl_named_node_t arenas_node[] = {
Jason Evans3c4d92e2014-10-12 22:53:59 -0700313 {NAME("narenas"), CTL(arenas_narenas)},
314 {NAME("initialized"), CTL(arenas_initialized)},
Jason Evans243f7a02016-02-19 20:09:31 -0800315 {NAME("decay_time"), CTL(arenas_decay_time)},
Jason Evans3c4d92e2014-10-12 22:53:59 -0700316 {NAME("quantum"), CTL(arenas_quantum)},
317 {NAME("page"), CTL(arenas_page)},
318 {NAME("tcache_max"), CTL(arenas_tcache_max)},
319 {NAME("nbins"), CTL(arenas_nbins)},
320 {NAME("nhbins"), CTL(arenas_nhbins)},
321 {NAME("bin"), CHILD(indexed, arenas_bin)},
Jason Evans7d63fed2016-05-31 14:50:21 -0700322 {NAME("nlextents"), CTL(arenas_nlextents)},
323 {NAME("lextent"), CHILD(indexed, arenas_lextent)},
Jason Evans3c4d92e2014-10-12 22:53:59 -0700324 {NAME("extend"), CTL(arenas_extend)}
Jason Evans3c234352010-01-27 13:10:55 -0800325};
326
Mike Hommey461ad5c2012-04-20 08:38:42 +0200327static const ctl_named_node_t prof_node[] = {
Jason Evansfc12c0b2014-10-03 23:25:30 -0700328 {NAME("thread_active_init"), CTL(prof_thread_active_init)},
Jason Evansf18c9822010-03-31 18:43:24 -0700329 {NAME("active"), CTL(prof_active)},
Jason Evansd34f9e72010-02-11 13:19:21 -0800330 {NAME("dump"), CTL(prof_dump)},
Jason Evans5b8ed5b2015-01-25 21:16:57 -0800331 {NAME("gdump"), CTL(prof_gdump)},
Jason Evans602c8e02014-08-18 16:22:13 -0700332 {NAME("reset"), CTL(prof_reset)},
333 {NAME("interval"), CTL(prof_interval)},
334 {NAME("lg_sample"), CTL(lg_prof_sample)}
Jason Evansd34f9e72010-02-11 13:19:21 -0800335};
Jason Evansd34f9e72010-02-11 13:19:21 -0800336
Mike Hommey461ad5c2012-04-20 08:38:42 +0200337static const ctl_named_node_t stats_arenas_i_small_node[] = {
Jason Evans3c4d92e2014-10-12 22:53:59 -0700338 {NAME("allocated"), CTL(stats_arenas_i_small_allocated)},
339 {NAME("nmalloc"), CTL(stats_arenas_i_small_nmalloc)},
340 {NAME("ndalloc"), CTL(stats_arenas_i_small_ndalloc)},
341 {NAME("nrequests"), CTL(stats_arenas_i_small_nrequests)}
Jason Evans3c234352010-01-27 13:10:55 -0800342};
343
Jason Evans7d63fed2016-05-31 14:50:21 -0700344static const ctl_named_node_t stats_arenas_i_large_node[] = {
345 {NAME("allocated"), CTL(stats_arenas_i_large_allocated)},
346 {NAME("nmalloc"), CTL(stats_arenas_i_large_nmalloc)},
347 {NAME("ndalloc"), CTL(stats_arenas_i_large_ndalloc)},
348 {NAME("nrequests"), CTL(stats_arenas_i_large_nrequests)}
Jason Evanse2deab72014-05-15 22:22:27 -0700349};
350
Mike Hommey461ad5c2012-04-20 08:38:42 +0200351static const ctl_named_node_t stats_arenas_i_bins_j_node[] = {
Jason Evans3c4d92e2014-10-12 22:53:59 -0700352 {NAME("nmalloc"), CTL(stats_arenas_i_bins_j_nmalloc)},
353 {NAME("ndalloc"), CTL(stats_arenas_i_bins_j_ndalloc)},
354 {NAME("nrequests"), CTL(stats_arenas_i_bins_j_nrequests)},
355 {NAME("curregs"), CTL(stats_arenas_i_bins_j_curregs)},
356 {NAME("nfills"), CTL(stats_arenas_i_bins_j_nfills)},
357 {NAME("nflushes"), CTL(stats_arenas_i_bins_j_nflushes)},
Jason Evans498856f2016-05-29 18:34:50 -0700358 {NAME("nslabs"), CTL(stats_arenas_i_bins_j_nslabs)},
359 {NAME("nreslabs"), CTL(stats_arenas_i_bins_j_nreslabs)},
360 {NAME("curslabs"), CTL(stats_arenas_i_bins_j_curslabs)}
Jason Evans3c234352010-01-27 13:10:55 -0800361};
Mike Hommey461ad5c2012-04-20 08:38:42 +0200362static const ctl_named_node_t super_stats_arenas_i_bins_j_node[] = {
Jason Evans3c4d92e2014-10-12 22:53:59 -0700363 {NAME(""), CHILD(named, stats_arenas_i_bins_j)}
Jason Evans3c234352010-01-27 13:10:55 -0800364};
365
Mike Hommey461ad5c2012-04-20 08:38:42 +0200366static const ctl_indexed_node_t stats_arenas_i_bins_node[] = {
Jason Evans3c234352010-01-27 13:10:55 -0800367 {INDEX(stats_arenas_i_bins_j)}
368};
369
Jason Evans7d63fed2016-05-31 14:50:21 -0700370static const ctl_named_node_t stats_arenas_i_lextents_j_node[] = {
371 {NAME("nmalloc"), CTL(stats_arenas_i_lextents_j_nmalloc)},
372 {NAME("ndalloc"), CTL(stats_arenas_i_lextents_j_ndalloc)},
373 {NAME("nrequests"), CTL(stats_arenas_i_lextents_j_nrequests)},
374 {NAME("curlextents"), CTL(stats_arenas_i_lextents_j_curlextents)}
Jason Evans3c4d92e2014-10-12 22:53:59 -0700375};
Jason Evans7d63fed2016-05-31 14:50:21 -0700376static const ctl_named_node_t super_stats_arenas_i_lextents_j_node[] = {
377 {NAME(""), CHILD(named, stats_arenas_i_lextents_j)}
Jason Evans3c4d92e2014-10-12 22:53:59 -0700378};
379
Jason Evans7d63fed2016-05-31 14:50:21 -0700380static const ctl_indexed_node_t stats_arenas_i_lextents_node[] = {
381 {INDEX(stats_arenas_i_lextents_j)}
Jason Evans3c4d92e2014-10-12 22:53:59 -0700382};
383
Mike Hommey461ad5c2012-04-20 08:38:42 +0200384static const ctl_named_node_t stats_arenas_i_node[] = {
Jason Evans3c4d92e2014-10-12 22:53:59 -0700385 {NAME("nthreads"), CTL(stats_arenas_i_nthreads)},
386 {NAME("dss"), CTL(stats_arenas_i_dss)},
Jason Evans243f7a02016-02-19 20:09:31 -0800387 {NAME("decay_time"), CTL(stats_arenas_i_decay_time)},
Jason Evans3c4d92e2014-10-12 22:53:59 -0700388 {NAME("pactive"), CTL(stats_arenas_i_pactive)},
389 {NAME("pdirty"), CTL(stats_arenas_i_pdirty)},
390 {NAME("mapped"), CTL(stats_arenas_i_mapped)},
Jason Evans04c3c0f2016-05-03 22:11:35 -0700391 {NAME("retained"), CTL(stats_arenas_i_retained)},
Jason Evans3c4d92e2014-10-12 22:53:59 -0700392 {NAME("npurge"), CTL(stats_arenas_i_npurge)},
393 {NAME("nmadvise"), CTL(stats_arenas_i_nmadvise)},
394 {NAME("purged"), CTL(stats_arenas_i_purged)},
Jason Evans751f2c32016-06-01 13:40:48 -0700395 {NAME("metadata"), CTL(stats_arenas_i_metadata)},
Jason Evans3c4d92e2014-10-12 22:53:59 -0700396 {NAME("small"), CHILD(named, stats_arenas_i_small)},
Jason Evans7d63fed2016-05-31 14:50:21 -0700397 {NAME("large"), CHILD(named, stats_arenas_i_large)},
Jason Evans3c4d92e2014-10-12 22:53:59 -0700398 {NAME("bins"), CHILD(indexed, stats_arenas_i_bins)},
Jason Evans7d63fed2016-05-31 14:50:21 -0700399 {NAME("lextents"), CHILD(indexed, stats_arenas_i_lextents)}
Jason Evans3c234352010-01-27 13:10:55 -0800400};
Mike Hommey461ad5c2012-04-20 08:38:42 +0200401static const ctl_named_node_t super_stats_arenas_i_node[] = {
Jason Evans3c4d92e2014-10-12 22:53:59 -0700402 {NAME(""), CHILD(named, stats_arenas_i)}
Jason Evans3c234352010-01-27 13:10:55 -0800403};
404
Mike Hommey461ad5c2012-04-20 08:38:42 +0200405static const ctl_indexed_node_t stats_arenas_node[] = {
Jason Evans3c234352010-01-27 13:10:55 -0800406 {INDEX(stats_arenas_i)}
407};
408
Mike Hommey461ad5c2012-04-20 08:38:42 +0200409static const ctl_named_node_t stats_node[] = {
Jason Evans3c4d92e2014-10-12 22:53:59 -0700410 {NAME("allocated"), CTL(stats_allocated)},
411 {NAME("active"), CTL(stats_active)},
Jason Evans4581b972014-11-27 17:22:36 -0200412 {NAME("metadata"), CTL(stats_metadata)},
Jason Evans4acd75a2015-03-23 17:25:57 -0700413 {NAME("resident"), CTL(stats_resident)},
Jason Evans3c4d92e2014-10-12 22:53:59 -0700414 {NAME("mapped"), CTL(stats_mapped)},
Jason Evans04c3c0f2016-05-03 22:11:35 -0700415 {NAME("retained"), CTL(stats_retained)},
Jason Evans3c4d92e2014-10-12 22:53:59 -0700416 {NAME("arenas"), CHILD(indexed, stats_arenas)}
Jason Evans3c234352010-01-27 13:10:55 -0800417};
418
Mike Hommey461ad5c2012-04-20 08:38:42 +0200419static const ctl_named_node_t root_node[] = {
Jason Evansa40bc7a2010-03-02 13:01:16 -0800420 {NAME("version"), CTL(version)},
Jason Evans3c234352010-01-27 13:10:55 -0800421 {NAME("epoch"), CTL(epoch)},
Jason Evans65f343a2012-04-23 19:31:45 -0700422 {NAME("thread"), CHILD(named, thread)},
423 {NAME("config"), CHILD(named, config)},
424 {NAME("opt"), CHILD(named, opt)},
Jason Evans1cb181e2015-01-29 15:30:47 -0800425 {NAME("tcache"), CHILD(named, tcache)},
Jason Evans609ae592012-10-11 13:53:15 -0700426 {NAME("arena"), CHILD(indexed, arena)},
Jason Evans65f343a2012-04-23 19:31:45 -0700427 {NAME("arenas"), CHILD(named, arenas)},
428 {NAME("prof"), CHILD(named, prof)},
429 {NAME("stats"), CHILD(named, stats)}
Jason Evans3c234352010-01-27 13:10:55 -0800430};
Mike Hommey461ad5c2012-04-20 08:38:42 +0200431static const ctl_named_node_t super_root_node[] = {
Jason Evans65f343a2012-04-23 19:31:45 -0700432 {NAME(""), CHILD(named, root)}
Jason Evans3c234352010-01-27 13:10:55 -0800433};
434
435#undef NAME
436#undef CHILD
437#undef CTL
438#undef INDEX
439
440/******************************************************************************/
441
Jason Evans3c234352010-01-27 13:10:55 -0800442static void
443ctl_arena_clear(ctl_arena_stats_t *astats)
444{
445
Jason Evans3c07f802016-02-27 20:40:13 -0800446 astats->nthreads = 0;
Jason Evans609ae592012-10-11 13:53:15 -0700447 astats->dss = dss_prec_names[dss_prec_limit];
Jason Evans243f7a02016-02-19 20:09:31 -0800448 astats->decay_time = -1;
Jason Evans3c234352010-01-27 13:10:55 -0800449 astats->pactive = 0;
450 astats->pdirty = 0;
Jason Evans7372b152012-02-10 20:22:09 -0800451 if (config_stats) {
452 memset(&astats->astats, 0, sizeof(arena_stats_t));
453 astats->allocated_small = 0;
454 astats->nmalloc_small = 0;
455 astats->ndalloc_small = 0;
456 astats->nrequests_small = 0;
Jason Evansb1726102012-02-28 16:50:47 -0800457 memset(astats->bstats, 0, NBINS * sizeof(malloc_bin_stats_t));
Jason Evans7d63fed2016-05-31 14:50:21 -0700458 memset(astats->lstats, 0, (NSIZES - NBINS) *
459 sizeof(malloc_large_stats_t));
Jason Evans7372b152012-02-10 20:22:09 -0800460 }
Jason Evans3c234352010-01-27 13:10:55 -0800461}
462
Jason Evans86815df2010-03-13 20:32:56 -0800463static void
Jason Evansc1e00ef2016-05-10 22:21:10 -0700464ctl_arena_stats_amerge(tsdn_t *tsdn, ctl_arena_stats_t *cstats, arena_t *arena)
Jason Evans86815df2010-03-13 20:32:56 -0800465{
466 unsigned i;
467
Jason Evans3c07f802016-02-27 20:40:13 -0800468 if (config_stats) {
Jason Evansc1e00ef2016-05-10 22:21:10 -0700469 arena_stats_merge(tsdn, arena, &cstats->nthreads, &cstats->dss,
Jason Evans63b56572016-10-12 10:40:27 -0700470 &cstats->decay_time, &cstats->pactive, &cstats->pdirty,
471 &cstats->astats, cstats->bstats, cstats->lstats);
Jason Evans86815df2010-03-13 20:32:56 -0800472
Jason Evans3c07f802016-02-27 20:40:13 -0800473 for (i = 0; i < NBINS; i++) {
474 cstats->allocated_small += cstats->bstats[i].curregs *
475 index2size(i);
476 cstats->nmalloc_small += cstats->bstats[i].nmalloc;
477 cstats->ndalloc_small += cstats->bstats[i].ndalloc;
478 cstats->nrequests_small += cstats->bstats[i].nrequests;
479 }
480 } else {
Jason Evansc1e00ef2016-05-10 22:21:10 -0700481 arena_basic_stats_merge(tsdn, arena, &cstats->nthreads,
Jason Evans63b56572016-10-12 10:40:27 -0700482 &cstats->dss, &cstats->decay_time, &cstats->pactive,
483 &cstats->pdirty);
Jason Evans86815df2010-03-13 20:32:56 -0800484 }
Jason Evans86815df2010-03-13 20:32:56 -0800485}
486
487static void
488ctl_arena_stats_smerge(ctl_arena_stats_t *sstats, ctl_arena_stats_t *astats)
489{
490 unsigned i;
491
Jason Evans3c07f802016-02-27 20:40:13 -0800492 sstats->nthreads += astats->nthreads;
Jason Evans86815df2010-03-13 20:32:56 -0800493 sstats->pactive += astats->pactive;
494 sstats->pdirty += astats->pdirty;
495
Jason Evans3c07f802016-02-27 20:40:13 -0800496 if (config_stats) {
497 sstats->astats.mapped += astats->astats.mapped;
Jason Evans04c3c0f2016-05-03 22:11:35 -0700498 sstats->astats.retained += astats->astats.retained;
Jason Evans3c07f802016-02-27 20:40:13 -0800499 sstats->astats.npurge += astats->astats.npurge;
500 sstats->astats.nmadvise += astats->astats.nmadvise;
501 sstats->astats.purged += astats->astats.purged;
Jason Evans86815df2010-03-13 20:32:56 -0800502
Jason Evans751f2c32016-06-01 13:40:48 -0700503 sstats->astats.metadata += astats->astats.metadata;
Jason Evans4581b972014-11-27 17:22:36 -0200504
Jason Evans3c07f802016-02-27 20:40:13 -0800505 sstats->allocated_small += astats->allocated_small;
506 sstats->nmalloc_small += astats->nmalloc_small;
507 sstats->ndalloc_small += astats->ndalloc_small;
508 sstats->nrequests_small += astats->nrequests_small;
Jason Evans86815df2010-03-13 20:32:56 -0800509
Jason Evans7d63fed2016-05-31 14:50:21 -0700510 sstats->astats.allocated_large +=
511 astats->astats.allocated_large;
512 sstats->astats.nmalloc_large += astats->astats.nmalloc_large;
513 sstats->astats.ndalloc_large += astats->astats.ndalloc_large;
514 sstats->astats.nrequests_large +=
515 astats->astats.nrequests_large;
Jason Evans86815df2010-03-13 20:32:56 -0800516
Jason Evans3c07f802016-02-27 20:40:13 -0800517 for (i = 0; i < NBINS; i++) {
518 sstats->bstats[i].nmalloc += astats->bstats[i].nmalloc;
519 sstats->bstats[i].ndalloc += astats->bstats[i].ndalloc;
520 sstats->bstats[i].nrequests +=
521 astats->bstats[i].nrequests;
522 sstats->bstats[i].curregs += astats->bstats[i].curregs;
523 if (config_tcache) {
524 sstats->bstats[i].nfills +=
525 astats->bstats[i].nfills;
526 sstats->bstats[i].nflushes +=
527 astats->bstats[i].nflushes;
528 }
Jason Evans498856f2016-05-29 18:34:50 -0700529 sstats->bstats[i].nslabs += astats->bstats[i].nslabs;
530 sstats->bstats[i].reslabs += astats->bstats[i].reslabs;
531 sstats->bstats[i].curslabs +=
532 astats->bstats[i].curslabs;
Jason Evans7372b152012-02-10 20:22:09 -0800533 }
Jason Evans3c4d92e2014-10-12 22:53:59 -0700534
Jason Evansed2c2422016-05-28 00:17:28 -0700535 for (i = 0; i < NSIZES - NBINS; i++) {
Jason Evans7d63fed2016-05-31 14:50:21 -0700536 sstats->lstats[i].nmalloc += astats->lstats[i].nmalloc;
537 sstats->lstats[i].ndalloc += astats->lstats[i].ndalloc;
538 sstats->lstats[i].nrequests +=
539 astats->lstats[i].nrequests;
540 sstats->lstats[i].curlextents +=
541 astats->lstats[i].curlextents;
Jason Evans3c07f802016-02-27 20:40:13 -0800542 }
Jason Evans3c4d92e2014-10-12 22:53:59 -0700543 }
Jason Evans86815df2010-03-13 20:32:56 -0800544}
Jason Evans86815df2010-03-13 20:32:56 -0800545
Jason Evans3c234352010-01-27 13:10:55 -0800546static void
Jason Evansc1e00ef2016-05-10 22:21:10 -0700547ctl_arena_refresh(tsdn_t *tsdn, arena_t *arena, unsigned i)
Jason Evans3c234352010-01-27 13:10:55 -0800548{
549 ctl_arena_stats_t *astats = &ctl_stats.arenas[i];
Jason Evans609ae592012-10-11 13:53:15 -0700550 ctl_arena_stats_t *sstats = &ctl_stats.arenas[ctl_stats.narenas];
Jason Evans3c234352010-01-27 13:10:55 -0800551
552 ctl_arena_clear(astats);
Jason Evansc1e00ef2016-05-10 22:21:10 -0700553 ctl_arena_stats_amerge(tsdn, astats, arena);
Jason Evans3c07f802016-02-27 20:40:13 -0800554 /* Merge into sum stats as well. */
555 ctl_arena_stats_smerge(sstats, astats);
Jason Evans3c234352010-01-27 13:10:55 -0800556}
557
Jason Evans609ae592012-10-11 13:53:15 -0700558static bool
Jason Evansc1e00ef2016-05-10 22:21:10 -0700559ctl_grow(tsdn_t *tsdn)
Jason Evans609ae592012-10-11 13:53:15 -0700560{
Jason Evans609ae592012-10-11 13:53:15 -0700561 ctl_arena_stats_t *astats;
Jason Evans609ae592012-10-11 13:53:15 -0700562
Jason Evans8bb31982014-10-07 23:14:57 -0700563 /* Initialize new arena. */
Jason Evansc1e00ef2016-05-10 22:21:10 -0700564 if (arena_init(tsdn, ctl_stats.narenas) == NULL)
Jason Evans8bb31982014-10-07 23:14:57 -0700565 return (true);
Jason Evans5460aa62014-09-22 21:09:23 -0700566
Jason Evans8bb31982014-10-07 23:14:57 -0700567 /* Allocate extended arena stats. */
568 astats = (ctl_arena_stats_t *)a0malloc((ctl_stats.narenas + 2) *
Jason Evans4581b972014-11-27 17:22:36 -0200569 sizeof(ctl_arena_stats_t));
Jason Evans7b651802013-10-20 14:09:54 -0700570 if (astats == NULL)
Jason Evans609ae592012-10-11 13:53:15 -0700571 return (true);
Jason Evans7b651802013-10-20 14:09:54 -0700572
573 /* Initialize the new astats element. */
574 memcpy(astats, ctl_stats.arenas, (ctl_stats.narenas + 1) *
575 sizeof(ctl_arena_stats_t));
576 memset(&astats[ctl_stats.narenas + 1], 0, sizeof(ctl_arena_stats_t));
Jason Evans609ae592012-10-11 13:53:15 -0700577 /* Swap merged stats to their new location. */
578 {
579 ctl_arena_stats_t tstats;
580 memcpy(&tstats, &astats[ctl_stats.narenas],
581 sizeof(ctl_arena_stats_t));
582 memcpy(&astats[ctl_stats.narenas],
583 &astats[ctl_stats.narenas + 1], sizeof(ctl_arena_stats_t));
584 memcpy(&astats[ctl_stats.narenas + 1], &tstats,
585 sizeof(ctl_arena_stats_t));
586 }
Jason Evans10aff3f2015-01-20 15:37:51 -0800587 a0dalloc(ctl_stats.arenas);
Jason Evans609ae592012-10-11 13:53:15 -0700588 ctl_stats.arenas = astats;
589 ctl_stats.narenas++;
Jason Evans609ae592012-10-11 13:53:15 -0700590
591 return (false);
592}
593
Jason Evans3c234352010-01-27 13:10:55 -0800594static void
Jason Evansc1e00ef2016-05-10 22:21:10 -0700595ctl_refresh(tsdn_t *tsdn)
Jason Evans3c234352010-01-27 13:10:55 -0800596{
597 unsigned i;
Jason Evans609ae592012-10-11 13:53:15 -0700598 VARIABLE_ARRAY(arena_t *, tarenas, ctl_stats.narenas);
Jason Evans3c234352010-01-27 13:10:55 -0800599
Jason Evans3c234352010-01-27 13:10:55 -0800600 /*
Jason Evans13668262010-01-31 03:57:29 -0800601 * Clear sum stats, since they will be merged into by
Jason Evans3c234352010-01-27 13:10:55 -0800602 * ctl_arena_refresh().
603 */
Jason Evans609ae592012-10-11 13:53:15 -0700604 ctl_arena_clear(&ctl_stats.arenas[ctl_stats.narenas]);
Jason Evans3c234352010-01-27 13:10:55 -0800605
Jason Evans767d8502016-02-24 23:58:10 -0800606 for (i = 0; i < ctl_stats.narenas; i++)
Jason Evansc1e00ef2016-05-10 22:21:10 -0700607 tarenas[i] = arena_get(tsdn, i, false);
Jason Evans8bb31982014-10-07 23:14:57 -0700608
Jason Evans609ae592012-10-11 13:53:15 -0700609 for (i = 0; i < ctl_stats.narenas; i++) {
Jason Evans3c234352010-01-27 13:10:55 -0800610 bool initialized = (tarenas[i] != NULL);
611
612 ctl_stats.arenas[i].initialized = initialized;
613 if (initialized)
Jason Evansc1e00ef2016-05-10 22:21:10 -0700614 ctl_arena_refresh(tsdn, tarenas[i], i);
Jason Evans3c234352010-01-27 13:10:55 -0800615 }
616
Jason Evans7372b152012-02-10 20:22:09 -0800617 if (config_stats) {
Jason Evans4acd75a2015-03-23 17:25:57 -0700618 size_t base_allocated, base_resident, base_mapped;
Jason Evansc1e00ef2016-05-10 22:21:10 -0700619 base_stats_get(tsdn, &base_allocated, &base_resident,
Jason Evansb2c0d632016-04-13 23:36:15 -0700620 &base_mapped);
Jason Evans609ae592012-10-11 13:53:15 -0700621 ctl_stats.allocated =
Jason Evans4acd75a2015-03-23 17:25:57 -0700622 ctl_stats.arenas[ctl_stats.narenas].allocated_small +
Jason Evans7d63fed2016-05-31 14:50:21 -0700623 ctl_stats.arenas[ctl_stats.narenas].astats.allocated_large;
Jason Evans609ae592012-10-11 13:53:15 -0700624 ctl_stats.active =
Jason Evanse2deab72014-05-15 22:22:27 -0700625 (ctl_stats.arenas[ctl_stats.narenas].pactive << LG_PAGE);
Jason Evans4acd75a2015-03-23 17:25:57 -0700626 ctl_stats.metadata = base_allocated +
Jason Evans751f2c32016-06-01 13:40:48 -0700627 ctl_stats.arenas[ctl_stats.narenas].astats.metadata;
Jason Evans4acd75a2015-03-23 17:25:57 -0700628 ctl_stats.resident = base_resident +
Jason Evans4acd75a2015-03-23 17:25:57 -0700629 ((ctl_stats.arenas[ctl_stats.narenas].pactive +
630 ctl_stats.arenas[ctl_stats.narenas].pdirty) << LG_PAGE);
631 ctl_stats.mapped = base_mapped +
Jason Evanscbf3a6d2015-02-11 12:24:27 -0800632 ctl_stats.arenas[ctl_stats.narenas].astats.mapped;
Jason Evans04c3c0f2016-05-03 22:11:35 -0700633 ctl_stats.retained =
634 ctl_stats.arenas[ctl_stats.narenas].astats.retained;
Jason Evans7372b152012-02-10 20:22:09 -0800635 }
Jason Evans3c234352010-01-27 13:10:55 -0800636
637 ctl_epoch++;
638}
639
640static bool
Jason Evansc1e00ef2016-05-10 22:21:10 -0700641ctl_init(tsdn_t *tsdn)
Jason Evans3c234352010-01-27 13:10:55 -0800642{
Jason Evansfc4dcfa2010-11-24 15:44:21 -0800643 bool ret;
Jason Evans3c234352010-01-27 13:10:55 -0800644
Jason Evansc1e00ef2016-05-10 22:21:10 -0700645 malloc_mutex_lock(tsdn, &ctl_mtx);
Jason Evans551ebc42014-10-03 10:16:09 -0700646 if (!ctl_initialized) {
Jason Evans3c234352010-01-27 13:10:55 -0800647 /*
648 * Allocate space for one extra arena stats element, which
649 * contains summed stats across all arenas.
650 */
Jason Evans8bb31982014-10-07 23:14:57 -0700651 ctl_stats.narenas = narenas_total_get();
652 ctl_stats.arenas = (ctl_arena_stats_t *)a0malloc(
Jason Evans4581b972014-11-27 17:22:36 -0200653 (ctl_stats.narenas + 1) * sizeof(ctl_arena_stats_t));
Jason Evansfc4dcfa2010-11-24 15:44:21 -0800654 if (ctl_stats.arenas == NULL) {
655 ret = true;
Jason Evansa1ee7832012-04-10 15:07:44 -0700656 goto label_return;
Jason Evansfc4dcfa2010-11-24 15:44:21 -0800657 }
Jason Evans609ae592012-10-11 13:53:15 -0700658 memset(ctl_stats.arenas, 0, (ctl_stats.narenas + 1) *
Jason Evans3c234352010-01-27 13:10:55 -0800659 sizeof(ctl_arena_stats_t));
Jason Evans609ae592012-10-11 13:53:15 -0700660 ctl_stats.arenas[ctl_stats.narenas].initialized = true;
Jason Evans3c234352010-01-27 13:10:55 -0800661
662 ctl_epoch = 0;
Jason Evansc1e00ef2016-05-10 22:21:10 -0700663 ctl_refresh(tsdn);
Jason Evans3c234352010-01-27 13:10:55 -0800664 ctl_initialized = true;
665 }
666
Jason Evansfc4dcfa2010-11-24 15:44:21 -0800667 ret = false;
Jason Evansa1ee7832012-04-10 15:07:44 -0700668label_return:
Jason Evansc1e00ef2016-05-10 22:21:10 -0700669 malloc_mutex_unlock(tsdn, &ctl_mtx);
Jason Evansfc4dcfa2010-11-24 15:44:21 -0800670 return (ret);
Jason Evans3c234352010-01-27 13:10:55 -0800671}
672
673static int
Jason Evansc1e00ef2016-05-10 22:21:10 -0700674ctl_lookup(tsdn_t *tsdn, const char *name, ctl_node_t const **nodesp,
Jason Evansb2c0d632016-04-13 23:36:15 -0700675 size_t *mibp, size_t *depthp)
Jason Evans3c234352010-01-27 13:10:55 -0800676{
677 int ret;
678 const char *elm, *tdot, *dot;
679 size_t elen, i, j;
Mike Hommey461ad5c2012-04-20 08:38:42 +0200680 const ctl_named_node_t *node;
Jason Evans3c234352010-01-27 13:10:55 -0800681
682 elm = name;
683 /* Equivalent to strchrnul(). */
684 dot = ((tdot = strchr(elm, '.')) != NULL) ? tdot : strchr(elm, '\0');
685 elen = (size_t)((uintptr_t)dot - (uintptr_t)elm);
686 if (elen == 0) {
687 ret = ENOENT;
Jason Evansa1ee7832012-04-10 15:07:44 -0700688 goto label_return;
Jason Evans3c234352010-01-27 13:10:55 -0800689 }
690 node = super_root_node;
691 for (i = 0; i < *depthp; i++) {
Mike Hommey461ad5c2012-04-20 08:38:42 +0200692 assert(node);
693 assert(node->nchildren > 0);
694 if (ctl_named_node(node->children) != NULL) {
695 const ctl_named_node_t *pnode = node;
Jason Evans3c234352010-01-27 13:10:55 -0800696
697 /* Children are named. */
Mike Hommey461ad5c2012-04-20 08:38:42 +0200698 for (j = 0; j < node->nchildren; j++) {
699 const ctl_named_node_t *child =
700 ctl_named_children(node, j);
701 if (strlen(child->name) == elen &&
702 strncmp(elm, child->name, elen) == 0) {
Jason Evans3c234352010-01-27 13:10:55 -0800703 node = child;
704 if (nodesp != NULL)
Mike Hommey461ad5c2012-04-20 08:38:42 +0200705 nodesp[i] =
706 (const ctl_node_t *)node;
Jason Evans3c234352010-01-27 13:10:55 -0800707 mibp[i] = j;
708 break;
709 }
710 }
711 if (node == pnode) {
712 ret = ENOENT;
Jason Evansa1ee7832012-04-10 15:07:44 -0700713 goto label_return;
Jason Evans3c234352010-01-27 13:10:55 -0800714 }
715 } else {
Jason Evans41b6afb2012-02-02 22:04:57 -0800716 uintmax_t index;
Mike Hommey461ad5c2012-04-20 08:38:42 +0200717 const ctl_indexed_node_t *inode;
Jason Evans3c234352010-01-27 13:10:55 -0800718
719 /* Children are indexed. */
Jason Evans41b6afb2012-02-02 22:04:57 -0800720 index = malloc_strtoumax(elm, NULL, 10);
721 if (index == UINTMAX_MAX || index > SIZE_T_MAX) {
Jason Evans3c234352010-01-27 13:10:55 -0800722 ret = ENOENT;
Jason Evansa1ee7832012-04-10 15:07:44 -0700723 goto label_return;
Jason Evans3c234352010-01-27 13:10:55 -0800724 }
725
Mike Hommey461ad5c2012-04-20 08:38:42 +0200726 inode = ctl_indexed_node(node->children);
Jason Evansc1e00ef2016-05-10 22:21:10 -0700727 node = inode->index(tsdn, mibp, *depthp, (size_t)index);
Jason Evans3c234352010-01-27 13:10:55 -0800728 if (node == NULL) {
729 ret = ENOENT;
Jason Evansa1ee7832012-04-10 15:07:44 -0700730 goto label_return;
Jason Evans3c234352010-01-27 13:10:55 -0800731 }
732
733 if (nodesp != NULL)
Mike Hommey461ad5c2012-04-20 08:38:42 +0200734 nodesp[i] = (const ctl_node_t *)node;
Jason Evans3c234352010-01-27 13:10:55 -0800735 mibp[i] = (size_t)index;
736 }
737
738 if (node->ctl != NULL) {
739 /* Terminal node. */
740 if (*dot != '\0') {
741 /*
742 * The name contains more elements than are
743 * in this path through the tree.
744 */
745 ret = ENOENT;
Jason Evansa1ee7832012-04-10 15:07:44 -0700746 goto label_return;
Jason Evans3c234352010-01-27 13:10:55 -0800747 }
748 /* Complete lookup successful. */
749 *depthp = i + 1;
750 break;
751 }
752
753 /* Update elm. */
754 if (*dot == '\0') {
755 /* No more elements. */
756 ret = ENOENT;
Jason Evansa1ee7832012-04-10 15:07:44 -0700757 goto label_return;
Jason Evans3c234352010-01-27 13:10:55 -0800758 }
759 elm = &dot[1];
760 dot = ((tdot = strchr(elm, '.')) != NULL) ? tdot :
761 strchr(elm, '\0');
762 elen = (size_t)((uintptr_t)dot - (uintptr_t)elm);
763 }
764
765 ret = 0;
Jason Evansa1ee7832012-04-10 15:07:44 -0700766label_return:
Jason Evans3c234352010-01-27 13:10:55 -0800767 return (ret);
768}
769
770int
Jason Evansb2c0d632016-04-13 23:36:15 -0700771ctl_byname(tsd_t *tsd, const char *name, void *oldp, size_t *oldlenp,
772 void *newp, size_t newlen)
Jason Evans3c234352010-01-27 13:10:55 -0800773{
774 int ret;
775 size_t depth;
776 ctl_node_t const *nodes[CTL_MAX_DEPTH];
777 size_t mib[CTL_MAX_DEPTH];
Mike Hommey461ad5c2012-04-20 08:38:42 +0200778 const ctl_named_node_t *node;
Jason Evans3c234352010-01-27 13:10:55 -0800779
Jason Evansc1e00ef2016-05-10 22:21:10 -0700780 if (!ctl_initialized && ctl_init(tsd_tsdn(tsd))) {
Jason Evans3c234352010-01-27 13:10:55 -0800781 ret = EAGAIN;
Jason Evansa1ee7832012-04-10 15:07:44 -0700782 goto label_return;
Jason Evans3c234352010-01-27 13:10:55 -0800783 }
784
785 depth = CTL_MAX_DEPTH;
Jason Evansc1e00ef2016-05-10 22:21:10 -0700786 ret = ctl_lookup(tsd_tsdn(tsd), name, nodes, mib, &depth);
Jason Evans3c234352010-01-27 13:10:55 -0800787 if (ret != 0)
Jason Evansa1ee7832012-04-10 15:07:44 -0700788 goto label_return;
Jason Evans3c234352010-01-27 13:10:55 -0800789
Mike Hommey461ad5c2012-04-20 08:38:42 +0200790 node = ctl_named_node(nodes[depth-1]);
791 if (node != NULL && node->ctl)
Jason Evansb2c0d632016-04-13 23:36:15 -0700792 ret = node->ctl(tsd, mib, depth, oldp, oldlenp, newp, newlen);
Mike Hommey461ad5c2012-04-20 08:38:42 +0200793 else {
Jason Evans3c234352010-01-27 13:10:55 -0800794 /* The name refers to a partial path through the ctl tree. */
795 ret = ENOENT;
Jason Evans3c234352010-01-27 13:10:55 -0800796 }
Jason Evans3c234352010-01-27 13:10:55 -0800797
Jason Evansa1ee7832012-04-10 15:07:44 -0700798label_return:
Jason Evans3c234352010-01-27 13:10:55 -0800799 return(ret);
800}
801
802int
Jason Evansc1e00ef2016-05-10 22:21:10 -0700803ctl_nametomib(tsdn_t *tsdn, const char *name, size_t *mibp, size_t *miblenp)
Jason Evans3c234352010-01-27 13:10:55 -0800804{
805 int ret;
806
Jason Evansc1e00ef2016-05-10 22:21:10 -0700807 if (!ctl_initialized && ctl_init(tsdn)) {
Jason Evans3c234352010-01-27 13:10:55 -0800808 ret = EAGAIN;
Jason Evansa1ee7832012-04-10 15:07:44 -0700809 goto label_return;
Jason Evans3c234352010-01-27 13:10:55 -0800810 }
811
Jason Evansc1e00ef2016-05-10 22:21:10 -0700812 ret = ctl_lookup(tsdn, name, NULL, mibp, miblenp);
Jason Evansa1ee7832012-04-10 15:07:44 -0700813label_return:
Jason Evans3c234352010-01-27 13:10:55 -0800814 return(ret);
815}
816
817int
Jason Evansb2c0d632016-04-13 23:36:15 -0700818ctl_bymib(tsd_t *tsd, const size_t *mib, size_t miblen, void *oldp,
819 size_t *oldlenp, void *newp, size_t newlen)
Jason Evans3c234352010-01-27 13:10:55 -0800820{
821 int ret;
Mike Hommey461ad5c2012-04-20 08:38:42 +0200822 const ctl_named_node_t *node;
Jason Evans3c234352010-01-27 13:10:55 -0800823 size_t i;
824
Jason Evansc1e00ef2016-05-10 22:21:10 -0700825 if (!ctl_initialized && ctl_init(tsd_tsdn(tsd))) {
Jason Evans3c234352010-01-27 13:10:55 -0800826 ret = EAGAIN;
Jason Evansa1ee7832012-04-10 15:07:44 -0700827 goto label_return;
Jason Evans3c234352010-01-27 13:10:55 -0800828 }
829
830 /* Iterate down the tree. */
831 node = super_root_node;
832 for (i = 0; i < miblen; i++) {
Mike Hommey461ad5c2012-04-20 08:38:42 +0200833 assert(node);
834 assert(node->nchildren > 0);
835 if (ctl_named_node(node->children) != NULL) {
Jason Evans3c234352010-01-27 13:10:55 -0800836 /* Children are named. */
Jason Evans8dd51152016-02-24 11:00:40 -0800837 if (node->nchildren <= (unsigned)mib[i]) {
Jason Evans3c234352010-01-27 13:10:55 -0800838 ret = ENOENT;
Jason Evansa1ee7832012-04-10 15:07:44 -0700839 goto label_return;
Jason Evans3c234352010-01-27 13:10:55 -0800840 }
Mike Hommey461ad5c2012-04-20 08:38:42 +0200841 node = ctl_named_children(node, mib[i]);
Jason Evans3c234352010-01-27 13:10:55 -0800842 } else {
Mike Hommey461ad5c2012-04-20 08:38:42 +0200843 const ctl_indexed_node_t *inode;
Jason Evans3c234352010-01-27 13:10:55 -0800844
845 /* Indexed element. */
Mike Hommey461ad5c2012-04-20 08:38:42 +0200846 inode = ctl_indexed_node(node->children);
Jason Evansc1e00ef2016-05-10 22:21:10 -0700847 node = inode->index(tsd_tsdn(tsd), mib, miblen, mib[i]);
Jason Evans3c234352010-01-27 13:10:55 -0800848 if (node == NULL) {
849 ret = ENOENT;
Jason Evansa1ee7832012-04-10 15:07:44 -0700850 goto label_return;
Jason Evans3c234352010-01-27 13:10:55 -0800851 }
852 }
853 }
854
855 /* Call the ctl function. */
Mike Hommey461ad5c2012-04-20 08:38:42 +0200856 if (node && node->ctl)
Jason Evansb2c0d632016-04-13 23:36:15 -0700857 ret = node->ctl(tsd, mib, miblen, oldp, oldlenp, newp, newlen);
Mike Hommey461ad5c2012-04-20 08:38:42 +0200858 else {
Jason Evans3c234352010-01-27 13:10:55 -0800859 /* Partial MIB. */
860 ret = ENOENT;
Jason Evans3c234352010-01-27 13:10:55 -0800861 }
Jason Evans3c234352010-01-27 13:10:55 -0800862
Jason Evansa1ee7832012-04-10 15:07:44 -0700863label_return:
Jason Evans3c234352010-01-27 13:10:55 -0800864 return(ret);
865}
866
867bool
868ctl_boot(void)
869{
870
Jason Evansb2c0d632016-04-13 23:36:15 -0700871 if (malloc_mutex_init(&ctl_mtx, "ctl", WITNESS_RANK_CTL))
Jason Evans3c234352010-01-27 13:10:55 -0800872 return (true);
873
874 ctl_initialized = false;
875
876 return (false);
877}
878
Jason Evans20f1fc92012-10-09 14:46:22 -0700879void
Jason Evansc1e00ef2016-05-10 22:21:10 -0700880ctl_prefork(tsdn_t *tsdn)
Jason Evans20f1fc92012-10-09 14:46:22 -0700881{
882
Jason Evansc1e00ef2016-05-10 22:21:10 -0700883 malloc_mutex_prefork(tsdn, &ctl_mtx);
Jason Evans20f1fc92012-10-09 14:46:22 -0700884}
885
886void
Jason Evansc1e00ef2016-05-10 22:21:10 -0700887ctl_postfork_parent(tsdn_t *tsdn)
Jason Evans20f1fc92012-10-09 14:46:22 -0700888{
889
Jason Evansc1e00ef2016-05-10 22:21:10 -0700890 malloc_mutex_postfork_parent(tsdn, &ctl_mtx);
Jason Evans20f1fc92012-10-09 14:46:22 -0700891}
892
893void
Jason Evansc1e00ef2016-05-10 22:21:10 -0700894ctl_postfork_child(tsdn_t *tsdn)
Jason Evans20f1fc92012-10-09 14:46:22 -0700895{
896
Jason Evansc1e00ef2016-05-10 22:21:10 -0700897 malloc_mutex_postfork_child(tsdn, &ctl_mtx);
Jason Evans20f1fc92012-10-09 14:46:22 -0700898}
899
Jason Evans3c234352010-01-27 13:10:55 -0800900/******************************************************************************/
901/* *_ctl() functions. */
902
903#define READONLY() do { \
904 if (newp != NULL || newlen != 0) { \
905 ret = EPERM; \
Jason Evans6b9ed672012-04-25 13:12:46 -0700906 goto label_return; \
Jason Evans3c234352010-01-27 13:10:55 -0800907 } \
908} while (0)
909
Jason Evans22ca8552010-03-02 11:57:30 -0800910#define WRITEONLY() do { \
Jason Evans3c234352010-01-27 13:10:55 -0800911 if (oldp != NULL || oldlenp != NULL) { \
912 ret = EPERM; \
Jason Evans6b9ed672012-04-25 13:12:46 -0700913 goto label_return; \
Jason Evans3c234352010-01-27 13:10:55 -0800914 } \
915} while (0)
916
Jason Evansfc12c0b2014-10-03 23:25:30 -0700917#define READ_XOR_WRITE() do { \
918 if ((oldp != NULL && oldlenp != NULL) && (newp != NULL || \
919 newlen != 0)) { \
920 ret = EPERM; \
921 goto label_return; \
922 } \
923} while (0)
924
Jason Evans3c234352010-01-27 13:10:55 -0800925#define READ(v, t) do { \
926 if (oldp != NULL && oldlenp != NULL) { \
927 if (*oldlenp != sizeof(t)) { \
928 size_t copylen = (sizeof(t) <= *oldlenp) \
929 ? sizeof(t) : *oldlenp; \
Jason Evans6eb84fb2012-11-29 22:13:04 -0800930 memcpy(oldp, (void *)&(v), copylen); \
Jason Evans3c234352010-01-27 13:10:55 -0800931 ret = EINVAL; \
Jason Evans6b9ed672012-04-25 13:12:46 -0700932 goto label_return; \
Jason Evansb49a3342015-07-28 11:28:19 -0400933 } \
934 *(t *)oldp = (v); \
Jason Evans3c234352010-01-27 13:10:55 -0800935 } \
936} while (0)
937
938#define WRITE(v, t) do { \
939 if (newp != NULL) { \
940 if (newlen != sizeof(t)) { \
941 ret = EINVAL; \
Jason Evans6b9ed672012-04-25 13:12:46 -0700942 goto label_return; \
Jason Evans3c234352010-01-27 13:10:55 -0800943 } \
Jason Evans6eb84fb2012-11-29 22:13:04 -0800944 (v) = *(t *)newp; \
Jason Evans3c234352010-01-27 13:10:55 -0800945 } \
946} while (0)
947
Jason Evans7372b152012-02-10 20:22:09 -0800948/*
949 * There's a lot of code duplication in the following macros due to limitations
950 * in how nested cpp macros are expanded.
951 */
952#define CTL_RO_CLGEN(c, l, n, v, t) \
953static int \
Jason Evansb2c0d632016-04-13 23:36:15 -0700954n##_ctl(tsd_t *tsd, const size_t *mib, size_t miblen, void *oldp, \
955 size_t *oldlenp, void *newp, size_t newlen) \
Jason Evans7372b152012-02-10 20:22:09 -0800956{ \
957 int ret; \
958 t oldval; \
959 \
Jason Evans551ebc42014-10-03 10:16:09 -0700960 if (!(c)) \
Jason Evans7372b152012-02-10 20:22:09 -0800961 return (ENOENT); \
962 if (l) \
Jason Evansc1e00ef2016-05-10 22:21:10 -0700963 malloc_mutex_lock(tsd_tsdn(tsd), &ctl_mtx); \
Jason Evans7372b152012-02-10 20:22:09 -0800964 READONLY(); \
Jason Evans6eb84fb2012-11-29 22:13:04 -0800965 oldval = (v); \
Jason Evans7372b152012-02-10 20:22:09 -0800966 READ(oldval, t); \
967 \
968 ret = 0; \
Jason Evans6b9ed672012-04-25 13:12:46 -0700969label_return: \
Jason Evans7372b152012-02-10 20:22:09 -0800970 if (l) \
Jason Evansc1e00ef2016-05-10 22:21:10 -0700971 malloc_mutex_unlock(tsd_tsdn(tsd), &ctl_mtx); \
Jason Evans7372b152012-02-10 20:22:09 -0800972 return (ret); \
973}
974
975#define CTL_RO_CGEN(c, n, v, t) \
976static int \
Jason Evansb2c0d632016-04-13 23:36:15 -0700977n##_ctl(tsd_t *tsd, const size_t *mib, size_t miblen, void *oldp, \
978 size_t *oldlenp, void *newp, size_t newlen) \
Jason Evans7372b152012-02-10 20:22:09 -0800979{ \
980 int ret; \
981 t oldval; \
982 \
Jason Evans551ebc42014-10-03 10:16:09 -0700983 if (!(c)) \
Jason Evans7372b152012-02-10 20:22:09 -0800984 return (ENOENT); \
Jason Evansc1e00ef2016-05-10 22:21:10 -0700985 malloc_mutex_lock(tsd_tsdn(tsd), &ctl_mtx); \
Jason Evans7372b152012-02-10 20:22:09 -0800986 READONLY(); \
Jason Evans6eb84fb2012-11-29 22:13:04 -0800987 oldval = (v); \
Jason Evans7372b152012-02-10 20:22:09 -0800988 READ(oldval, t); \
989 \
990 ret = 0; \
Jason Evans6b9ed672012-04-25 13:12:46 -0700991label_return: \
Jason Evansc1e00ef2016-05-10 22:21:10 -0700992 malloc_mutex_unlock(tsd_tsdn(tsd), &ctl_mtx); \
Jason Evans7372b152012-02-10 20:22:09 -0800993 return (ret); \
994}
995
Jason Evans3c234352010-01-27 13:10:55 -0800996#define CTL_RO_GEN(n, v, t) \
997static int \
Jason Evansb2c0d632016-04-13 23:36:15 -0700998n##_ctl(tsd_t *tsd, const size_t *mib, size_t miblen, void *oldp, \
999 size_t *oldlenp, void *newp, size_t newlen) \
Jason Evans3c234352010-01-27 13:10:55 -08001000{ \
1001 int ret; \
1002 t oldval; \
1003 \
Jason Evansc1e00ef2016-05-10 22:21:10 -07001004 malloc_mutex_lock(tsd_tsdn(tsd), &ctl_mtx); \
Jason Evansfc4dcfa2010-11-24 15:44:21 -08001005 READONLY(); \
Jason Evans6eb84fb2012-11-29 22:13:04 -08001006 oldval = (v); \
Jason Evansfc4dcfa2010-11-24 15:44:21 -08001007 READ(oldval, t); \
1008 \
1009 ret = 0; \
Jason Evans6b9ed672012-04-25 13:12:46 -07001010label_return: \
Jason Evansc1e00ef2016-05-10 22:21:10 -07001011 malloc_mutex_unlock(tsd_tsdn(tsd), &ctl_mtx); \
Jason Evansfc4dcfa2010-11-24 15:44:21 -08001012 return (ret); \
1013}
1014
1015/*
1016 * ctl_mtx is not acquired, under the assumption that no pertinent data will
1017 * mutate during the call.
1018 */
Jason Evans7372b152012-02-10 20:22:09 -08001019#define CTL_RO_NL_CGEN(c, n, v, t) \
1020static int \
Jason Evansb2c0d632016-04-13 23:36:15 -07001021n##_ctl(tsd_t *tsd, const size_t *mib, size_t miblen, void *oldp, \
1022 size_t *oldlenp, void *newp, size_t newlen) \
Jason Evans7372b152012-02-10 20:22:09 -08001023{ \
1024 int ret; \
1025 t oldval; \
1026 \
Jason Evans551ebc42014-10-03 10:16:09 -07001027 if (!(c)) \
Jason Evans7372b152012-02-10 20:22:09 -08001028 return (ENOENT); \
1029 READONLY(); \
Jason Evans6eb84fb2012-11-29 22:13:04 -08001030 oldval = (v); \
Jason Evans7372b152012-02-10 20:22:09 -08001031 READ(oldval, t); \
1032 \
1033 ret = 0; \
Jason Evans6b9ed672012-04-25 13:12:46 -07001034label_return: \
Jason Evans7372b152012-02-10 20:22:09 -08001035 return (ret); \
1036}
1037
1038#define CTL_RO_NL_GEN(n, v, t) \
Jason Evansfc4dcfa2010-11-24 15:44:21 -08001039static int \
Jason Evansb2c0d632016-04-13 23:36:15 -07001040n##_ctl(tsd_t *tsd, const size_t *mib, size_t miblen, void *oldp, \
1041 size_t *oldlenp, void *newp, size_t newlen) \
Jason Evansfc4dcfa2010-11-24 15:44:21 -08001042{ \
1043 int ret; \
1044 t oldval; \
1045 \
Jason Evans3c234352010-01-27 13:10:55 -08001046 READONLY(); \
Jason Evans6eb84fb2012-11-29 22:13:04 -08001047 oldval = (v); \
Jason Evans3c234352010-01-27 13:10:55 -08001048 READ(oldval, t); \
1049 \
1050 ret = 0; \
Jason Evans6b9ed672012-04-25 13:12:46 -07001051label_return: \
Jason Evans3c234352010-01-27 13:10:55 -08001052 return (ret); \
1053}
1054
Jason Evans5460aa62014-09-22 21:09:23 -07001055#define CTL_TSD_RO_NL_CGEN(c, n, m, t) \
1056static int \
Jason Evansb2c0d632016-04-13 23:36:15 -07001057n##_ctl(tsd_t *tsd, const size_t *mib, size_t miblen, void *oldp, \
1058 size_t *oldlenp, void *newp, size_t newlen) \
Jason Evans5460aa62014-09-22 21:09:23 -07001059{ \
1060 int ret; \
1061 t oldval; \
Jason Evans5460aa62014-09-22 21:09:23 -07001062 \
Jason Evans551ebc42014-10-03 10:16:09 -07001063 if (!(c)) \
Jason Evans5460aa62014-09-22 21:09:23 -07001064 return (ENOENT); \
1065 READONLY(); \
Jason Evans5460aa62014-09-22 21:09:23 -07001066 oldval = (m(tsd)); \
1067 READ(oldval, t); \
1068 \
1069 ret = 0; \
1070label_return: \
1071 return (ret); \
1072}
1073
Jason Evansf8290092016-02-07 14:23:22 -08001074#define CTL_RO_CONFIG_GEN(n, t) \
Jason Evans3c234352010-01-27 13:10:55 -08001075static int \
Jason Evansb2c0d632016-04-13 23:36:15 -07001076n##_ctl(tsd_t *tsd, const size_t *mib, size_t miblen, void *oldp, \
1077 size_t *oldlenp, void *newp, size_t newlen) \
Jason Evans3c234352010-01-27 13:10:55 -08001078{ \
1079 int ret; \
Jason Evansf8290092016-02-07 14:23:22 -08001080 t oldval; \
Jason Evans3c234352010-01-27 13:10:55 -08001081 \
1082 READONLY(); \
Jason Evans7372b152012-02-10 20:22:09 -08001083 oldval = n; \
Jason Evansf8290092016-02-07 14:23:22 -08001084 READ(oldval, t); \
Jason Evans3c234352010-01-27 13:10:55 -08001085 \
1086 ret = 0; \
Jason Evans6b9ed672012-04-25 13:12:46 -07001087label_return: \
Jason Evans3c234352010-01-27 13:10:55 -08001088 return (ret); \
1089}
1090
Jason Evansd8a39002013-12-19 21:40:41 -08001091/******************************************************************************/
1092
Jason Evansfc4dcfa2010-11-24 15:44:21 -08001093CTL_RO_NL_GEN(version, JEMALLOC_VERSION, const char *)
Jason Evansa40bc7a2010-03-02 13:01:16 -08001094
Jason Evans3c234352010-01-27 13:10:55 -08001095static int
Jason Evansb2c0d632016-04-13 23:36:15 -07001096epoch_ctl(tsd_t *tsd, const size_t *mib, size_t miblen, void *oldp,
1097 size_t *oldlenp, void *newp, size_t newlen)
Jason Evans3c234352010-01-27 13:10:55 -08001098{
1099 int ret;
Jason Evans3ab682d2013-10-19 17:19:49 -07001100 UNUSED uint64_t newval;
Jason Evans3c234352010-01-27 13:10:55 -08001101
Jason Evansc1e00ef2016-05-10 22:21:10 -07001102 malloc_mutex_lock(tsd_tsdn(tsd), &ctl_mtx);
Jason Evans3c234352010-01-27 13:10:55 -08001103 WRITE(newval, uint64_t);
Jason Evans6b9ed672012-04-25 13:12:46 -07001104 if (newp != NULL)
Jason Evansc1e00ef2016-05-10 22:21:10 -07001105 ctl_refresh(tsd_tsdn(tsd));
Jason Evans3c234352010-01-27 13:10:55 -08001106 READ(ctl_epoch, uint64_t);
1107
1108 ret = 0;
Jason Evansa1ee7832012-04-10 15:07:44 -07001109label_return:
Jason Evansc1e00ef2016-05-10 22:21:10 -07001110 malloc_mutex_unlock(tsd_tsdn(tsd), &ctl_mtx);
Jason Evans3c234352010-01-27 13:10:55 -08001111 return (ret);
1112}
1113
Jason Evansd8a39002013-12-19 21:40:41 -08001114/******************************************************************************/
Jason Evansd4be8b72012-03-26 18:54:44 -07001115
Jason Evansf8290092016-02-07 14:23:22 -08001116CTL_RO_CONFIG_GEN(config_cache_oblivious, bool)
1117CTL_RO_CONFIG_GEN(config_debug, bool)
1118CTL_RO_CONFIG_GEN(config_fill, bool)
1119CTL_RO_CONFIG_GEN(config_lazy_lock, bool)
1120CTL_RO_CONFIG_GEN(config_malloc_conf, const char *)
1121CTL_RO_CONFIG_GEN(config_munmap, bool)
1122CTL_RO_CONFIG_GEN(config_prof, bool)
1123CTL_RO_CONFIG_GEN(config_prof_libgcc, bool)
1124CTL_RO_CONFIG_GEN(config_prof_libunwind, bool)
1125CTL_RO_CONFIG_GEN(config_stats, bool)
1126CTL_RO_CONFIG_GEN(config_tcache, bool)
1127CTL_RO_CONFIG_GEN(config_tls, bool)
1128CTL_RO_CONFIG_GEN(config_utrace, bool)
Jason Evansf8290092016-02-07 14:23:22 -08001129CTL_RO_CONFIG_GEN(config_xmalloc, bool)
Jason Evansd4be8b72012-03-26 18:54:44 -07001130
Jason Evansd8a39002013-12-19 21:40:41 -08001131/******************************************************************************/
Jason Evansd4be8b72012-03-26 18:54:44 -07001132
Jason Evansd8a39002013-12-19 21:40:41 -08001133CTL_RO_NL_GEN(opt_abort, opt_abort, bool)
1134CTL_RO_NL_GEN(opt_dss, opt_dss, const char *)
Jason Evans8f683b92016-02-24 11:03:40 -08001135CTL_RO_NL_GEN(opt_narenas, opt_narenas, unsigned)
Jason Evans243f7a02016-02-19 20:09:31 -08001136CTL_RO_NL_GEN(opt_decay_time, opt_decay_time, ssize_t)
Jason Evansd8a39002013-12-19 21:40:41 -08001137CTL_RO_NL_GEN(opt_stats_print, opt_stats_print, bool)
Guilherme Goncalves2c5cb612014-12-08 19:12:41 -02001138CTL_RO_NL_CGEN(config_fill, opt_junk, opt_junk, const char *)
Jason Evansd8a39002013-12-19 21:40:41 -08001139CTL_RO_NL_CGEN(config_fill, opt_zero, opt_zero, bool)
1140CTL_RO_NL_CGEN(config_utrace, opt_utrace, opt_utrace, bool)
Jason Evansd8a39002013-12-19 21:40:41 -08001141CTL_RO_NL_CGEN(config_xmalloc, opt_xmalloc, opt_xmalloc, bool)
1142CTL_RO_NL_CGEN(config_tcache, opt_tcache, opt_tcache, bool)
1143CTL_RO_NL_CGEN(config_tcache, opt_lg_tcache_max, opt_lg_tcache_max, ssize_t)
1144CTL_RO_NL_CGEN(config_prof, opt_prof, opt_prof, bool)
1145CTL_RO_NL_CGEN(config_prof, opt_prof_prefix, opt_prof_prefix, const char *)
Jason Evansfc12c0b2014-10-03 23:25:30 -07001146CTL_RO_NL_CGEN(config_prof, opt_prof_active, opt_prof_active, bool)
1147CTL_RO_NL_CGEN(config_prof, opt_prof_thread_active_init,
1148 opt_prof_thread_active_init, bool)
Jason Evansd8a39002013-12-19 21:40:41 -08001149CTL_RO_NL_CGEN(config_prof, opt_lg_prof_sample, opt_lg_prof_sample, size_t)
1150CTL_RO_NL_CGEN(config_prof, opt_prof_accum, opt_prof_accum, bool)
1151CTL_RO_NL_CGEN(config_prof, opt_lg_prof_interval, opt_lg_prof_interval, ssize_t)
1152CTL_RO_NL_CGEN(config_prof, opt_prof_gdump, opt_prof_gdump, bool)
1153CTL_RO_NL_CGEN(config_prof, opt_prof_final, opt_prof_final, bool)
1154CTL_RO_NL_CGEN(config_prof, opt_prof_leak, opt_prof_leak, bool)
Jason Evansd4be8b72012-03-26 18:54:44 -07001155
Jason Evansd8a39002013-12-19 21:40:41 -08001156/******************************************************************************/
Jason Evans3c234352010-01-27 13:10:55 -08001157
Jason Evansb267d0f2010-08-13 15:42:29 -07001158static int
Jason Evansb2c0d632016-04-13 23:36:15 -07001159thread_arena_ctl(tsd_t *tsd, const size_t *mib, size_t miblen, void *oldp,
1160 size_t *oldlenp, void *newp, size_t newlen)
Jason Evansb267d0f2010-08-13 15:42:29 -07001161{
1162 int ret;
Jason Evans1cb181e2015-01-29 15:30:47 -08001163 arena_t *oldarena;
Jason Evansb267d0f2010-08-13 15:42:29 -07001164 unsigned newind, oldind;
1165
Jason Evans90827a32016-05-03 15:00:42 -07001166 oldarena = arena_choose(tsd, NULL);
Jason Evans1cb181e2015-01-29 15:30:47 -08001167 if (oldarena == NULL)
Jason Evans8bb31982014-10-07 23:14:57 -07001168 return (EAGAIN);
Jason Evans5460aa62014-09-22 21:09:23 -07001169
Jason Evans1cb181e2015-01-29 15:30:47 -08001170 newind = oldind = oldarena->ind;
Jason Evansa7153a02011-03-14 11:39:49 -07001171 WRITE(newind, unsigned);
1172 READ(oldind, unsigned);
Jason Evansb267d0f2010-08-13 15:42:29 -07001173 if (newind != oldind) {
Jason Evans1cb181e2015-01-29 15:30:47 -08001174 arena_t *newarena;
1175
Jason Evansb6c08672016-10-03 10:37:12 -07001176 if (newind >= narenas_total_get()) {
Jason Evansb267d0f2010-08-13 15:42:29 -07001177 /* New arena index is out of range. */
1178 ret = EFAULT;
Jason Evansa1ee7832012-04-10 15:07:44 -07001179 goto label_return;
Jason Evansb267d0f2010-08-13 15:42:29 -07001180 }
1181
1182 /* Initialize arena if necessary. */
Jason Evansc1e00ef2016-05-10 22:21:10 -07001183 newarena = arena_get(tsd_tsdn(tsd), newind, true);
Jason Evans1cb181e2015-01-29 15:30:47 -08001184 if (newarena == NULL) {
Jason Evansb267d0f2010-08-13 15:42:29 -07001185 ret = EAGAIN;
Jason Evansa1ee7832012-04-10 15:07:44 -07001186 goto label_return;
Jason Evansb267d0f2010-08-13 15:42:29 -07001187 }
Jason Evans8bb31982014-10-07 23:14:57 -07001188 /* Set new arena/tcache associations. */
1189 arena_migrate(tsd, oldind, newind);
Jason Evans7372b152012-02-10 20:22:09 -08001190 if (config_tcache) {
Jason Evans5460aa62014-09-22 21:09:23 -07001191 tcache_t *tcache = tsd_tcache_get(tsd);
Jason Evans1cb181e2015-01-29 15:30:47 -08001192 if (tcache != NULL) {
Jason Evansc1e00ef2016-05-10 22:21:10 -07001193 tcache_arena_reassociate(tsd_tsdn(tsd), tcache,
1194 oldarena, newarena);
Jason Evans1cb181e2015-01-29 15:30:47 -08001195 }
Jason Evans624f2f32010-12-29 12:21:05 -08001196 }
Jason Evansb267d0f2010-08-13 15:42:29 -07001197 }
1198
1199 ret = 0;
Jason Evansa1ee7832012-04-10 15:07:44 -07001200label_return:
Jason Evansb267d0f2010-08-13 15:42:29 -07001201 return (ret);
1202}
Jason Evansb267d0f2010-08-13 15:42:29 -07001203
Jason Evans5460aa62014-09-22 21:09:23 -07001204CTL_TSD_RO_NL_CGEN(config_stats, thread_allocated, tsd_thread_allocated_get,
1205 uint64_t)
1206CTL_TSD_RO_NL_CGEN(config_stats, thread_allocatedp, tsd_thread_allocatedp_get,
1207 uint64_t *)
1208CTL_TSD_RO_NL_CGEN(config_stats, thread_deallocated, tsd_thread_deallocated_get,
1209 uint64_t)
1210CTL_TSD_RO_NL_CGEN(config_stats, thread_deallocatedp,
1211 tsd_thread_deallocatedp_get, uint64_t *)
Jason Evans93443682010-10-20 17:39:18 -07001212
Jason Evansd8a39002013-12-19 21:40:41 -08001213static int
Jason Evansb2c0d632016-04-13 23:36:15 -07001214thread_tcache_enabled_ctl(tsd_t *tsd, const size_t *mib, size_t miblen,
1215 void *oldp, size_t *oldlenp, void *newp, size_t newlen)
Jason Evansd8a39002013-12-19 21:40:41 -08001216{
1217 int ret;
1218 bool oldval;
Jason Evans3c234352010-01-27 13:10:55 -08001219
Jason Evans551ebc42014-10-03 10:16:09 -07001220 if (!config_tcache)
Jason Evansd8a39002013-12-19 21:40:41 -08001221 return (ENOENT);
Jason Evans3c234352010-01-27 13:10:55 -08001222
Jason Evansd8a39002013-12-19 21:40:41 -08001223 oldval = tcache_enabled_get();
1224 if (newp != NULL) {
1225 if (newlen != sizeof(bool)) {
1226 ret = EINVAL;
1227 goto label_return;
1228 }
1229 tcache_enabled_set(*(bool *)newp);
1230 }
1231 READ(oldval, bool);
Jason Evans3c234352010-01-27 13:10:55 -08001232
Jason Evansd8a39002013-12-19 21:40:41 -08001233 ret = 0;
1234label_return:
1235 return (ret);
1236}
1237
1238static int
Jason Evansb2c0d632016-04-13 23:36:15 -07001239thread_tcache_flush_ctl(tsd_t *tsd, const size_t *mib, size_t miblen,
1240 void *oldp, size_t *oldlenp, void *newp, size_t newlen)
Jason Evansd8a39002013-12-19 21:40:41 -08001241{
1242 int ret;
1243
Jason Evans551ebc42014-10-03 10:16:09 -07001244 if (!config_tcache)
Jason Evansd8a39002013-12-19 21:40:41 -08001245 return (ENOENT);
1246
1247 READONLY();
1248 WRITEONLY();
1249
1250 tcache_flush();
1251
1252 ret = 0;
1253label_return:
1254 return (ret);
1255}
Jason Evans3c234352010-01-27 13:10:55 -08001256
Jason Evans602c8e02014-08-18 16:22:13 -07001257static int
Jason Evansb2c0d632016-04-13 23:36:15 -07001258thread_prof_name_ctl(tsd_t *tsd, const size_t *mib, size_t miblen, void *oldp,
Jason Evans602c8e02014-08-18 16:22:13 -07001259 size_t *oldlenp, void *newp, size_t newlen)
1260{
1261 int ret;
Jason Evans602c8e02014-08-18 16:22:13 -07001262
Jason Evans551ebc42014-10-03 10:16:09 -07001263 if (!config_prof)
Jason Evans602c8e02014-08-18 16:22:13 -07001264 return (ENOENT);
1265
Jason Evansfc12c0b2014-10-03 23:25:30 -07001266 READ_XOR_WRITE();
1267
Jason Evans602c8e02014-08-18 16:22:13 -07001268 if (newp != NULL) {
1269 if (newlen != sizeof(const char *)) {
1270 ret = EINVAL;
1271 goto label_return;
1272 }
Jason Evans5460aa62014-09-22 21:09:23 -07001273
Jason Evansfc12c0b2014-10-03 23:25:30 -07001274 if ((ret = prof_thread_name_set(tsd, *(const char **)newp)) !=
1275 0)
Jason Evans602c8e02014-08-18 16:22:13 -07001276 goto label_return;
Jason Evansfc12c0b2014-10-03 23:25:30 -07001277 } else {
Jason Evansb2c0d632016-04-13 23:36:15 -07001278 const char *oldname = prof_thread_name_get(tsd);
Jason Evansfc12c0b2014-10-03 23:25:30 -07001279 READ(oldname, const char *);
Jason Evans602c8e02014-08-18 16:22:13 -07001280 }
Jason Evans602c8e02014-08-18 16:22:13 -07001281
1282 ret = 0;
1283label_return:
1284 return (ret);
1285}
1286
1287static int
Jason Evansb2c0d632016-04-13 23:36:15 -07001288thread_prof_active_ctl(tsd_t *tsd, const size_t *mib, size_t miblen, void *oldp,
Jason Evans602c8e02014-08-18 16:22:13 -07001289 size_t *oldlenp, void *newp, size_t newlen)
1290{
1291 int ret;
1292 bool oldval;
1293
Jason Evans551ebc42014-10-03 10:16:09 -07001294 if (!config_prof)
Jason Evans602c8e02014-08-18 16:22:13 -07001295 return (ENOENT);
1296
Jason Evansb2c0d632016-04-13 23:36:15 -07001297 oldval = prof_thread_active_get(tsd);
Jason Evans602c8e02014-08-18 16:22:13 -07001298 if (newp != NULL) {
1299 if (newlen != sizeof(bool)) {
1300 ret = EINVAL;
1301 goto label_return;
1302 }
Jason Evansb2c0d632016-04-13 23:36:15 -07001303 if (prof_thread_active_set(tsd, *(bool *)newp)) {
Jason Evans602c8e02014-08-18 16:22:13 -07001304 ret = EAGAIN;
1305 goto label_return;
1306 }
1307 }
1308 READ(oldval, bool);
1309
1310 ret = 0;
1311label_return:
1312 return (ret);
1313}
1314
Jason Evans3c234352010-01-27 13:10:55 -08001315/******************************************************************************/
1316
Jason Evans1cb181e2015-01-29 15:30:47 -08001317static int
Jason Evansb2c0d632016-04-13 23:36:15 -07001318tcache_create_ctl(tsd_t *tsd, const size_t *mib, size_t miblen, void *oldp,
1319 size_t *oldlenp, void *newp, size_t newlen)
Jason Evans1cb181e2015-01-29 15:30:47 -08001320{
1321 int ret;
Jason Evans1cb181e2015-01-29 15:30:47 -08001322 unsigned tcache_ind;
1323
1324 if (!config_tcache)
1325 return (ENOENT);
1326
Jason Evansc1e00ef2016-05-10 22:21:10 -07001327 malloc_mutex_lock(tsd_tsdn(tsd), &ctl_mtx);
Jason Evans1cb181e2015-01-29 15:30:47 -08001328 READONLY();
Jason Evansb54d1602016-10-20 23:59:12 -07001329 if (tcaches_create(tsd, &tcache_ind)) {
Jason Evans1cb181e2015-01-29 15:30:47 -08001330 ret = EFAULT;
1331 goto label_return;
1332 }
1333 READ(tcache_ind, unsigned);
1334
1335 ret = 0;
1336label_return:
Jason Evansc1e00ef2016-05-10 22:21:10 -07001337 malloc_mutex_unlock(tsd_tsdn(tsd), &ctl_mtx);
Jason Evans1cb181e2015-01-29 15:30:47 -08001338 return (ret);
1339}
1340
1341static int
Jason Evansb2c0d632016-04-13 23:36:15 -07001342tcache_flush_ctl(tsd_t *tsd, const size_t *mib, size_t miblen, void *oldp,
1343 size_t *oldlenp, void *newp, size_t newlen)
Jason Evans1cb181e2015-01-29 15:30:47 -08001344{
1345 int ret;
Jason Evans1cb181e2015-01-29 15:30:47 -08001346 unsigned tcache_ind;
1347
1348 if (!config_tcache)
1349 return (ENOENT);
1350
Jason Evans1cb181e2015-01-29 15:30:47 -08001351 WRITEONLY();
1352 tcache_ind = UINT_MAX;
1353 WRITE(tcache_ind, unsigned);
1354 if (tcache_ind == UINT_MAX) {
1355 ret = EFAULT;
1356 goto label_return;
1357 }
1358 tcaches_flush(tsd, tcache_ind);
1359
1360 ret = 0;
1361label_return:
1362 return (ret);
1363}
1364
1365static int
Jason Evansb2c0d632016-04-13 23:36:15 -07001366tcache_destroy_ctl(tsd_t *tsd, const size_t *mib, size_t miblen, void *oldp,
Jason Evans1cb181e2015-01-29 15:30:47 -08001367 size_t *oldlenp, void *newp, size_t newlen)
1368{
1369 int ret;
Jason Evans1cb181e2015-01-29 15:30:47 -08001370 unsigned tcache_ind;
1371
1372 if (!config_tcache)
1373 return (ENOENT);
1374
Jason Evans1cb181e2015-01-29 15:30:47 -08001375 WRITEONLY();
1376 tcache_ind = UINT_MAX;
1377 WRITE(tcache_ind, unsigned);
1378 if (tcache_ind == UINT_MAX) {
1379 ret = EFAULT;
1380 goto label_return;
1381 }
1382 tcaches_destroy(tsd, tcache_ind);
1383
1384 ret = 0;
1385label_return:
1386 return (ret);
1387}
1388
1389/******************************************************************************/
1390
Jason Evans34457f52012-11-03 21:18:28 -07001391static void
Jason Evansc1e00ef2016-05-10 22:21:10 -07001392arena_i_purge(tsdn_t *tsdn, unsigned arena_ind, bool all)
Jason Evans609ae592012-10-11 13:53:15 -07001393{
Jason Evans609ae592012-10-11 13:53:15 -07001394
Jason Evansc1e00ef2016-05-10 22:21:10 -07001395 malloc_mutex_lock(tsdn, &ctl_mtx);
Jason Evans243f7a02016-02-19 20:09:31 -08001396 {
Jason Evans243f7a02016-02-19 20:09:31 -08001397 unsigned narenas = ctl_stats.narenas;
Jason Evans609ae592012-10-11 13:53:15 -07001398
Jason Evans243f7a02016-02-19 20:09:31 -08001399 if (arena_ind == narenas) {
1400 unsigned i;
Jason Evans243f7a02016-02-19 20:09:31 -08001401 VARIABLE_ARRAY(arena_t *, tarenas, narenas);
1402
Jason Evans767d8502016-02-24 23:58:10 -08001403 for (i = 0; i < narenas; i++)
Jason Evansc1e00ef2016-05-10 22:21:10 -07001404 tarenas[i] = arena_get(tsdn, i, false);
Jason Evans243f7a02016-02-19 20:09:31 -08001405
1406 /*
1407 * No further need to hold ctl_mtx, since narenas and
1408 * tarenas contain everything needed below.
1409 */
Jason Evansc1e00ef2016-05-10 22:21:10 -07001410 malloc_mutex_unlock(tsdn, &ctl_mtx);
Jason Evans243f7a02016-02-19 20:09:31 -08001411
1412 for (i = 0; i < narenas; i++) {
1413 if (tarenas[i] != NULL)
Jason Evansc1e00ef2016-05-10 22:21:10 -07001414 arena_purge(tsdn, tarenas[i], all);
Jason Evans243f7a02016-02-19 20:09:31 -08001415 }
1416 } else {
1417 arena_t *tarena;
1418
1419 assert(arena_ind < narenas);
1420
Jason Evansc1e00ef2016-05-10 22:21:10 -07001421 tarena = arena_get(tsdn, arena_ind, false);
Jason Evans243f7a02016-02-19 20:09:31 -08001422
1423 /* No further need to hold ctl_mtx. */
Jason Evansc1e00ef2016-05-10 22:21:10 -07001424 malloc_mutex_unlock(tsdn, &ctl_mtx);
Jason Evans243f7a02016-02-19 20:09:31 -08001425
1426 if (tarena != NULL)
Jason Evansc1e00ef2016-05-10 22:21:10 -07001427 arena_purge(tsdn, tarena, all);
Jason Evans609ae592012-10-11 13:53:15 -07001428 }
1429 }
Jason Evans609ae592012-10-11 13:53:15 -07001430}
1431
1432static int
Jason Evansb2c0d632016-04-13 23:36:15 -07001433arena_i_purge_ctl(tsd_t *tsd, const size_t *mib, size_t miblen, void *oldp,
1434 size_t *oldlenp, void *newp, size_t newlen)
Jason Evans609ae592012-10-11 13:53:15 -07001435{
1436 int ret;
1437
1438 READONLY();
1439 WRITEONLY();
Jason Evansc1e00ef2016-05-10 22:21:10 -07001440 arena_i_purge(tsd_tsdn(tsd), (unsigned)mib[1], true);
Jason Evans243f7a02016-02-19 20:09:31 -08001441
1442 ret = 0;
1443label_return:
1444 return (ret);
1445}
1446
1447static int
Jason Evansb2c0d632016-04-13 23:36:15 -07001448arena_i_decay_ctl(tsd_t *tsd, const size_t *mib, size_t miblen, void *oldp,
1449 size_t *oldlenp, void *newp, size_t newlen)
Jason Evans243f7a02016-02-19 20:09:31 -08001450{
1451 int ret;
1452
1453 READONLY();
1454 WRITEONLY();
Jason Evansc1e00ef2016-05-10 22:21:10 -07001455 arena_i_purge(tsd_tsdn(tsd), (unsigned)mib[1], false);
Jason Evans609ae592012-10-11 13:53:15 -07001456
Jason Evans34457f52012-11-03 21:18:28 -07001457 ret = 0;
Jason Evans609ae592012-10-11 13:53:15 -07001458label_return:
1459 return (ret);
1460}
1461
1462static int
Jason Evans19ff2ce2016-04-22 14:37:17 -07001463arena_i_reset_ctl(tsd_t *tsd, const size_t *mib, size_t miblen, void *oldp,
1464 size_t *oldlenp, void *newp, size_t newlen)
1465{
1466 int ret;
1467 unsigned arena_ind;
1468 arena_t *arena;
1469
1470 READONLY();
1471 WRITEONLY();
1472
Jason Evans19ff2ce2016-04-22 14:37:17 -07001473 arena_ind = (unsigned)mib[1];
1474 if (config_debug) {
Jason Evansc1e00ef2016-05-10 22:21:10 -07001475 malloc_mutex_lock(tsd_tsdn(tsd), &ctl_mtx);
Jason Evans19ff2ce2016-04-22 14:37:17 -07001476 assert(arena_ind < ctl_stats.narenas);
Jason Evansc1e00ef2016-05-10 22:21:10 -07001477 malloc_mutex_unlock(tsd_tsdn(tsd), &ctl_mtx);
Jason Evans19ff2ce2016-04-22 14:37:17 -07001478 }
1479 assert(arena_ind >= opt_narenas);
1480
Jason Evansc1e00ef2016-05-10 22:21:10 -07001481 arena = arena_get(tsd_tsdn(tsd), arena_ind, false);
Jason Evans19ff2ce2016-04-22 14:37:17 -07001482
1483 arena_reset(tsd, arena);
1484
1485 ret = 0;
1486label_return:
1487 return (ret);
1488}
1489
1490static int
Jason Evansb2c0d632016-04-13 23:36:15 -07001491arena_i_dss_ctl(tsd_t *tsd, const size_t *mib, size_t miblen, void *oldp,
1492 size_t *oldlenp, void *newp, size_t newlen)
Jason Evans609ae592012-10-11 13:53:15 -07001493{
Jason Evans586c8ed2014-08-15 12:20:20 -07001494 int ret;
1495 const char *dss = NULL;
Jason Evans8dd51152016-02-24 11:00:40 -08001496 unsigned arena_ind = (unsigned)mib[1];
Jason Evans609ae592012-10-11 13:53:15 -07001497 dss_prec_t dss_prec_old = dss_prec_limit;
1498 dss_prec_t dss_prec = dss_prec_limit;
1499
Jason Evansc1e00ef2016-05-10 22:21:10 -07001500 malloc_mutex_lock(tsd_tsdn(tsd), &ctl_mtx);
Jason Evans609ae592012-10-11 13:53:15 -07001501 WRITE(dss, const char *);
Jason Evans586c8ed2014-08-15 12:20:20 -07001502 if (dss != NULL) {
1503 int i;
1504 bool match = false;
1505
1506 for (i = 0; i < dss_prec_limit; i++) {
1507 if (strcmp(dss_prec_names[i], dss) == 0) {
1508 dss_prec = i;
1509 match = true;
1510 break;
1511 }
Jason Evans609ae592012-10-11 13:53:15 -07001512 }
Jason Evans586c8ed2014-08-15 12:20:20 -07001513
Jason Evans551ebc42014-10-03 10:16:09 -07001514 if (!match) {
Jason Evans586c8ed2014-08-15 12:20:20 -07001515 ret = EINVAL;
1516 goto label_return;
1517 }
Jason Evans609ae592012-10-11 13:53:15 -07001518 }
1519
1520 if (arena_ind < ctl_stats.narenas) {
Jason Evansc1e00ef2016-05-10 22:21:10 -07001521 arena_t *arena = arena_get(tsd_tsdn(tsd), arena_ind, false);
Jason Evans586c8ed2014-08-15 12:20:20 -07001522 if (arena == NULL || (dss_prec != dss_prec_limit &&
Jason Evansc1e00ef2016-05-10 22:21:10 -07001523 arena_dss_prec_set(tsd_tsdn(tsd), arena, dss_prec))) {
Jason Evans586c8ed2014-08-15 12:20:20 -07001524 ret = EFAULT;
1525 goto label_return;
1526 }
Jason Evansc1e00ef2016-05-10 22:21:10 -07001527 dss_prec_old = arena_dss_prec_get(tsd_tsdn(tsd), arena);
Jason Evans609ae592012-10-11 13:53:15 -07001528 } else {
Jason Evans586c8ed2014-08-15 12:20:20 -07001529 if (dss_prec != dss_prec_limit &&
Jason Evans577d4572016-10-13 12:18:38 -07001530 extent_dss_prec_set(dss_prec)) {
Jason Evans586c8ed2014-08-15 12:20:20 -07001531 ret = EFAULT;
1532 goto label_return;
1533 }
Jason Evans577d4572016-10-13 12:18:38 -07001534 dss_prec_old = extent_dss_prec_get();
Jason Evans609ae592012-10-11 13:53:15 -07001535 }
Jason Evans586c8ed2014-08-15 12:20:20 -07001536
Jason Evans609ae592012-10-11 13:53:15 -07001537 dss = dss_prec_names[dss_prec_old];
1538 READ(dss, const char *);
Jason Evans609ae592012-10-11 13:53:15 -07001539
1540 ret = 0;
1541label_return:
Jason Evansc1e00ef2016-05-10 22:21:10 -07001542 malloc_mutex_unlock(tsd_tsdn(tsd), &ctl_mtx);
Jason Evans609ae592012-10-11 13:53:15 -07001543 return (ret);
1544}
1545
aravindfb7fe502014-05-05 15:16:56 -07001546static int
Jason Evansb2c0d632016-04-13 23:36:15 -07001547arena_i_decay_time_ctl(tsd_t *tsd, const size_t *mib, size_t miblen, void *oldp,
Jason Evans243f7a02016-02-19 20:09:31 -08001548 size_t *oldlenp, void *newp, size_t newlen)
1549{
1550 int ret;
Jason Evans8dd51152016-02-24 11:00:40 -08001551 unsigned arena_ind = (unsigned)mib[1];
Jason Evans243f7a02016-02-19 20:09:31 -08001552 arena_t *arena;
1553
Jason Evansc1e00ef2016-05-10 22:21:10 -07001554 arena = arena_get(tsd_tsdn(tsd), arena_ind, false);
Jason Evans243f7a02016-02-19 20:09:31 -08001555 if (arena == NULL) {
1556 ret = EFAULT;
1557 goto label_return;
1558 }
1559
1560 if (oldp != NULL && oldlenp != NULL) {
Jason Evansc1e00ef2016-05-10 22:21:10 -07001561 size_t oldval = arena_decay_time_get(tsd_tsdn(tsd), arena);
Jason Evans243f7a02016-02-19 20:09:31 -08001562 READ(oldval, ssize_t);
1563 }
1564 if (newp != NULL) {
1565 if (newlen != sizeof(ssize_t)) {
1566 ret = EINVAL;
1567 goto label_return;
1568 }
Jason Evansc1e00ef2016-05-10 22:21:10 -07001569 if (arena_decay_time_set(tsd_tsdn(tsd), arena,
1570 *(ssize_t *)newp)) {
Jason Evans243f7a02016-02-19 20:09:31 -08001571 ret = EFAULT;
1572 goto label_return;
1573 }
1574 }
1575
1576 ret = 0;
1577label_return:
1578 return (ret);
1579}
1580
1581static int
Jason Evans9c305c92016-05-31 15:03:51 -07001582arena_i_extent_hooks_ctl(tsd_t *tsd, const size_t *mib, size_t miblen,
Jason Evansb2c0d632016-04-13 23:36:15 -07001583 void *oldp, size_t *oldlenp, void *newp, size_t newlen)
Jason Evansb49a3342015-07-28 11:28:19 -04001584{
1585 int ret;
Jason Evans8dd51152016-02-24 11:00:40 -08001586 unsigned arena_ind = (unsigned)mib[1];
Jason Evansb49a3342015-07-28 11:28:19 -04001587 arena_t *arena;
1588
Jason Evansc1e00ef2016-05-10 22:21:10 -07001589 malloc_mutex_lock(tsd_tsdn(tsd), &ctl_mtx);
Jason Evansb49a3342015-07-28 11:28:19 -04001590 if (arena_ind < narenas_total_get() && (arena =
Jason Evansc1e00ef2016-05-10 22:21:10 -07001591 arena_get(tsd_tsdn(tsd), arena_ind, false)) != NULL) {
Jason Evansb49a3342015-07-28 11:28:19 -04001592 if (newp != NULL) {
Jason Evansf02fec82016-06-03 19:39:14 -07001593 extent_hooks_t *old_extent_hooks;
1594 extent_hooks_t *new_extent_hooks
1595 JEMALLOC_CC_SILENCE_INIT(NULL);
Jason Evansf8f05422016-06-03 12:05:53 -07001596 WRITE(new_extent_hooks, extent_hooks_t *);
1597 old_extent_hooks = extent_hooks_set(arena,
1598 new_extent_hooks);
1599 READ(old_extent_hooks, extent_hooks_t *);
Jason Evansb49a3342015-07-28 11:28:19 -04001600 } else {
Jason Evansf8f05422016-06-03 12:05:53 -07001601 extent_hooks_t *old_extent_hooks =
1602 extent_hooks_get(arena);
1603 READ(old_extent_hooks, extent_hooks_t *);
Jason Evansb49a3342015-07-28 11:28:19 -04001604 }
1605 } else {
1606 ret = EFAULT;
1607 goto label_return;
1608 }
1609 ret = 0;
1610label_return:
Jason Evansc1e00ef2016-05-10 22:21:10 -07001611 malloc_mutex_unlock(tsd_tsdn(tsd), &ctl_mtx);
Jason Evansb49a3342015-07-28 11:28:19 -04001612 return (ret);
aravindfb7fe502014-05-05 15:16:56 -07001613}
1614
Jason Evans609ae592012-10-11 13:53:15 -07001615static const ctl_named_node_t *
Jason Evansc1e00ef2016-05-10 22:21:10 -07001616arena_i_index(tsdn_t *tsdn, const size_t *mib, size_t miblen, size_t i)
Jason Evans609ae592012-10-11 13:53:15 -07001617{
Jason Evansb2c0d632016-04-13 23:36:15 -07001618 const ctl_named_node_t *ret;
Jason Evans609ae592012-10-11 13:53:15 -07001619
Jason Evansc1e00ef2016-05-10 22:21:10 -07001620 malloc_mutex_lock(tsdn, &ctl_mtx);
Jason Evans609ae592012-10-11 13:53:15 -07001621 if (i > ctl_stats.narenas) {
1622 ret = NULL;
1623 goto label_return;
1624 }
1625
1626 ret = super_arena_i_node;
1627label_return:
Jason Evansc1e00ef2016-05-10 22:21:10 -07001628 malloc_mutex_unlock(tsdn, &ctl_mtx);
Jason Evans609ae592012-10-11 13:53:15 -07001629 return (ret);
1630}
1631
Jason Evans609ae592012-10-11 13:53:15 -07001632/******************************************************************************/
1633
Jason Evans609ae592012-10-11 13:53:15 -07001634static int
Jason Evansb2c0d632016-04-13 23:36:15 -07001635arenas_narenas_ctl(tsd_t *tsd, const size_t *mib, size_t miblen, void *oldp,
Jason Evans609ae592012-10-11 13:53:15 -07001636 size_t *oldlenp, void *newp, size_t newlen)
1637{
1638 int ret;
1639 unsigned narenas;
1640
Jason Evansc1e00ef2016-05-10 22:21:10 -07001641 malloc_mutex_lock(tsd_tsdn(tsd), &ctl_mtx);
Jason Evans609ae592012-10-11 13:53:15 -07001642 READONLY();
1643 if (*oldlenp != sizeof(unsigned)) {
1644 ret = EINVAL;
1645 goto label_return;
1646 }
1647 narenas = ctl_stats.narenas;
1648 READ(narenas, unsigned);
1649
1650 ret = 0;
1651label_return:
Jason Evansc1e00ef2016-05-10 22:21:10 -07001652 malloc_mutex_unlock(tsd_tsdn(tsd), &ctl_mtx);
Jason Evans609ae592012-10-11 13:53:15 -07001653 return (ret);
1654}
Jason Evans3c234352010-01-27 13:10:55 -08001655
1656static int
Jason Evansb2c0d632016-04-13 23:36:15 -07001657arenas_initialized_ctl(tsd_t *tsd, const size_t *mib, size_t miblen, void *oldp,
Jason Evans3c234352010-01-27 13:10:55 -08001658 size_t *oldlenp, void *newp, size_t newlen)
1659{
1660 int ret;
1661 unsigned nread, i;
1662
Jason Evansc1e00ef2016-05-10 22:21:10 -07001663 malloc_mutex_lock(tsd_tsdn(tsd), &ctl_mtx);
Jason Evans3c234352010-01-27 13:10:55 -08001664 READONLY();
Jason Evans609ae592012-10-11 13:53:15 -07001665 if (*oldlenp != ctl_stats.narenas * sizeof(bool)) {
Jason Evans3c234352010-01-27 13:10:55 -08001666 ret = EINVAL;
Jason Evans609ae592012-10-11 13:53:15 -07001667 nread = (*oldlenp < ctl_stats.narenas * sizeof(bool))
Jason Evans8dd51152016-02-24 11:00:40 -08001668 ? (unsigned)(*oldlenp / sizeof(bool)) : ctl_stats.narenas;
Jason Evans3c234352010-01-27 13:10:55 -08001669 } else {
1670 ret = 0;
Jason Evans609ae592012-10-11 13:53:15 -07001671 nread = ctl_stats.narenas;
Jason Evans3c234352010-01-27 13:10:55 -08001672 }
1673
1674 for (i = 0; i < nread; i++)
1675 ((bool *)oldp)[i] = ctl_stats.arenas[i].initialized;
1676
Jason Evansa1ee7832012-04-10 15:07:44 -07001677label_return:
Jason Evansc1e00ef2016-05-10 22:21:10 -07001678 malloc_mutex_unlock(tsd_tsdn(tsd), &ctl_mtx);
Jason Evans3c234352010-01-27 13:10:55 -08001679 return (ret);
1680}
1681
Jason Evans8d6a3e82015-03-18 18:55:33 -07001682static int
Jason Evansb2c0d632016-04-13 23:36:15 -07001683arenas_decay_time_ctl(tsd_t *tsd, const size_t *mib, size_t miblen, void *oldp,
Jason Evans243f7a02016-02-19 20:09:31 -08001684 size_t *oldlenp, void *newp, size_t newlen)
1685{
1686 int ret;
1687
1688 if (oldp != NULL && oldlenp != NULL) {
1689 size_t oldval = arena_decay_time_default_get();
1690 READ(oldval, ssize_t);
1691 }
1692 if (newp != NULL) {
1693 if (newlen != sizeof(ssize_t)) {
1694 ret = EINVAL;
1695 goto label_return;
1696 }
1697 if (arena_decay_time_default_set(*(ssize_t *)newp)) {
1698 ret = EFAULT;
1699 goto label_return;
1700 }
1701 }
1702
1703 ret = 0;
1704label_return:
1705 return (ret);
1706}
1707
Jason Evansfc4dcfa2010-11-24 15:44:21 -08001708CTL_RO_NL_GEN(arenas_quantum, QUANTUM, size_t)
Jason Evansae4c7b42012-04-02 07:04:34 -07001709CTL_RO_NL_GEN(arenas_page, PAGE, size_t)
Jason Evans7372b152012-02-10 20:22:09 -08001710CTL_RO_NL_CGEN(config_tcache, arenas_tcache_max, tcache_maxclass, size_t)
Jason Evansb1726102012-02-28 16:50:47 -08001711CTL_RO_NL_GEN(arenas_nbins, NBINS, unsigned)
Jason Evans7372b152012-02-10 20:22:09 -08001712CTL_RO_NL_CGEN(config_tcache, arenas_nhbins, nhbins, unsigned)
Jason Evansd8a39002013-12-19 21:40:41 -08001713CTL_RO_NL_GEN(arenas_bin_i_size, arena_bin_info[mib[2]].reg_size, size_t)
1714CTL_RO_NL_GEN(arenas_bin_i_nregs, arena_bin_info[mib[2]].nregs, uint32_t)
Jason Evans498856f2016-05-29 18:34:50 -07001715CTL_RO_NL_GEN(arenas_bin_i_slab_size, arena_bin_info[mib[2]].slab_size, size_t)
Jason Evansd8a39002013-12-19 21:40:41 -08001716static const ctl_named_node_t *
Jason Evansc1e00ef2016-05-10 22:21:10 -07001717arenas_bin_i_index(tsdn_t *tsdn, const size_t *mib, size_t miblen, size_t i)
Jason Evansd8a39002013-12-19 21:40:41 -08001718{
1719
1720 if (i > NBINS)
1721 return (NULL);
1722 return (super_arenas_bin_i_node);
1723}
1724
Jason Evans7d63fed2016-05-31 14:50:21 -07001725CTL_RO_NL_GEN(arenas_nlextents, NSIZES - NBINS, unsigned)
1726CTL_RO_NL_GEN(arenas_lextent_i_size, index2size(NBINS+(szind_t)mib[2]), size_t)
Jason Evans3c4d92e2014-10-12 22:53:59 -07001727static const ctl_named_node_t *
Jason Evans7d63fed2016-05-31 14:50:21 -07001728arenas_lextent_i_index(tsdn_t *tsdn, const size_t *mib, size_t miblen, size_t i)
Jason Evans3c4d92e2014-10-12 22:53:59 -07001729{
1730
Jason Evansed2c2422016-05-28 00:17:28 -07001731 if (i > NSIZES - NBINS)
Jason Evans3c4d92e2014-10-12 22:53:59 -07001732 return (NULL);
Jason Evans7d63fed2016-05-31 14:50:21 -07001733 return (super_arenas_lextent_i_node);
Jason Evans3c4d92e2014-10-12 22:53:59 -07001734}
1735
Jason Evans6005f072010-09-30 16:55:08 -07001736static int
Jason Evansb2c0d632016-04-13 23:36:15 -07001737arenas_extend_ctl(tsd_t *tsd, const size_t *mib, size_t miblen, void *oldp,
1738 size_t *oldlenp, void *newp, size_t newlen)
Jason Evans609ae592012-10-11 13:53:15 -07001739{
1740 int ret;
Jason Evans6eb84fb2012-11-29 22:13:04 -08001741 unsigned narenas;
Jason Evans609ae592012-10-11 13:53:15 -07001742
Jason Evansc1e00ef2016-05-10 22:21:10 -07001743 malloc_mutex_lock(tsd_tsdn(tsd), &ctl_mtx);
Jason Evans609ae592012-10-11 13:53:15 -07001744 READONLY();
Jason Evansc1e00ef2016-05-10 22:21:10 -07001745 if (ctl_grow(tsd_tsdn(tsd))) {
Jason Evans609ae592012-10-11 13:53:15 -07001746 ret = EAGAIN;
1747 goto label_return;
1748 }
Jason Evans6eb84fb2012-11-29 22:13:04 -08001749 narenas = ctl_stats.narenas - 1;
1750 READ(narenas, unsigned);
Jason Evans609ae592012-10-11 13:53:15 -07001751
Jason Evans6005f072010-09-30 16:55:08 -07001752 ret = 0;
Jason Evansa1ee7832012-04-10 15:07:44 -07001753label_return:
Jason Evansc1e00ef2016-05-10 22:21:10 -07001754 malloc_mutex_unlock(tsd_tsdn(tsd), &ctl_mtx);
Jason Evans6005f072010-09-30 16:55:08 -07001755 return (ret);
1756}
1757
Jason Evans3c234352010-01-27 13:10:55 -08001758/******************************************************************************/
1759
Jason Evansd34f9e72010-02-11 13:19:21 -08001760static int
Jason Evansb2c0d632016-04-13 23:36:15 -07001761prof_thread_active_init_ctl(tsd_t *tsd, const size_t *mib, size_t miblen,
1762 void *oldp, size_t *oldlenp, void *newp, size_t newlen)
1763{
1764 int ret;
1765 bool oldval;
1766
1767 if (!config_prof)
1768 return (ENOENT);
1769
1770 if (newp != NULL) {
1771 if (newlen != sizeof(bool)) {
1772 ret = EINVAL;
1773 goto label_return;
1774 }
Jason Evansc1e00ef2016-05-10 22:21:10 -07001775 oldval = prof_thread_active_init_set(tsd_tsdn(tsd),
1776 *(bool *)newp);
Jason Evansb2c0d632016-04-13 23:36:15 -07001777 } else
Jason Evansc1e00ef2016-05-10 22:21:10 -07001778 oldval = prof_thread_active_init_get(tsd_tsdn(tsd));
Jason Evansb2c0d632016-04-13 23:36:15 -07001779 READ(oldval, bool);
1780
1781 ret = 0;
1782label_return:
1783 return (ret);
1784}
1785
1786static int
1787prof_active_ctl(tsd_t *tsd, const size_t *mib, size_t miblen, void *oldp,
Jason Evansfc12c0b2014-10-03 23:25:30 -07001788 size_t *oldlenp, void *newp, size_t newlen)
1789{
1790 int ret;
1791 bool oldval;
1792
1793 if (!config_prof)
1794 return (ENOENT);
1795
1796 if (newp != NULL) {
1797 if (newlen != sizeof(bool)) {
1798 ret = EINVAL;
1799 goto label_return;
1800 }
Jason Evansc1e00ef2016-05-10 22:21:10 -07001801 oldval = prof_active_set(tsd_tsdn(tsd), *(bool *)newp);
Jason Evansfc12c0b2014-10-03 23:25:30 -07001802 } else
Jason Evansc1e00ef2016-05-10 22:21:10 -07001803 oldval = prof_active_get(tsd_tsdn(tsd));
Jason Evansfc12c0b2014-10-03 23:25:30 -07001804 READ(oldval, bool);
1805
1806 ret = 0;
1807label_return:
1808 return (ret);
1809}
1810
1811static int
Jason Evansb2c0d632016-04-13 23:36:15 -07001812prof_dump_ctl(tsd_t *tsd, const size_t *mib, size_t miblen, void *oldp,
1813 size_t *oldlenp, void *newp, size_t newlen)
Jason Evansd34f9e72010-02-11 13:19:21 -08001814{
1815 int ret;
Jason Evans22ca8552010-03-02 11:57:30 -08001816 const char *filename = NULL;
Jason Evansd34f9e72010-02-11 13:19:21 -08001817
Jason Evans551ebc42014-10-03 10:16:09 -07001818 if (!config_prof)
Jason Evans7372b152012-02-10 20:22:09 -08001819 return (ENOENT);
1820
Jason Evans22ca8552010-03-02 11:57:30 -08001821 WRITEONLY();
1822 WRITE(filename, const char *);
Jason Evansd34f9e72010-02-11 13:19:21 -08001823
Jason Evansb2c0d632016-04-13 23:36:15 -07001824 if (prof_mdump(tsd, filename)) {
Jason Evans22ca8552010-03-02 11:57:30 -08001825 ret = EFAULT;
Jason Evansa1ee7832012-04-10 15:07:44 -07001826 goto label_return;
Jason Evans22ca8552010-03-02 11:57:30 -08001827 }
Jason Evansd34f9e72010-02-11 13:19:21 -08001828
1829 ret = 0;
Jason Evansa1ee7832012-04-10 15:07:44 -07001830label_return:
Jason Evansd34f9e72010-02-11 13:19:21 -08001831 return (ret);
1832}
1833
Jason Evans602c8e02014-08-18 16:22:13 -07001834static int
Jason Evansb2c0d632016-04-13 23:36:15 -07001835prof_gdump_ctl(tsd_t *tsd, const size_t *mib, size_t miblen, void *oldp,
1836 size_t *oldlenp, void *newp, size_t newlen)
Jason Evans5b8ed5b2015-01-25 21:16:57 -08001837{
1838 int ret;
1839 bool oldval;
1840
1841 if (!config_prof)
1842 return (ENOENT);
1843
1844 if (newp != NULL) {
1845 if (newlen != sizeof(bool)) {
1846 ret = EINVAL;
1847 goto label_return;
1848 }
Jason Evansc1e00ef2016-05-10 22:21:10 -07001849 oldval = prof_gdump_set(tsd_tsdn(tsd), *(bool *)newp);
Jason Evans5b8ed5b2015-01-25 21:16:57 -08001850 } else
Jason Evansc1e00ef2016-05-10 22:21:10 -07001851 oldval = prof_gdump_get(tsd_tsdn(tsd));
Jason Evans5b8ed5b2015-01-25 21:16:57 -08001852 READ(oldval, bool);
1853
1854 ret = 0;
1855label_return:
1856 return (ret);
1857}
1858
1859static int
Jason Evansb2c0d632016-04-13 23:36:15 -07001860prof_reset_ctl(tsd_t *tsd, const size_t *mib, size_t miblen, void *oldp,
1861 size_t *oldlenp, void *newp, size_t newlen)
Jason Evans602c8e02014-08-18 16:22:13 -07001862{
1863 int ret;
1864 size_t lg_sample = lg_prof_sample;
1865
Jason Evans551ebc42014-10-03 10:16:09 -07001866 if (!config_prof)
Jason Evans602c8e02014-08-18 16:22:13 -07001867 return (ENOENT);
1868
1869 WRITEONLY();
1870 WRITE(lg_sample, size_t);
1871 if (lg_sample >= (sizeof(uint64_t) << 3))
1872 lg_sample = (sizeof(uint64_t) << 3) - 1;
1873
Jason Evansb54d1602016-10-20 23:59:12 -07001874 prof_reset(tsd, lg_sample);
Jason Evans602c8e02014-08-18 16:22:13 -07001875
1876 ret = 0;
1877label_return:
1878 return (ret);
1879}
1880
Jason Evans7372b152012-02-10 20:22:09 -08001881CTL_RO_NL_CGEN(config_prof, prof_interval, prof_interval, uint64_t)
Jason Evans602c8e02014-08-18 16:22:13 -07001882CTL_RO_NL_CGEN(config_prof, lg_prof_sample, lg_prof_sample, size_t)
Jason Evansd34f9e72010-02-11 13:19:21 -08001883
1884/******************************************************************************/
1885
Jason Evansd8a39002013-12-19 21:40:41 -08001886CTL_RO_CGEN(config_stats, stats_allocated, ctl_stats.allocated, size_t)
1887CTL_RO_CGEN(config_stats, stats_active, ctl_stats.active, size_t)
Jason Evans4581b972014-11-27 17:22:36 -02001888CTL_RO_CGEN(config_stats, stats_metadata, ctl_stats.metadata, size_t)
Jason Evans4acd75a2015-03-23 17:25:57 -07001889CTL_RO_CGEN(config_stats, stats_resident, ctl_stats.resident, size_t)
Jason Evansd8a39002013-12-19 21:40:41 -08001890CTL_RO_CGEN(config_stats, stats_mapped, ctl_stats.mapped, size_t)
Jason Evans04c3c0f2016-05-03 22:11:35 -07001891CTL_RO_CGEN(config_stats, stats_retained, ctl_stats.retained, size_t)
Jason Evansd8a39002013-12-19 21:40:41 -08001892
Jason Evansd8a39002013-12-19 21:40:41 -08001893CTL_RO_GEN(stats_arenas_i_dss, ctl_stats.arenas[mib[2]].dss, const char *)
Jason Evans243f7a02016-02-19 20:09:31 -08001894CTL_RO_GEN(stats_arenas_i_decay_time, ctl_stats.arenas[mib[2]].decay_time,
1895 ssize_t)
Jason Evansd8a39002013-12-19 21:40:41 -08001896CTL_RO_GEN(stats_arenas_i_nthreads, ctl_stats.arenas[mib[2]].nthreads, unsigned)
1897CTL_RO_GEN(stats_arenas_i_pactive, ctl_stats.arenas[mib[2]].pactive, size_t)
1898CTL_RO_GEN(stats_arenas_i_pdirty, ctl_stats.arenas[mib[2]].pdirty, size_t)
1899CTL_RO_CGEN(config_stats, stats_arenas_i_mapped,
1900 ctl_stats.arenas[mib[2]].astats.mapped, size_t)
Jason Evans04c3c0f2016-05-03 22:11:35 -07001901CTL_RO_CGEN(config_stats, stats_arenas_i_retained,
1902 ctl_stats.arenas[mib[2]].astats.retained, size_t)
Jason Evansd8a39002013-12-19 21:40:41 -08001903CTL_RO_CGEN(config_stats, stats_arenas_i_npurge,
1904 ctl_stats.arenas[mib[2]].astats.npurge, uint64_t)
1905CTL_RO_CGEN(config_stats, stats_arenas_i_nmadvise,
1906 ctl_stats.arenas[mib[2]].astats.nmadvise, uint64_t)
1907CTL_RO_CGEN(config_stats, stats_arenas_i_purged,
1908 ctl_stats.arenas[mib[2]].astats.purged, uint64_t)
Jason Evans751f2c32016-06-01 13:40:48 -07001909CTL_RO_CGEN(config_stats, stats_arenas_i_metadata,
1910 ctl_stats.arenas[mib[2]].astats.metadata, size_t)
Jason Evansd8a39002013-12-19 21:40:41 -08001911
Jason Evans7372b152012-02-10 20:22:09 -08001912CTL_RO_CGEN(config_stats, stats_arenas_i_small_allocated,
Jason Evans86815df2010-03-13 20:32:56 -08001913 ctl_stats.arenas[mib[2]].allocated_small, size_t)
Jason Evans7372b152012-02-10 20:22:09 -08001914CTL_RO_CGEN(config_stats, stats_arenas_i_small_nmalloc,
Jason Evans86815df2010-03-13 20:32:56 -08001915 ctl_stats.arenas[mib[2]].nmalloc_small, uint64_t)
Jason Evans7372b152012-02-10 20:22:09 -08001916CTL_RO_CGEN(config_stats, stats_arenas_i_small_ndalloc,
Jason Evans86815df2010-03-13 20:32:56 -08001917 ctl_stats.arenas[mib[2]].ndalloc_small, uint64_t)
Jason Evans7372b152012-02-10 20:22:09 -08001918CTL_RO_CGEN(config_stats, stats_arenas_i_small_nrequests,
Jason Evans86815df2010-03-13 20:32:56 -08001919 ctl_stats.arenas[mib[2]].nrequests_small, uint64_t)
Jason Evans7d63fed2016-05-31 14:50:21 -07001920CTL_RO_CGEN(config_stats, stats_arenas_i_large_allocated,
1921 ctl_stats.arenas[mib[2]].astats.allocated_large, size_t)
1922CTL_RO_CGEN(config_stats, stats_arenas_i_large_nmalloc,
1923 ctl_stats.arenas[mib[2]].astats.nmalloc_large, uint64_t)
1924CTL_RO_CGEN(config_stats, stats_arenas_i_large_ndalloc,
1925 ctl_stats.arenas[mib[2]].astats.ndalloc_large, uint64_t)
1926CTL_RO_CGEN(config_stats, stats_arenas_i_large_nrequests,
1927 ctl_stats.arenas[mib[2]].astats.nmalloc_large, uint64_t) /* Intentional. */
Jason Evans3c234352010-01-27 13:10:55 -08001928
Jason Evans7372b152012-02-10 20:22:09 -08001929CTL_RO_CGEN(config_stats, stats_arenas_i_bins_j_nmalloc,
Jason Evans86815df2010-03-13 20:32:56 -08001930 ctl_stats.arenas[mib[2]].bstats[mib[4]].nmalloc, uint64_t)
Jason Evans7372b152012-02-10 20:22:09 -08001931CTL_RO_CGEN(config_stats, stats_arenas_i_bins_j_ndalloc,
Jason Evans86815df2010-03-13 20:32:56 -08001932 ctl_stats.arenas[mib[2]].bstats[mib[4]].ndalloc, uint64_t)
Jason Evans7372b152012-02-10 20:22:09 -08001933CTL_RO_CGEN(config_stats, stats_arenas_i_bins_j_nrequests,
Jason Evans3c234352010-01-27 13:10:55 -08001934 ctl_stats.arenas[mib[2]].bstats[mib[4]].nrequests, uint64_t)
Jason Evans3c4d92e2014-10-12 22:53:59 -07001935CTL_RO_CGEN(config_stats, stats_arenas_i_bins_j_curregs,
1936 ctl_stats.arenas[mib[2]].bstats[mib[4]].curregs, size_t)
Jason Evans7372b152012-02-10 20:22:09 -08001937CTL_RO_CGEN(config_stats && config_tcache, stats_arenas_i_bins_j_nfills,
Jason Evans3c234352010-01-27 13:10:55 -08001938 ctl_stats.arenas[mib[2]].bstats[mib[4]].nfills, uint64_t)
Jason Evans7372b152012-02-10 20:22:09 -08001939CTL_RO_CGEN(config_stats && config_tcache, stats_arenas_i_bins_j_nflushes,
Jason Evans3c234352010-01-27 13:10:55 -08001940 ctl_stats.arenas[mib[2]].bstats[mib[4]].nflushes, uint64_t)
Jason Evans498856f2016-05-29 18:34:50 -07001941CTL_RO_CGEN(config_stats, stats_arenas_i_bins_j_nslabs,
1942 ctl_stats.arenas[mib[2]].bstats[mib[4]].nslabs, uint64_t)
1943CTL_RO_CGEN(config_stats, stats_arenas_i_bins_j_nreslabs,
1944 ctl_stats.arenas[mib[2]].bstats[mib[4]].reslabs, uint64_t)
1945CTL_RO_CGEN(config_stats, stats_arenas_i_bins_j_curslabs,
1946 ctl_stats.arenas[mib[2]].bstats[mib[4]].curslabs, size_t)
Jason Evans3c234352010-01-27 13:10:55 -08001947
Jason Evans609ae592012-10-11 13:53:15 -07001948static const ctl_named_node_t *
Jason Evansc1e00ef2016-05-10 22:21:10 -07001949stats_arenas_i_bins_j_index(tsdn_t *tsdn, const size_t *mib, size_t miblen,
Jason Evansb2c0d632016-04-13 23:36:15 -07001950 size_t j)
Jason Evans3c234352010-01-27 13:10:55 -08001951{
1952
Jason Evansb1726102012-02-28 16:50:47 -08001953 if (j > NBINS)
Jason Evans3c234352010-01-27 13:10:55 -08001954 return (NULL);
1955 return (super_stats_arenas_i_bins_j_node);
1956}
1957
Jason Evans7d63fed2016-05-31 14:50:21 -07001958CTL_RO_CGEN(config_stats, stats_arenas_i_lextents_j_nmalloc,
1959 ctl_stats.arenas[mib[2]].lstats[mib[4]].nmalloc, uint64_t)
1960CTL_RO_CGEN(config_stats, stats_arenas_i_lextents_j_ndalloc,
1961 ctl_stats.arenas[mib[2]].lstats[mib[4]].ndalloc, uint64_t)
1962CTL_RO_CGEN(config_stats, stats_arenas_i_lextents_j_nrequests,
1963 ctl_stats.arenas[mib[2]].lstats[mib[4]].nrequests, uint64_t)
1964CTL_RO_CGEN(config_stats, stats_arenas_i_lextents_j_curlextents,
1965 ctl_stats.arenas[mib[2]].lstats[mib[4]].curlextents, size_t)
Jason Evans3c4d92e2014-10-12 22:53:59 -07001966
1967static const ctl_named_node_t *
Jason Evans7d63fed2016-05-31 14:50:21 -07001968stats_arenas_i_lextents_j_index(tsdn_t *tsdn, const size_t *mib, size_t miblen,
Jason Evansb2c0d632016-04-13 23:36:15 -07001969 size_t j)
Jason Evans3c4d92e2014-10-12 22:53:59 -07001970{
1971
Jason Evansed2c2422016-05-28 00:17:28 -07001972 if (j > NSIZES - NBINS)
Jason Evans3c4d92e2014-10-12 22:53:59 -07001973 return (NULL);
Jason Evans7d63fed2016-05-31 14:50:21 -07001974 return (super_stats_arenas_i_lextents_j_node);
Jason Evans3c4d92e2014-10-12 22:53:59 -07001975}
1976
Jason Evans609ae592012-10-11 13:53:15 -07001977static const ctl_named_node_t *
Jason Evansc1e00ef2016-05-10 22:21:10 -07001978stats_arenas_i_index(tsdn_t *tsdn, const size_t *mib, size_t miblen, size_t i)
Jason Evans3c234352010-01-27 13:10:55 -08001979{
Mike Hommey461ad5c2012-04-20 08:38:42 +02001980 const ctl_named_node_t * ret;
Jason Evans3c234352010-01-27 13:10:55 -08001981
Jason Evansc1e00ef2016-05-10 22:21:10 -07001982 malloc_mutex_lock(tsdn, &ctl_mtx);
Jason Evans551ebc42014-10-03 10:16:09 -07001983 if (i > ctl_stats.narenas || !ctl_stats.arenas[i].initialized) {
Jason Evansfc4dcfa2010-11-24 15:44:21 -08001984 ret = NULL;
Jason Evansa1ee7832012-04-10 15:07:44 -07001985 goto label_return;
Jason Evansfc4dcfa2010-11-24 15:44:21 -08001986 }
1987
1988 ret = super_stats_arenas_i_node;
Jason Evansa1ee7832012-04-10 15:07:44 -07001989label_return:
Jason Evansc1e00ef2016-05-10 22:21:10 -07001990 malloc_mutex_unlock(tsdn, &ctl_mtx);
Jason Evansfc4dcfa2010-11-24 15:44:21 -08001991 return (ret);
Jason Evans3c234352010-01-27 13:10:55 -08001992}