blob: 45e397b82b8cf5140de2c27ff5c503ef7c737bd0 [file] [log] [blame]
Jason Evans3c234352010-01-27 13:10:55 -08001#define JEMALLOC_CTL_C_
Jason Evans376b1522010-02-11 14:45:59 -08002#include "jemalloc/internal/jemalloc_internal.h"
Jason Evans3c234352010-01-27 13:10:55 -08003
4/******************************************************************************/
5/* Data. */
6
Jason Evansfc4dcfa2010-11-24 15:44:21 -08007/*
8 * ctl_mtx protects the following:
Jason Evansd778dd22017-01-03 12:40:54 -08009 * - ctl_stats->*
Jason Evansfc4dcfa2010-11-24 15:44:21 -080010 */
Jason Evans3c234352010-01-27 13:10:55 -080011static malloc_mutex_t ctl_mtx;
12static bool ctl_initialized;
Jason Evansd778dd22017-01-03 12:40:54 -080013static ctl_stats_t *ctl_stats;
Jason Evans3c234352010-01-27 13:10:55 -080014
15/******************************************************************************/
Mike Hommey461ad5c2012-04-20 08:38:42 +020016/* Helpers for named and indexed nodes. */
17
Jason Evansaf1f5922014-10-30 16:38:08 -070018JEMALLOC_INLINE_C const ctl_named_node_t *
Mike Hommey461ad5c2012-04-20 08:38:42 +020019ctl_named_node(const ctl_node_t *node)
20{
21
22 return ((node->named) ? (const ctl_named_node_t *)node : NULL);
23}
24
Jason Evansaf1f5922014-10-30 16:38:08 -070025JEMALLOC_INLINE_C const ctl_named_node_t *
Jason Evans8dd51152016-02-24 11:00:40 -080026ctl_named_children(const ctl_named_node_t *node, size_t index)
Mike Hommey461ad5c2012-04-20 08:38:42 +020027{
28 const ctl_named_node_t *children = ctl_named_node(node->children);
29
30 return (children ? &children[index] : NULL);
31}
32
Jason Evansaf1f5922014-10-30 16:38:08 -070033JEMALLOC_INLINE_C const ctl_indexed_node_t *
Mike Hommey461ad5c2012-04-20 08:38:42 +020034ctl_indexed_node(const ctl_node_t *node)
35{
36
Jason Evans551ebc42014-10-03 10:16:09 -070037 return (!node->named ? (const ctl_indexed_node_t *)node : NULL);
Mike Hommey461ad5c2012-04-20 08:38:42 +020038}
39
40/******************************************************************************/
Jason Evans3c234352010-01-27 13:10:55 -080041/* Function prototypes for non-inline static functions. */
42
43#define CTL_PROTO(n) \
Jason Evansb2c0d632016-04-13 23:36:15 -070044static int n##_ctl(tsd_t *tsd, const size_t *mib, size_t miblen, \
45 void *oldp, size_t *oldlenp, void *newp, size_t newlen);
Jason Evans3c234352010-01-27 13:10:55 -080046
47#define INDEX_PROTO(n) \
Jason Evansc1e00ef2016-05-10 22:21:10 -070048static const ctl_named_node_t *n##_index(tsdn_t *tsdn, \
Jason Evansb2c0d632016-04-13 23:36:15 -070049 const size_t *mib, size_t miblen, size_t i);
Jason Evans3c234352010-01-27 13:10:55 -080050
Jason Evans3c234352010-01-27 13:10:55 -080051static void ctl_arena_clear(ctl_arena_stats_t *astats);
Jason Evansc1e00ef2016-05-10 22:21:10 -070052static void ctl_arena_stats_amerge(tsdn_t *tsdn, ctl_arena_stats_t *cstats,
Jason Evans86815df2010-03-13 20:32:56 -080053 arena_t *arena);
54static void ctl_arena_stats_smerge(ctl_arena_stats_t *sstats,
55 ctl_arena_stats_t *astats);
Jason Evansc1e00ef2016-05-10 22:21:10 -070056static void ctl_arena_refresh(tsdn_t *tsdn, arena_t *arena, unsigned i);
Jason Evansa0dd3a42016-12-22 16:39:10 -060057static bool ctl_grow(tsdn_t *tsdn, extent_hooks_t *extent_hooks);
Jason Evansc1e00ef2016-05-10 22:21:10 -070058static void ctl_refresh(tsdn_t *tsdn);
59static bool ctl_init(tsdn_t *tsdn);
60static int ctl_lookup(tsdn_t *tsdn, const char *name,
Jason Evansb2c0d632016-04-13 23:36:15 -070061 ctl_node_t const **nodesp, size_t *mibp, size_t *depthp);
Jason Evans3c234352010-01-27 13:10:55 -080062
Jason Evansa40bc7a2010-03-02 13:01:16 -080063CTL_PROTO(version)
Jason Evans3c234352010-01-27 13:10:55 -080064CTL_PROTO(epoch)
Jason Evansd4be8b72012-03-26 18:54:44 -070065CTL_PROTO(thread_tcache_enabled)
Jason Evanse7b8fa12012-03-16 17:09:32 -070066CTL_PROTO(thread_tcache_flush)
Jason Evans602c8e02014-08-18 16:22:13 -070067CTL_PROTO(thread_prof_name)
68CTL_PROTO(thread_prof_active)
Jason Evansb267d0f2010-08-13 15:42:29 -070069CTL_PROTO(thread_arena)
Jason Evans93443682010-10-20 17:39:18 -070070CTL_PROTO(thread_allocated)
Jason Evansecf229a2010-12-03 15:55:47 -080071CTL_PROTO(thread_allocatedp)
Jason Evans93443682010-10-20 17:39:18 -070072CTL_PROTO(thread_deallocated)
Jason Evansecf229a2010-12-03 15:55:47 -080073CTL_PROTO(thread_deallocatedp)
Jason Evansf2bc8522015-07-17 16:38:25 -070074CTL_PROTO(config_cache_oblivious)
Jason Evans3c234352010-01-27 13:10:55 -080075CTL_PROTO(config_debug)
Jason Evans3c234352010-01-27 13:10:55 -080076CTL_PROTO(config_fill)
77CTL_PROTO(config_lazy_lock)
Jason Evansf8290092016-02-07 14:23:22 -080078CTL_PROTO(config_malloc_conf)
Jason Evans59ae2762012-04-16 17:52:27 -070079CTL_PROTO(config_munmap)
Jason Evansd34f9e72010-02-11 13:19:21 -080080CTL_PROTO(config_prof)
81CTL_PROTO(config_prof_libgcc)
82CTL_PROTO(config_prof_libunwind)
Jason Evans3c234352010-01-27 13:10:55 -080083CTL_PROTO(config_stats)
Jason Evans3c234352010-01-27 13:10:55 -080084CTL_PROTO(config_tcache)
Jason Evans3c234352010-01-27 13:10:55 -080085CTL_PROTO(config_tls)
Jason Evansb1476112012-04-05 13:36:17 -070086CTL_PROTO(config_utrace)
Jason Evans3c234352010-01-27 13:10:55 -080087CTL_PROTO(config_xmalloc)
88CTL_PROTO(opt_abort)
Jason Evans609ae592012-10-11 13:53:15 -070089CTL_PROTO(opt_dss)
Jason Evanse7339702010-10-23 18:37:06 -070090CTL_PROTO(opt_narenas)
Jason Evans243f7a02016-02-19 20:09:31 -080091CTL_PROTO(opt_decay_time)
Jason Evanse7339702010-10-23 18:37:06 -070092CTL_PROTO(opt_stats_print)
Jason Evans3c234352010-01-27 13:10:55 -080093CTL_PROTO(opt_junk)
Jason Evanse7339702010-10-23 18:37:06 -070094CTL_PROTO(opt_zero)
Jason Evansb1476112012-04-05 13:36:17 -070095CTL_PROTO(opt_utrace)
Jason Evans3c234352010-01-27 13:10:55 -080096CTL_PROTO(opt_xmalloc)
Jason Evans3fa9a2f2010-03-07 15:34:14 -080097CTL_PROTO(opt_tcache)
Jason Evansf3ca7c82012-04-04 16:16:09 -070098CTL_PROTO(opt_lg_tcache_max)
Jason Evansd34f9e72010-02-11 13:19:21 -080099CTL_PROTO(opt_prof)
Jason Evanse7339702010-10-23 18:37:06 -0700100CTL_PROTO(opt_prof_prefix)
Jason Evansf18c9822010-03-31 18:43:24 -0700101CTL_PROTO(opt_prof_active)
Jason Evansfc12c0b2014-10-03 23:25:30 -0700102CTL_PROTO(opt_prof_thread_active_init)
Jason Evansb9477e72010-03-01 20:15:26 -0800103CTL_PROTO(opt_lg_prof_sample)
Jason Evansd34f9e72010-02-11 13:19:21 -0800104CTL_PROTO(opt_lg_prof_interval)
Jason Evanse7339702010-10-23 18:37:06 -0700105CTL_PROTO(opt_prof_gdump)
Jason Evans0b25fe72012-04-17 16:39:33 -0700106CTL_PROTO(opt_prof_final)
Jason Evansd34f9e72010-02-11 13:19:21 -0800107CTL_PROTO(opt_prof_leak)
Jason Evansa881cd22010-10-02 15:18:50 -0700108CTL_PROTO(opt_prof_accum)
Jason Evans1cb181e2015-01-29 15:30:47 -0800109CTL_PROTO(tcache_create)
110CTL_PROTO(tcache_flush)
111CTL_PROTO(tcache_destroy)
Jason Evansdc2125c2017-01-04 10:21:53 -0800112CTL_PROTO(arena_i_initialized)
Jason Evans609ae592012-10-11 13:53:15 -0700113CTL_PROTO(arena_i_purge)
Jason Evans243f7a02016-02-19 20:09:31 -0800114CTL_PROTO(arena_i_decay)
Jason Evans19ff2ce2016-04-22 14:37:17 -0700115CTL_PROTO(arena_i_reset)
Jason Evans609ae592012-10-11 13:53:15 -0700116CTL_PROTO(arena_i_dss)
Jason Evans243f7a02016-02-19 20:09:31 -0800117CTL_PROTO(arena_i_decay_time)
Jason Evans9c305c92016-05-31 15:03:51 -0700118CTL_PROTO(arena_i_extent_hooks)
Jason Evans609ae592012-10-11 13:53:15 -0700119INDEX_PROTO(arena_i)
Jason Evans3c234352010-01-27 13:10:55 -0800120CTL_PROTO(arenas_bin_i_size)
121CTL_PROTO(arenas_bin_i_nregs)
Jason Evans498856f2016-05-29 18:34:50 -0700122CTL_PROTO(arenas_bin_i_slab_size)
Jason Evans3c234352010-01-27 13:10:55 -0800123INDEX_PROTO(arenas_bin_i)
Jason Evans7d63fed2016-05-31 14:50:21 -0700124CTL_PROTO(arenas_lextent_i_size)
125INDEX_PROTO(arenas_lextent_i)
Jason Evans3c234352010-01-27 13:10:55 -0800126CTL_PROTO(arenas_narenas)
Jason Evans243f7a02016-02-19 20:09:31 -0800127CTL_PROTO(arenas_decay_time)
Jason Evans3c234352010-01-27 13:10:55 -0800128CTL_PROTO(arenas_quantum)
Jason Evansae4c7b42012-04-02 07:04:34 -0700129CTL_PROTO(arenas_page)
Jason Evansdafde142010-03-17 16:27:39 -0700130CTL_PROTO(arenas_tcache_max)
Jason Evans3c234352010-01-27 13:10:55 -0800131CTL_PROTO(arenas_nbins)
Jason Evansdafde142010-03-17 16:27:39 -0700132CTL_PROTO(arenas_nhbins)
Jason Evans7d63fed2016-05-31 14:50:21 -0700133CTL_PROTO(arenas_nlextents)
Jason Evans0f04bb12017-01-03 08:21:29 -0800134CTL_PROTO(arenas_create)
Jason Evansfc12c0b2014-10-03 23:25:30 -0700135CTL_PROTO(prof_thread_active_init)
Jason Evansf18c9822010-03-31 18:43:24 -0700136CTL_PROTO(prof_active)
Jason Evansd34f9e72010-02-11 13:19:21 -0800137CTL_PROTO(prof_dump)
Jason Evans5b8ed5b2015-01-25 21:16:57 -0800138CTL_PROTO(prof_gdump)
Jason Evans602c8e02014-08-18 16:22:13 -0700139CTL_PROTO(prof_reset)
Jason Evansd34f9e72010-02-11 13:19:21 -0800140CTL_PROTO(prof_interval)
Jason Evans602c8e02014-08-18 16:22:13 -0700141CTL_PROTO(lg_prof_sample)
Jason Evans3c234352010-01-27 13:10:55 -0800142CTL_PROTO(stats_arenas_i_small_allocated)
143CTL_PROTO(stats_arenas_i_small_nmalloc)
144CTL_PROTO(stats_arenas_i_small_ndalloc)
Jason Evans86815df2010-03-13 20:32:56 -0800145CTL_PROTO(stats_arenas_i_small_nrequests)
Jason Evans7d63fed2016-05-31 14:50:21 -0700146CTL_PROTO(stats_arenas_i_large_allocated)
147CTL_PROTO(stats_arenas_i_large_nmalloc)
148CTL_PROTO(stats_arenas_i_large_ndalloc)
149CTL_PROTO(stats_arenas_i_large_nrequests)
Jason Evans86815df2010-03-13 20:32:56 -0800150CTL_PROTO(stats_arenas_i_bins_j_nmalloc)
151CTL_PROTO(stats_arenas_i_bins_j_ndalloc)
Jason Evans3c234352010-01-27 13:10:55 -0800152CTL_PROTO(stats_arenas_i_bins_j_nrequests)
Jason Evans3c4d92e2014-10-12 22:53:59 -0700153CTL_PROTO(stats_arenas_i_bins_j_curregs)
Jason Evans3c234352010-01-27 13:10:55 -0800154CTL_PROTO(stats_arenas_i_bins_j_nfills)
155CTL_PROTO(stats_arenas_i_bins_j_nflushes)
Jason Evans498856f2016-05-29 18:34:50 -0700156CTL_PROTO(stats_arenas_i_bins_j_nslabs)
157CTL_PROTO(stats_arenas_i_bins_j_nreslabs)
158CTL_PROTO(stats_arenas_i_bins_j_curslabs)
Jason Evans3c234352010-01-27 13:10:55 -0800159INDEX_PROTO(stats_arenas_i_bins_j)
Jason Evans7d63fed2016-05-31 14:50:21 -0700160CTL_PROTO(stats_arenas_i_lextents_j_nmalloc)
161CTL_PROTO(stats_arenas_i_lextents_j_ndalloc)
162CTL_PROTO(stats_arenas_i_lextents_j_nrequests)
163CTL_PROTO(stats_arenas_i_lextents_j_curlextents)
164INDEX_PROTO(stats_arenas_i_lextents_j)
Jason Evans597632b2011-03-18 13:41:33 -0700165CTL_PROTO(stats_arenas_i_nthreads)
Jason Evans609ae592012-10-11 13:53:15 -0700166CTL_PROTO(stats_arenas_i_dss)
Jason Evans243f7a02016-02-19 20:09:31 -0800167CTL_PROTO(stats_arenas_i_decay_time)
Jason Evans3c234352010-01-27 13:10:55 -0800168CTL_PROTO(stats_arenas_i_pactive)
169CTL_PROTO(stats_arenas_i_pdirty)
Jason Evans3c234352010-01-27 13:10:55 -0800170CTL_PROTO(stats_arenas_i_mapped)
Jason Evans04c3c0f2016-05-03 22:11:35 -0700171CTL_PROTO(stats_arenas_i_retained)
Jason Evans3c234352010-01-27 13:10:55 -0800172CTL_PROTO(stats_arenas_i_npurge)
173CTL_PROTO(stats_arenas_i_nmadvise)
174CTL_PROTO(stats_arenas_i_purged)
Jason Evansa0dd3a42016-12-22 16:39:10 -0600175CTL_PROTO(stats_arenas_i_base)
176CTL_PROTO(stats_arenas_i_internal)
177CTL_PROTO(stats_arenas_i_resident)
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 Evansdc2125c2017-01-04 10:21:53 -0800273 {NAME("initialized"), CTL(arena_i_initialized)},
Jason Evans3c4d92e2014-10-12 22:53:59 -0700274 {NAME("purge"), CTL(arena_i_purge)},
Jason Evans243f7a02016-02-19 20:09:31 -0800275 {NAME("decay"), CTL(arena_i_decay)},
Jason Evans19ff2ce2016-04-22 14:37:17 -0700276 {NAME("reset"), CTL(arena_i_reset)},
Jason Evans3c4d92e2014-10-12 22:53:59 -0700277 {NAME("dss"), CTL(arena_i_dss)},
Jason Evans243f7a02016-02-19 20:09:31 -0800278 {NAME("decay_time"), CTL(arena_i_decay_time)},
Jason Evans9c305c92016-05-31 15:03:51 -0700279 {NAME("extent_hooks"), CTL(arena_i_extent_hooks)}
Jason Evans609ae592012-10-11 13:53:15 -0700280};
281static const ctl_named_node_t super_arena_i_node[] = {
Jason Evans3c4d92e2014-10-12 22:53:59 -0700282 {NAME(""), CHILD(named, arena_i)}
Jason Evans609ae592012-10-11 13:53:15 -0700283};
284
285static const ctl_indexed_node_t arena_node[] = {
286 {INDEX(arena_i)}
287};
288
Mike Hommey461ad5c2012-04-20 08:38:42 +0200289static const ctl_named_node_t arenas_bin_i_node[] = {
Jason Evans3c4d92e2014-10-12 22:53:59 -0700290 {NAME("size"), CTL(arenas_bin_i_size)},
291 {NAME("nregs"), CTL(arenas_bin_i_nregs)},
Jason Evans498856f2016-05-29 18:34:50 -0700292 {NAME("slab_size"), CTL(arenas_bin_i_slab_size)}
Jason Evans3c234352010-01-27 13:10:55 -0800293};
Mike Hommey461ad5c2012-04-20 08:38:42 +0200294static const ctl_named_node_t super_arenas_bin_i_node[] = {
Jason Evans3c4d92e2014-10-12 22:53:59 -0700295 {NAME(""), CHILD(named, arenas_bin_i)}
Jason Evans3c234352010-01-27 13:10:55 -0800296};
297
Mike Hommey461ad5c2012-04-20 08:38:42 +0200298static const ctl_indexed_node_t arenas_bin_node[] = {
Jason Evans3c234352010-01-27 13:10:55 -0800299 {INDEX(arenas_bin_i)}
300};
301
Jason Evans7d63fed2016-05-31 14:50:21 -0700302static const ctl_named_node_t arenas_lextent_i_node[] = {
303 {NAME("size"), CTL(arenas_lextent_i_size)}
Jason Evans3c4d92e2014-10-12 22:53:59 -0700304};
Jason Evans7d63fed2016-05-31 14:50:21 -0700305static const ctl_named_node_t super_arenas_lextent_i_node[] = {
306 {NAME(""), CHILD(named, arenas_lextent_i)}
Jason Evans3c4d92e2014-10-12 22:53:59 -0700307};
308
Jason Evans7d63fed2016-05-31 14:50:21 -0700309static const ctl_indexed_node_t arenas_lextent_node[] = {
310 {INDEX(arenas_lextent_i)}
Jason Evans3c4d92e2014-10-12 22:53:59 -0700311};
312
Mike Hommey461ad5c2012-04-20 08:38:42 +0200313static const ctl_named_node_t arenas_node[] = {
Jason Evans3c4d92e2014-10-12 22:53:59 -0700314 {NAME("narenas"), CTL(arenas_narenas)},
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 Evans0f04bb12017-01-03 08:21:29 -0800324 {NAME("create"), CTL(arenas_create)}
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 Evansa0dd3a42016-12-22 16:39:10 -0600395 {NAME("base"), CTL(stats_arenas_i_base)},
396 {NAME("internal"), CTL(stats_arenas_i_internal)},
397 {NAME("resident"), CTL(stats_arenas_i_resident)},
Jason Evans3c4d92e2014-10-12 22:53:59 -0700398 {NAME("small"), CHILD(named, stats_arenas_i_small)},
Jason Evans7d63fed2016-05-31 14:50:21 -0700399 {NAME("large"), CHILD(named, stats_arenas_i_large)},
Jason Evans3c4d92e2014-10-12 22:53:59 -0700400 {NAME("bins"), CHILD(indexed, stats_arenas_i_bins)},
Jason Evans7d63fed2016-05-31 14:50:21 -0700401 {NAME("lextents"), CHILD(indexed, stats_arenas_i_lextents)}
Jason Evans3c234352010-01-27 13:10:55 -0800402};
Mike Hommey461ad5c2012-04-20 08:38:42 +0200403static const ctl_named_node_t super_stats_arenas_i_node[] = {
Jason Evans3c4d92e2014-10-12 22:53:59 -0700404 {NAME(""), CHILD(named, stats_arenas_i)}
Jason Evans3c234352010-01-27 13:10:55 -0800405};
406
Mike Hommey461ad5c2012-04-20 08:38:42 +0200407static const ctl_indexed_node_t stats_arenas_node[] = {
Jason Evans3c234352010-01-27 13:10:55 -0800408 {INDEX(stats_arenas_i)}
409};
410
Mike Hommey461ad5c2012-04-20 08:38:42 +0200411static const ctl_named_node_t stats_node[] = {
Jason Evans3c4d92e2014-10-12 22:53:59 -0700412 {NAME("allocated"), CTL(stats_allocated)},
413 {NAME("active"), CTL(stats_active)},
Jason Evans4581b972014-11-27 17:22:36 -0200414 {NAME("metadata"), CTL(stats_metadata)},
Jason Evans4acd75a2015-03-23 17:25:57 -0700415 {NAME("resident"), CTL(stats_resident)},
Jason Evans3c4d92e2014-10-12 22:53:59 -0700416 {NAME("mapped"), CTL(stats_mapped)},
Jason Evans04c3c0f2016-05-03 22:11:35 -0700417 {NAME("retained"), CTL(stats_retained)},
Jason Evans3c4d92e2014-10-12 22:53:59 -0700418 {NAME("arenas"), CHILD(indexed, stats_arenas)}
Jason Evans3c234352010-01-27 13:10:55 -0800419};
420
Mike Hommey461ad5c2012-04-20 08:38:42 +0200421static const ctl_named_node_t root_node[] = {
Jason Evansa40bc7a2010-03-02 13:01:16 -0800422 {NAME("version"), CTL(version)},
Jason Evans3c234352010-01-27 13:10:55 -0800423 {NAME("epoch"), CTL(epoch)},
Jason Evans65f343a2012-04-23 19:31:45 -0700424 {NAME("thread"), CHILD(named, thread)},
425 {NAME("config"), CHILD(named, config)},
426 {NAME("opt"), CHILD(named, opt)},
Jason Evans1cb181e2015-01-29 15:30:47 -0800427 {NAME("tcache"), CHILD(named, tcache)},
Jason Evans609ae592012-10-11 13:53:15 -0700428 {NAME("arena"), CHILD(indexed, arena)},
Jason Evans65f343a2012-04-23 19:31:45 -0700429 {NAME("arenas"), CHILD(named, arenas)},
430 {NAME("prof"), CHILD(named, prof)},
431 {NAME("stats"), CHILD(named, stats)}
Jason Evans3c234352010-01-27 13:10:55 -0800432};
Mike Hommey461ad5c2012-04-20 08:38:42 +0200433static const ctl_named_node_t super_root_node[] = {
Jason Evans65f343a2012-04-23 19:31:45 -0700434 {NAME(""), CHILD(named, root)}
Jason Evans3c234352010-01-27 13:10:55 -0800435};
436
437#undef NAME
438#undef CHILD
439#undef CTL
440#undef INDEX
441
442/******************************************************************************/
443
Jason Evans3dc4e832017-01-03 07:27:42 -0800444static unsigned
445stats_arenas_i2a_impl(size_t i, bool compat, bool validate)
446{
447 unsigned a;
448
449 cassert(config_stats);
450
451 switch (i) {
452 case MALLCTL_ARENAS_ALL:
453 a = 0;
454 break;
455 default:
Jason Evansd778dd22017-01-03 12:40:54 -0800456 if (compat && i == ctl_stats->narenas) {
Jason Evans3dc4e832017-01-03 07:27:42 -0800457 /*
458 * Provide deprecated backward compatibility for
459 * accessing the merged stats at index narenas rather
460 * than via MALLCTL_ARENAS_ALL. This is scheduled for
461 * removal in 6.0.0.
462 */
463 a = 0;
Jason Evansd778dd22017-01-03 12:40:54 -0800464 } else if (validate && i >= ctl_stats->narenas)
Jason Evans3dc4e832017-01-03 07:27:42 -0800465 a = UINT_MAX;
466 else {
467 /*
468 * This function should never be called for an index
469 * more than one past the range of indices that have
470 * initialized stats.
471 */
Jason Evansd778dd22017-01-03 12:40:54 -0800472 assert(i < ctl_stats->narenas || (!validate && i ==
473 ctl_stats->narenas));
Jason Evans3dc4e832017-01-03 07:27:42 -0800474 a = (unsigned)i + 1;
475 }
476 break;
477 }
478
479 return (a);
480}
481
482static ctl_arena_stats_t *
Jason Evansd778dd22017-01-03 12:40:54 -0800483stats_arenas_i_impl(tsdn_t *tsdn, size_t i, bool compat, bool init)
484{
485 ctl_arena_stats_t *ret;
486
487 assert(!compat || !init);
488
489 ret = ctl_stats->arenas[stats_arenas_i2a_impl(i, compat, false)];
490 if (init && ret == NULL) {
491 ret = (ctl_arena_stats_t *)base_alloc(tsdn, b0get(),
492 sizeof(ctl_arena_stats_t), QUANTUM);
493 if (ret == NULL)
494 return (NULL);
495 ctl_stats->arenas[stats_arenas_i2a_impl(i, compat, false)] =
496 ret;
497 }
498
499 return (ret);
500}
501
502static ctl_arena_stats_t *
Jason Evans3dc4e832017-01-03 07:27:42 -0800503stats_arenas_i(size_t i)
504{
Jason Evansd778dd22017-01-03 12:40:54 -0800505 ctl_arena_stats_t *ret = stats_arenas_i_impl(TSDN_NULL, i, true, false);
506 assert(ret != NULL);
507 return (ret);
Jason Evans3dc4e832017-01-03 07:27:42 -0800508}
509
Jason Evans3c234352010-01-27 13:10:55 -0800510static void
511ctl_arena_clear(ctl_arena_stats_t *astats)
512{
513
Jason Evans3c07f802016-02-27 20:40:13 -0800514 astats->nthreads = 0;
Jason Evans609ae592012-10-11 13:53:15 -0700515 astats->dss = dss_prec_names[dss_prec_limit];
Jason Evans243f7a02016-02-19 20:09:31 -0800516 astats->decay_time = -1;
Jason Evans3c234352010-01-27 13:10:55 -0800517 astats->pactive = 0;
518 astats->pdirty = 0;
Jason Evans7372b152012-02-10 20:22:09 -0800519 if (config_stats) {
520 memset(&astats->astats, 0, sizeof(arena_stats_t));
521 astats->allocated_small = 0;
522 astats->nmalloc_small = 0;
523 astats->ndalloc_small = 0;
524 astats->nrequests_small = 0;
Jason Evansb1726102012-02-28 16:50:47 -0800525 memset(astats->bstats, 0, NBINS * sizeof(malloc_bin_stats_t));
Jason Evans7d63fed2016-05-31 14:50:21 -0700526 memset(astats->lstats, 0, (NSIZES - NBINS) *
527 sizeof(malloc_large_stats_t));
Jason Evans7372b152012-02-10 20:22:09 -0800528 }
Jason Evans3c234352010-01-27 13:10:55 -0800529}
530
Jason Evans86815df2010-03-13 20:32:56 -0800531static void
Jason Evansc1e00ef2016-05-10 22:21:10 -0700532ctl_arena_stats_amerge(tsdn_t *tsdn, ctl_arena_stats_t *cstats, arena_t *arena)
Jason Evans86815df2010-03-13 20:32:56 -0800533{
534 unsigned i;
535
Jason Evans3c07f802016-02-27 20:40:13 -0800536 if (config_stats) {
Jason Evansc1e00ef2016-05-10 22:21:10 -0700537 arena_stats_merge(tsdn, arena, &cstats->nthreads, &cstats->dss,
Jason Evans63b56572016-10-12 10:40:27 -0700538 &cstats->decay_time, &cstats->pactive, &cstats->pdirty,
539 &cstats->astats, cstats->bstats, cstats->lstats);
Jason Evans86815df2010-03-13 20:32:56 -0800540
Jason Evans3c07f802016-02-27 20:40:13 -0800541 for (i = 0; i < NBINS; i++) {
542 cstats->allocated_small += cstats->bstats[i].curregs *
543 index2size(i);
544 cstats->nmalloc_small += cstats->bstats[i].nmalloc;
545 cstats->ndalloc_small += cstats->bstats[i].ndalloc;
546 cstats->nrequests_small += cstats->bstats[i].nrequests;
547 }
548 } else {
Jason Evansc1e00ef2016-05-10 22:21:10 -0700549 arena_basic_stats_merge(tsdn, arena, &cstats->nthreads,
Jason Evans63b56572016-10-12 10:40:27 -0700550 &cstats->dss, &cstats->decay_time, &cstats->pactive,
551 &cstats->pdirty);
Jason Evans86815df2010-03-13 20:32:56 -0800552 }
Jason Evans86815df2010-03-13 20:32:56 -0800553}
554
555static void
556ctl_arena_stats_smerge(ctl_arena_stats_t *sstats, ctl_arena_stats_t *astats)
557{
558 unsigned i;
559
Jason Evans3c07f802016-02-27 20:40:13 -0800560 sstats->nthreads += astats->nthreads;
Jason Evans86815df2010-03-13 20:32:56 -0800561 sstats->pactive += astats->pactive;
562 sstats->pdirty += astats->pdirty;
563
Jason Evans3c07f802016-02-27 20:40:13 -0800564 if (config_stats) {
565 sstats->astats.mapped += astats->astats.mapped;
Jason Evans04c3c0f2016-05-03 22:11:35 -0700566 sstats->astats.retained += astats->astats.retained;
Jason Evans3c07f802016-02-27 20:40:13 -0800567 sstats->astats.npurge += astats->astats.npurge;
568 sstats->astats.nmadvise += astats->astats.nmadvise;
569 sstats->astats.purged += astats->astats.purged;
Jason Evans86815df2010-03-13 20:32:56 -0800570
Jason Evansa0dd3a42016-12-22 16:39:10 -0600571 sstats->astats.base += astats->astats.base;
572 sstats->astats.internal += astats->astats.internal;
573 sstats->astats.resident += astats->astats.resident;
Jason Evans4581b972014-11-27 17:22:36 -0200574
Jason Evans3c07f802016-02-27 20:40:13 -0800575 sstats->allocated_small += astats->allocated_small;
576 sstats->nmalloc_small += astats->nmalloc_small;
577 sstats->ndalloc_small += astats->ndalloc_small;
578 sstats->nrequests_small += astats->nrequests_small;
Jason Evans86815df2010-03-13 20:32:56 -0800579
Jason Evans7d63fed2016-05-31 14:50:21 -0700580 sstats->astats.allocated_large +=
581 astats->astats.allocated_large;
582 sstats->astats.nmalloc_large += astats->astats.nmalloc_large;
583 sstats->astats.ndalloc_large += astats->astats.ndalloc_large;
584 sstats->astats.nrequests_large +=
585 astats->astats.nrequests_large;
Jason Evans86815df2010-03-13 20:32:56 -0800586
Jason Evans3c07f802016-02-27 20:40:13 -0800587 for (i = 0; i < NBINS; i++) {
588 sstats->bstats[i].nmalloc += astats->bstats[i].nmalloc;
589 sstats->bstats[i].ndalloc += astats->bstats[i].ndalloc;
590 sstats->bstats[i].nrequests +=
591 astats->bstats[i].nrequests;
592 sstats->bstats[i].curregs += astats->bstats[i].curregs;
593 if (config_tcache) {
594 sstats->bstats[i].nfills +=
595 astats->bstats[i].nfills;
596 sstats->bstats[i].nflushes +=
597 astats->bstats[i].nflushes;
598 }
Jason Evans498856f2016-05-29 18:34:50 -0700599 sstats->bstats[i].nslabs += astats->bstats[i].nslabs;
600 sstats->bstats[i].reslabs += astats->bstats[i].reslabs;
601 sstats->bstats[i].curslabs +=
602 astats->bstats[i].curslabs;
Jason Evans7372b152012-02-10 20:22:09 -0800603 }
Jason Evans3c4d92e2014-10-12 22:53:59 -0700604
Jason Evansed2c2422016-05-28 00:17:28 -0700605 for (i = 0; i < NSIZES - NBINS; i++) {
Jason Evans7d63fed2016-05-31 14:50:21 -0700606 sstats->lstats[i].nmalloc += astats->lstats[i].nmalloc;
607 sstats->lstats[i].ndalloc += astats->lstats[i].ndalloc;
608 sstats->lstats[i].nrequests +=
609 astats->lstats[i].nrequests;
610 sstats->lstats[i].curlextents +=
611 astats->lstats[i].curlextents;
Jason Evans3c07f802016-02-27 20:40:13 -0800612 }
Jason Evans3c4d92e2014-10-12 22:53:59 -0700613 }
Jason Evans86815df2010-03-13 20:32:56 -0800614}
Jason Evans86815df2010-03-13 20:32:56 -0800615
Jason Evans3c234352010-01-27 13:10:55 -0800616static void
Jason Evansc1e00ef2016-05-10 22:21:10 -0700617ctl_arena_refresh(tsdn_t *tsdn, arena_t *arena, unsigned i)
Jason Evans3c234352010-01-27 13:10:55 -0800618{
Jason Evans3dc4e832017-01-03 07:27:42 -0800619 ctl_arena_stats_t *astats = stats_arenas_i(i);
620 ctl_arena_stats_t *sstats = stats_arenas_i(MALLCTL_ARENAS_ALL);
Jason Evans3c234352010-01-27 13:10:55 -0800621
622 ctl_arena_clear(astats);
Jason Evansc1e00ef2016-05-10 22:21:10 -0700623 ctl_arena_stats_amerge(tsdn, astats, arena);
Jason Evans3c07f802016-02-27 20:40:13 -0800624 /* Merge into sum stats as well. */
625 ctl_arena_stats_smerge(sstats, astats);
Jason Evans3c234352010-01-27 13:10:55 -0800626}
627
Jason Evans609ae592012-10-11 13:53:15 -0700628static bool
Jason Evansa0dd3a42016-12-22 16:39:10 -0600629ctl_grow(tsdn_t *tsdn, extent_hooks_t *extent_hooks)
Jason Evans609ae592012-10-11 13:53:15 -0700630{
Jason Evansd778dd22017-01-03 12:40:54 -0800631
632 /* Trigger stats allocation. */
633 if (stats_arenas_i_impl(tsdn, ctl_stats->narenas, false, true) == NULL)
634 return (true);
Jason Evans609ae592012-10-11 13:53:15 -0700635
Jason Evans8bb31982014-10-07 23:14:57 -0700636 /* Initialize new arena. */
Jason Evansd778dd22017-01-03 12:40:54 -0800637 if (arena_init(tsdn, ctl_stats->narenas, extent_hooks) == NULL)
Jason Evans8bb31982014-10-07 23:14:57 -0700638 return (true);
Jason Evansd778dd22017-01-03 12:40:54 -0800639 ctl_stats->narenas++;
Jason Evans609ae592012-10-11 13:53:15 -0700640
641 return (false);
642}
643
Jason Evans3c234352010-01-27 13:10:55 -0800644static void
Jason Evansc1e00ef2016-05-10 22:21:10 -0700645ctl_refresh(tsdn_t *tsdn)
Jason Evans3c234352010-01-27 13:10:55 -0800646{
647 unsigned i;
Jason Evans3dc4e832017-01-03 07:27:42 -0800648 ctl_arena_stats_t *sstats = stats_arenas_i(MALLCTL_ARENAS_ALL);
Jason Evansd778dd22017-01-03 12:40:54 -0800649 VARIABLE_ARRAY(arena_t *, tarenas, ctl_stats->narenas);
Jason Evans3c234352010-01-27 13:10:55 -0800650
Jason Evans3c234352010-01-27 13:10:55 -0800651 /*
Jason Evans13668262010-01-31 03:57:29 -0800652 * Clear sum stats, since they will be merged into by
Jason Evans3c234352010-01-27 13:10:55 -0800653 * ctl_arena_refresh().
654 */
Jason Evans3dc4e832017-01-03 07:27:42 -0800655 ctl_arena_clear(sstats);
Jason Evans3c234352010-01-27 13:10:55 -0800656
Jason Evansd778dd22017-01-03 12:40:54 -0800657 for (i = 0; i < ctl_stats->narenas; i++)
Jason Evansc1e00ef2016-05-10 22:21:10 -0700658 tarenas[i] = arena_get(tsdn, i, false);
Jason Evans8bb31982014-10-07 23:14:57 -0700659
Jason Evansd778dd22017-01-03 12:40:54 -0800660 for (i = 0; i < ctl_stats->narenas; i++) {
Jason Evans3dc4e832017-01-03 07:27:42 -0800661 ctl_arena_stats_t *astats = stats_arenas_i(i);
Jason Evans3c234352010-01-27 13:10:55 -0800662 bool initialized = (tarenas[i] != NULL);
663
Jason Evans3dc4e832017-01-03 07:27:42 -0800664 astats->initialized = initialized;
Jason Evans3c234352010-01-27 13:10:55 -0800665 if (initialized)
Jason Evansc1e00ef2016-05-10 22:21:10 -0700666 ctl_arena_refresh(tsdn, tarenas[i], i);
Jason Evans3c234352010-01-27 13:10:55 -0800667 }
668
Jason Evans7372b152012-02-10 20:22:09 -0800669 if (config_stats) {
Jason Evansd778dd22017-01-03 12:40:54 -0800670 ctl_stats->allocated = sstats->allocated_small +
Jason Evans3dc4e832017-01-03 07:27:42 -0800671 sstats->astats.allocated_large;
Jason Evansd778dd22017-01-03 12:40:54 -0800672 ctl_stats->active = (sstats->pactive << LG_PAGE);
673 ctl_stats->metadata = sstats->astats.base +
Jason Evans3dc4e832017-01-03 07:27:42 -0800674 sstats->astats.internal;
Jason Evansd778dd22017-01-03 12:40:54 -0800675 ctl_stats->resident = sstats->astats.resident;
676 ctl_stats->mapped = sstats->astats.mapped;
677 ctl_stats->retained = sstats->astats.retained;
Jason Evans7372b152012-02-10 20:22:09 -0800678 }
Jason Evans3c234352010-01-27 13:10:55 -0800679
Jason Evansc0a05e62017-01-03 15:09:50 -0800680 ctl_stats->epoch++;
Jason Evans3c234352010-01-27 13:10:55 -0800681}
682
683static bool
Jason Evansc1e00ef2016-05-10 22:21:10 -0700684ctl_init(tsdn_t *tsdn)
Jason Evans3c234352010-01-27 13:10:55 -0800685{
Jason Evansfc4dcfa2010-11-24 15:44:21 -0800686 bool ret;
Jason Evans3c234352010-01-27 13:10:55 -0800687
Jason Evansc1e00ef2016-05-10 22:21:10 -0700688 malloc_mutex_lock(tsdn, &ctl_mtx);
Jason Evans551ebc42014-10-03 10:16:09 -0700689 if (!ctl_initialized) {
Jason Evansd778dd22017-01-03 12:40:54 -0800690 ctl_arena_stats_t *sstats;
691 unsigned i;
692
Jason Evans3c234352010-01-27 13:10:55 -0800693 /*
Jason Evansd778dd22017-01-03 12:40:54 -0800694 * Allocate demand-zeroed space for pointers to the full range
695 * of supported arena indices.
Jason Evans3c234352010-01-27 13:10:55 -0800696 */
Jason Evansd778dd22017-01-03 12:40:54 -0800697 if (ctl_stats == NULL) {
698 ctl_stats = (ctl_stats_t *)base_alloc(tsdn, b0get(),
699 sizeof(ctl_stats_t), QUANTUM);
700 if (ctl_stats == NULL) {
701 ret = true;
702 goto label_return;
703 }
704 }
705
706 /*
707 * Allocate space for the current full range of arenas here
708 * rather than doing it lazily elsewhere, in order to limit when
709 * OOM-caused errors can occur.
710 */
711 if ((sstats = stats_arenas_i_impl(tsdn, MALLCTL_ARENAS_ALL,
712 false, true)) == NULL) {
Jason Evansfc4dcfa2010-11-24 15:44:21 -0800713 ret = true;
Jason Evansa1ee7832012-04-10 15:07:44 -0700714 goto label_return;
Jason Evansfc4dcfa2010-11-24 15:44:21 -0800715 }
Jason Evansd778dd22017-01-03 12:40:54 -0800716 sstats->initialized = true;
717
718 ctl_stats->narenas = narenas_total_get();
719 for (i = 0; i < ctl_stats->narenas; i++) {
720 if (stats_arenas_i_impl(tsdn, i, false, true) == NULL) {
721 ret = true;
722 goto label_return;
723 }
724 }
Jason Evans3c234352010-01-27 13:10:55 -0800725
Jason Evansc0a05e62017-01-03 15:09:50 -0800726 ctl_stats->epoch = 0;
Jason Evansc1e00ef2016-05-10 22:21:10 -0700727 ctl_refresh(tsdn);
Jason Evans3c234352010-01-27 13:10:55 -0800728 ctl_initialized = true;
729 }
730
Jason Evansfc4dcfa2010-11-24 15:44:21 -0800731 ret = false;
Jason Evansa1ee7832012-04-10 15:07:44 -0700732label_return:
Jason Evansc1e00ef2016-05-10 22:21:10 -0700733 malloc_mutex_unlock(tsdn, &ctl_mtx);
Jason Evansfc4dcfa2010-11-24 15:44:21 -0800734 return (ret);
Jason Evans3c234352010-01-27 13:10:55 -0800735}
736
737static int
Jason Evansc1e00ef2016-05-10 22:21:10 -0700738ctl_lookup(tsdn_t *tsdn, const char *name, ctl_node_t const **nodesp,
Jason Evansb2c0d632016-04-13 23:36:15 -0700739 size_t *mibp, size_t *depthp)
Jason Evans3c234352010-01-27 13:10:55 -0800740{
741 int ret;
742 const char *elm, *tdot, *dot;
743 size_t elen, i, j;
Mike Hommey461ad5c2012-04-20 08:38:42 +0200744 const ctl_named_node_t *node;
Jason Evans3c234352010-01-27 13:10:55 -0800745
746 elm = name;
747 /* Equivalent to strchrnul(). */
748 dot = ((tdot = strchr(elm, '.')) != NULL) ? tdot : strchr(elm, '\0');
749 elen = (size_t)((uintptr_t)dot - (uintptr_t)elm);
750 if (elen == 0) {
751 ret = ENOENT;
Jason Evansa1ee7832012-04-10 15:07:44 -0700752 goto label_return;
Jason Evans3c234352010-01-27 13:10:55 -0800753 }
754 node = super_root_node;
755 for (i = 0; i < *depthp; i++) {
Mike Hommey461ad5c2012-04-20 08:38:42 +0200756 assert(node);
757 assert(node->nchildren > 0);
758 if (ctl_named_node(node->children) != NULL) {
759 const ctl_named_node_t *pnode = node;
Jason Evans3c234352010-01-27 13:10:55 -0800760
761 /* Children are named. */
Mike Hommey461ad5c2012-04-20 08:38:42 +0200762 for (j = 0; j < node->nchildren; j++) {
763 const ctl_named_node_t *child =
764 ctl_named_children(node, j);
765 if (strlen(child->name) == elen &&
766 strncmp(elm, child->name, elen) == 0) {
Jason Evans3c234352010-01-27 13:10:55 -0800767 node = child;
768 if (nodesp != NULL)
Mike Hommey461ad5c2012-04-20 08:38:42 +0200769 nodesp[i] =
770 (const ctl_node_t *)node;
Jason Evans3c234352010-01-27 13:10:55 -0800771 mibp[i] = j;
772 break;
773 }
774 }
775 if (node == pnode) {
776 ret = ENOENT;
Jason Evansa1ee7832012-04-10 15:07:44 -0700777 goto label_return;
Jason Evans3c234352010-01-27 13:10:55 -0800778 }
779 } else {
Jason Evans41b6afb2012-02-02 22:04:57 -0800780 uintmax_t index;
Mike Hommey461ad5c2012-04-20 08:38:42 +0200781 const ctl_indexed_node_t *inode;
Jason Evans3c234352010-01-27 13:10:55 -0800782
783 /* Children are indexed. */
Jason Evans41b6afb2012-02-02 22:04:57 -0800784 index = malloc_strtoumax(elm, NULL, 10);
785 if (index == UINTMAX_MAX || index > SIZE_T_MAX) {
Jason Evans3c234352010-01-27 13:10:55 -0800786 ret = ENOENT;
Jason Evansa1ee7832012-04-10 15:07:44 -0700787 goto label_return;
Jason Evans3c234352010-01-27 13:10:55 -0800788 }
789
Mike Hommey461ad5c2012-04-20 08:38:42 +0200790 inode = ctl_indexed_node(node->children);
Jason Evansc1e00ef2016-05-10 22:21:10 -0700791 node = inode->index(tsdn, mibp, *depthp, (size_t)index);
Jason Evans3c234352010-01-27 13:10:55 -0800792 if (node == NULL) {
793 ret = ENOENT;
Jason Evansa1ee7832012-04-10 15:07:44 -0700794 goto label_return;
Jason Evans3c234352010-01-27 13:10:55 -0800795 }
796
797 if (nodesp != NULL)
Mike Hommey461ad5c2012-04-20 08:38:42 +0200798 nodesp[i] = (const ctl_node_t *)node;
Jason Evans3c234352010-01-27 13:10:55 -0800799 mibp[i] = (size_t)index;
800 }
801
802 if (node->ctl != NULL) {
803 /* Terminal node. */
804 if (*dot != '\0') {
805 /*
806 * The name contains more elements than are
807 * in this path through the tree.
808 */
809 ret = ENOENT;
Jason Evansa1ee7832012-04-10 15:07:44 -0700810 goto label_return;
Jason Evans3c234352010-01-27 13:10:55 -0800811 }
812 /* Complete lookup successful. */
813 *depthp = i + 1;
814 break;
815 }
816
817 /* Update elm. */
818 if (*dot == '\0') {
819 /* No more elements. */
820 ret = ENOENT;
Jason Evansa1ee7832012-04-10 15:07:44 -0700821 goto label_return;
Jason Evans3c234352010-01-27 13:10:55 -0800822 }
823 elm = &dot[1];
824 dot = ((tdot = strchr(elm, '.')) != NULL) ? tdot :
825 strchr(elm, '\0');
826 elen = (size_t)((uintptr_t)dot - (uintptr_t)elm);
827 }
828
829 ret = 0;
Jason Evansa1ee7832012-04-10 15:07:44 -0700830label_return:
Jason Evans3c234352010-01-27 13:10:55 -0800831 return (ret);
832}
833
834int
Jason Evansb2c0d632016-04-13 23:36:15 -0700835ctl_byname(tsd_t *tsd, const char *name, void *oldp, size_t *oldlenp,
836 void *newp, size_t newlen)
Jason Evans3c234352010-01-27 13:10:55 -0800837{
838 int ret;
839 size_t depth;
840 ctl_node_t const *nodes[CTL_MAX_DEPTH];
841 size_t mib[CTL_MAX_DEPTH];
Mike Hommey461ad5c2012-04-20 08:38:42 +0200842 const ctl_named_node_t *node;
Jason Evans3c234352010-01-27 13:10:55 -0800843
Jason Evansc1e00ef2016-05-10 22:21:10 -0700844 if (!ctl_initialized && ctl_init(tsd_tsdn(tsd))) {
Jason Evans3c234352010-01-27 13:10:55 -0800845 ret = EAGAIN;
Jason Evansa1ee7832012-04-10 15:07:44 -0700846 goto label_return;
Jason Evans3c234352010-01-27 13:10:55 -0800847 }
848
849 depth = CTL_MAX_DEPTH;
Jason Evansc1e00ef2016-05-10 22:21:10 -0700850 ret = ctl_lookup(tsd_tsdn(tsd), name, nodes, mib, &depth);
Jason Evans3c234352010-01-27 13:10:55 -0800851 if (ret != 0)
Jason Evansa1ee7832012-04-10 15:07:44 -0700852 goto label_return;
Jason Evans3c234352010-01-27 13:10:55 -0800853
Mike Hommey461ad5c2012-04-20 08:38:42 +0200854 node = ctl_named_node(nodes[depth-1]);
855 if (node != NULL && node->ctl)
Jason Evansb2c0d632016-04-13 23:36:15 -0700856 ret = node->ctl(tsd, mib, depth, oldp, oldlenp, newp, newlen);
Mike Hommey461ad5c2012-04-20 08:38:42 +0200857 else {
Jason Evans3c234352010-01-27 13:10:55 -0800858 /* The name refers to a partial path through the ctl tree. */
859 ret = ENOENT;
Jason Evans3c234352010-01-27 13:10:55 -0800860 }
Jason Evans3c234352010-01-27 13:10:55 -0800861
Jason Evansa1ee7832012-04-10 15:07:44 -0700862label_return:
Jason Evans3c234352010-01-27 13:10:55 -0800863 return(ret);
864}
865
866int
Jason Evansc1e00ef2016-05-10 22:21:10 -0700867ctl_nametomib(tsdn_t *tsdn, const char *name, size_t *mibp, size_t *miblenp)
Jason Evans3c234352010-01-27 13:10:55 -0800868{
869 int ret;
870
Jason Evansc1e00ef2016-05-10 22:21:10 -0700871 if (!ctl_initialized && ctl_init(tsdn)) {
Jason Evans3c234352010-01-27 13:10:55 -0800872 ret = EAGAIN;
Jason Evansa1ee7832012-04-10 15:07:44 -0700873 goto label_return;
Jason Evans3c234352010-01-27 13:10:55 -0800874 }
875
Jason Evansc1e00ef2016-05-10 22:21:10 -0700876 ret = ctl_lookup(tsdn, name, NULL, mibp, miblenp);
Jason Evansa1ee7832012-04-10 15:07:44 -0700877label_return:
Jason Evans3c234352010-01-27 13:10:55 -0800878 return(ret);
879}
880
881int
Jason Evansb2c0d632016-04-13 23:36:15 -0700882ctl_bymib(tsd_t *tsd, const size_t *mib, size_t miblen, void *oldp,
883 size_t *oldlenp, void *newp, size_t newlen)
Jason Evans3c234352010-01-27 13:10:55 -0800884{
885 int ret;
Mike Hommey461ad5c2012-04-20 08:38:42 +0200886 const ctl_named_node_t *node;
Jason Evans3c234352010-01-27 13:10:55 -0800887 size_t i;
888
Jason Evansc1e00ef2016-05-10 22:21:10 -0700889 if (!ctl_initialized && ctl_init(tsd_tsdn(tsd))) {
Jason Evans3c234352010-01-27 13:10:55 -0800890 ret = EAGAIN;
Jason Evansa1ee7832012-04-10 15:07:44 -0700891 goto label_return;
Jason Evans3c234352010-01-27 13:10:55 -0800892 }
893
894 /* Iterate down the tree. */
895 node = super_root_node;
896 for (i = 0; i < miblen; i++) {
Mike Hommey461ad5c2012-04-20 08:38:42 +0200897 assert(node);
898 assert(node->nchildren > 0);
899 if (ctl_named_node(node->children) != NULL) {
Jason Evans3c234352010-01-27 13:10:55 -0800900 /* Children are named. */
Jason Evans6edbedd2017-01-04 07:51:49 -0800901 if (node->nchildren <= mib[i]) {
Jason Evans3c234352010-01-27 13:10:55 -0800902 ret = ENOENT;
Jason Evansa1ee7832012-04-10 15:07:44 -0700903 goto label_return;
Jason Evans3c234352010-01-27 13:10:55 -0800904 }
Mike Hommey461ad5c2012-04-20 08:38:42 +0200905 node = ctl_named_children(node, mib[i]);
Jason Evans3c234352010-01-27 13:10:55 -0800906 } else {
Mike Hommey461ad5c2012-04-20 08:38:42 +0200907 const ctl_indexed_node_t *inode;
Jason Evans3c234352010-01-27 13:10:55 -0800908
909 /* Indexed element. */
Mike Hommey461ad5c2012-04-20 08:38:42 +0200910 inode = ctl_indexed_node(node->children);
Jason Evansc1e00ef2016-05-10 22:21:10 -0700911 node = inode->index(tsd_tsdn(tsd), mib, miblen, mib[i]);
Jason Evans3c234352010-01-27 13:10:55 -0800912 if (node == NULL) {
913 ret = ENOENT;
Jason Evansa1ee7832012-04-10 15:07:44 -0700914 goto label_return;
Jason Evans3c234352010-01-27 13:10:55 -0800915 }
916 }
917 }
918
919 /* Call the ctl function. */
Mike Hommey461ad5c2012-04-20 08:38:42 +0200920 if (node && node->ctl)
Jason Evansb2c0d632016-04-13 23:36:15 -0700921 ret = node->ctl(tsd, mib, miblen, oldp, oldlenp, newp, newlen);
Mike Hommey461ad5c2012-04-20 08:38:42 +0200922 else {
Jason Evans3c234352010-01-27 13:10:55 -0800923 /* Partial MIB. */
924 ret = ENOENT;
Jason Evans3c234352010-01-27 13:10:55 -0800925 }
Jason Evans3c234352010-01-27 13:10:55 -0800926
Jason Evansa1ee7832012-04-10 15:07:44 -0700927label_return:
Jason Evans3c234352010-01-27 13:10:55 -0800928 return(ret);
929}
930
931bool
932ctl_boot(void)
933{
934
Jason Evansb2c0d632016-04-13 23:36:15 -0700935 if (malloc_mutex_init(&ctl_mtx, "ctl", WITNESS_RANK_CTL))
Jason Evans3c234352010-01-27 13:10:55 -0800936 return (true);
937
938 ctl_initialized = false;
939
940 return (false);
941}
942
Jason Evans20f1fc92012-10-09 14:46:22 -0700943void
Jason Evansc1e00ef2016-05-10 22:21:10 -0700944ctl_prefork(tsdn_t *tsdn)
Jason Evans20f1fc92012-10-09 14:46:22 -0700945{
946
Jason Evansc1e00ef2016-05-10 22:21:10 -0700947 malloc_mutex_prefork(tsdn, &ctl_mtx);
Jason Evans20f1fc92012-10-09 14:46:22 -0700948}
949
950void
Jason Evansc1e00ef2016-05-10 22:21:10 -0700951ctl_postfork_parent(tsdn_t *tsdn)
Jason Evans20f1fc92012-10-09 14:46:22 -0700952{
953
Jason Evansc1e00ef2016-05-10 22:21:10 -0700954 malloc_mutex_postfork_parent(tsdn, &ctl_mtx);
Jason Evans20f1fc92012-10-09 14:46:22 -0700955}
956
957void
Jason Evansc1e00ef2016-05-10 22:21:10 -0700958ctl_postfork_child(tsdn_t *tsdn)
Jason Evans20f1fc92012-10-09 14:46:22 -0700959{
960
Jason Evansc1e00ef2016-05-10 22:21:10 -0700961 malloc_mutex_postfork_child(tsdn, &ctl_mtx);
Jason Evans20f1fc92012-10-09 14:46:22 -0700962}
963
Jason Evans3c234352010-01-27 13:10:55 -0800964/******************************************************************************/
965/* *_ctl() functions. */
966
967#define READONLY() do { \
968 if (newp != NULL || newlen != 0) { \
969 ret = EPERM; \
Jason Evans6b9ed672012-04-25 13:12:46 -0700970 goto label_return; \
Jason Evans3c234352010-01-27 13:10:55 -0800971 } \
972} while (0)
973
Jason Evans22ca8552010-03-02 11:57:30 -0800974#define WRITEONLY() do { \
Jason Evans3c234352010-01-27 13:10:55 -0800975 if (oldp != NULL || oldlenp != NULL) { \
976 ret = EPERM; \
Jason Evans6b9ed672012-04-25 13:12:46 -0700977 goto label_return; \
Jason Evans3c234352010-01-27 13:10:55 -0800978 } \
979} while (0)
980
Jason Evansfc12c0b2014-10-03 23:25:30 -0700981#define READ_XOR_WRITE() do { \
982 if ((oldp != NULL && oldlenp != NULL) && (newp != NULL || \
983 newlen != 0)) { \
984 ret = EPERM; \
985 goto label_return; \
986 } \
987} while (0)
988
Jason Evans3c234352010-01-27 13:10:55 -0800989#define READ(v, t) do { \
990 if (oldp != NULL && oldlenp != NULL) { \
991 if (*oldlenp != sizeof(t)) { \
992 size_t copylen = (sizeof(t) <= *oldlenp) \
993 ? sizeof(t) : *oldlenp; \
Jason Evans6eb84fb2012-11-29 22:13:04 -0800994 memcpy(oldp, (void *)&(v), copylen); \
Jason Evans3c234352010-01-27 13:10:55 -0800995 ret = EINVAL; \
Jason Evans6b9ed672012-04-25 13:12:46 -0700996 goto label_return; \
Jason Evansb49a3342015-07-28 11:28:19 -0400997 } \
998 *(t *)oldp = (v); \
Jason Evans3c234352010-01-27 13:10:55 -0800999 } \
1000} while (0)
1001
1002#define WRITE(v, t) do { \
1003 if (newp != NULL) { \
1004 if (newlen != sizeof(t)) { \
1005 ret = EINVAL; \
Jason Evans6b9ed672012-04-25 13:12:46 -07001006 goto label_return; \
Jason Evans3c234352010-01-27 13:10:55 -08001007 } \
Jason Evans6eb84fb2012-11-29 22:13:04 -08001008 (v) = *(t *)newp; \
Jason Evans3c234352010-01-27 13:10:55 -08001009 } \
1010} while (0)
1011
Jason Evans6edbedd2017-01-04 07:51:49 -08001012#define MIB_UNSIGNED(v, i) do { \
1013 if (mib[i] > UINT_MAX) { \
1014 ret = EFAULT; \
1015 goto label_return; \
1016 } \
1017 v = (unsigned)mib[i]; \
1018} while (0)
1019
Jason Evans7372b152012-02-10 20:22:09 -08001020/*
1021 * There's a lot of code duplication in the following macros due to limitations
1022 * in how nested cpp macros are expanded.
1023 */
1024#define CTL_RO_CLGEN(c, l, n, v, t) \
1025static int \
Jason Evansb2c0d632016-04-13 23:36:15 -07001026n##_ctl(tsd_t *tsd, const size_t *mib, size_t miblen, void *oldp, \
1027 size_t *oldlenp, void *newp, size_t newlen) \
Jason Evans7372b152012-02-10 20:22:09 -08001028{ \
1029 int ret; \
1030 t oldval; \
1031 \
Jason Evans551ebc42014-10-03 10:16:09 -07001032 if (!(c)) \
Jason Evans7372b152012-02-10 20:22:09 -08001033 return (ENOENT); \
1034 if (l) \
Jason Evansc1e00ef2016-05-10 22:21:10 -07001035 malloc_mutex_lock(tsd_tsdn(tsd), &ctl_mtx); \
Jason Evans7372b152012-02-10 20:22:09 -08001036 READONLY(); \
Jason Evans6eb84fb2012-11-29 22:13:04 -08001037 oldval = (v); \
Jason Evans7372b152012-02-10 20:22:09 -08001038 READ(oldval, t); \
1039 \
1040 ret = 0; \
Jason Evans6b9ed672012-04-25 13:12:46 -07001041label_return: \
Jason Evans7372b152012-02-10 20:22:09 -08001042 if (l) \
Jason Evansc1e00ef2016-05-10 22:21:10 -07001043 malloc_mutex_unlock(tsd_tsdn(tsd), &ctl_mtx); \
Jason Evans7372b152012-02-10 20:22:09 -08001044 return (ret); \
1045}
1046
1047#define CTL_RO_CGEN(c, n, v, t) \
1048static int \
Jason Evansb2c0d632016-04-13 23:36:15 -07001049n##_ctl(tsd_t *tsd, const size_t *mib, size_t miblen, void *oldp, \
1050 size_t *oldlenp, void *newp, size_t newlen) \
Jason Evans7372b152012-02-10 20:22:09 -08001051{ \
1052 int ret; \
1053 t oldval; \
1054 \
Jason Evans551ebc42014-10-03 10:16:09 -07001055 if (!(c)) \
Jason Evans7372b152012-02-10 20:22:09 -08001056 return (ENOENT); \
Jason Evansc1e00ef2016-05-10 22:21:10 -07001057 malloc_mutex_lock(tsd_tsdn(tsd), &ctl_mtx); \
Jason Evans7372b152012-02-10 20:22:09 -08001058 READONLY(); \
Jason Evans6eb84fb2012-11-29 22:13:04 -08001059 oldval = (v); \
Jason Evans7372b152012-02-10 20:22:09 -08001060 READ(oldval, t); \
1061 \
1062 ret = 0; \
Jason Evans6b9ed672012-04-25 13:12:46 -07001063label_return: \
Jason Evansc1e00ef2016-05-10 22:21:10 -07001064 malloc_mutex_unlock(tsd_tsdn(tsd), &ctl_mtx); \
Jason Evans7372b152012-02-10 20:22:09 -08001065 return (ret); \
1066}
1067
Jason Evans3c234352010-01-27 13:10:55 -08001068#define CTL_RO_GEN(n, v, t) \
1069static int \
Jason Evansb2c0d632016-04-13 23:36:15 -07001070n##_ctl(tsd_t *tsd, const size_t *mib, size_t miblen, void *oldp, \
1071 size_t *oldlenp, void *newp, size_t newlen) \
Jason Evans3c234352010-01-27 13:10:55 -08001072{ \
1073 int ret; \
1074 t oldval; \
1075 \
Jason Evansc1e00ef2016-05-10 22:21:10 -07001076 malloc_mutex_lock(tsd_tsdn(tsd), &ctl_mtx); \
Jason Evansfc4dcfa2010-11-24 15:44:21 -08001077 READONLY(); \
Jason Evans6eb84fb2012-11-29 22:13:04 -08001078 oldval = (v); \
Jason Evansfc4dcfa2010-11-24 15:44:21 -08001079 READ(oldval, t); \
1080 \
1081 ret = 0; \
Jason Evans6b9ed672012-04-25 13:12:46 -07001082label_return: \
Jason Evansc1e00ef2016-05-10 22:21:10 -07001083 malloc_mutex_unlock(tsd_tsdn(tsd), &ctl_mtx); \
Jason Evansfc4dcfa2010-11-24 15:44:21 -08001084 return (ret); \
1085}
1086
1087/*
1088 * ctl_mtx is not acquired, under the assumption that no pertinent data will
1089 * mutate during the call.
1090 */
Jason Evans7372b152012-02-10 20:22:09 -08001091#define CTL_RO_NL_CGEN(c, n, v, t) \
1092static int \
Jason Evansb2c0d632016-04-13 23:36:15 -07001093n##_ctl(tsd_t *tsd, const size_t *mib, size_t miblen, void *oldp, \
1094 size_t *oldlenp, void *newp, size_t newlen) \
Jason Evans7372b152012-02-10 20:22:09 -08001095{ \
1096 int ret; \
1097 t oldval; \
1098 \
Jason Evans551ebc42014-10-03 10:16:09 -07001099 if (!(c)) \
Jason Evans7372b152012-02-10 20:22:09 -08001100 return (ENOENT); \
1101 READONLY(); \
Jason Evans6eb84fb2012-11-29 22:13:04 -08001102 oldval = (v); \
Jason Evans7372b152012-02-10 20:22:09 -08001103 READ(oldval, t); \
1104 \
1105 ret = 0; \
Jason Evans6b9ed672012-04-25 13:12:46 -07001106label_return: \
Jason Evans7372b152012-02-10 20:22:09 -08001107 return (ret); \
1108}
1109
1110#define CTL_RO_NL_GEN(n, v, t) \
Jason Evansfc4dcfa2010-11-24 15:44:21 -08001111static int \
Jason Evansb2c0d632016-04-13 23:36:15 -07001112n##_ctl(tsd_t *tsd, const size_t *mib, size_t miblen, void *oldp, \
1113 size_t *oldlenp, void *newp, size_t newlen) \
Jason Evansfc4dcfa2010-11-24 15:44:21 -08001114{ \
1115 int ret; \
1116 t oldval; \
1117 \
Jason Evans3c234352010-01-27 13:10:55 -08001118 READONLY(); \
Jason Evans6eb84fb2012-11-29 22:13:04 -08001119 oldval = (v); \
Jason Evans3c234352010-01-27 13:10:55 -08001120 READ(oldval, t); \
1121 \
1122 ret = 0; \
Jason Evans6b9ed672012-04-25 13:12:46 -07001123label_return: \
Jason Evans3c234352010-01-27 13:10:55 -08001124 return (ret); \
1125}
1126
Jason Evans5460aa62014-09-22 21:09:23 -07001127#define CTL_TSD_RO_NL_CGEN(c, n, m, t) \
1128static int \
Jason Evansb2c0d632016-04-13 23:36:15 -07001129n##_ctl(tsd_t *tsd, const size_t *mib, size_t miblen, void *oldp, \
1130 size_t *oldlenp, void *newp, size_t newlen) \
Jason Evans5460aa62014-09-22 21:09:23 -07001131{ \
1132 int ret; \
1133 t oldval; \
Jason Evans5460aa62014-09-22 21:09:23 -07001134 \
Jason Evans551ebc42014-10-03 10:16:09 -07001135 if (!(c)) \
Jason Evans5460aa62014-09-22 21:09:23 -07001136 return (ENOENT); \
1137 READONLY(); \
Jason Evans5460aa62014-09-22 21:09:23 -07001138 oldval = (m(tsd)); \
1139 READ(oldval, t); \
1140 \
1141 ret = 0; \
1142label_return: \
1143 return (ret); \
1144}
1145
Jason Evansf8290092016-02-07 14:23:22 -08001146#define CTL_RO_CONFIG_GEN(n, t) \
Jason Evans3c234352010-01-27 13:10:55 -08001147static int \
Jason Evansb2c0d632016-04-13 23:36:15 -07001148n##_ctl(tsd_t *tsd, const size_t *mib, size_t miblen, void *oldp, \
1149 size_t *oldlenp, void *newp, size_t newlen) \
Jason Evans3c234352010-01-27 13:10:55 -08001150{ \
1151 int ret; \
Jason Evansf8290092016-02-07 14:23:22 -08001152 t oldval; \
Jason Evans3c234352010-01-27 13:10:55 -08001153 \
1154 READONLY(); \
Jason Evans7372b152012-02-10 20:22:09 -08001155 oldval = n; \
Jason Evansf8290092016-02-07 14:23:22 -08001156 READ(oldval, t); \
Jason Evans3c234352010-01-27 13:10:55 -08001157 \
1158 ret = 0; \
Jason Evans6b9ed672012-04-25 13:12:46 -07001159label_return: \
Jason Evans3c234352010-01-27 13:10:55 -08001160 return (ret); \
1161}
1162
Jason Evansd8a39002013-12-19 21:40:41 -08001163/******************************************************************************/
1164
Jason Evansfc4dcfa2010-11-24 15:44:21 -08001165CTL_RO_NL_GEN(version, JEMALLOC_VERSION, const char *)
Jason Evansa40bc7a2010-03-02 13:01:16 -08001166
Jason Evans3c234352010-01-27 13:10:55 -08001167static int
Jason Evansb2c0d632016-04-13 23:36:15 -07001168epoch_ctl(tsd_t *tsd, const size_t *mib, size_t miblen, void *oldp,
1169 size_t *oldlenp, void *newp, size_t newlen)
Jason Evans3c234352010-01-27 13:10:55 -08001170{
1171 int ret;
Jason Evans3ab682d2013-10-19 17:19:49 -07001172 UNUSED uint64_t newval;
Jason Evans3c234352010-01-27 13:10:55 -08001173
Jason Evansc1e00ef2016-05-10 22:21:10 -07001174 malloc_mutex_lock(tsd_tsdn(tsd), &ctl_mtx);
Jason Evans3c234352010-01-27 13:10:55 -08001175 WRITE(newval, uint64_t);
Jason Evans6b9ed672012-04-25 13:12:46 -07001176 if (newp != NULL)
Jason Evansc1e00ef2016-05-10 22:21:10 -07001177 ctl_refresh(tsd_tsdn(tsd));
Jason Evansc0a05e62017-01-03 15:09:50 -08001178 READ(ctl_stats->epoch, uint64_t);
Jason Evans3c234352010-01-27 13:10:55 -08001179
1180 ret = 0;
Jason Evansa1ee7832012-04-10 15:07:44 -07001181label_return:
Jason Evansc1e00ef2016-05-10 22:21:10 -07001182 malloc_mutex_unlock(tsd_tsdn(tsd), &ctl_mtx);
Jason Evans3c234352010-01-27 13:10:55 -08001183 return (ret);
1184}
1185
Jason Evansd8a39002013-12-19 21:40:41 -08001186/******************************************************************************/
Jason Evansd4be8b72012-03-26 18:54:44 -07001187
Jason Evansf8290092016-02-07 14:23:22 -08001188CTL_RO_CONFIG_GEN(config_cache_oblivious, bool)
1189CTL_RO_CONFIG_GEN(config_debug, bool)
1190CTL_RO_CONFIG_GEN(config_fill, bool)
1191CTL_RO_CONFIG_GEN(config_lazy_lock, bool)
1192CTL_RO_CONFIG_GEN(config_malloc_conf, const char *)
1193CTL_RO_CONFIG_GEN(config_munmap, bool)
1194CTL_RO_CONFIG_GEN(config_prof, bool)
1195CTL_RO_CONFIG_GEN(config_prof_libgcc, bool)
1196CTL_RO_CONFIG_GEN(config_prof_libunwind, bool)
1197CTL_RO_CONFIG_GEN(config_stats, bool)
1198CTL_RO_CONFIG_GEN(config_tcache, bool)
1199CTL_RO_CONFIG_GEN(config_tls, bool)
1200CTL_RO_CONFIG_GEN(config_utrace, bool)
Jason Evansf8290092016-02-07 14:23:22 -08001201CTL_RO_CONFIG_GEN(config_xmalloc, bool)
Jason Evansd4be8b72012-03-26 18:54:44 -07001202
Jason Evansd8a39002013-12-19 21:40:41 -08001203/******************************************************************************/
Jason Evansd4be8b72012-03-26 18:54:44 -07001204
Jason Evansd8a39002013-12-19 21:40:41 -08001205CTL_RO_NL_GEN(opt_abort, opt_abort, bool)
1206CTL_RO_NL_GEN(opt_dss, opt_dss, const char *)
Jason Evans8f683b92016-02-24 11:03:40 -08001207CTL_RO_NL_GEN(opt_narenas, opt_narenas, unsigned)
Jason Evans243f7a02016-02-19 20:09:31 -08001208CTL_RO_NL_GEN(opt_decay_time, opt_decay_time, ssize_t)
Jason Evansd8a39002013-12-19 21:40:41 -08001209CTL_RO_NL_GEN(opt_stats_print, opt_stats_print, bool)
Guilherme Goncalves2c5cb612014-12-08 19:12:41 -02001210CTL_RO_NL_CGEN(config_fill, opt_junk, opt_junk, const char *)
Jason Evansd8a39002013-12-19 21:40:41 -08001211CTL_RO_NL_CGEN(config_fill, opt_zero, opt_zero, bool)
1212CTL_RO_NL_CGEN(config_utrace, opt_utrace, opt_utrace, bool)
Jason Evansd8a39002013-12-19 21:40:41 -08001213CTL_RO_NL_CGEN(config_xmalloc, opt_xmalloc, opt_xmalloc, bool)
1214CTL_RO_NL_CGEN(config_tcache, opt_tcache, opt_tcache, bool)
1215CTL_RO_NL_CGEN(config_tcache, opt_lg_tcache_max, opt_lg_tcache_max, ssize_t)
1216CTL_RO_NL_CGEN(config_prof, opt_prof, opt_prof, bool)
1217CTL_RO_NL_CGEN(config_prof, opt_prof_prefix, opt_prof_prefix, const char *)
Jason Evansfc12c0b2014-10-03 23:25:30 -07001218CTL_RO_NL_CGEN(config_prof, opt_prof_active, opt_prof_active, bool)
1219CTL_RO_NL_CGEN(config_prof, opt_prof_thread_active_init,
1220 opt_prof_thread_active_init, bool)
Jason Evansd8a39002013-12-19 21:40:41 -08001221CTL_RO_NL_CGEN(config_prof, opt_lg_prof_sample, opt_lg_prof_sample, size_t)
1222CTL_RO_NL_CGEN(config_prof, opt_prof_accum, opt_prof_accum, bool)
1223CTL_RO_NL_CGEN(config_prof, opt_lg_prof_interval, opt_lg_prof_interval, ssize_t)
1224CTL_RO_NL_CGEN(config_prof, opt_prof_gdump, opt_prof_gdump, bool)
1225CTL_RO_NL_CGEN(config_prof, opt_prof_final, opt_prof_final, bool)
1226CTL_RO_NL_CGEN(config_prof, opt_prof_leak, opt_prof_leak, bool)
Jason Evansd4be8b72012-03-26 18:54:44 -07001227
Jason Evansd8a39002013-12-19 21:40:41 -08001228/******************************************************************************/
Jason Evans3c234352010-01-27 13:10:55 -08001229
Jason Evansb267d0f2010-08-13 15:42:29 -07001230static int
Jason Evansb2c0d632016-04-13 23:36:15 -07001231thread_arena_ctl(tsd_t *tsd, const size_t *mib, size_t miblen, void *oldp,
1232 size_t *oldlenp, void *newp, size_t newlen)
Jason Evansb267d0f2010-08-13 15:42:29 -07001233{
1234 int ret;
Jason Evans1cb181e2015-01-29 15:30:47 -08001235 arena_t *oldarena;
Jason Evansb267d0f2010-08-13 15:42:29 -07001236 unsigned newind, oldind;
1237
Jason Evans90827a32016-05-03 15:00:42 -07001238 oldarena = arena_choose(tsd, NULL);
Jason Evans1cb181e2015-01-29 15:30:47 -08001239 if (oldarena == NULL)
Jason Evans8bb31982014-10-07 23:14:57 -07001240 return (EAGAIN);
Jason Evans5460aa62014-09-22 21:09:23 -07001241
Jason Evansa0dd3a42016-12-22 16:39:10 -06001242 newind = oldind = arena_ind_get(oldarena);
Jason Evansa7153a02011-03-14 11:39:49 -07001243 WRITE(newind, unsigned);
1244 READ(oldind, unsigned);
Jason Evansb267d0f2010-08-13 15:42:29 -07001245 if (newind != oldind) {
Jason Evans1cb181e2015-01-29 15:30:47 -08001246 arena_t *newarena;
1247
Jason Evansb6c08672016-10-03 10:37:12 -07001248 if (newind >= narenas_total_get()) {
Jason Evansb267d0f2010-08-13 15:42:29 -07001249 /* New arena index is out of range. */
1250 ret = EFAULT;
Jason Evansa1ee7832012-04-10 15:07:44 -07001251 goto label_return;
Jason Evansb267d0f2010-08-13 15:42:29 -07001252 }
1253
1254 /* Initialize arena if necessary. */
Jason Evansc1e00ef2016-05-10 22:21:10 -07001255 newarena = arena_get(tsd_tsdn(tsd), newind, true);
Jason Evans1cb181e2015-01-29 15:30:47 -08001256 if (newarena == NULL) {
Jason Evansb267d0f2010-08-13 15:42:29 -07001257 ret = EAGAIN;
Jason Evansa1ee7832012-04-10 15:07:44 -07001258 goto label_return;
Jason Evansb267d0f2010-08-13 15:42:29 -07001259 }
Jason Evans8bb31982014-10-07 23:14:57 -07001260 /* Set new arena/tcache associations. */
1261 arena_migrate(tsd, oldind, newind);
Jason Evans7372b152012-02-10 20:22:09 -08001262 if (config_tcache) {
Jason Evans5460aa62014-09-22 21:09:23 -07001263 tcache_t *tcache = tsd_tcache_get(tsd);
Jason Evans1cb181e2015-01-29 15:30:47 -08001264 if (tcache != NULL) {
Jason Evansc1e00ef2016-05-10 22:21:10 -07001265 tcache_arena_reassociate(tsd_tsdn(tsd), tcache,
1266 oldarena, newarena);
Jason Evans1cb181e2015-01-29 15:30:47 -08001267 }
Jason Evans624f2f32010-12-29 12:21:05 -08001268 }
Jason Evansb267d0f2010-08-13 15:42:29 -07001269 }
1270
1271 ret = 0;
Jason Evansa1ee7832012-04-10 15:07:44 -07001272label_return:
Jason Evansb267d0f2010-08-13 15:42:29 -07001273 return (ret);
1274}
Jason Evansb267d0f2010-08-13 15:42:29 -07001275
Jason Evans5460aa62014-09-22 21:09:23 -07001276CTL_TSD_RO_NL_CGEN(config_stats, thread_allocated, tsd_thread_allocated_get,
1277 uint64_t)
1278CTL_TSD_RO_NL_CGEN(config_stats, thread_allocatedp, tsd_thread_allocatedp_get,
1279 uint64_t *)
1280CTL_TSD_RO_NL_CGEN(config_stats, thread_deallocated, tsd_thread_deallocated_get,
1281 uint64_t)
1282CTL_TSD_RO_NL_CGEN(config_stats, thread_deallocatedp,
1283 tsd_thread_deallocatedp_get, uint64_t *)
Jason Evans93443682010-10-20 17:39:18 -07001284
Jason Evansd8a39002013-12-19 21:40:41 -08001285static int
Jason Evansb2c0d632016-04-13 23:36:15 -07001286thread_tcache_enabled_ctl(tsd_t *tsd, const size_t *mib, size_t miblen,
1287 void *oldp, size_t *oldlenp, void *newp, size_t newlen)
Jason Evansd8a39002013-12-19 21:40:41 -08001288{
1289 int ret;
1290 bool oldval;
Jason Evans3c234352010-01-27 13:10:55 -08001291
Jason Evans551ebc42014-10-03 10:16:09 -07001292 if (!config_tcache)
Jason Evansd8a39002013-12-19 21:40:41 -08001293 return (ENOENT);
Jason Evans3c234352010-01-27 13:10:55 -08001294
Jason Evansd8a39002013-12-19 21:40:41 -08001295 oldval = tcache_enabled_get();
1296 if (newp != NULL) {
1297 if (newlen != sizeof(bool)) {
1298 ret = EINVAL;
1299 goto label_return;
1300 }
1301 tcache_enabled_set(*(bool *)newp);
1302 }
1303 READ(oldval, bool);
Jason Evans3c234352010-01-27 13:10:55 -08001304
Jason Evansd8a39002013-12-19 21:40:41 -08001305 ret = 0;
1306label_return:
1307 return (ret);
1308}
1309
1310static int
Jason Evansb2c0d632016-04-13 23:36:15 -07001311thread_tcache_flush_ctl(tsd_t *tsd, const size_t *mib, size_t miblen,
1312 void *oldp, size_t *oldlenp, void *newp, size_t newlen)
Jason Evansd8a39002013-12-19 21:40:41 -08001313{
1314 int ret;
1315
Jason Evans551ebc42014-10-03 10:16:09 -07001316 if (!config_tcache)
Jason Evansd8a39002013-12-19 21:40:41 -08001317 return (ENOENT);
1318
1319 READONLY();
1320 WRITEONLY();
1321
1322 tcache_flush();
1323
1324 ret = 0;
1325label_return:
1326 return (ret);
1327}
Jason Evans3c234352010-01-27 13:10:55 -08001328
Jason Evans602c8e02014-08-18 16:22:13 -07001329static int
Jason Evansb2c0d632016-04-13 23:36:15 -07001330thread_prof_name_ctl(tsd_t *tsd, const size_t *mib, size_t miblen, void *oldp,
Jason Evans602c8e02014-08-18 16:22:13 -07001331 size_t *oldlenp, void *newp, size_t newlen)
1332{
1333 int ret;
Jason Evans602c8e02014-08-18 16:22:13 -07001334
Jason Evans551ebc42014-10-03 10:16:09 -07001335 if (!config_prof)
Jason Evans602c8e02014-08-18 16:22:13 -07001336 return (ENOENT);
1337
Jason Evansfc12c0b2014-10-03 23:25:30 -07001338 READ_XOR_WRITE();
1339
Jason Evans602c8e02014-08-18 16:22:13 -07001340 if (newp != NULL) {
1341 if (newlen != sizeof(const char *)) {
1342 ret = EINVAL;
1343 goto label_return;
1344 }
Jason Evans5460aa62014-09-22 21:09:23 -07001345
Jason Evansfc12c0b2014-10-03 23:25:30 -07001346 if ((ret = prof_thread_name_set(tsd, *(const char **)newp)) !=
1347 0)
Jason Evans602c8e02014-08-18 16:22:13 -07001348 goto label_return;
Jason Evansfc12c0b2014-10-03 23:25:30 -07001349 } else {
Jason Evansb2c0d632016-04-13 23:36:15 -07001350 const char *oldname = prof_thread_name_get(tsd);
Jason Evansfc12c0b2014-10-03 23:25:30 -07001351 READ(oldname, const char *);
Jason Evans602c8e02014-08-18 16:22:13 -07001352 }
Jason Evans602c8e02014-08-18 16:22:13 -07001353
1354 ret = 0;
1355label_return:
1356 return (ret);
1357}
1358
1359static int
Jason Evansb2c0d632016-04-13 23:36:15 -07001360thread_prof_active_ctl(tsd_t *tsd, const size_t *mib, size_t miblen, void *oldp,
Jason Evans602c8e02014-08-18 16:22:13 -07001361 size_t *oldlenp, void *newp, size_t newlen)
1362{
1363 int ret;
1364 bool oldval;
1365
Jason Evans551ebc42014-10-03 10:16:09 -07001366 if (!config_prof)
Jason Evans602c8e02014-08-18 16:22:13 -07001367 return (ENOENT);
1368
Jason Evansb2c0d632016-04-13 23:36:15 -07001369 oldval = prof_thread_active_get(tsd);
Jason Evans602c8e02014-08-18 16:22:13 -07001370 if (newp != NULL) {
1371 if (newlen != sizeof(bool)) {
1372 ret = EINVAL;
1373 goto label_return;
1374 }
Jason Evansb2c0d632016-04-13 23:36:15 -07001375 if (prof_thread_active_set(tsd, *(bool *)newp)) {
Jason Evans602c8e02014-08-18 16:22:13 -07001376 ret = EAGAIN;
1377 goto label_return;
1378 }
1379 }
1380 READ(oldval, bool);
1381
1382 ret = 0;
1383label_return:
1384 return (ret);
1385}
1386
Jason Evans3c234352010-01-27 13:10:55 -08001387/******************************************************************************/
1388
Jason Evans1cb181e2015-01-29 15:30:47 -08001389static int
Jason Evansb2c0d632016-04-13 23:36:15 -07001390tcache_create_ctl(tsd_t *tsd, const size_t *mib, size_t miblen, void *oldp,
1391 size_t *oldlenp, void *newp, size_t newlen)
Jason Evans1cb181e2015-01-29 15:30:47 -08001392{
1393 int ret;
Jason Evans1cb181e2015-01-29 15:30:47 -08001394 unsigned tcache_ind;
1395
1396 if (!config_tcache)
1397 return (ENOENT);
1398
Jason Evansc1e00ef2016-05-10 22:21:10 -07001399 malloc_mutex_lock(tsd_tsdn(tsd), &ctl_mtx);
Jason Evans1cb181e2015-01-29 15:30:47 -08001400 READONLY();
Jason Evansb54d1602016-10-20 23:59:12 -07001401 if (tcaches_create(tsd, &tcache_ind)) {
Jason Evans1cb181e2015-01-29 15:30:47 -08001402 ret = EFAULT;
1403 goto label_return;
1404 }
1405 READ(tcache_ind, unsigned);
1406
1407 ret = 0;
1408label_return:
Jason Evansc1e00ef2016-05-10 22:21:10 -07001409 malloc_mutex_unlock(tsd_tsdn(tsd), &ctl_mtx);
Jason Evans1cb181e2015-01-29 15:30:47 -08001410 return (ret);
1411}
1412
1413static int
Jason Evansb2c0d632016-04-13 23:36:15 -07001414tcache_flush_ctl(tsd_t *tsd, const size_t *mib, size_t miblen, void *oldp,
1415 size_t *oldlenp, void *newp, size_t newlen)
Jason Evans1cb181e2015-01-29 15:30:47 -08001416{
1417 int ret;
Jason Evans1cb181e2015-01-29 15:30:47 -08001418 unsigned tcache_ind;
1419
1420 if (!config_tcache)
1421 return (ENOENT);
1422
Jason Evans1cb181e2015-01-29 15:30:47 -08001423 WRITEONLY();
1424 tcache_ind = UINT_MAX;
1425 WRITE(tcache_ind, unsigned);
1426 if (tcache_ind == UINT_MAX) {
1427 ret = EFAULT;
1428 goto label_return;
1429 }
1430 tcaches_flush(tsd, tcache_ind);
1431
1432 ret = 0;
1433label_return:
1434 return (ret);
1435}
1436
1437static int
Jason Evansb2c0d632016-04-13 23:36:15 -07001438tcache_destroy_ctl(tsd_t *tsd, const size_t *mib, size_t miblen, void *oldp,
Jason Evans1cb181e2015-01-29 15:30:47 -08001439 size_t *oldlenp, void *newp, size_t newlen)
1440{
1441 int ret;
Jason Evans1cb181e2015-01-29 15:30:47 -08001442 unsigned tcache_ind;
1443
1444 if (!config_tcache)
1445 return (ENOENT);
1446
Jason Evans1cb181e2015-01-29 15:30:47 -08001447 WRITEONLY();
1448 tcache_ind = UINT_MAX;
1449 WRITE(tcache_ind, unsigned);
1450 if (tcache_ind == UINT_MAX) {
1451 ret = EFAULT;
1452 goto label_return;
1453 }
1454 tcaches_destroy(tsd, tcache_ind);
1455
1456 ret = 0;
1457label_return:
1458 return (ret);
1459}
1460
1461/******************************************************************************/
1462
Jason Evansdc2125c2017-01-04 10:21:53 -08001463static int
1464arena_i_initialized_ctl(tsd_t *tsd, const size_t *mib, size_t miblen,
1465 void *oldp, size_t *oldlenp, void *newp, size_t newlen)
1466{
1467 int ret;
1468 tsdn_t *tsdn = tsd_tsdn(tsd);
1469 unsigned arena_ind;
1470 bool initialized;
1471
1472 READONLY();
1473 MIB_UNSIGNED(arena_ind, 1);
1474
1475 malloc_mutex_lock(tsdn, &ctl_mtx);
1476 initialized = stats_arenas_i(arena_ind)->initialized;
1477 malloc_mutex_unlock(tsdn, &ctl_mtx);
1478
1479 READ(initialized, bool);
1480
1481 ret = 0;
1482label_return:
1483 return (ret);
1484}
1485
Jason Evans34457f52012-11-03 21:18:28 -07001486static void
Jason Evansc1e00ef2016-05-10 22:21:10 -07001487arena_i_purge(tsdn_t *tsdn, unsigned arena_ind, bool all)
Jason Evans609ae592012-10-11 13:53:15 -07001488{
Jason Evans609ae592012-10-11 13:53:15 -07001489
Jason Evansc1e00ef2016-05-10 22:21:10 -07001490 malloc_mutex_lock(tsdn, &ctl_mtx);
Jason Evans243f7a02016-02-19 20:09:31 -08001491 {
Jason Evansd778dd22017-01-03 12:40:54 -08001492 unsigned narenas = ctl_stats->narenas;
Jason Evans609ae592012-10-11 13:53:15 -07001493
Jason Evans3dc4e832017-01-03 07:27:42 -08001494 /*
1495 * Access via index narenas is deprecated, and scheduled for
1496 * removal in 6.0.0.
1497 */
1498 if (arena_ind == MALLCTL_ARENAS_ALL || arena_ind == narenas) {
Jason Evans243f7a02016-02-19 20:09:31 -08001499 unsigned i;
Jason Evans243f7a02016-02-19 20:09:31 -08001500 VARIABLE_ARRAY(arena_t *, tarenas, narenas);
1501
Jason Evans767d8502016-02-24 23:58:10 -08001502 for (i = 0; i < narenas; i++)
Jason Evansc1e00ef2016-05-10 22:21:10 -07001503 tarenas[i] = arena_get(tsdn, i, false);
Jason Evans243f7a02016-02-19 20:09:31 -08001504
1505 /*
1506 * No further need to hold ctl_mtx, since narenas and
1507 * tarenas contain everything needed below.
1508 */
Jason Evansc1e00ef2016-05-10 22:21:10 -07001509 malloc_mutex_unlock(tsdn, &ctl_mtx);
Jason Evans243f7a02016-02-19 20:09:31 -08001510
1511 for (i = 0; i < narenas; i++) {
1512 if (tarenas[i] != NULL)
Jason Evansc1e00ef2016-05-10 22:21:10 -07001513 arena_purge(tsdn, tarenas[i], all);
Jason Evans243f7a02016-02-19 20:09:31 -08001514 }
1515 } else {
1516 arena_t *tarena;
1517
1518 assert(arena_ind < narenas);
1519
Jason Evansc1e00ef2016-05-10 22:21:10 -07001520 tarena = arena_get(tsdn, arena_ind, false);
Jason Evans243f7a02016-02-19 20:09:31 -08001521
1522 /* No further need to hold ctl_mtx. */
Jason Evansc1e00ef2016-05-10 22:21:10 -07001523 malloc_mutex_unlock(tsdn, &ctl_mtx);
Jason Evans243f7a02016-02-19 20:09:31 -08001524
1525 if (tarena != NULL)
Jason Evansc1e00ef2016-05-10 22:21:10 -07001526 arena_purge(tsdn, tarena, all);
Jason Evans609ae592012-10-11 13:53:15 -07001527 }
1528 }
Jason Evans609ae592012-10-11 13:53:15 -07001529}
1530
1531static int
Jason Evansb2c0d632016-04-13 23:36:15 -07001532arena_i_purge_ctl(tsd_t *tsd, const size_t *mib, size_t miblen, void *oldp,
1533 size_t *oldlenp, void *newp, size_t newlen)
Jason Evans609ae592012-10-11 13:53:15 -07001534{
1535 int ret;
Jason Evans6edbedd2017-01-04 07:51:49 -08001536 unsigned arena_ind;
Jason Evans609ae592012-10-11 13:53:15 -07001537
1538 READONLY();
1539 WRITEONLY();
Jason Evans6edbedd2017-01-04 07:51:49 -08001540 MIB_UNSIGNED(arena_ind, 1);
1541 arena_i_purge(tsd_tsdn(tsd), arena_ind, true);
Jason Evans243f7a02016-02-19 20:09:31 -08001542
1543 ret = 0;
1544label_return:
1545 return (ret);
1546}
1547
1548static int
Jason Evansb2c0d632016-04-13 23:36:15 -07001549arena_i_decay_ctl(tsd_t *tsd, const size_t *mib, size_t miblen, void *oldp,
1550 size_t *oldlenp, void *newp, size_t newlen)
Jason Evans243f7a02016-02-19 20:09:31 -08001551{
1552 int ret;
Jason Evans6edbedd2017-01-04 07:51:49 -08001553 unsigned arena_ind;
Jason Evans243f7a02016-02-19 20:09:31 -08001554
1555 READONLY();
1556 WRITEONLY();
Jason Evans6edbedd2017-01-04 07:51:49 -08001557 MIB_UNSIGNED(arena_ind, 1);
1558 arena_i_purge(tsd_tsdn(tsd), arena_ind, false);
Jason Evans609ae592012-10-11 13:53:15 -07001559
Jason Evans34457f52012-11-03 21:18:28 -07001560 ret = 0;
Jason Evans609ae592012-10-11 13:53:15 -07001561label_return:
1562 return (ret);
1563}
1564
1565static int
Jason Evans19ff2ce2016-04-22 14:37:17 -07001566arena_i_reset_ctl(tsd_t *tsd, const size_t *mib, size_t miblen, void *oldp,
1567 size_t *oldlenp, void *newp, size_t newlen)
1568{
1569 int ret;
1570 unsigned arena_ind;
1571 arena_t *arena;
1572
1573 READONLY();
1574 WRITEONLY();
Jason Evans6edbedd2017-01-04 07:51:49 -08001575 MIB_UNSIGNED(arena_ind, 1);
Jason Evans19ff2ce2016-04-22 14:37:17 -07001576
Jason Evans19ff2ce2016-04-22 14:37:17 -07001577 if (config_debug) {
Jason Evansc1e00ef2016-05-10 22:21:10 -07001578 malloc_mutex_lock(tsd_tsdn(tsd), &ctl_mtx);
Jason Evansd778dd22017-01-03 12:40:54 -08001579 assert(arena_ind < ctl_stats->narenas);
Jason Evansc1e00ef2016-05-10 22:21:10 -07001580 malloc_mutex_unlock(tsd_tsdn(tsd), &ctl_mtx);
Jason Evans19ff2ce2016-04-22 14:37:17 -07001581 }
1582 assert(arena_ind >= opt_narenas);
1583
Jason Evansc1e00ef2016-05-10 22:21:10 -07001584 arena = arena_get(tsd_tsdn(tsd), arena_ind, false);
Jason Evans3dc4e832017-01-03 07:27:42 -08001585 if (arena == NULL) {
1586 ret = EFAULT;
1587 goto label_return;
1588 }
Jason Evans19ff2ce2016-04-22 14:37:17 -07001589
1590 arena_reset(tsd, arena);
1591
1592 ret = 0;
1593label_return:
1594 return (ret);
1595}
1596
1597static int
Jason Evansb2c0d632016-04-13 23:36:15 -07001598arena_i_dss_ctl(tsd_t *tsd, const size_t *mib, size_t miblen, void *oldp,
1599 size_t *oldlenp, void *newp, size_t newlen)
Jason Evans609ae592012-10-11 13:53:15 -07001600{
Jason Evans586c8ed2014-08-15 12:20:20 -07001601 int ret;
1602 const char *dss = NULL;
Jason Evans6edbedd2017-01-04 07:51:49 -08001603 unsigned arena_ind;
Jason Evans609ae592012-10-11 13:53:15 -07001604 dss_prec_t dss_prec_old = dss_prec_limit;
1605 dss_prec_t dss_prec = dss_prec_limit;
1606
Jason Evansc1e00ef2016-05-10 22:21:10 -07001607 malloc_mutex_lock(tsd_tsdn(tsd), &ctl_mtx);
Jason Evans609ae592012-10-11 13:53:15 -07001608 WRITE(dss, const char *);
Jason Evans6edbedd2017-01-04 07:51:49 -08001609 MIB_UNSIGNED(arena_ind, 1);
Jason Evans586c8ed2014-08-15 12:20:20 -07001610 if (dss != NULL) {
1611 int i;
1612 bool match = false;
1613
1614 for (i = 0; i < dss_prec_limit; i++) {
1615 if (strcmp(dss_prec_names[i], dss) == 0) {
1616 dss_prec = i;
1617 match = true;
1618 break;
1619 }
Jason Evans609ae592012-10-11 13:53:15 -07001620 }
Jason Evans586c8ed2014-08-15 12:20:20 -07001621
Jason Evans551ebc42014-10-03 10:16:09 -07001622 if (!match) {
Jason Evans586c8ed2014-08-15 12:20:20 -07001623 ret = EINVAL;
1624 goto label_return;
1625 }
Jason Evans609ae592012-10-11 13:53:15 -07001626 }
1627
Jason Evans3dc4e832017-01-03 07:27:42 -08001628 /*
1629 * Access via index narenas is deprecated, and scheduled for removal in
1630 * 6.0.0.
1631 */
Jason Evansd778dd22017-01-03 12:40:54 -08001632 if (arena_ind == MALLCTL_ARENAS_ALL || arena_ind ==
1633 ctl_stats->narenas) {
Jason Evans3dc4e832017-01-03 07:27:42 -08001634 if (dss_prec != dss_prec_limit &&
1635 extent_dss_prec_set(dss_prec)) {
1636 ret = EFAULT;
1637 goto label_return;
1638 }
1639 dss_prec_old = extent_dss_prec_get();
1640 } else {
Jason Evansc1e00ef2016-05-10 22:21:10 -07001641 arena_t *arena = arena_get(tsd_tsdn(tsd), arena_ind, false);
Jason Evans586c8ed2014-08-15 12:20:20 -07001642 if (arena == NULL || (dss_prec != dss_prec_limit &&
Jason Evansc1e00ef2016-05-10 22:21:10 -07001643 arena_dss_prec_set(tsd_tsdn(tsd), arena, dss_prec))) {
Jason Evans586c8ed2014-08-15 12:20:20 -07001644 ret = EFAULT;
1645 goto label_return;
1646 }
Jason Evansc1e00ef2016-05-10 22:21:10 -07001647 dss_prec_old = arena_dss_prec_get(tsd_tsdn(tsd), arena);
Jason Evans609ae592012-10-11 13:53:15 -07001648 }
Jason Evans586c8ed2014-08-15 12:20:20 -07001649
Jason Evans609ae592012-10-11 13:53:15 -07001650 dss = dss_prec_names[dss_prec_old];
1651 READ(dss, const char *);
Jason Evans609ae592012-10-11 13:53:15 -07001652
1653 ret = 0;
1654label_return:
Jason Evansc1e00ef2016-05-10 22:21:10 -07001655 malloc_mutex_unlock(tsd_tsdn(tsd), &ctl_mtx);
Jason Evans609ae592012-10-11 13:53:15 -07001656 return (ret);
1657}
1658
aravindfb7fe502014-05-05 15:16:56 -07001659static int
Jason Evansb2c0d632016-04-13 23:36:15 -07001660arena_i_decay_time_ctl(tsd_t *tsd, const size_t *mib, size_t miblen, void *oldp,
Jason Evans243f7a02016-02-19 20:09:31 -08001661 size_t *oldlenp, void *newp, size_t newlen)
1662{
1663 int ret;
Jason Evans6edbedd2017-01-04 07:51:49 -08001664 unsigned arena_ind;
Jason Evans243f7a02016-02-19 20:09:31 -08001665 arena_t *arena;
1666
Jason Evans6edbedd2017-01-04 07:51:49 -08001667 MIB_UNSIGNED(arena_ind, 1);
Jason Evansc1e00ef2016-05-10 22:21:10 -07001668 arena = arena_get(tsd_tsdn(tsd), arena_ind, false);
Jason Evans243f7a02016-02-19 20:09:31 -08001669 if (arena == NULL) {
1670 ret = EFAULT;
1671 goto label_return;
1672 }
1673
1674 if (oldp != NULL && oldlenp != NULL) {
Jason Evansc1e00ef2016-05-10 22:21:10 -07001675 size_t oldval = arena_decay_time_get(tsd_tsdn(tsd), arena);
Jason Evans243f7a02016-02-19 20:09:31 -08001676 READ(oldval, ssize_t);
1677 }
1678 if (newp != NULL) {
1679 if (newlen != sizeof(ssize_t)) {
1680 ret = EINVAL;
1681 goto label_return;
1682 }
Jason Evansc1e00ef2016-05-10 22:21:10 -07001683 if (arena_decay_time_set(tsd_tsdn(tsd), arena,
1684 *(ssize_t *)newp)) {
Jason Evans243f7a02016-02-19 20:09:31 -08001685 ret = EFAULT;
1686 goto label_return;
1687 }
1688 }
1689
1690 ret = 0;
1691label_return:
1692 return (ret);
1693}
1694
1695static int
Jason Evans9c305c92016-05-31 15:03:51 -07001696arena_i_extent_hooks_ctl(tsd_t *tsd, const size_t *mib, size_t miblen,
Jason Evansb2c0d632016-04-13 23:36:15 -07001697 void *oldp, size_t *oldlenp, void *newp, size_t newlen)
Jason Evansb49a3342015-07-28 11:28:19 -04001698{
1699 int ret;
Jason Evans6edbedd2017-01-04 07:51:49 -08001700 unsigned arena_ind;
Jason Evansb49a3342015-07-28 11:28:19 -04001701 arena_t *arena;
1702
Jason Evansc1e00ef2016-05-10 22:21:10 -07001703 malloc_mutex_lock(tsd_tsdn(tsd), &ctl_mtx);
Jason Evans6edbedd2017-01-04 07:51:49 -08001704 MIB_UNSIGNED(arena_ind, 1);
Jason Evansb49a3342015-07-28 11:28:19 -04001705 if (arena_ind < narenas_total_get() && (arena =
Jason Evansc1e00ef2016-05-10 22:21:10 -07001706 arena_get(tsd_tsdn(tsd), arena_ind, false)) != NULL) {
Jason Evansb49a3342015-07-28 11:28:19 -04001707 if (newp != NULL) {
Jason Evansf02fec82016-06-03 19:39:14 -07001708 extent_hooks_t *old_extent_hooks;
1709 extent_hooks_t *new_extent_hooks
1710 JEMALLOC_CC_SILENCE_INIT(NULL);
Jason Evansf8f05422016-06-03 12:05:53 -07001711 WRITE(new_extent_hooks, extent_hooks_t *);
1712 old_extent_hooks = extent_hooks_set(arena,
1713 new_extent_hooks);
1714 READ(old_extent_hooks, extent_hooks_t *);
Jason Evansb49a3342015-07-28 11:28:19 -04001715 } else {
Jason Evansf8f05422016-06-03 12:05:53 -07001716 extent_hooks_t *old_extent_hooks =
1717 extent_hooks_get(arena);
1718 READ(old_extent_hooks, extent_hooks_t *);
Jason Evansb49a3342015-07-28 11:28:19 -04001719 }
1720 } else {
1721 ret = EFAULT;
1722 goto label_return;
1723 }
1724 ret = 0;
1725label_return:
Jason Evansc1e00ef2016-05-10 22:21:10 -07001726 malloc_mutex_unlock(tsd_tsdn(tsd), &ctl_mtx);
Jason Evansb49a3342015-07-28 11:28:19 -04001727 return (ret);
aravindfb7fe502014-05-05 15:16:56 -07001728}
1729
Jason Evans609ae592012-10-11 13:53:15 -07001730static const ctl_named_node_t *
Jason Evansc1e00ef2016-05-10 22:21:10 -07001731arena_i_index(tsdn_t *tsdn, const size_t *mib, size_t miblen, size_t i)
Jason Evans609ae592012-10-11 13:53:15 -07001732{
Jason Evansb2c0d632016-04-13 23:36:15 -07001733 const ctl_named_node_t *ret;
Jason Evans609ae592012-10-11 13:53:15 -07001734
Jason Evansc1e00ef2016-05-10 22:21:10 -07001735 malloc_mutex_lock(tsdn, &ctl_mtx);
Jason Evansd778dd22017-01-03 12:40:54 -08001736 if (i > ctl_stats->narenas && i != MALLCTL_ARENAS_ALL) {
Jason Evans609ae592012-10-11 13:53:15 -07001737 ret = NULL;
1738 goto label_return;
1739 }
1740
1741 ret = super_arena_i_node;
1742label_return:
Jason Evansc1e00ef2016-05-10 22:21:10 -07001743 malloc_mutex_unlock(tsdn, &ctl_mtx);
Jason Evans609ae592012-10-11 13:53:15 -07001744 return (ret);
1745}
1746
Jason Evans609ae592012-10-11 13:53:15 -07001747/******************************************************************************/
1748
Jason Evans609ae592012-10-11 13:53:15 -07001749static int
Jason Evansb2c0d632016-04-13 23:36:15 -07001750arenas_narenas_ctl(tsd_t *tsd, const size_t *mib, size_t miblen, void *oldp,
Jason Evans609ae592012-10-11 13:53:15 -07001751 size_t *oldlenp, void *newp, size_t newlen)
1752{
1753 int ret;
1754 unsigned narenas;
1755
Jason Evansc1e00ef2016-05-10 22:21:10 -07001756 malloc_mutex_lock(tsd_tsdn(tsd), &ctl_mtx);
Jason Evans609ae592012-10-11 13:53:15 -07001757 READONLY();
1758 if (*oldlenp != sizeof(unsigned)) {
1759 ret = EINVAL;
1760 goto label_return;
1761 }
Jason Evansd778dd22017-01-03 12:40:54 -08001762 narenas = ctl_stats->narenas;
Jason Evans609ae592012-10-11 13:53:15 -07001763 READ(narenas, unsigned);
1764
1765 ret = 0;
1766label_return:
Jason Evansc1e00ef2016-05-10 22:21:10 -07001767 malloc_mutex_unlock(tsd_tsdn(tsd), &ctl_mtx);
Jason Evans609ae592012-10-11 13:53:15 -07001768 return (ret);
1769}
Jason Evans3c234352010-01-27 13:10:55 -08001770
1771static int
Jason Evansb2c0d632016-04-13 23:36:15 -07001772arenas_decay_time_ctl(tsd_t *tsd, const size_t *mib, size_t miblen, void *oldp,
Jason Evans243f7a02016-02-19 20:09:31 -08001773 size_t *oldlenp, void *newp, size_t newlen)
1774{
1775 int ret;
1776
1777 if (oldp != NULL && oldlenp != NULL) {
1778 size_t oldval = arena_decay_time_default_get();
1779 READ(oldval, ssize_t);
1780 }
1781 if (newp != NULL) {
1782 if (newlen != sizeof(ssize_t)) {
1783 ret = EINVAL;
1784 goto label_return;
1785 }
1786 if (arena_decay_time_default_set(*(ssize_t *)newp)) {
1787 ret = EFAULT;
1788 goto label_return;
1789 }
1790 }
1791
1792 ret = 0;
1793label_return:
1794 return (ret);
1795}
1796
Jason Evansfc4dcfa2010-11-24 15:44:21 -08001797CTL_RO_NL_GEN(arenas_quantum, QUANTUM, size_t)
Jason Evansae4c7b42012-04-02 07:04:34 -07001798CTL_RO_NL_GEN(arenas_page, PAGE, size_t)
Jason Evans7372b152012-02-10 20:22:09 -08001799CTL_RO_NL_CGEN(config_tcache, arenas_tcache_max, tcache_maxclass, size_t)
Jason Evansb1726102012-02-28 16:50:47 -08001800CTL_RO_NL_GEN(arenas_nbins, NBINS, unsigned)
Jason Evans7372b152012-02-10 20:22:09 -08001801CTL_RO_NL_CGEN(config_tcache, arenas_nhbins, nhbins, unsigned)
Jason Evansd8a39002013-12-19 21:40:41 -08001802CTL_RO_NL_GEN(arenas_bin_i_size, arena_bin_info[mib[2]].reg_size, size_t)
1803CTL_RO_NL_GEN(arenas_bin_i_nregs, arena_bin_info[mib[2]].nregs, uint32_t)
Jason Evans498856f2016-05-29 18:34:50 -07001804CTL_RO_NL_GEN(arenas_bin_i_slab_size, arena_bin_info[mib[2]].slab_size, size_t)
Jason Evansd8a39002013-12-19 21:40:41 -08001805static const ctl_named_node_t *
Jason Evansc1e00ef2016-05-10 22:21:10 -07001806arenas_bin_i_index(tsdn_t *tsdn, const size_t *mib, size_t miblen, size_t i)
Jason Evansd8a39002013-12-19 21:40:41 -08001807{
1808
1809 if (i > NBINS)
1810 return (NULL);
1811 return (super_arenas_bin_i_node);
1812}
1813
Jason Evans7d63fed2016-05-31 14:50:21 -07001814CTL_RO_NL_GEN(arenas_nlextents, NSIZES - NBINS, unsigned)
1815CTL_RO_NL_GEN(arenas_lextent_i_size, index2size(NBINS+(szind_t)mib[2]), size_t)
Jason Evans3c4d92e2014-10-12 22:53:59 -07001816static const ctl_named_node_t *
Jason Evans7d63fed2016-05-31 14:50:21 -07001817arenas_lextent_i_index(tsdn_t *tsdn, const size_t *mib, size_t miblen, size_t i)
Jason Evans3c4d92e2014-10-12 22:53:59 -07001818{
1819
Jason Evansed2c2422016-05-28 00:17:28 -07001820 if (i > NSIZES - NBINS)
Jason Evans3c4d92e2014-10-12 22:53:59 -07001821 return (NULL);
Jason Evans7d63fed2016-05-31 14:50:21 -07001822 return (super_arenas_lextent_i_node);
Jason Evans3c4d92e2014-10-12 22:53:59 -07001823}
1824
Jason Evans6005f072010-09-30 16:55:08 -07001825static int
Jason Evans0f04bb12017-01-03 08:21:29 -08001826arenas_create_ctl(tsd_t *tsd, const size_t *mib, size_t miblen, void *oldp,
Jason Evansb2c0d632016-04-13 23:36:15 -07001827 size_t *oldlenp, void *newp, size_t newlen)
Jason Evans609ae592012-10-11 13:53:15 -07001828{
1829 int ret;
Jason Evansa0dd3a42016-12-22 16:39:10 -06001830 extent_hooks_t *extent_hooks;
Jason Evans6eb84fb2012-11-29 22:13:04 -08001831 unsigned narenas;
Jason Evans609ae592012-10-11 13:53:15 -07001832
Jason Evansc1e00ef2016-05-10 22:21:10 -07001833 malloc_mutex_lock(tsd_tsdn(tsd), &ctl_mtx);
Jason Evansa0dd3a42016-12-22 16:39:10 -06001834
1835 extent_hooks = (extent_hooks_t *)&extent_hooks_default;
1836 WRITE(extent_hooks, extent_hooks_t *);
1837 if (ctl_grow(tsd_tsdn(tsd), extent_hooks)) {
Jason Evans609ae592012-10-11 13:53:15 -07001838 ret = EAGAIN;
1839 goto label_return;
1840 }
Jason Evansd778dd22017-01-03 12:40:54 -08001841 narenas = ctl_stats->narenas - 1;
Jason Evans6eb84fb2012-11-29 22:13:04 -08001842 READ(narenas, unsigned);
Jason Evans609ae592012-10-11 13:53:15 -07001843
Jason Evans6005f072010-09-30 16:55:08 -07001844 ret = 0;
Jason Evansa1ee7832012-04-10 15:07:44 -07001845label_return:
Jason Evansc1e00ef2016-05-10 22:21:10 -07001846 malloc_mutex_unlock(tsd_tsdn(tsd), &ctl_mtx);
Jason Evans6005f072010-09-30 16:55:08 -07001847 return (ret);
1848}
1849
Jason Evans3c234352010-01-27 13:10:55 -08001850/******************************************************************************/
1851
Jason Evansd34f9e72010-02-11 13:19:21 -08001852static int
Jason Evansb2c0d632016-04-13 23:36:15 -07001853prof_thread_active_init_ctl(tsd_t *tsd, const size_t *mib, size_t miblen,
1854 void *oldp, size_t *oldlenp, void *newp, size_t newlen)
1855{
1856 int ret;
1857 bool oldval;
1858
1859 if (!config_prof)
1860 return (ENOENT);
1861
1862 if (newp != NULL) {
1863 if (newlen != sizeof(bool)) {
1864 ret = EINVAL;
1865 goto label_return;
1866 }
Jason Evansc1e00ef2016-05-10 22:21:10 -07001867 oldval = prof_thread_active_init_set(tsd_tsdn(tsd),
1868 *(bool *)newp);
Jason Evansb2c0d632016-04-13 23:36:15 -07001869 } else
Jason Evansc1e00ef2016-05-10 22:21:10 -07001870 oldval = prof_thread_active_init_get(tsd_tsdn(tsd));
Jason Evansb2c0d632016-04-13 23:36:15 -07001871 READ(oldval, bool);
1872
1873 ret = 0;
1874label_return:
1875 return (ret);
1876}
1877
1878static int
1879prof_active_ctl(tsd_t *tsd, const size_t *mib, size_t miblen, void *oldp,
Jason Evansfc12c0b2014-10-03 23:25:30 -07001880 size_t *oldlenp, void *newp, size_t newlen)
1881{
1882 int ret;
1883 bool oldval;
1884
1885 if (!config_prof)
1886 return (ENOENT);
1887
1888 if (newp != NULL) {
1889 if (newlen != sizeof(bool)) {
1890 ret = EINVAL;
1891 goto label_return;
1892 }
Jason Evansc1e00ef2016-05-10 22:21:10 -07001893 oldval = prof_active_set(tsd_tsdn(tsd), *(bool *)newp);
Jason Evansfc12c0b2014-10-03 23:25:30 -07001894 } else
Jason Evansc1e00ef2016-05-10 22:21:10 -07001895 oldval = prof_active_get(tsd_tsdn(tsd));
Jason Evansfc12c0b2014-10-03 23:25:30 -07001896 READ(oldval, bool);
1897
1898 ret = 0;
1899label_return:
1900 return (ret);
1901}
1902
1903static int
Jason Evansb2c0d632016-04-13 23:36:15 -07001904prof_dump_ctl(tsd_t *tsd, const size_t *mib, size_t miblen, void *oldp,
1905 size_t *oldlenp, void *newp, size_t newlen)
Jason Evansd34f9e72010-02-11 13:19:21 -08001906{
1907 int ret;
Jason Evans22ca8552010-03-02 11:57:30 -08001908 const char *filename = NULL;
Jason Evansd34f9e72010-02-11 13:19:21 -08001909
Jason Evans551ebc42014-10-03 10:16:09 -07001910 if (!config_prof)
Jason Evans7372b152012-02-10 20:22:09 -08001911 return (ENOENT);
1912
Jason Evans22ca8552010-03-02 11:57:30 -08001913 WRITEONLY();
1914 WRITE(filename, const char *);
Jason Evansd34f9e72010-02-11 13:19:21 -08001915
Jason Evansb2c0d632016-04-13 23:36:15 -07001916 if (prof_mdump(tsd, filename)) {
Jason Evans22ca8552010-03-02 11:57:30 -08001917 ret = EFAULT;
Jason Evansa1ee7832012-04-10 15:07:44 -07001918 goto label_return;
Jason Evans22ca8552010-03-02 11:57:30 -08001919 }
Jason Evansd34f9e72010-02-11 13:19:21 -08001920
1921 ret = 0;
Jason Evansa1ee7832012-04-10 15:07:44 -07001922label_return:
Jason Evansd34f9e72010-02-11 13:19:21 -08001923 return (ret);
1924}
1925
Jason Evans602c8e02014-08-18 16:22:13 -07001926static int
Jason Evansb2c0d632016-04-13 23:36:15 -07001927prof_gdump_ctl(tsd_t *tsd, const size_t *mib, size_t miblen, void *oldp,
1928 size_t *oldlenp, void *newp, size_t newlen)
Jason Evans5b8ed5b2015-01-25 21:16:57 -08001929{
1930 int ret;
1931 bool oldval;
1932
1933 if (!config_prof)
1934 return (ENOENT);
1935
1936 if (newp != NULL) {
1937 if (newlen != sizeof(bool)) {
1938 ret = EINVAL;
1939 goto label_return;
1940 }
Jason Evansc1e00ef2016-05-10 22:21:10 -07001941 oldval = prof_gdump_set(tsd_tsdn(tsd), *(bool *)newp);
Jason Evans5b8ed5b2015-01-25 21:16:57 -08001942 } else
Jason Evansc1e00ef2016-05-10 22:21:10 -07001943 oldval = prof_gdump_get(tsd_tsdn(tsd));
Jason Evans5b8ed5b2015-01-25 21:16:57 -08001944 READ(oldval, bool);
1945
1946 ret = 0;
1947label_return:
1948 return (ret);
1949}
1950
1951static int
Jason Evansb2c0d632016-04-13 23:36:15 -07001952prof_reset_ctl(tsd_t *tsd, const size_t *mib, size_t miblen, void *oldp,
1953 size_t *oldlenp, void *newp, size_t newlen)
Jason Evans602c8e02014-08-18 16:22:13 -07001954{
1955 int ret;
1956 size_t lg_sample = lg_prof_sample;
1957
Jason Evans551ebc42014-10-03 10:16:09 -07001958 if (!config_prof)
Jason Evans602c8e02014-08-18 16:22:13 -07001959 return (ENOENT);
1960
1961 WRITEONLY();
1962 WRITE(lg_sample, size_t);
1963 if (lg_sample >= (sizeof(uint64_t) << 3))
1964 lg_sample = (sizeof(uint64_t) << 3) - 1;
1965
Jason Evansb54d1602016-10-20 23:59:12 -07001966 prof_reset(tsd, lg_sample);
Jason Evans602c8e02014-08-18 16:22:13 -07001967
1968 ret = 0;
1969label_return:
1970 return (ret);
1971}
1972
Jason Evans7372b152012-02-10 20:22:09 -08001973CTL_RO_NL_CGEN(config_prof, prof_interval, prof_interval, uint64_t)
Jason Evans602c8e02014-08-18 16:22:13 -07001974CTL_RO_NL_CGEN(config_prof, lg_prof_sample, lg_prof_sample, size_t)
Jason Evansd34f9e72010-02-11 13:19:21 -08001975
1976/******************************************************************************/
1977
Jason Evansd778dd22017-01-03 12:40:54 -08001978CTL_RO_CGEN(config_stats, stats_allocated, ctl_stats->allocated, size_t)
1979CTL_RO_CGEN(config_stats, stats_active, ctl_stats->active, size_t)
1980CTL_RO_CGEN(config_stats, stats_metadata, ctl_stats->metadata, size_t)
1981CTL_RO_CGEN(config_stats, stats_resident, ctl_stats->resident, size_t)
1982CTL_RO_CGEN(config_stats, stats_mapped, ctl_stats->mapped, size_t)
1983CTL_RO_CGEN(config_stats, stats_retained, ctl_stats->retained, size_t)
Jason Evansd8a39002013-12-19 21:40:41 -08001984
Jason Evans3dc4e832017-01-03 07:27:42 -08001985CTL_RO_GEN(stats_arenas_i_dss, stats_arenas_i(mib[2])->dss, const char *)
1986CTL_RO_GEN(stats_arenas_i_decay_time, stats_arenas_i(mib[2])->decay_time,
Jason Evans243f7a02016-02-19 20:09:31 -08001987 ssize_t)
Jason Evans3dc4e832017-01-03 07:27:42 -08001988CTL_RO_GEN(stats_arenas_i_nthreads, stats_arenas_i(mib[2])->nthreads,
1989 unsigned)
1990CTL_RO_GEN(stats_arenas_i_pactive, stats_arenas_i(mib[2])->pactive, size_t)
1991CTL_RO_GEN(stats_arenas_i_pdirty, stats_arenas_i(mib[2])->pdirty, size_t)
Jason Evansd8a39002013-12-19 21:40:41 -08001992CTL_RO_CGEN(config_stats, stats_arenas_i_mapped,
Jason Evans3dc4e832017-01-03 07:27:42 -08001993 stats_arenas_i(mib[2])->astats.mapped, size_t)
Jason Evans04c3c0f2016-05-03 22:11:35 -07001994CTL_RO_CGEN(config_stats, stats_arenas_i_retained,
Jason Evans3dc4e832017-01-03 07:27:42 -08001995 stats_arenas_i(mib[2])->astats.retained, size_t)
Jason Evansd8a39002013-12-19 21:40:41 -08001996CTL_RO_CGEN(config_stats, stats_arenas_i_npurge,
Jason Evans3dc4e832017-01-03 07:27:42 -08001997 stats_arenas_i(mib[2])->astats.npurge, uint64_t)
Jason Evansd8a39002013-12-19 21:40:41 -08001998CTL_RO_CGEN(config_stats, stats_arenas_i_nmadvise,
Jason Evans3dc4e832017-01-03 07:27:42 -08001999 stats_arenas_i(mib[2])->astats.nmadvise, uint64_t)
Jason Evansd8a39002013-12-19 21:40:41 -08002000CTL_RO_CGEN(config_stats, stats_arenas_i_purged,
Jason Evans3dc4e832017-01-03 07:27:42 -08002001 stats_arenas_i(mib[2])->astats.purged, uint64_t)
Jason Evansa0dd3a42016-12-22 16:39:10 -06002002CTL_RO_CGEN(config_stats, stats_arenas_i_base,
Jason Evans3dc4e832017-01-03 07:27:42 -08002003 stats_arenas_i(mib[2])->astats.base, size_t)
Jason Evansa0dd3a42016-12-22 16:39:10 -06002004CTL_RO_CGEN(config_stats, stats_arenas_i_internal,
Jason Evans3dc4e832017-01-03 07:27:42 -08002005 stats_arenas_i(mib[2])->astats.internal, size_t)
Jason Evansa0dd3a42016-12-22 16:39:10 -06002006CTL_RO_CGEN(config_stats, stats_arenas_i_resident,
Jason Evans3dc4e832017-01-03 07:27:42 -08002007 stats_arenas_i(mib[2])->astats.resident, size_t)
Jason Evansd8a39002013-12-19 21:40:41 -08002008
Jason Evans7372b152012-02-10 20:22:09 -08002009CTL_RO_CGEN(config_stats, stats_arenas_i_small_allocated,
Jason Evans3dc4e832017-01-03 07:27:42 -08002010 stats_arenas_i(mib[2])->allocated_small, size_t)
Jason Evans7372b152012-02-10 20:22:09 -08002011CTL_RO_CGEN(config_stats, stats_arenas_i_small_nmalloc,
Jason Evans3dc4e832017-01-03 07:27:42 -08002012 stats_arenas_i(mib[2])->nmalloc_small, uint64_t)
Jason Evans7372b152012-02-10 20:22:09 -08002013CTL_RO_CGEN(config_stats, stats_arenas_i_small_ndalloc,
Jason Evans3dc4e832017-01-03 07:27:42 -08002014 stats_arenas_i(mib[2])->ndalloc_small, uint64_t)
Jason Evans7372b152012-02-10 20:22:09 -08002015CTL_RO_CGEN(config_stats, stats_arenas_i_small_nrequests,
Jason Evans3dc4e832017-01-03 07:27:42 -08002016 stats_arenas_i(mib[2])->nrequests_small, uint64_t)
Jason Evans7d63fed2016-05-31 14:50:21 -07002017CTL_RO_CGEN(config_stats, stats_arenas_i_large_allocated,
Jason Evans3dc4e832017-01-03 07:27:42 -08002018 stats_arenas_i(mib[2])->astats.allocated_large, size_t)
Jason Evans7d63fed2016-05-31 14:50:21 -07002019CTL_RO_CGEN(config_stats, stats_arenas_i_large_nmalloc,
Jason Evans3dc4e832017-01-03 07:27:42 -08002020 stats_arenas_i(mib[2])->astats.nmalloc_large, uint64_t)
Jason Evans7d63fed2016-05-31 14:50:21 -07002021CTL_RO_CGEN(config_stats, stats_arenas_i_large_ndalloc,
Jason Evans3dc4e832017-01-03 07:27:42 -08002022 stats_arenas_i(mib[2])->astats.ndalloc_large, uint64_t)
Jason Evans7d63fed2016-05-31 14:50:21 -07002023CTL_RO_CGEN(config_stats, stats_arenas_i_large_nrequests,
Jason Evans3dc4e832017-01-03 07:27:42 -08002024 stats_arenas_i(mib[2])->astats.nmalloc_large, uint64_t) /* Intentional. */
Jason Evans3c234352010-01-27 13:10:55 -08002025
Jason Evans7372b152012-02-10 20:22:09 -08002026CTL_RO_CGEN(config_stats, stats_arenas_i_bins_j_nmalloc,
Jason Evans3dc4e832017-01-03 07:27:42 -08002027 stats_arenas_i(mib[2])->bstats[mib[4]].nmalloc, uint64_t)
Jason Evans7372b152012-02-10 20:22:09 -08002028CTL_RO_CGEN(config_stats, stats_arenas_i_bins_j_ndalloc,
Jason Evans3dc4e832017-01-03 07:27:42 -08002029 stats_arenas_i(mib[2])->bstats[mib[4]].ndalloc, uint64_t)
Jason Evans7372b152012-02-10 20:22:09 -08002030CTL_RO_CGEN(config_stats, stats_arenas_i_bins_j_nrequests,
Jason Evans3dc4e832017-01-03 07:27:42 -08002031 stats_arenas_i(mib[2])->bstats[mib[4]].nrequests, uint64_t)
Jason Evans3c4d92e2014-10-12 22:53:59 -07002032CTL_RO_CGEN(config_stats, stats_arenas_i_bins_j_curregs,
Jason Evans3dc4e832017-01-03 07:27:42 -08002033 stats_arenas_i(mib[2])->bstats[mib[4]].curregs, size_t)
Jason Evans7372b152012-02-10 20:22:09 -08002034CTL_RO_CGEN(config_stats && config_tcache, stats_arenas_i_bins_j_nfills,
Jason Evans3dc4e832017-01-03 07:27:42 -08002035 stats_arenas_i(mib[2])->bstats[mib[4]].nfills, uint64_t)
Jason Evans7372b152012-02-10 20:22:09 -08002036CTL_RO_CGEN(config_stats && config_tcache, stats_arenas_i_bins_j_nflushes,
Jason Evans3dc4e832017-01-03 07:27:42 -08002037 stats_arenas_i(mib[2])->bstats[mib[4]].nflushes, uint64_t)
Jason Evans498856f2016-05-29 18:34:50 -07002038CTL_RO_CGEN(config_stats, stats_arenas_i_bins_j_nslabs,
Jason Evans3dc4e832017-01-03 07:27:42 -08002039 stats_arenas_i(mib[2])->bstats[mib[4]].nslabs, uint64_t)
Jason Evans498856f2016-05-29 18:34:50 -07002040CTL_RO_CGEN(config_stats, stats_arenas_i_bins_j_nreslabs,
Jason Evans3dc4e832017-01-03 07:27:42 -08002041 stats_arenas_i(mib[2])->bstats[mib[4]].reslabs, uint64_t)
Jason Evans498856f2016-05-29 18:34:50 -07002042CTL_RO_CGEN(config_stats, stats_arenas_i_bins_j_curslabs,
Jason Evans3dc4e832017-01-03 07:27:42 -08002043 stats_arenas_i(mib[2])->bstats[mib[4]].curslabs, size_t)
Jason Evans3c234352010-01-27 13:10:55 -08002044
Jason Evans609ae592012-10-11 13:53:15 -07002045static const ctl_named_node_t *
Jason Evansc1e00ef2016-05-10 22:21:10 -07002046stats_arenas_i_bins_j_index(tsdn_t *tsdn, const size_t *mib, size_t miblen,
Jason Evansb2c0d632016-04-13 23:36:15 -07002047 size_t j)
Jason Evans3c234352010-01-27 13:10:55 -08002048{
2049
Jason Evansb1726102012-02-28 16:50:47 -08002050 if (j > NBINS)
Jason Evans3c234352010-01-27 13:10:55 -08002051 return (NULL);
2052 return (super_stats_arenas_i_bins_j_node);
2053}
2054
Jason Evans7d63fed2016-05-31 14:50:21 -07002055CTL_RO_CGEN(config_stats, stats_arenas_i_lextents_j_nmalloc,
Jason Evans3dc4e832017-01-03 07:27:42 -08002056 stats_arenas_i(mib[2])->lstats[mib[4]].nmalloc, uint64_t)
Jason Evans7d63fed2016-05-31 14:50:21 -07002057CTL_RO_CGEN(config_stats, stats_arenas_i_lextents_j_ndalloc,
Jason Evans3dc4e832017-01-03 07:27:42 -08002058 stats_arenas_i(mib[2])->lstats[mib[4]].ndalloc, uint64_t)
Jason Evans7d63fed2016-05-31 14:50:21 -07002059CTL_RO_CGEN(config_stats, stats_arenas_i_lextents_j_nrequests,
Jason Evans3dc4e832017-01-03 07:27:42 -08002060 stats_arenas_i(mib[2])->lstats[mib[4]].nrequests, uint64_t)
Jason Evans7d63fed2016-05-31 14:50:21 -07002061CTL_RO_CGEN(config_stats, stats_arenas_i_lextents_j_curlextents,
Jason Evans3dc4e832017-01-03 07:27:42 -08002062 stats_arenas_i(mib[2])->lstats[mib[4]].curlextents, size_t)
Jason Evans3c4d92e2014-10-12 22:53:59 -07002063
2064static const ctl_named_node_t *
Jason Evans7d63fed2016-05-31 14:50:21 -07002065stats_arenas_i_lextents_j_index(tsdn_t *tsdn, const size_t *mib, size_t miblen,
Jason Evansb2c0d632016-04-13 23:36:15 -07002066 size_t j)
Jason Evans3c4d92e2014-10-12 22:53:59 -07002067{
2068
Jason Evansed2c2422016-05-28 00:17:28 -07002069 if (j > NSIZES - NBINS)
Jason Evans3c4d92e2014-10-12 22:53:59 -07002070 return (NULL);
Jason Evans7d63fed2016-05-31 14:50:21 -07002071 return (super_stats_arenas_i_lextents_j_node);
Jason Evans3c4d92e2014-10-12 22:53:59 -07002072}
2073
Jason Evans609ae592012-10-11 13:53:15 -07002074static const ctl_named_node_t *
Jason Evansc1e00ef2016-05-10 22:21:10 -07002075stats_arenas_i_index(tsdn_t *tsdn, const size_t *mib, size_t miblen, size_t i)
Jason Evans3c234352010-01-27 13:10:55 -08002076{
Jason Evans3dc4e832017-01-03 07:27:42 -08002077 const ctl_named_node_t *ret;
2078 size_t a;
Jason Evans3c234352010-01-27 13:10:55 -08002079
Jason Evansc1e00ef2016-05-10 22:21:10 -07002080 malloc_mutex_lock(tsdn, &ctl_mtx);
Jason Evans3dc4e832017-01-03 07:27:42 -08002081 a = stats_arenas_i2a_impl(i, true, true);
Jason Evansd778dd22017-01-03 12:40:54 -08002082 if (a == UINT_MAX || !ctl_stats->arenas[a]->initialized) {
Jason Evansfc4dcfa2010-11-24 15:44:21 -08002083 ret = NULL;
Jason Evansa1ee7832012-04-10 15:07:44 -07002084 goto label_return;
Jason Evansfc4dcfa2010-11-24 15:44:21 -08002085 }
2086
2087 ret = super_stats_arenas_i_node;
Jason Evansa1ee7832012-04-10 15:07:44 -07002088label_return:
Jason Evansc1e00ef2016-05-10 22:21:10 -07002089 malloc_mutex_unlock(tsdn, &ctl_mtx);
Jason Evansfc4dcfa2010-11-24 15:44:21 -08002090 return (ret);
Jason Evans3c234352010-01-27 13:10:55 -08002091}