blob: 17bd0719735fbd264f8f3a0f891d84fc71323a63 [file] [log] [blame]
Jason Evans3c234352010-01-27 13:10:55 -08001#define JEMALLOC_CTL_C_
Jason Evans376b1522010-02-11 14:45:59 -08002#include "jemalloc/internal/jemalloc_internal.h"
Jason Evans3c234352010-01-27 13:10:55 -08003
4/******************************************************************************/
5/* Data. */
6
Jason Evansfc4dcfa2010-11-24 15:44:21 -08007/*
8 * ctl_mtx protects the following:
9 * - ctl_stats.*
Jason Evansfc4dcfa2010-11-24 15:44:21 -080010 */
Jason Evans3c234352010-01-27 13:10:55 -080011static malloc_mutex_t ctl_mtx;
12static bool ctl_initialized;
13static uint64_t ctl_epoch;
14static ctl_stats_t ctl_stats;
15
16/******************************************************************************/
Mike Hommey461ad5c2012-04-20 08:38:42 +020017/* Helpers for named and indexed nodes. */
18
Jason Evansaf1f5922014-10-30 16:38:08 -070019JEMALLOC_INLINE_C const ctl_named_node_t *
Mike Hommey461ad5c2012-04-20 08:38:42 +020020ctl_named_node(const ctl_node_t *node)
21{
22
23 return ((node->named) ? (const ctl_named_node_t *)node : NULL);
24}
25
Jason Evansaf1f5922014-10-30 16:38:08 -070026JEMALLOC_INLINE_C const ctl_named_node_t *
Christopher Ferrise4294032016-03-02 14:33:02 -080027ctl_named_children(const ctl_named_node_t *node, size_t index)
Mike Hommey461ad5c2012-04-20 08:38:42 +020028{
29 const ctl_named_node_t *children = ctl_named_node(node->children);
30
31 return (children ? &children[index] : NULL);
32}
33
Jason Evansaf1f5922014-10-30 16:38:08 -070034JEMALLOC_INLINE_C const ctl_indexed_node_t *
Mike Hommey461ad5c2012-04-20 08:38:42 +020035ctl_indexed_node(const ctl_node_t *node)
36{
37
Jason Evans551ebc42014-10-03 10:16:09 -070038 return (!node->named ? (const ctl_indexed_node_t *)node : NULL);
Mike Hommey461ad5c2012-04-20 08:38:42 +020039}
40
41/******************************************************************************/
Jason Evans3c234352010-01-27 13:10:55 -080042/* Function prototypes for non-inline static functions. */
43
44#define CTL_PROTO(n) \
45static int n##_ctl(const size_t *mib, size_t miblen, void *oldp, \
46 size_t *oldlenp, void *newp, size_t newlen);
47
48#define INDEX_PROTO(n) \
Jason Evans609ae592012-10-11 13:53:15 -070049static const ctl_named_node_t *n##_index(const size_t *mib, \
50 size_t miblen, size_t i);
Jason Evans3c234352010-01-27 13:10:55 -080051
Jason Evans3c234352010-01-27 13:10:55 -080052static bool ctl_arena_init(ctl_arena_stats_t *astats);
Jason Evans3c234352010-01-27 13:10:55 -080053static void ctl_arena_clear(ctl_arena_stats_t *astats);
Jason Evans86815df2010-03-13 20:32:56 -080054static void ctl_arena_stats_amerge(ctl_arena_stats_t *cstats,
55 arena_t *arena);
56static void ctl_arena_stats_smerge(ctl_arena_stats_t *sstats,
57 ctl_arena_stats_t *astats);
Jason Evans3c234352010-01-27 13:10:55 -080058static void ctl_arena_refresh(arena_t *arena, unsigned i);
Jason Evans609ae592012-10-11 13:53:15 -070059static bool ctl_grow(void);
Jason Evans3c234352010-01-27 13:10:55 -080060static void ctl_refresh(void);
61static bool ctl_init(void);
62static int ctl_lookup(const char *name, ctl_node_t const **nodesp,
63 size_t *mibp, size_t *depthp);
64
Jason Evansa40bc7a2010-03-02 13:01:16 -080065CTL_PROTO(version)
Jason Evans3c234352010-01-27 13:10:55 -080066CTL_PROTO(epoch)
Jason Evansd4be8b72012-03-26 18:54:44 -070067CTL_PROTO(thread_tcache_enabled)
Jason Evanse7b8fa12012-03-16 17:09:32 -070068CTL_PROTO(thread_tcache_flush)
Jason Evans602c8e02014-08-18 16:22:13 -070069CTL_PROTO(thread_prof_name)
70CTL_PROTO(thread_prof_active)
Jason Evansb267d0f2010-08-13 15:42:29 -070071CTL_PROTO(thread_arena)
Jason Evans93443682010-10-20 17:39:18 -070072CTL_PROTO(thread_allocated)
Jason Evansecf229a2010-12-03 15:55:47 -080073CTL_PROTO(thread_allocatedp)
Jason Evans93443682010-10-20 17:39:18 -070074CTL_PROTO(thread_deallocated)
Jason Evansecf229a2010-12-03 15:55:47 -080075CTL_PROTO(thread_deallocatedp)
Jason Evansf2bc8522015-07-17 16:38:25 -070076CTL_PROTO(config_cache_oblivious)
Jason Evans3c234352010-01-27 13:10:55 -080077CTL_PROTO(config_debug)
Jason Evans3c234352010-01-27 13:10:55 -080078CTL_PROTO(config_fill)
79CTL_PROTO(config_lazy_lock)
Christopher Ferrise4294032016-03-02 14:33:02 -080080CTL_PROTO(config_malloc_conf)
Jason Evans59ae2762012-04-16 17:52:27 -070081CTL_PROTO(config_munmap)
Jason Evansd34f9e72010-02-11 13:19:21 -080082CTL_PROTO(config_prof)
83CTL_PROTO(config_prof_libgcc)
84CTL_PROTO(config_prof_libunwind)
Jason Evans3c234352010-01-27 13:10:55 -080085CTL_PROTO(config_stats)
Jason Evans3c234352010-01-27 13:10:55 -080086CTL_PROTO(config_tcache)
Jason Evans3c234352010-01-27 13:10:55 -080087CTL_PROTO(config_tls)
Jason Evansb1476112012-04-05 13:36:17 -070088CTL_PROTO(config_utrace)
Jason Evans122449b2012-04-06 00:35:09 -070089CTL_PROTO(config_valgrind)
Jason Evans3c234352010-01-27 13:10:55 -080090CTL_PROTO(config_xmalloc)
91CTL_PROTO(opt_abort)
Jason Evans609ae592012-10-11 13:53:15 -070092CTL_PROTO(opt_dss)
Jason Evanse7339702010-10-23 18:37:06 -070093CTL_PROTO(opt_lg_chunk)
94CTL_PROTO(opt_narenas)
Christopher Ferrise4294032016-03-02 14:33:02 -080095CTL_PROTO(opt_purge)
Jason Evanse7339702010-10-23 18:37:06 -070096CTL_PROTO(opt_lg_dirty_mult)
Christopher Ferrise4294032016-03-02 14:33:02 -080097CTL_PROTO(opt_decay_time)
Jason Evanse7339702010-10-23 18:37:06 -070098CTL_PROTO(opt_stats_print)
Jason Evans3c234352010-01-27 13:10:55 -080099CTL_PROTO(opt_junk)
Jason Evanse7339702010-10-23 18:37:06 -0700100CTL_PROTO(opt_zero)
Jason Evans122449b2012-04-06 00:35:09 -0700101CTL_PROTO(opt_quarantine)
102CTL_PROTO(opt_redzone)
Jason Evansb1476112012-04-05 13:36:17 -0700103CTL_PROTO(opt_utrace)
Jason Evans3c234352010-01-27 13:10:55 -0800104CTL_PROTO(opt_xmalloc)
Jason Evans3fa9a2f2010-03-07 15:34:14 -0800105CTL_PROTO(opt_tcache)
Jason Evansf3ca7c82012-04-04 16:16:09 -0700106CTL_PROTO(opt_lg_tcache_max)
Jason Evansd34f9e72010-02-11 13:19:21 -0800107CTL_PROTO(opt_prof)
Jason Evanse7339702010-10-23 18:37:06 -0700108CTL_PROTO(opt_prof_prefix)
Jason Evansf18c9822010-03-31 18:43:24 -0700109CTL_PROTO(opt_prof_active)
Jason Evansfc12c0b2014-10-03 23:25:30 -0700110CTL_PROTO(opt_prof_thread_active_init)
Jason Evansb9477e72010-03-01 20:15:26 -0800111CTL_PROTO(opt_lg_prof_sample)
Jason Evansd34f9e72010-02-11 13:19:21 -0800112CTL_PROTO(opt_lg_prof_interval)
Jason Evanse7339702010-10-23 18:37:06 -0700113CTL_PROTO(opt_prof_gdump)
Jason Evans0b25fe72012-04-17 16:39:33 -0700114CTL_PROTO(opt_prof_final)
Jason Evansd34f9e72010-02-11 13:19:21 -0800115CTL_PROTO(opt_prof_leak)
Jason Evansa881cd22010-10-02 15:18:50 -0700116CTL_PROTO(opt_prof_accum)
Jason Evans1cb181e2015-01-29 15:30:47 -0800117CTL_PROTO(tcache_create)
118CTL_PROTO(tcache_flush)
119CTL_PROTO(tcache_destroy)
Christopher Ferrise4294032016-03-02 14:33:02 -0800120static void arena_i_purge(unsigned arena_ind, bool all);
Jason Evans609ae592012-10-11 13:53:15 -0700121CTL_PROTO(arena_i_purge)
Christopher Ferrise4294032016-03-02 14:33:02 -0800122CTL_PROTO(arena_i_decay)
Jason Evans609ae592012-10-11 13:53:15 -0700123CTL_PROTO(arena_i_dss)
Jason Evans8d6a3e82015-03-18 18:55:33 -0700124CTL_PROTO(arena_i_lg_dirty_mult)
Christopher Ferrise4294032016-03-02 14:33:02 -0800125CTL_PROTO(arena_i_decay_time)
Jason Evansb49a3342015-07-28 11:28:19 -0400126CTL_PROTO(arena_i_chunk_hooks)
Jason Evans609ae592012-10-11 13:53:15 -0700127INDEX_PROTO(arena_i)
Jason Evans3c234352010-01-27 13:10:55 -0800128CTL_PROTO(arenas_bin_i_size)
129CTL_PROTO(arenas_bin_i_nregs)
130CTL_PROTO(arenas_bin_i_run_size)
131INDEX_PROTO(arenas_bin_i)
132CTL_PROTO(arenas_lrun_i_size)
133INDEX_PROTO(arenas_lrun_i)
Jason Evans3c4d92e2014-10-12 22:53:59 -0700134CTL_PROTO(arenas_hchunk_i_size)
135INDEX_PROTO(arenas_hchunk_i)
Jason Evans3c234352010-01-27 13:10:55 -0800136CTL_PROTO(arenas_narenas)
137CTL_PROTO(arenas_initialized)
Jason Evans8d6a3e82015-03-18 18:55:33 -0700138CTL_PROTO(arenas_lg_dirty_mult)
Christopher Ferrise4294032016-03-02 14:33:02 -0800139CTL_PROTO(arenas_decay_time)
Jason Evans3c234352010-01-27 13:10:55 -0800140CTL_PROTO(arenas_quantum)
Jason Evansae4c7b42012-04-02 07:04:34 -0700141CTL_PROTO(arenas_page)
Jason Evansdafde142010-03-17 16:27:39 -0700142CTL_PROTO(arenas_tcache_max)
Jason Evans3c234352010-01-27 13:10:55 -0800143CTL_PROTO(arenas_nbins)
Jason Evansdafde142010-03-17 16:27:39 -0700144CTL_PROTO(arenas_nhbins)
Jason Evans3c234352010-01-27 13:10:55 -0800145CTL_PROTO(arenas_nlruns)
Jason Evans3c4d92e2014-10-12 22:53:59 -0700146CTL_PROTO(arenas_nhchunks)
Jason Evans609ae592012-10-11 13:53:15 -0700147CTL_PROTO(arenas_extend)
Jason Evansfc12c0b2014-10-03 23:25:30 -0700148CTL_PROTO(prof_thread_active_init)
Jason Evansf18c9822010-03-31 18:43:24 -0700149CTL_PROTO(prof_active)
Jason Evansd34f9e72010-02-11 13:19:21 -0800150CTL_PROTO(prof_dump)
Jason Evans5b8ed5b2015-01-25 21:16:57 -0800151CTL_PROTO(prof_gdump)
Jason Evans602c8e02014-08-18 16:22:13 -0700152CTL_PROTO(prof_reset)
Jason Evansd34f9e72010-02-11 13:19:21 -0800153CTL_PROTO(prof_interval)
Jason Evans602c8e02014-08-18 16:22:13 -0700154CTL_PROTO(lg_prof_sample)
Jason Evans3c234352010-01-27 13:10:55 -0800155CTL_PROTO(stats_arenas_i_small_allocated)
156CTL_PROTO(stats_arenas_i_small_nmalloc)
157CTL_PROTO(stats_arenas_i_small_ndalloc)
Jason Evans86815df2010-03-13 20:32:56 -0800158CTL_PROTO(stats_arenas_i_small_nrequests)
Jason Evans3c234352010-01-27 13:10:55 -0800159CTL_PROTO(stats_arenas_i_large_allocated)
160CTL_PROTO(stats_arenas_i_large_nmalloc)
161CTL_PROTO(stats_arenas_i_large_ndalloc)
Jason Evansdafde142010-03-17 16:27:39 -0700162CTL_PROTO(stats_arenas_i_large_nrequests)
Jason Evanse2deab72014-05-15 22:22:27 -0700163CTL_PROTO(stats_arenas_i_huge_allocated)
164CTL_PROTO(stats_arenas_i_huge_nmalloc)
165CTL_PROTO(stats_arenas_i_huge_ndalloc)
166CTL_PROTO(stats_arenas_i_huge_nrequests)
Jason Evans86815df2010-03-13 20:32:56 -0800167CTL_PROTO(stats_arenas_i_bins_j_nmalloc)
168CTL_PROTO(stats_arenas_i_bins_j_ndalloc)
Jason Evans3c234352010-01-27 13:10:55 -0800169CTL_PROTO(stats_arenas_i_bins_j_nrequests)
Jason Evans3c4d92e2014-10-12 22:53:59 -0700170CTL_PROTO(stats_arenas_i_bins_j_curregs)
Jason Evans3c234352010-01-27 13:10:55 -0800171CTL_PROTO(stats_arenas_i_bins_j_nfills)
172CTL_PROTO(stats_arenas_i_bins_j_nflushes)
Jason Evans3c234352010-01-27 13:10:55 -0800173CTL_PROTO(stats_arenas_i_bins_j_nruns)
174CTL_PROTO(stats_arenas_i_bins_j_nreruns)
Jason Evans3c234352010-01-27 13:10:55 -0800175CTL_PROTO(stats_arenas_i_bins_j_curruns)
176INDEX_PROTO(stats_arenas_i_bins_j)
Jason Evansdafde142010-03-17 16:27:39 -0700177CTL_PROTO(stats_arenas_i_lruns_j_nmalloc)
178CTL_PROTO(stats_arenas_i_lruns_j_ndalloc)
Jason Evans3c234352010-01-27 13:10:55 -0800179CTL_PROTO(stats_arenas_i_lruns_j_nrequests)
Jason Evans3c234352010-01-27 13:10:55 -0800180CTL_PROTO(stats_arenas_i_lruns_j_curruns)
181INDEX_PROTO(stats_arenas_i_lruns_j)
Jason Evans3c4d92e2014-10-12 22:53:59 -0700182CTL_PROTO(stats_arenas_i_hchunks_j_nmalloc)
183CTL_PROTO(stats_arenas_i_hchunks_j_ndalloc)
184CTL_PROTO(stats_arenas_i_hchunks_j_nrequests)
185CTL_PROTO(stats_arenas_i_hchunks_j_curhchunks)
186INDEX_PROTO(stats_arenas_i_hchunks_j)
Jason Evans597632b2011-03-18 13:41:33 -0700187CTL_PROTO(stats_arenas_i_nthreads)
Jason Evans609ae592012-10-11 13:53:15 -0700188CTL_PROTO(stats_arenas_i_dss)
Jason Evans562d2662015-03-24 16:36:12 -0700189CTL_PROTO(stats_arenas_i_lg_dirty_mult)
Christopher Ferrise4294032016-03-02 14:33:02 -0800190CTL_PROTO(stats_arenas_i_decay_time)
Jason Evans3c234352010-01-27 13:10:55 -0800191CTL_PROTO(stats_arenas_i_pactive)
192CTL_PROTO(stats_arenas_i_pdirty)
Jason Evans3c234352010-01-27 13:10:55 -0800193CTL_PROTO(stats_arenas_i_mapped)
194CTL_PROTO(stats_arenas_i_npurge)
195CTL_PROTO(stats_arenas_i_nmadvise)
196CTL_PROTO(stats_arenas_i_purged)
Jason Evans4581b972014-11-27 17:22:36 -0200197CTL_PROTO(stats_arenas_i_metadata_mapped)
198CTL_PROTO(stats_arenas_i_metadata_allocated)
Jason Evans3c234352010-01-27 13:10:55 -0800199INDEX_PROTO(stats_arenas_i)
Jason Evans0657f122011-03-18 17:56:14 -0700200CTL_PROTO(stats_cactive)
Jason Evans3c234352010-01-27 13:10:55 -0800201CTL_PROTO(stats_allocated)
202CTL_PROTO(stats_active)
Jason Evans4581b972014-11-27 17:22:36 -0200203CTL_PROTO(stats_metadata)
Jason Evans4acd75a2015-03-23 17:25:57 -0700204CTL_PROTO(stats_resident)
Jason Evans3c234352010-01-27 13:10:55 -0800205CTL_PROTO(stats_mapped)
Jason Evans3c234352010-01-27 13:10:55 -0800206
207/******************************************************************************/
208/* mallctl tree. */
209
210/* Maximum tree depth. */
211#define CTL_MAX_DEPTH 6
212
Mike Hommey461ad5c2012-04-20 08:38:42 +0200213#define NAME(n) {true}, n
Jason Evans65f343a2012-04-23 19:31:45 -0700214#define CHILD(t, c) \
215 sizeof(c##_node) / sizeof(ctl_##t##_node_t), \
216 (ctl_node_t *)c##_node, \
217 NULL
Mike Hommey461ad5c2012-04-20 08:38:42 +0200218#define CTL(c) 0, NULL, c##_ctl
Jason Evans3c234352010-01-27 13:10:55 -0800219
220/*
221 * Only handles internal indexed nodes, since there are currently no external
222 * ones.
223 */
Mike Hommey461ad5c2012-04-20 08:38:42 +0200224#define INDEX(i) {false}, i##_index
Jason Evans3c234352010-01-27 13:10:55 -0800225
Jason Evans602c8e02014-08-18 16:22:13 -0700226static const ctl_named_node_t thread_tcache_node[] = {
Jason Evansd4be8b72012-03-26 18:54:44 -0700227 {NAME("enabled"), CTL(thread_tcache_enabled)},
Jason Evanse7b8fa12012-03-16 17:09:32 -0700228 {NAME("flush"), CTL(thread_tcache_flush)}
Jason Evans3c234352010-01-27 13:10:55 -0800229};
Jason Evans3c234352010-01-27 13:10:55 -0800230
Jason Evans602c8e02014-08-18 16:22:13 -0700231static const ctl_named_node_t thread_prof_node[] = {
232 {NAME("name"), CTL(thread_prof_name)},
233 {NAME("active"), CTL(thread_prof_active)}
234};
235
Mike Hommey461ad5c2012-04-20 08:38:42 +0200236static const ctl_named_node_t thread_node[] = {
Jason Evans7372b152012-02-10 20:22:09 -0800237 {NAME("arena"), CTL(thread_arena)},
Jason Evans93443682010-10-20 17:39:18 -0700238 {NAME("allocated"), CTL(thread_allocated)},
Jason Evansecf229a2010-12-03 15:55:47 -0800239 {NAME("allocatedp"), CTL(thread_allocatedp)},
240 {NAME("deallocated"), CTL(thread_deallocated)},
Jason Evanse7b8fa12012-03-16 17:09:32 -0700241 {NAME("deallocatedp"), CTL(thread_deallocatedp)},
Jason Evans602c8e02014-08-18 16:22:13 -0700242 {NAME("tcache"), CHILD(named, thread_tcache)},
243 {NAME("prof"), CHILD(named, thread_prof)}
Jason Evansb267d0f2010-08-13 15:42:29 -0700244};
Jason Evansb267d0f2010-08-13 15:42:29 -0700245
Mike Hommey461ad5c2012-04-20 08:38:42 +0200246static const ctl_named_node_t config_node[] = {
Jason Evansf2bc8522015-07-17 16:38:25 -0700247 {NAME("cache_oblivious"), CTL(config_cache_oblivious)},
Jason Evans3c4d92e2014-10-12 22:53:59 -0700248 {NAME("debug"), CTL(config_debug)},
249 {NAME("fill"), CTL(config_fill)},
250 {NAME("lazy_lock"), CTL(config_lazy_lock)},
Christopher Ferrise4294032016-03-02 14:33:02 -0800251 {NAME("malloc_conf"), CTL(config_malloc_conf)},
Jason Evans3c4d92e2014-10-12 22:53:59 -0700252 {NAME("munmap"), CTL(config_munmap)},
253 {NAME("prof"), CTL(config_prof)},
254 {NAME("prof_libgcc"), CTL(config_prof_libgcc)},
255 {NAME("prof_libunwind"), CTL(config_prof_libunwind)},
256 {NAME("stats"), CTL(config_stats)},
257 {NAME("tcache"), CTL(config_tcache)},
258 {NAME("tls"), CTL(config_tls)},
259 {NAME("utrace"), CTL(config_utrace)},
260 {NAME("valgrind"), CTL(config_valgrind)},
261 {NAME("xmalloc"), CTL(config_xmalloc)}
Jason Evans3c234352010-01-27 13:10:55 -0800262};
263
Mike Hommey461ad5c2012-04-20 08:38:42 +0200264static const ctl_named_node_t opt_node[] = {
Jason Evans3c4d92e2014-10-12 22:53:59 -0700265 {NAME("abort"), CTL(opt_abort)},
266 {NAME("dss"), CTL(opt_dss)},
267 {NAME("lg_chunk"), CTL(opt_lg_chunk)},
268 {NAME("narenas"), CTL(opt_narenas)},
Christopher Ferrise4294032016-03-02 14:33:02 -0800269 {NAME("purge"), CTL(opt_purge)},
Jason Evans3c4d92e2014-10-12 22:53:59 -0700270 {NAME("lg_dirty_mult"), CTL(opt_lg_dirty_mult)},
Christopher Ferrise4294032016-03-02 14:33:02 -0800271 {NAME("decay_time"), CTL(opt_decay_time)},
Jason Evans3c4d92e2014-10-12 22:53:59 -0700272 {NAME("stats_print"), CTL(opt_stats_print)},
273 {NAME("junk"), CTL(opt_junk)},
274 {NAME("zero"), CTL(opt_zero)},
275 {NAME("quarantine"), CTL(opt_quarantine)},
276 {NAME("redzone"), CTL(opt_redzone)},
277 {NAME("utrace"), CTL(opt_utrace)},
278 {NAME("xmalloc"), CTL(opt_xmalloc)},
279 {NAME("tcache"), CTL(opt_tcache)},
280 {NAME("lg_tcache_max"), CTL(opt_lg_tcache_max)},
281 {NAME("prof"), CTL(opt_prof)},
282 {NAME("prof_prefix"), CTL(opt_prof_prefix)},
283 {NAME("prof_active"), CTL(opt_prof_active)},
Jason Evansfc12c0b2014-10-03 23:25:30 -0700284 {NAME("prof_thread_active_init"), CTL(opt_prof_thread_active_init)},
Jason Evans3c4d92e2014-10-12 22:53:59 -0700285 {NAME("lg_prof_sample"), CTL(opt_lg_prof_sample)},
286 {NAME("lg_prof_interval"), CTL(opt_lg_prof_interval)},
287 {NAME("prof_gdump"), CTL(opt_prof_gdump)},
288 {NAME("prof_final"), CTL(opt_prof_final)},
289 {NAME("prof_leak"), CTL(opt_prof_leak)},
290 {NAME("prof_accum"), CTL(opt_prof_accum)}
Jason Evans3c234352010-01-27 13:10:55 -0800291};
292
Jason Evans1cb181e2015-01-29 15:30:47 -0800293static const ctl_named_node_t tcache_node[] = {
294 {NAME("create"), CTL(tcache_create)},
295 {NAME("flush"), CTL(tcache_flush)},
296 {NAME("destroy"), CTL(tcache_destroy)}
297};
298
Jason Evans609ae592012-10-11 13:53:15 -0700299static const ctl_named_node_t arena_i_node[] = {
Jason Evans3c4d92e2014-10-12 22:53:59 -0700300 {NAME("purge"), CTL(arena_i_purge)},
Christopher Ferrise4294032016-03-02 14:33:02 -0800301 {NAME("decay"), CTL(arena_i_decay)},
Jason Evans3c4d92e2014-10-12 22:53:59 -0700302 {NAME("dss"), CTL(arena_i_dss)},
Jason Evans8d6a3e82015-03-18 18:55:33 -0700303 {NAME("lg_dirty_mult"), CTL(arena_i_lg_dirty_mult)},
Christopher Ferrise4294032016-03-02 14:33:02 -0800304 {NAME("decay_time"), CTL(arena_i_decay_time)},
Jason Evansb49a3342015-07-28 11:28:19 -0400305 {NAME("chunk_hooks"), CTL(arena_i_chunk_hooks)}
Jason Evans609ae592012-10-11 13:53:15 -0700306};
307static const ctl_named_node_t super_arena_i_node[] = {
Jason Evans3c4d92e2014-10-12 22:53:59 -0700308 {NAME(""), CHILD(named, arena_i)}
Jason Evans609ae592012-10-11 13:53:15 -0700309};
310
311static const ctl_indexed_node_t arena_node[] = {
312 {INDEX(arena_i)}
313};
314
Mike Hommey461ad5c2012-04-20 08:38:42 +0200315static const ctl_named_node_t arenas_bin_i_node[] = {
Jason Evans3c4d92e2014-10-12 22:53:59 -0700316 {NAME("size"), CTL(arenas_bin_i_size)},
317 {NAME("nregs"), CTL(arenas_bin_i_nregs)},
318 {NAME("run_size"), CTL(arenas_bin_i_run_size)}
Jason Evans3c234352010-01-27 13:10:55 -0800319};
Mike Hommey461ad5c2012-04-20 08:38:42 +0200320static const ctl_named_node_t super_arenas_bin_i_node[] = {
Jason Evans3c4d92e2014-10-12 22:53:59 -0700321 {NAME(""), CHILD(named, arenas_bin_i)}
Jason Evans3c234352010-01-27 13:10:55 -0800322};
323
Mike Hommey461ad5c2012-04-20 08:38:42 +0200324static const ctl_indexed_node_t arenas_bin_node[] = {
Jason Evans3c234352010-01-27 13:10:55 -0800325 {INDEX(arenas_bin_i)}
326};
327
Mike Hommey461ad5c2012-04-20 08:38:42 +0200328static const ctl_named_node_t arenas_lrun_i_node[] = {
Jason Evans3c4d92e2014-10-12 22:53:59 -0700329 {NAME("size"), CTL(arenas_lrun_i_size)}
Jason Evans3c234352010-01-27 13:10:55 -0800330};
Mike Hommey461ad5c2012-04-20 08:38:42 +0200331static const ctl_named_node_t super_arenas_lrun_i_node[] = {
Jason Evans3c4d92e2014-10-12 22:53:59 -0700332 {NAME(""), CHILD(named, arenas_lrun_i)}
Jason Evans3c234352010-01-27 13:10:55 -0800333};
334
Mike Hommey461ad5c2012-04-20 08:38:42 +0200335static const ctl_indexed_node_t arenas_lrun_node[] = {
Jason Evans3c234352010-01-27 13:10:55 -0800336 {INDEX(arenas_lrun_i)}
337};
338
Jason Evans3c4d92e2014-10-12 22:53:59 -0700339static const ctl_named_node_t arenas_hchunk_i_node[] = {
340 {NAME("size"), CTL(arenas_hchunk_i_size)}
341};
342static const ctl_named_node_t super_arenas_hchunk_i_node[] = {
343 {NAME(""), CHILD(named, arenas_hchunk_i)}
344};
345
346static const ctl_indexed_node_t arenas_hchunk_node[] = {
347 {INDEX(arenas_hchunk_i)}
348};
349
Mike Hommey461ad5c2012-04-20 08:38:42 +0200350static const ctl_named_node_t arenas_node[] = {
Jason Evans3c4d92e2014-10-12 22:53:59 -0700351 {NAME("narenas"), CTL(arenas_narenas)},
352 {NAME("initialized"), CTL(arenas_initialized)},
Jason Evans8d6a3e82015-03-18 18:55:33 -0700353 {NAME("lg_dirty_mult"), CTL(arenas_lg_dirty_mult)},
Christopher Ferrise4294032016-03-02 14:33:02 -0800354 {NAME("decay_time"), CTL(arenas_decay_time)},
Jason Evans3c4d92e2014-10-12 22:53:59 -0700355 {NAME("quantum"), CTL(arenas_quantum)},
356 {NAME("page"), CTL(arenas_page)},
357 {NAME("tcache_max"), CTL(arenas_tcache_max)},
358 {NAME("nbins"), CTL(arenas_nbins)},
359 {NAME("nhbins"), CTL(arenas_nhbins)},
360 {NAME("bin"), CHILD(indexed, arenas_bin)},
361 {NAME("nlruns"), CTL(arenas_nlruns)},
362 {NAME("lrun"), CHILD(indexed, arenas_lrun)},
363 {NAME("nhchunks"), CTL(arenas_nhchunks)},
364 {NAME("hchunk"), CHILD(indexed, arenas_hchunk)},
365 {NAME("extend"), CTL(arenas_extend)}
Jason Evans3c234352010-01-27 13:10:55 -0800366};
367
Mike Hommey461ad5c2012-04-20 08:38:42 +0200368static const ctl_named_node_t prof_node[] = {
Jason Evansfc12c0b2014-10-03 23:25:30 -0700369 {NAME("thread_active_init"), CTL(prof_thread_active_init)},
Jason Evansf18c9822010-03-31 18:43:24 -0700370 {NAME("active"), CTL(prof_active)},
Jason Evansd34f9e72010-02-11 13:19:21 -0800371 {NAME("dump"), CTL(prof_dump)},
Jason Evans5b8ed5b2015-01-25 21:16:57 -0800372 {NAME("gdump"), CTL(prof_gdump)},
Jason Evans602c8e02014-08-18 16:22:13 -0700373 {NAME("reset"), CTL(prof_reset)},
374 {NAME("interval"), CTL(prof_interval)},
375 {NAME("lg_sample"), CTL(lg_prof_sample)}
Jason Evansd34f9e72010-02-11 13:19:21 -0800376};
Jason Evansd34f9e72010-02-11 13:19:21 -0800377
Jason Evans4581b972014-11-27 17:22:36 -0200378static const ctl_named_node_t stats_arenas_i_metadata_node[] = {
379 {NAME("mapped"), CTL(stats_arenas_i_metadata_mapped)},
380 {NAME("allocated"), CTL(stats_arenas_i_metadata_allocated)}
381};
382
Mike Hommey461ad5c2012-04-20 08:38:42 +0200383static const ctl_named_node_t stats_arenas_i_small_node[] = {
Jason Evans3c4d92e2014-10-12 22:53:59 -0700384 {NAME("allocated"), CTL(stats_arenas_i_small_allocated)},
385 {NAME("nmalloc"), CTL(stats_arenas_i_small_nmalloc)},
386 {NAME("ndalloc"), CTL(stats_arenas_i_small_ndalloc)},
387 {NAME("nrequests"), CTL(stats_arenas_i_small_nrequests)}
Jason Evans3c234352010-01-27 13:10:55 -0800388};
389
Mike Hommey461ad5c2012-04-20 08:38:42 +0200390static const ctl_named_node_t stats_arenas_i_large_node[] = {
Jason Evans3c4d92e2014-10-12 22:53:59 -0700391 {NAME("allocated"), CTL(stats_arenas_i_large_allocated)},
392 {NAME("nmalloc"), CTL(stats_arenas_i_large_nmalloc)},
393 {NAME("ndalloc"), CTL(stats_arenas_i_large_ndalloc)},
394 {NAME("nrequests"), CTL(stats_arenas_i_large_nrequests)}
Jason Evans3c234352010-01-27 13:10:55 -0800395};
396
Jason Evanse2deab72014-05-15 22:22:27 -0700397static const ctl_named_node_t stats_arenas_i_huge_node[] = {
Jason Evans3c4d92e2014-10-12 22:53:59 -0700398 {NAME("allocated"), CTL(stats_arenas_i_huge_allocated)},
399 {NAME("nmalloc"), CTL(stats_arenas_i_huge_nmalloc)},
400 {NAME("ndalloc"), CTL(stats_arenas_i_huge_ndalloc)},
401 {NAME("nrequests"), CTL(stats_arenas_i_huge_nrequests)}
Jason Evanse2deab72014-05-15 22:22:27 -0700402};
403
Mike Hommey461ad5c2012-04-20 08:38:42 +0200404static const ctl_named_node_t stats_arenas_i_bins_j_node[] = {
Jason Evans3c4d92e2014-10-12 22:53:59 -0700405 {NAME("nmalloc"), CTL(stats_arenas_i_bins_j_nmalloc)},
406 {NAME("ndalloc"), CTL(stats_arenas_i_bins_j_ndalloc)},
407 {NAME("nrequests"), CTL(stats_arenas_i_bins_j_nrequests)},
408 {NAME("curregs"), CTL(stats_arenas_i_bins_j_curregs)},
409 {NAME("nfills"), CTL(stats_arenas_i_bins_j_nfills)},
410 {NAME("nflushes"), CTL(stats_arenas_i_bins_j_nflushes)},
411 {NAME("nruns"), CTL(stats_arenas_i_bins_j_nruns)},
412 {NAME("nreruns"), CTL(stats_arenas_i_bins_j_nreruns)},
413 {NAME("curruns"), CTL(stats_arenas_i_bins_j_curruns)}
Jason Evans3c234352010-01-27 13:10:55 -0800414};
Mike Hommey461ad5c2012-04-20 08:38:42 +0200415static const ctl_named_node_t super_stats_arenas_i_bins_j_node[] = {
Jason Evans3c4d92e2014-10-12 22:53:59 -0700416 {NAME(""), CHILD(named, stats_arenas_i_bins_j)}
Jason Evans3c234352010-01-27 13:10:55 -0800417};
418
Mike Hommey461ad5c2012-04-20 08:38:42 +0200419static const ctl_indexed_node_t stats_arenas_i_bins_node[] = {
Jason Evans3c234352010-01-27 13:10:55 -0800420 {INDEX(stats_arenas_i_bins_j)}
421};
422
Mike Hommey461ad5c2012-04-20 08:38:42 +0200423static const ctl_named_node_t stats_arenas_i_lruns_j_node[] = {
Jason Evans3c4d92e2014-10-12 22:53:59 -0700424 {NAME("nmalloc"), CTL(stats_arenas_i_lruns_j_nmalloc)},
425 {NAME("ndalloc"), CTL(stats_arenas_i_lruns_j_ndalloc)},
426 {NAME("nrequests"), CTL(stats_arenas_i_lruns_j_nrequests)},
427 {NAME("curruns"), CTL(stats_arenas_i_lruns_j_curruns)}
Jason Evans3c234352010-01-27 13:10:55 -0800428};
Mike Hommey461ad5c2012-04-20 08:38:42 +0200429static const ctl_named_node_t super_stats_arenas_i_lruns_j_node[] = {
Jason Evans3c4d92e2014-10-12 22:53:59 -0700430 {NAME(""), CHILD(named, stats_arenas_i_lruns_j)}
Jason Evans3c234352010-01-27 13:10:55 -0800431};
432
Mike Hommey461ad5c2012-04-20 08:38:42 +0200433static const ctl_indexed_node_t stats_arenas_i_lruns_node[] = {
Jason Evans3c234352010-01-27 13:10:55 -0800434 {INDEX(stats_arenas_i_lruns_j)}
435};
Jason Evans3c234352010-01-27 13:10:55 -0800436
Jason Evans3c4d92e2014-10-12 22:53:59 -0700437static const ctl_named_node_t stats_arenas_i_hchunks_j_node[] = {
438 {NAME("nmalloc"), CTL(stats_arenas_i_hchunks_j_nmalloc)},
439 {NAME("ndalloc"), CTL(stats_arenas_i_hchunks_j_ndalloc)},
440 {NAME("nrequests"), CTL(stats_arenas_i_hchunks_j_nrequests)},
441 {NAME("curhchunks"), CTL(stats_arenas_i_hchunks_j_curhchunks)}
442};
443static const ctl_named_node_t super_stats_arenas_i_hchunks_j_node[] = {
444 {NAME(""), CHILD(named, stats_arenas_i_hchunks_j)}
445};
446
447static const ctl_indexed_node_t stats_arenas_i_hchunks_node[] = {
448 {INDEX(stats_arenas_i_hchunks_j)}
449};
450
Mike Hommey461ad5c2012-04-20 08:38:42 +0200451static const ctl_named_node_t stats_arenas_i_node[] = {
Jason Evans3c4d92e2014-10-12 22:53:59 -0700452 {NAME("nthreads"), CTL(stats_arenas_i_nthreads)},
453 {NAME("dss"), CTL(stats_arenas_i_dss)},
Jason Evans562d2662015-03-24 16:36:12 -0700454 {NAME("lg_dirty_mult"), CTL(stats_arenas_i_lg_dirty_mult)},
Christopher Ferrise4294032016-03-02 14:33:02 -0800455 {NAME("decay_time"), CTL(stats_arenas_i_decay_time)},
Jason Evans3c4d92e2014-10-12 22:53:59 -0700456 {NAME("pactive"), CTL(stats_arenas_i_pactive)},
457 {NAME("pdirty"), CTL(stats_arenas_i_pdirty)},
458 {NAME("mapped"), CTL(stats_arenas_i_mapped)},
459 {NAME("npurge"), CTL(stats_arenas_i_npurge)},
460 {NAME("nmadvise"), CTL(stats_arenas_i_nmadvise)},
461 {NAME("purged"), CTL(stats_arenas_i_purged)},
Jason Evans4581b972014-11-27 17:22:36 -0200462 {NAME("metadata"), CHILD(named, stats_arenas_i_metadata)},
Jason Evans3c4d92e2014-10-12 22:53:59 -0700463 {NAME("small"), CHILD(named, stats_arenas_i_small)},
464 {NAME("large"), CHILD(named, stats_arenas_i_large)},
465 {NAME("huge"), CHILD(named, stats_arenas_i_huge)},
466 {NAME("bins"), CHILD(indexed, stats_arenas_i_bins)},
467 {NAME("lruns"), CHILD(indexed, stats_arenas_i_lruns)},
468 {NAME("hchunks"), CHILD(indexed, stats_arenas_i_hchunks)}
Jason Evans3c234352010-01-27 13:10:55 -0800469};
Mike Hommey461ad5c2012-04-20 08:38:42 +0200470static const ctl_named_node_t super_stats_arenas_i_node[] = {
Jason Evans3c4d92e2014-10-12 22:53:59 -0700471 {NAME(""), CHILD(named, stats_arenas_i)}
Jason Evans3c234352010-01-27 13:10:55 -0800472};
473
Mike Hommey461ad5c2012-04-20 08:38:42 +0200474static const ctl_indexed_node_t stats_arenas_node[] = {
Jason Evans3c234352010-01-27 13:10:55 -0800475 {INDEX(stats_arenas_i)}
476};
477
Mike Hommey461ad5c2012-04-20 08:38:42 +0200478static const ctl_named_node_t stats_node[] = {
Jason Evans3c4d92e2014-10-12 22:53:59 -0700479 {NAME("cactive"), CTL(stats_cactive)},
480 {NAME("allocated"), CTL(stats_allocated)},
481 {NAME("active"), CTL(stats_active)},
Jason Evans4581b972014-11-27 17:22:36 -0200482 {NAME("metadata"), CTL(stats_metadata)},
Jason Evans4acd75a2015-03-23 17:25:57 -0700483 {NAME("resident"), CTL(stats_resident)},
Jason Evans3c4d92e2014-10-12 22:53:59 -0700484 {NAME("mapped"), CTL(stats_mapped)},
Jason Evans3c4d92e2014-10-12 22:53:59 -0700485 {NAME("arenas"), CHILD(indexed, stats_arenas)}
Jason Evans3c234352010-01-27 13:10:55 -0800486};
487
Mike Hommey461ad5c2012-04-20 08:38:42 +0200488static const ctl_named_node_t root_node[] = {
Jason Evansa40bc7a2010-03-02 13:01:16 -0800489 {NAME("version"), CTL(version)},
Jason Evans3c234352010-01-27 13:10:55 -0800490 {NAME("epoch"), CTL(epoch)},
Jason Evans65f343a2012-04-23 19:31:45 -0700491 {NAME("thread"), CHILD(named, thread)},
492 {NAME("config"), CHILD(named, config)},
493 {NAME("opt"), CHILD(named, opt)},
Jason Evans1cb181e2015-01-29 15:30:47 -0800494 {NAME("tcache"), CHILD(named, tcache)},
Jason Evans609ae592012-10-11 13:53:15 -0700495 {NAME("arena"), CHILD(indexed, arena)},
Jason Evans65f343a2012-04-23 19:31:45 -0700496 {NAME("arenas"), CHILD(named, arenas)},
497 {NAME("prof"), CHILD(named, prof)},
498 {NAME("stats"), CHILD(named, stats)}
Jason Evans3c234352010-01-27 13:10:55 -0800499};
Mike Hommey461ad5c2012-04-20 08:38:42 +0200500static const ctl_named_node_t super_root_node[] = {
Jason Evans65f343a2012-04-23 19:31:45 -0700501 {NAME(""), CHILD(named, root)}
Jason Evans3c234352010-01-27 13:10:55 -0800502};
503
504#undef NAME
505#undef CHILD
506#undef CTL
507#undef INDEX
508
509/******************************************************************************/
510
Jason Evans3c234352010-01-27 13:10:55 -0800511static bool
512ctl_arena_init(ctl_arena_stats_t *astats)
513{
514
Jason Evans3c234352010-01-27 13:10:55 -0800515 if (astats->lstats == NULL) {
Jason Evans8bb31982014-10-07 23:14:57 -0700516 astats->lstats = (malloc_large_stats_t *)a0malloc(nlclasses *
Jason Evans4581b972014-11-27 17:22:36 -0200517 sizeof(malloc_large_stats_t));
Jason Evans3c234352010-01-27 13:10:55 -0800518 if (astats->lstats == NULL)
519 return (true);
520 }
521
Jason Evans3c4d92e2014-10-12 22:53:59 -0700522 if (astats->hstats == NULL) {
523 astats->hstats = (malloc_huge_stats_t *)a0malloc(nhclasses *
Jason Evans4581b972014-11-27 17:22:36 -0200524 sizeof(malloc_huge_stats_t));
Jason Evans3c4d92e2014-10-12 22:53:59 -0700525 if (astats->hstats == NULL)
526 return (true);
527 }
528
Jason Evans3c234352010-01-27 13:10:55 -0800529 return (false);
530}
Jason Evans3c234352010-01-27 13:10:55 -0800531
532static void
533ctl_arena_clear(ctl_arena_stats_t *astats)
534{
535
Christopher Ferrise4294032016-03-02 14:33:02 -0800536 astats->nthreads = 0;
Jason Evans609ae592012-10-11 13:53:15 -0700537 astats->dss = dss_prec_names[dss_prec_limit];
Jason Evans562d2662015-03-24 16:36:12 -0700538 astats->lg_dirty_mult = -1;
Christopher Ferrise4294032016-03-02 14:33:02 -0800539 astats->decay_time = -1;
Jason Evans3c234352010-01-27 13:10:55 -0800540 astats->pactive = 0;
541 astats->pdirty = 0;
Jason Evans7372b152012-02-10 20:22:09 -0800542 if (config_stats) {
543 memset(&astats->astats, 0, sizeof(arena_stats_t));
544 astats->allocated_small = 0;
545 astats->nmalloc_small = 0;
546 astats->ndalloc_small = 0;
547 astats->nrequests_small = 0;
Jason Evansb1726102012-02-28 16:50:47 -0800548 memset(astats->bstats, 0, NBINS * sizeof(malloc_bin_stats_t));
Jason Evans7372b152012-02-10 20:22:09 -0800549 memset(astats->lstats, 0, nlclasses *
550 sizeof(malloc_large_stats_t));
Jason Evans3c4d92e2014-10-12 22:53:59 -0700551 memset(astats->hstats, 0, nhclasses *
552 sizeof(malloc_huge_stats_t));
Jason Evans7372b152012-02-10 20:22:09 -0800553 }
Jason Evans3c234352010-01-27 13:10:55 -0800554}
555
Jason Evans86815df2010-03-13 20:32:56 -0800556static void
557ctl_arena_stats_amerge(ctl_arena_stats_t *cstats, arena_t *arena)
558{
559 unsigned i;
560
Christopher Ferrise4294032016-03-02 14:33:02 -0800561 if (config_stats) {
562 arena_stats_merge(arena, &cstats->nthreads, &cstats->dss,
563 &cstats->lg_dirty_mult, &cstats->decay_time,
564 &cstats->pactive, &cstats->pdirty, &cstats->astats,
565 cstats->bstats, cstats->lstats, cstats->hstats);
Jason Evans86815df2010-03-13 20:32:56 -0800566
Christopher Ferrise4294032016-03-02 14:33:02 -0800567 for (i = 0; i < NBINS; i++) {
568 cstats->allocated_small += cstats->bstats[i].curregs *
569 index2size(i);
570 cstats->nmalloc_small += cstats->bstats[i].nmalloc;
571 cstats->ndalloc_small += cstats->bstats[i].ndalloc;
572 cstats->nrequests_small += cstats->bstats[i].nrequests;
573 }
574 } else {
575 arena_basic_stats_merge(arena, &cstats->nthreads, &cstats->dss,
576 &cstats->lg_dirty_mult, &cstats->decay_time,
577 &cstats->pactive, &cstats->pdirty);
Jason Evans86815df2010-03-13 20:32:56 -0800578 }
Jason Evans86815df2010-03-13 20:32:56 -0800579}
580
581static void
582ctl_arena_stats_smerge(ctl_arena_stats_t *sstats, ctl_arena_stats_t *astats)
583{
584 unsigned i;
585
Christopher Ferrise4294032016-03-02 14:33:02 -0800586 sstats->nthreads += astats->nthreads;
Jason Evans86815df2010-03-13 20:32:56 -0800587 sstats->pactive += astats->pactive;
588 sstats->pdirty += astats->pdirty;
589
Christopher Ferrise4294032016-03-02 14:33:02 -0800590 if (config_stats) {
591 sstats->astats.mapped += astats->astats.mapped;
592 sstats->astats.npurge += astats->astats.npurge;
593 sstats->astats.nmadvise += astats->astats.nmadvise;
594 sstats->astats.purged += astats->astats.purged;
Jason Evans86815df2010-03-13 20:32:56 -0800595
Christopher Ferrise4294032016-03-02 14:33:02 -0800596 sstats->astats.metadata_mapped +=
597 astats->astats.metadata_mapped;
598 sstats->astats.metadata_allocated +=
599 astats->astats.metadata_allocated;
Jason Evans4581b972014-11-27 17:22:36 -0200600
Christopher Ferrise4294032016-03-02 14:33:02 -0800601 sstats->allocated_small += astats->allocated_small;
602 sstats->nmalloc_small += astats->nmalloc_small;
603 sstats->ndalloc_small += astats->ndalloc_small;
604 sstats->nrequests_small += astats->nrequests_small;
Jason Evans86815df2010-03-13 20:32:56 -0800605
Christopher Ferrise4294032016-03-02 14:33:02 -0800606 sstats->astats.allocated_large +=
607 astats->astats.allocated_large;
608 sstats->astats.nmalloc_large += astats->astats.nmalloc_large;
609 sstats->astats.ndalloc_large += astats->astats.ndalloc_large;
610 sstats->astats.nrequests_large +=
611 astats->astats.nrequests_large;
Jason Evans86815df2010-03-13 20:32:56 -0800612
Christopher Ferrise4294032016-03-02 14:33:02 -0800613 sstats->astats.allocated_huge += astats->astats.allocated_huge;
614 sstats->astats.nmalloc_huge += astats->astats.nmalloc_huge;
615 sstats->astats.ndalloc_huge += astats->astats.ndalloc_huge;
Jason Evans86815df2010-03-13 20:32:56 -0800616
Christopher Ferrise4294032016-03-02 14:33:02 -0800617 for (i = 0; i < NBINS; i++) {
618 sstats->bstats[i].nmalloc += astats->bstats[i].nmalloc;
619 sstats->bstats[i].ndalloc += astats->bstats[i].ndalloc;
620 sstats->bstats[i].nrequests +=
621 astats->bstats[i].nrequests;
622 sstats->bstats[i].curregs += astats->bstats[i].curregs;
623 if (config_tcache) {
624 sstats->bstats[i].nfills +=
625 astats->bstats[i].nfills;
626 sstats->bstats[i].nflushes +=
627 astats->bstats[i].nflushes;
628 }
629 sstats->bstats[i].nruns += astats->bstats[i].nruns;
630 sstats->bstats[i].reruns += astats->bstats[i].reruns;
631 sstats->bstats[i].curruns += astats->bstats[i].curruns;
Jason Evans7372b152012-02-10 20:22:09 -0800632 }
Jason Evans3c4d92e2014-10-12 22:53:59 -0700633
Christopher Ferrise4294032016-03-02 14:33:02 -0800634 for (i = 0; i < nlclasses; i++) {
635 sstats->lstats[i].nmalloc += astats->lstats[i].nmalloc;
636 sstats->lstats[i].ndalloc += astats->lstats[i].ndalloc;
637 sstats->lstats[i].nrequests +=
638 astats->lstats[i].nrequests;
639 sstats->lstats[i].curruns += astats->lstats[i].curruns;
640 }
Jason Evans3c4d92e2014-10-12 22:53:59 -0700641
Christopher Ferrise4294032016-03-02 14:33:02 -0800642 for (i = 0; i < nhclasses; i++) {
643 sstats->hstats[i].nmalloc += astats->hstats[i].nmalloc;
644 sstats->hstats[i].ndalloc += astats->hstats[i].ndalloc;
645 sstats->hstats[i].curhchunks +=
646 astats->hstats[i].curhchunks;
647 }
Jason Evans3c4d92e2014-10-12 22:53:59 -0700648 }
Jason Evans86815df2010-03-13 20:32:56 -0800649}
Jason Evans86815df2010-03-13 20:32:56 -0800650
Jason Evans3c234352010-01-27 13:10:55 -0800651static void
652ctl_arena_refresh(arena_t *arena, unsigned i)
653{
654 ctl_arena_stats_t *astats = &ctl_stats.arenas[i];
Jason Evans609ae592012-10-11 13:53:15 -0700655 ctl_arena_stats_t *sstats = &ctl_stats.arenas[ctl_stats.narenas];
Jason Evans3c234352010-01-27 13:10:55 -0800656
657 ctl_arena_clear(astats);
Christopher Ferrise4294032016-03-02 14:33:02 -0800658 ctl_arena_stats_amerge(astats, arena);
659 /* Merge into sum stats as well. */
660 ctl_arena_stats_smerge(sstats, astats);
Jason Evans3c234352010-01-27 13:10:55 -0800661}
662
Jason Evans609ae592012-10-11 13:53:15 -0700663static bool
664ctl_grow(void)
665{
Jason Evans609ae592012-10-11 13:53:15 -0700666 ctl_arena_stats_t *astats;
Jason Evans609ae592012-10-11 13:53:15 -0700667
Jason Evans8bb31982014-10-07 23:14:57 -0700668 /* Initialize new arena. */
669 if (arena_init(ctl_stats.narenas) == NULL)
670 return (true);
Jason Evans5460aa62014-09-22 21:09:23 -0700671
Jason Evans8bb31982014-10-07 23:14:57 -0700672 /* Allocate extended arena stats. */
673 astats = (ctl_arena_stats_t *)a0malloc((ctl_stats.narenas + 2) *
Jason Evans4581b972014-11-27 17:22:36 -0200674 sizeof(ctl_arena_stats_t));
Jason Evans7b651802013-10-20 14:09:54 -0700675 if (astats == NULL)
Jason Evans609ae592012-10-11 13:53:15 -0700676 return (true);
Jason Evans7b651802013-10-20 14:09:54 -0700677
678 /* Initialize the new astats element. */
679 memcpy(astats, ctl_stats.arenas, (ctl_stats.narenas + 1) *
680 sizeof(ctl_arena_stats_t));
681 memset(&astats[ctl_stats.narenas + 1], 0, sizeof(ctl_arena_stats_t));
682 if (ctl_arena_init(&astats[ctl_stats.narenas + 1])) {
Jason Evans10aff3f2015-01-20 15:37:51 -0800683 a0dalloc(astats);
Jason Evans7b651802013-10-20 14:09:54 -0700684 return (true);
685 }
Jason Evans609ae592012-10-11 13:53:15 -0700686 /* Swap merged stats to their new location. */
687 {
688 ctl_arena_stats_t tstats;
689 memcpy(&tstats, &astats[ctl_stats.narenas],
690 sizeof(ctl_arena_stats_t));
691 memcpy(&astats[ctl_stats.narenas],
692 &astats[ctl_stats.narenas + 1], sizeof(ctl_arena_stats_t));
693 memcpy(&astats[ctl_stats.narenas + 1], &tstats,
694 sizeof(ctl_arena_stats_t));
695 }
Jason Evans10aff3f2015-01-20 15:37:51 -0800696 a0dalloc(ctl_stats.arenas);
Jason Evans609ae592012-10-11 13:53:15 -0700697 ctl_stats.arenas = astats;
698 ctl_stats.narenas++;
Jason Evans609ae592012-10-11 13:53:15 -0700699
700 return (false);
701}
702
Jason Evans3c234352010-01-27 13:10:55 -0800703static void
704ctl_refresh(void)
705{
706 unsigned i;
Jason Evans609ae592012-10-11 13:53:15 -0700707 VARIABLE_ARRAY(arena_t *, tarenas, ctl_stats.narenas);
Jason Evans3c234352010-01-27 13:10:55 -0800708
Jason Evans3c234352010-01-27 13:10:55 -0800709 /*
Jason Evans13668262010-01-31 03:57:29 -0800710 * Clear sum stats, since they will be merged into by
Jason Evans3c234352010-01-27 13:10:55 -0800711 * ctl_arena_refresh().
712 */
Jason Evans609ae592012-10-11 13:53:15 -0700713 ctl_arena_clear(&ctl_stats.arenas[ctl_stats.narenas]);
Jason Evans3c234352010-01-27 13:10:55 -0800714
Christopher Ferrise4294032016-03-02 14:33:02 -0800715 for (i = 0; i < ctl_stats.narenas; i++)
716 tarenas[i] = arena_get(i, false);
Jason Evans8bb31982014-10-07 23:14:57 -0700717
Jason Evans609ae592012-10-11 13:53:15 -0700718 for (i = 0; i < ctl_stats.narenas; i++) {
Jason Evans3c234352010-01-27 13:10:55 -0800719 bool initialized = (tarenas[i] != NULL);
720
721 ctl_stats.arenas[i].initialized = initialized;
722 if (initialized)
723 ctl_arena_refresh(tarenas[i], i);
724 }
725
Jason Evans7372b152012-02-10 20:22:09 -0800726 if (config_stats) {
Jason Evans4acd75a2015-03-23 17:25:57 -0700727 size_t base_allocated, base_resident, base_mapped;
728 base_stats_get(&base_allocated, &base_resident, &base_mapped);
Jason Evans609ae592012-10-11 13:53:15 -0700729 ctl_stats.allocated =
Jason Evans4acd75a2015-03-23 17:25:57 -0700730 ctl_stats.arenas[ctl_stats.narenas].allocated_small +
731 ctl_stats.arenas[ctl_stats.narenas].astats.allocated_large +
732 ctl_stats.arenas[ctl_stats.narenas].astats.allocated_huge;
Jason Evans609ae592012-10-11 13:53:15 -0700733 ctl_stats.active =
Jason Evanse2deab72014-05-15 22:22:27 -0700734 (ctl_stats.arenas[ctl_stats.narenas].pactive << LG_PAGE);
Jason Evans4acd75a2015-03-23 17:25:57 -0700735 ctl_stats.metadata = base_allocated +
736 ctl_stats.arenas[ctl_stats.narenas].astats.metadata_mapped +
737 ctl_stats.arenas[ctl_stats.narenas].astats
Jason Evans4581b972014-11-27 17:22:36 -0200738 .metadata_allocated;
Jason Evans4acd75a2015-03-23 17:25:57 -0700739 ctl_stats.resident = base_resident +
740 ctl_stats.arenas[ctl_stats.narenas].astats.metadata_mapped +
741 ((ctl_stats.arenas[ctl_stats.narenas].pactive +
742 ctl_stats.arenas[ctl_stats.narenas].pdirty) << LG_PAGE);
743 ctl_stats.mapped = base_mapped +
Jason Evanscbf3a6d2015-02-11 12:24:27 -0800744 ctl_stats.arenas[ctl_stats.narenas].astats.mapped;
Jason Evans7372b152012-02-10 20:22:09 -0800745 }
Jason Evans3c234352010-01-27 13:10:55 -0800746
747 ctl_epoch++;
748}
749
750static bool
751ctl_init(void)
752{
Jason Evansfc4dcfa2010-11-24 15:44:21 -0800753 bool ret;
Jason Evans3c234352010-01-27 13:10:55 -0800754
Jason Evansfc4dcfa2010-11-24 15:44:21 -0800755 malloc_mutex_lock(&ctl_mtx);
Jason Evans551ebc42014-10-03 10:16:09 -0700756 if (!ctl_initialized) {
Jason Evans3c234352010-01-27 13:10:55 -0800757 /*
758 * Allocate space for one extra arena stats element, which
759 * contains summed stats across all arenas.
760 */
Jason Evans8bb31982014-10-07 23:14:57 -0700761 ctl_stats.narenas = narenas_total_get();
762 ctl_stats.arenas = (ctl_arena_stats_t *)a0malloc(
Jason Evans4581b972014-11-27 17:22:36 -0200763 (ctl_stats.narenas + 1) * sizeof(ctl_arena_stats_t));
Jason Evansfc4dcfa2010-11-24 15:44:21 -0800764 if (ctl_stats.arenas == NULL) {
765 ret = true;
Jason Evansa1ee7832012-04-10 15:07:44 -0700766 goto label_return;
Jason Evansfc4dcfa2010-11-24 15:44:21 -0800767 }
Jason Evans609ae592012-10-11 13:53:15 -0700768 memset(ctl_stats.arenas, 0, (ctl_stats.narenas + 1) *
Jason Evans3c234352010-01-27 13:10:55 -0800769 sizeof(ctl_arena_stats_t));
770
771 /*
772 * Initialize all stats structures, regardless of whether they
773 * ever get used. Lazy initialization would allow errors to
774 * cause inconsistent state to be viewable by the application.
775 */
Jason Evans7372b152012-02-10 20:22:09 -0800776 if (config_stats) {
777 unsigned i;
Jason Evans609ae592012-10-11 13:53:15 -0700778 for (i = 0; i <= ctl_stats.narenas; i++) {
Jason Evans7372b152012-02-10 20:22:09 -0800779 if (ctl_arena_init(&ctl_stats.arenas[i])) {
Jason Evans8bb31982014-10-07 23:14:57 -0700780 unsigned j;
781 for (j = 0; j < i; j++) {
Jason Evans10aff3f2015-01-20 15:37:51 -0800782 a0dalloc(
Jason Evans8bb31982014-10-07 23:14:57 -0700783 ctl_stats.arenas[j].lstats);
Jason Evans10aff3f2015-01-20 15:37:51 -0800784 a0dalloc(
Jason Evans3c4d92e2014-10-12 22:53:59 -0700785 ctl_stats.arenas[j].hstats);
Jason Evans8bb31982014-10-07 23:14:57 -0700786 }
Jason Evans10aff3f2015-01-20 15:37:51 -0800787 a0dalloc(ctl_stats.arenas);
Jason Evans8bb31982014-10-07 23:14:57 -0700788 ctl_stats.arenas = NULL;
Jason Evans7372b152012-02-10 20:22:09 -0800789 ret = true;
Jason Evansa1ee7832012-04-10 15:07:44 -0700790 goto label_return;
Jason Evans7372b152012-02-10 20:22:09 -0800791 }
Jason Evansfc4dcfa2010-11-24 15:44:21 -0800792 }
Jason Evans3c234352010-01-27 13:10:55 -0800793 }
Jason Evans609ae592012-10-11 13:53:15 -0700794 ctl_stats.arenas[ctl_stats.narenas].initialized = true;
Jason Evans3c234352010-01-27 13:10:55 -0800795
796 ctl_epoch = 0;
797 ctl_refresh();
798 ctl_initialized = true;
799 }
800
Jason Evansfc4dcfa2010-11-24 15:44:21 -0800801 ret = false;
Jason Evansa1ee7832012-04-10 15:07:44 -0700802label_return:
Jason Evansfc4dcfa2010-11-24 15:44:21 -0800803 malloc_mutex_unlock(&ctl_mtx);
804 return (ret);
Jason Evans3c234352010-01-27 13:10:55 -0800805}
806
807static int
808ctl_lookup(const char *name, ctl_node_t const **nodesp, size_t *mibp,
809 size_t *depthp)
810{
811 int ret;
812 const char *elm, *tdot, *dot;
813 size_t elen, i, j;
Mike Hommey461ad5c2012-04-20 08:38:42 +0200814 const ctl_named_node_t *node;
Jason Evans3c234352010-01-27 13:10:55 -0800815
816 elm = name;
817 /* Equivalent to strchrnul(). */
818 dot = ((tdot = strchr(elm, '.')) != NULL) ? tdot : strchr(elm, '\0');
819 elen = (size_t)((uintptr_t)dot - (uintptr_t)elm);
820 if (elen == 0) {
821 ret = ENOENT;
Jason Evansa1ee7832012-04-10 15:07:44 -0700822 goto label_return;
Jason Evans3c234352010-01-27 13:10:55 -0800823 }
824 node = super_root_node;
825 for (i = 0; i < *depthp; i++) {
Mike Hommey461ad5c2012-04-20 08:38:42 +0200826 assert(node);
827 assert(node->nchildren > 0);
828 if (ctl_named_node(node->children) != NULL) {
829 const ctl_named_node_t *pnode = node;
Jason Evans3c234352010-01-27 13:10:55 -0800830
831 /* Children are named. */
Mike Hommey461ad5c2012-04-20 08:38:42 +0200832 for (j = 0; j < node->nchildren; j++) {
833 const ctl_named_node_t *child =
834 ctl_named_children(node, j);
835 if (strlen(child->name) == elen &&
836 strncmp(elm, child->name, elen) == 0) {
Jason Evans3c234352010-01-27 13:10:55 -0800837 node = child;
838 if (nodesp != NULL)
Mike Hommey461ad5c2012-04-20 08:38:42 +0200839 nodesp[i] =
840 (const ctl_node_t *)node;
Jason Evans3c234352010-01-27 13:10:55 -0800841 mibp[i] = j;
842 break;
843 }
844 }
845 if (node == pnode) {
846 ret = ENOENT;
Jason Evansa1ee7832012-04-10 15:07:44 -0700847 goto label_return;
Jason Evans3c234352010-01-27 13:10:55 -0800848 }
849 } else {
Jason Evans41b6afb2012-02-02 22:04:57 -0800850 uintmax_t index;
Mike Hommey461ad5c2012-04-20 08:38:42 +0200851 const ctl_indexed_node_t *inode;
Jason Evans3c234352010-01-27 13:10:55 -0800852
853 /* Children are indexed. */
Jason Evans41b6afb2012-02-02 22:04:57 -0800854 index = malloc_strtoumax(elm, NULL, 10);
855 if (index == UINTMAX_MAX || index > SIZE_T_MAX) {
Jason Evans3c234352010-01-27 13:10:55 -0800856 ret = ENOENT;
Jason Evansa1ee7832012-04-10 15:07:44 -0700857 goto label_return;
Jason Evans3c234352010-01-27 13:10:55 -0800858 }
859
Mike Hommey461ad5c2012-04-20 08:38:42 +0200860 inode = ctl_indexed_node(node->children);
861 node = inode->index(mibp, *depthp, (size_t)index);
Jason Evans3c234352010-01-27 13:10:55 -0800862 if (node == NULL) {
863 ret = ENOENT;
Jason Evansa1ee7832012-04-10 15:07:44 -0700864 goto label_return;
Jason Evans3c234352010-01-27 13:10:55 -0800865 }
866
867 if (nodesp != NULL)
Mike Hommey461ad5c2012-04-20 08:38:42 +0200868 nodesp[i] = (const ctl_node_t *)node;
Jason Evans3c234352010-01-27 13:10:55 -0800869 mibp[i] = (size_t)index;
870 }
871
872 if (node->ctl != NULL) {
873 /* Terminal node. */
874 if (*dot != '\0') {
875 /*
876 * The name contains more elements than are
877 * in this path through the tree.
878 */
879 ret = ENOENT;
Jason Evansa1ee7832012-04-10 15:07:44 -0700880 goto label_return;
Jason Evans3c234352010-01-27 13:10:55 -0800881 }
882 /* Complete lookup successful. */
883 *depthp = i + 1;
884 break;
885 }
886
887 /* Update elm. */
888 if (*dot == '\0') {
889 /* No more elements. */
890 ret = ENOENT;
Jason Evansa1ee7832012-04-10 15:07:44 -0700891 goto label_return;
Jason Evans3c234352010-01-27 13:10:55 -0800892 }
893 elm = &dot[1];
894 dot = ((tdot = strchr(elm, '.')) != NULL) ? tdot :
895 strchr(elm, '\0');
896 elen = (size_t)((uintptr_t)dot - (uintptr_t)elm);
897 }
898
899 ret = 0;
Jason Evansa1ee7832012-04-10 15:07:44 -0700900label_return:
Jason Evans3c234352010-01-27 13:10:55 -0800901 return (ret);
902}
903
904int
905ctl_byname(const char *name, void *oldp, size_t *oldlenp, void *newp,
906 size_t newlen)
907{
908 int ret;
909 size_t depth;
910 ctl_node_t const *nodes[CTL_MAX_DEPTH];
911 size_t mib[CTL_MAX_DEPTH];
Mike Hommey461ad5c2012-04-20 08:38:42 +0200912 const ctl_named_node_t *node;
Jason Evans3c234352010-01-27 13:10:55 -0800913
Jason Evans551ebc42014-10-03 10:16:09 -0700914 if (!ctl_initialized && ctl_init()) {
Jason Evans3c234352010-01-27 13:10:55 -0800915 ret = EAGAIN;
Jason Evansa1ee7832012-04-10 15:07:44 -0700916 goto label_return;
Jason Evans3c234352010-01-27 13:10:55 -0800917 }
918
919 depth = CTL_MAX_DEPTH;
920 ret = ctl_lookup(name, nodes, mib, &depth);
921 if (ret != 0)
Jason Evansa1ee7832012-04-10 15:07:44 -0700922 goto label_return;
Jason Evans3c234352010-01-27 13:10:55 -0800923
Mike Hommey461ad5c2012-04-20 08:38:42 +0200924 node = ctl_named_node(nodes[depth-1]);
925 if (node != NULL && node->ctl)
926 ret = node->ctl(mib, depth, oldp, oldlenp, newp, newlen);
927 else {
Jason Evans3c234352010-01-27 13:10:55 -0800928 /* The name refers to a partial path through the ctl tree. */
929 ret = ENOENT;
Jason Evans3c234352010-01-27 13:10:55 -0800930 }
Jason Evans3c234352010-01-27 13:10:55 -0800931
Jason Evansa1ee7832012-04-10 15:07:44 -0700932label_return:
Jason Evans3c234352010-01-27 13:10:55 -0800933 return(ret);
934}
935
936int
937ctl_nametomib(const char *name, size_t *mibp, size_t *miblenp)
938{
939 int ret;
940
Jason Evans551ebc42014-10-03 10:16:09 -0700941 if (!ctl_initialized && ctl_init()) {
Jason Evans3c234352010-01-27 13:10:55 -0800942 ret = EAGAIN;
Jason Evansa1ee7832012-04-10 15:07:44 -0700943 goto label_return;
Jason Evans3c234352010-01-27 13:10:55 -0800944 }
945
946 ret = ctl_lookup(name, NULL, mibp, miblenp);
Jason Evansa1ee7832012-04-10 15:07:44 -0700947label_return:
Jason Evans3c234352010-01-27 13:10:55 -0800948 return(ret);
949}
950
951int
952ctl_bymib(const size_t *mib, size_t miblen, void *oldp, size_t *oldlenp,
953 void *newp, size_t newlen)
954{
955 int ret;
Mike Hommey461ad5c2012-04-20 08:38:42 +0200956 const ctl_named_node_t *node;
Jason Evans3c234352010-01-27 13:10:55 -0800957 size_t i;
958
Jason Evans551ebc42014-10-03 10:16:09 -0700959 if (!ctl_initialized && ctl_init()) {
Jason Evans3c234352010-01-27 13:10:55 -0800960 ret = EAGAIN;
Jason Evansa1ee7832012-04-10 15:07:44 -0700961 goto label_return;
Jason Evans3c234352010-01-27 13:10:55 -0800962 }
963
964 /* Iterate down the tree. */
965 node = super_root_node;
966 for (i = 0; i < miblen; i++) {
Mike Hommey461ad5c2012-04-20 08:38:42 +0200967 assert(node);
968 assert(node->nchildren > 0);
969 if (ctl_named_node(node->children) != NULL) {
Jason Evans3c234352010-01-27 13:10:55 -0800970 /* Children are named. */
Christopher Ferrise4294032016-03-02 14:33:02 -0800971 if (node->nchildren <= (unsigned)mib[i]) {
Jason Evans3c234352010-01-27 13:10:55 -0800972 ret = ENOENT;
Jason Evansa1ee7832012-04-10 15:07:44 -0700973 goto label_return;
Jason Evans3c234352010-01-27 13:10:55 -0800974 }
Mike Hommey461ad5c2012-04-20 08:38:42 +0200975 node = ctl_named_children(node, mib[i]);
Jason Evans3c234352010-01-27 13:10:55 -0800976 } else {
Mike Hommey461ad5c2012-04-20 08:38:42 +0200977 const ctl_indexed_node_t *inode;
Jason Evans3c234352010-01-27 13:10:55 -0800978
979 /* Indexed element. */
Mike Hommey461ad5c2012-04-20 08:38:42 +0200980 inode = ctl_indexed_node(node->children);
981 node = inode->index(mib, miblen, mib[i]);
Jason Evans3c234352010-01-27 13:10:55 -0800982 if (node == NULL) {
983 ret = ENOENT;
Jason Evansa1ee7832012-04-10 15:07:44 -0700984 goto label_return;
Jason Evans3c234352010-01-27 13:10:55 -0800985 }
986 }
987 }
988
989 /* Call the ctl function. */
Mike Hommey461ad5c2012-04-20 08:38:42 +0200990 if (node && node->ctl)
991 ret = node->ctl(mib, miblen, oldp, oldlenp, newp, newlen);
992 else {
Jason Evans3c234352010-01-27 13:10:55 -0800993 /* Partial MIB. */
994 ret = ENOENT;
Jason Evans3c234352010-01-27 13:10:55 -0800995 }
Jason Evans3c234352010-01-27 13:10:55 -0800996
Jason Evansa1ee7832012-04-10 15:07:44 -0700997label_return:
Jason Evans3c234352010-01-27 13:10:55 -0800998 return(ret);
999}
1000
1001bool
1002ctl_boot(void)
1003{
1004
1005 if (malloc_mutex_init(&ctl_mtx))
1006 return (true);
1007
1008 ctl_initialized = false;
1009
1010 return (false);
1011}
1012
Jason Evans20f1fc92012-10-09 14:46:22 -07001013void
1014ctl_prefork(void)
1015{
1016
Jason Evansf1c3da82013-10-21 14:59:10 -07001017 malloc_mutex_prefork(&ctl_mtx);
Jason Evans20f1fc92012-10-09 14:46:22 -07001018}
1019
1020void
1021ctl_postfork_parent(void)
1022{
1023
1024 malloc_mutex_postfork_parent(&ctl_mtx);
1025}
1026
1027void
1028ctl_postfork_child(void)
1029{
1030
1031 malloc_mutex_postfork_child(&ctl_mtx);
1032}
1033
Jason Evans3c234352010-01-27 13:10:55 -08001034/******************************************************************************/
1035/* *_ctl() functions. */
1036
1037#define READONLY() do { \
1038 if (newp != NULL || newlen != 0) { \
1039 ret = EPERM; \
Jason Evans6b9ed672012-04-25 13:12:46 -07001040 goto label_return; \
Jason Evans3c234352010-01-27 13:10:55 -08001041 } \
1042} while (0)
1043
Jason Evans22ca8552010-03-02 11:57:30 -08001044#define WRITEONLY() do { \
Jason Evans3c234352010-01-27 13:10:55 -08001045 if (oldp != NULL || oldlenp != NULL) { \
1046 ret = EPERM; \
Jason Evans6b9ed672012-04-25 13:12:46 -07001047 goto label_return; \
Jason Evans3c234352010-01-27 13:10:55 -08001048 } \
1049} while (0)
1050
Jason Evansfc12c0b2014-10-03 23:25:30 -07001051#define READ_XOR_WRITE() do { \
1052 if ((oldp != NULL && oldlenp != NULL) && (newp != NULL || \
1053 newlen != 0)) { \
1054 ret = EPERM; \
1055 goto label_return; \
1056 } \
1057} while (0)
1058
Jason Evans3c234352010-01-27 13:10:55 -08001059#define READ(v, t) do { \
1060 if (oldp != NULL && oldlenp != NULL) { \
1061 if (*oldlenp != sizeof(t)) { \
1062 size_t copylen = (sizeof(t) <= *oldlenp) \
1063 ? sizeof(t) : *oldlenp; \
Jason Evans6eb84fb2012-11-29 22:13:04 -08001064 memcpy(oldp, (void *)&(v), copylen); \
Jason Evans3c234352010-01-27 13:10:55 -08001065 ret = EINVAL; \
Jason Evans6b9ed672012-04-25 13:12:46 -07001066 goto label_return; \
Jason Evansb49a3342015-07-28 11:28:19 -04001067 } \
1068 *(t *)oldp = (v); \
Jason Evans3c234352010-01-27 13:10:55 -08001069 } \
1070} while (0)
1071
1072#define WRITE(v, t) do { \
1073 if (newp != NULL) { \
1074 if (newlen != sizeof(t)) { \
1075 ret = EINVAL; \
Jason Evans6b9ed672012-04-25 13:12:46 -07001076 goto label_return; \
Jason Evans3c234352010-01-27 13:10:55 -08001077 } \
Jason Evans6eb84fb2012-11-29 22:13:04 -08001078 (v) = *(t *)newp; \
Jason Evans3c234352010-01-27 13:10:55 -08001079 } \
1080} while (0)
1081
Jason Evans7372b152012-02-10 20:22:09 -08001082/*
1083 * There's a lot of code duplication in the following macros due to limitations
1084 * in how nested cpp macros are expanded.
1085 */
1086#define CTL_RO_CLGEN(c, l, n, v, t) \
1087static int \
1088n##_ctl(const size_t *mib, size_t miblen, void *oldp, size_t *oldlenp, \
1089 void *newp, size_t newlen) \
1090{ \
1091 int ret; \
1092 t oldval; \
1093 \
Jason Evans551ebc42014-10-03 10:16:09 -07001094 if (!(c)) \
Jason Evans7372b152012-02-10 20:22:09 -08001095 return (ENOENT); \
1096 if (l) \
1097 malloc_mutex_lock(&ctl_mtx); \
1098 READONLY(); \
Jason Evans6eb84fb2012-11-29 22:13:04 -08001099 oldval = (v); \
Jason Evans7372b152012-02-10 20:22:09 -08001100 READ(oldval, t); \
1101 \
1102 ret = 0; \
Jason Evans6b9ed672012-04-25 13:12:46 -07001103label_return: \
Jason Evans7372b152012-02-10 20:22:09 -08001104 if (l) \
1105 malloc_mutex_unlock(&ctl_mtx); \
1106 return (ret); \
1107}
1108
1109#define CTL_RO_CGEN(c, n, v, t) \
1110static int \
1111n##_ctl(const size_t *mib, size_t miblen, void *oldp, size_t *oldlenp, \
1112 void *newp, size_t newlen) \
1113{ \
1114 int ret; \
1115 t oldval; \
1116 \
Jason Evans551ebc42014-10-03 10:16:09 -07001117 if (!(c)) \
Jason Evans7372b152012-02-10 20:22:09 -08001118 return (ENOENT); \
1119 malloc_mutex_lock(&ctl_mtx); \
1120 READONLY(); \
Jason Evans6eb84fb2012-11-29 22:13:04 -08001121 oldval = (v); \
Jason Evans7372b152012-02-10 20:22:09 -08001122 READ(oldval, t); \
1123 \
1124 ret = 0; \
Jason Evans6b9ed672012-04-25 13:12:46 -07001125label_return: \
Jason Evans7372b152012-02-10 20:22:09 -08001126 malloc_mutex_unlock(&ctl_mtx); \
1127 return (ret); \
1128}
1129
Jason Evans3c234352010-01-27 13:10:55 -08001130#define CTL_RO_GEN(n, v, t) \
1131static int \
1132n##_ctl(const size_t *mib, size_t miblen, void *oldp, size_t *oldlenp, \
1133 void *newp, size_t newlen) \
1134{ \
1135 int ret; \
1136 t oldval; \
1137 \
Jason Evansfc4dcfa2010-11-24 15:44:21 -08001138 malloc_mutex_lock(&ctl_mtx); \
1139 READONLY(); \
Jason Evans6eb84fb2012-11-29 22:13:04 -08001140 oldval = (v); \
Jason Evansfc4dcfa2010-11-24 15:44:21 -08001141 READ(oldval, t); \
1142 \
1143 ret = 0; \
Jason Evans6b9ed672012-04-25 13:12:46 -07001144label_return: \
Jason Evansfc4dcfa2010-11-24 15:44:21 -08001145 malloc_mutex_unlock(&ctl_mtx); \
1146 return (ret); \
1147}
1148
1149/*
1150 * ctl_mtx is not acquired, under the assumption that no pertinent data will
1151 * mutate during the call.
1152 */
Jason Evans7372b152012-02-10 20:22:09 -08001153#define CTL_RO_NL_CGEN(c, n, v, t) \
1154static int \
1155n##_ctl(const size_t *mib, size_t miblen, void *oldp, size_t *oldlenp, \
1156 void *newp, size_t newlen) \
1157{ \
1158 int ret; \
1159 t oldval; \
1160 \
Jason Evans551ebc42014-10-03 10:16:09 -07001161 if (!(c)) \
Jason Evans7372b152012-02-10 20:22:09 -08001162 return (ENOENT); \
1163 READONLY(); \
Jason Evans6eb84fb2012-11-29 22:13:04 -08001164 oldval = (v); \
Jason Evans7372b152012-02-10 20:22:09 -08001165 READ(oldval, t); \
1166 \
1167 ret = 0; \
Jason Evans6b9ed672012-04-25 13:12:46 -07001168label_return: \
Jason Evans7372b152012-02-10 20:22:09 -08001169 return (ret); \
1170}
1171
1172#define CTL_RO_NL_GEN(n, v, t) \
Jason Evansfc4dcfa2010-11-24 15:44:21 -08001173static int \
1174n##_ctl(const size_t *mib, size_t miblen, void *oldp, size_t *oldlenp, \
1175 void *newp, size_t newlen) \
1176{ \
1177 int ret; \
1178 t oldval; \
1179 \
Jason Evans3c234352010-01-27 13:10:55 -08001180 READONLY(); \
Jason Evans6eb84fb2012-11-29 22:13:04 -08001181 oldval = (v); \
Jason Evans3c234352010-01-27 13:10:55 -08001182 READ(oldval, t); \
1183 \
1184 ret = 0; \
Jason Evans6b9ed672012-04-25 13:12:46 -07001185label_return: \
Jason Evans3c234352010-01-27 13:10:55 -08001186 return (ret); \
1187}
1188
Jason Evans5460aa62014-09-22 21:09:23 -07001189#define CTL_TSD_RO_NL_CGEN(c, n, m, t) \
1190static int \
1191n##_ctl(const size_t *mib, size_t miblen, void *oldp, size_t *oldlenp, \
1192 void *newp, size_t newlen) \
1193{ \
1194 int ret; \
1195 t oldval; \
1196 tsd_t *tsd; \
1197 \
Jason Evans551ebc42014-10-03 10:16:09 -07001198 if (!(c)) \
Jason Evans5460aa62014-09-22 21:09:23 -07001199 return (ENOENT); \
1200 READONLY(); \
Jason Evans029d44c2014-10-04 11:12:53 -07001201 tsd = tsd_fetch(); \
Jason Evans5460aa62014-09-22 21:09:23 -07001202 oldval = (m(tsd)); \
1203 READ(oldval, t); \
1204 \
1205 ret = 0; \
1206label_return: \
1207 return (ret); \
1208}
1209
Christopher Ferrise4294032016-03-02 14:33:02 -08001210#define CTL_RO_CONFIG_GEN(n, t) \
Jason Evans3c234352010-01-27 13:10:55 -08001211static int \
1212n##_ctl(const size_t *mib, size_t miblen, void *oldp, size_t *oldlenp, \
1213 void *newp, size_t newlen) \
1214{ \
1215 int ret; \
Christopher Ferrise4294032016-03-02 14:33:02 -08001216 t oldval; \
Jason Evans3c234352010-01-27 13:10:55 -08001217 \
1218 READONLY(); \
Jason Evans7372b152012-02-10 20:22:09 -08001219 oldval = n; \
Christopher Ferrise4294032016-03-02 14:33:02 -08001220 READ(oldval, t); \
Jason Evans3c234352010-01-27 13:10:55 -08001221 \
1222 ret = 0; \
Jason Evans6b9ed672012-04-25 13:12:46 -07001223label_return: \
Jason Evans3c234352010-01-27 13:10:55 -08001224 return (ret); \
1225}
1226
Jason Evansd8a39002013-12-19 21:40:41 -08001227/******************************************************************************/
1228
Jason Evansfc4dcfa2010-11-24 15:44:21 -08001229CTL_RO_NL_GEN(version, JEMALLOC_VERSION, const char *)
Jason Evansa40bc7a2010-03-02 13:01:16 -08001230
Jason Evans3c234352010-01-27 13:10:55 -08001231static int
1232epoch_ctl(const size_t *mib, size_t miblen, void *oldp, size_t *oldlenp,
1233 void *newp, size_t newlen)
1234{
1235 int ret;
Jason Evans3ab682d2013-10-19 17:19:49 -07001236 UNUSED uint64_t newval;
Jason Evans3c234352010-01-27 13:10:55 -08001237
Jason Evansfc4dcfa2010-11-24 15:44:21 -08001238 malloc_mutex_lock(&ctl_mtx);
Jason Evans3c234352010-01-27 13:10:55 -08001239 WRITE(newval, uint64_t);
Jason Evans6b9ed672012-04-25 13:12:46 -07001240 if (newp != NULL)
Jason Evans3c234352010-01-27 13:10:55 -08001241 ctl_refresh();
1242 READ(ctl_epoch, uint64_t);
1243
1244 ret = 0;
Jason Evansa1ee7832012-04-10 15:07:44 -07001245label_return:
Jason Evansfc4dcfa2010-11-24 15:44:21 -08001246 malloc_mutex_unlock(&ctl_mtx);
Jason Evans3c234352010-01-27 13:10:55 -08001247 return (ret);
1248}
1249
Jason Evansd8a39002013-12-19 21:40:41 -08001250/******************************************************************************/
Jason Evansd4be8b72012-03-26 18:54:44 -07001251
Christopher Ferrise4294032016-03-02 14:33:02 -08001252CTL_RO_CONFIG_GEN(config_cache_oblivious, bool)
1253CTL_RO_CONFIG_GEN(config_debug, bool)
1254CTL_RO_CONFIG_GEN(config_fill, bool)
1255CTL_RO_CONFIG_GEN(config_lazy_lock, bool)
1256CTL_RO_CONFIG_GEN(config_malloc_conf, const char *)
1257CTL_RO_CONFIG_GEN(config_munmap, bool)
1258CTL_RO_CONFIG_GEN(config_prof, bool)
1259CTL_RO_CONFIG_GEN(config_prof_libgcc, bool)
1260CTL_RO_CONFIG_GEN(config_prof_libunwind, bool)
1261CTL_RO_CONFIG_GEN(config_stats, bool)
1262CTL_RO_CONFIG_GEN(config_tcache, bool)
1263CTL_RO_CONFIG_GEN(config_tls, bool)
1264CTL_RO_CONFIG_GEN(config_utrace, bool)
1265CTL_RO_CONFIG_GEN(config_valgrind, bool)
1266CTL_RO_CONFIG_GEN(config_xmalloc, bool)
Jason Evansd4be8b72012-03-26 18:54:44 -07001267
Jason Evansd8a39002013-12-19 21:40:41 -08001268/******************************************************************************/
Jason Evansd4be8b72012-03-26 18:54:44 -07001269
Jason Evansd8a39002013-12-19 21:40:41 -08001270CTL_RO_NL_GEN(opt_abort, opt_abort, bool)
1271CTL_RO_NL_GEN(opt_dss, opt_dss, const char *)
1272CTL_RO_NL_GEN(opt_lg_chunk, opt_lg_chunk, size_t)
Christopher Ferrise4294032016-03-02 14:33:02 -08001273CTL_RO_NL_GEN(opt_narenas, opt_narenas, unsigned)
1274CTL_RO_NL_GEN(opt_purge, purge_mode_names[opt_purge], const char *)
Jason Evansd8a39002013-12-19 21:40:41 -08001275CTL_RO_NL_GEN(opt_lg_dirty_mult, opt_lg_dirty_mult, ssize_t)
Christopher Ferrise4294032016-03-02 14:33:02 -08001276CTL_RO_NL_GEN(opt_decay_time, opt_decay_time, ssize_t)
Jason Evansd8a39002013-12-19 21:40:41 -08001277CTL_RO_NL_GEN(opt_stats_print, opt_stats_print, bool)
Guilherme Goncalves2c5cb612014-12-08 19:12:41 -02001278CTL_RO_NL_CGEN(config_fill, opt_junk, opt_junk, const char *)
Jason Evansd8a39002013-12-19 21:40:41 -08001279CTL_RO_NL_CGEN(config_fill, opt_quarantine, opt_quarantine, size_t)
1280CTL_RO_NL_CGEN(config_fill, opt_redzone, opt_redzone, bool)
1281CTL_RO_NL_CGEN(config_fill, opt_zero, opt_zero, bool)
1282CTL_RO_NL_CGEN(config_utrace, opt_utrace, opt_utrace, bool)
Jason Evansd8a39002013-12-19 21:40:41 -08001283CTL_RO_NL_CGEN(config_xmalloc, opt_xmalloc, opt_xmalloc, bool)
1284CTL_RO_NL_CGEN(config_tcache, opt_tcache, opt_tcache, bool)
1285CTL_RO_NL_CGEN(config_tcache, opt_lg_tcache_max, opt_lg_tcache_max, ssize_t)
1286CTL_RO_NL_CGEN(config_prof, opt_prof, opt_prof, bool)
1287CTL_RO_NL_CGEN(config_prof, opt_prof_prefix, opt_prof_prefix, const char *)
Jason Evansfc12c0b2014-10-03 23:25:30 -07001288CTL_RO_NL_CGEN(config_prof, opt_prof_active, opt_prof_active, bool)
1289CTL_RO_NL_CGEN(config_prof, opt_prof_thread_active_init,
1290 opt_prof_thread_active_init, bool)
Jason Evansd8a39002013-12-19 21:40:41 -08001291CTL_RO_NL_CGEN(config_prof, opt_lg_prof_sample, opt_lg_prof_sample, size_t)
1292CTL_RO_NL_CGEN(config_prof, opt_prof_accum, opt_prof_accum, bool)
1293CTL_RO_NL_CGEN(config_prof, opt_lg_prof_interval, opt_lg_prof_interval, ssize_t)
1294CTL_RO_NL_CGEN(config_prof, opt_prof_gdump, opt_prof_gdump, bool)
1295CTL_RO_NL_CGEN(config_prof, opt_prof_final, opt_prof_final, bool)
1296CTL_RO_NL_CGEN(config_prof, opt_prof_leak, opt_prof_leak, bool)
Jason Evansd4be8b72012-03-26 18:54:44 -07001297
Jason Evansd8a39002013-12-19 21:40:41 -08001298/******************************************************************************/
Jason Evans3c234352010-01-27 13:10:55 -08001299
Jason Evansb267d0f2010-08-13 15:42:29 -07001300static int
1301thread_arena_ctl(const size_t *mib, size_t miblen, void *oldp, size_t *oldlenp,
1302 void *newp, size_t newlen)
1303{
1304 int ret;
Jason Evans5460aa62014-09-22 21:09:23 -07001305 tsd_t *tsd;
Jason Evans1cb181e2015-01-29 15:30:47 -08001306 arena_t *oldarena;
Jason Evansb267d0f2010-08-13 15:42:29 -07001307 unsigned newind, oldind;
1308
Jason Evans029d44c2014-10-04 11:12:53 -07001309 tsd = tsd_fetch();
Jason Evans1cb181e2015-01-29 15:30:47 -08001310 oldarena = arena_choose(tsd, NULL);
1311 if (oldarena == NULL)
Jason Evans8bb31982014-10-07 23:14:57 -07001312 return (EAGAIN);
Jason Evans5460aa62014-09-22 21:09:23 -07001313
Jason Evans609ae592012-10-11 13:53:15 -07001314 malloc_mutex_lock(&ctl_mtx);
Jason Evans1cb181e2015-01-29 15:30:47 -08001315 newind = oldind = oldarena->ind;
Jason Evansa7153a02011-03-14 11:39:49 -07001316 WRITE(newind, unsigned);
1317 READ(oldind, unsigned);
Jason Evansb267d0f2010-08-13 15:42:29 -07001318 if (newind != oldind) {
Jason Evans1cb181e2015-01-29 15:30:47 -08001319 arena_t *newarena;
1320
Jason Evans609ae592012-10-11 13:53:15 -07001321 if (newind >= ctl_stats.narenas) {
Jason Evansb267d0f2010-08-13 15:42:29 -07001322 /* New arena index is out of range. */
1323 ret = EFAULT;
Jason Evansa1ee7832012-04-10 15:07:44 -07001324 goto label_return;
Jason Evansb267d0f2010-08-13 15:42:29 -07001325 }
1326
1327 /* Initialize arena if necessary. */
Christopher Ferrise4294032016-03-02 14:33:02 -08001328 newarena = arena_get(newind, true);
Jason Evans1cb181e2015-01-29 15:30:47 -08001329 if (newarena == NULL) {
Jason Evansb267d0f2010-08-13 15:42:29 -07001330 ret = EAGAIN;
Jason Evansa1ee7832012-04-10 15:07:44 -07001331 goto label_return;
Jason Evansb267d0f2010-08-13 15:42:29 -07001332 }
Jason Evans8bb31982014-10-07 23:14:57 -07001333 /* Set new arena/tcache associations. */
1334 arena_migrate(tsd, oldind, newind);
Jason Evans7372b152012-02-10 20:22:09 -08001335 if (config_tcache) {
Jason Evans5460aa62014-09-22 21:09:23 -07001336 tcache_t *tcache = tsd_tcache_get(tsd);
Jason Evans1cb181e2015-01-29 15:30:47 -08001337 if (tcache != NULL) {
1338 tcache_arena_reassociate(tcache, oldarena,
1339 newarena);
1340 }
Jason Evans624f2f32010-12-29 12:21:05 -08001341 }
Jason Evansb267d0f2010-08-13 15:42:29 -07001342 }
1343
1344 ret = 0;
Jason Evansa1ee7832012-04-10 15:07:44 -07001345label_return:
Jason Evans609ae592012-10-11 13:53:15 -07001346 malloc_mutex_unlock(&ctl_mtx);
Jason Evansb267d0f2010-08-13 15:42:29 -07001347 return (ret);
1348}
Jason Evansb267d0f2010-08-13 15:42:29 -07001349
Jason Evans5460aa62014-09-22 21:09:23 -07001350CTL_TSD_RO_NL_CGEN(config_stats, thread_allocated, tsd_thread_allocated_get,
1351 uint64_t)
1352CTL_TSD_RO_NL_CGEN(config_stats, thread_allocatedp, tsd_thread_allocatedp_get,
1353 uint64_t *)
1354CTL_TSD_RO_NL_CGEN(config_stats, thread_deallocated, tsd_thread_deallocated_get,
1355 uint64_t)
1356CTL_TSD_RO_NL_CGEN(config_stats, thread_deallocatedp,
1357 tsd_thread_deallocatedp_get, uint64_t *)
Jason Evans93443682010-10-20 17:39:18 -07001358
Jason Evansd8a39002013-12-19 21:40:41 -08001359static int
1360thread_tcache_enabled_ctl(const size_t *mib, size_t miblen, void *oldp,
1361 size_t *oldlenp, void *newp, size_t newlen)
1362{
1363 int ret;
1364 bool oldval;
Jason Evans3c234352010-01-27 13:10:55 -08001365
Jason Evans551ebc42014-10-03 10:16:09 -07001366 if (!config_tcache)
Jason Evansd8a39002013-12-19 21:40:41 -08001367 return (ENOENT);
Jason Evans3c234352010-01-27 13:10:55 -08001368
Jason Evansd8a39002013-12-19 21:40:41 -08001369 oldval = tcache_enabled_get();
1370 if (newp != NULL) {
1371 if (newlen != sizeof(bool)) {
1372 ret = EINVAL;
1373 goto label_return;
1374 }
1375 tcache_enabled_set(*(bool *)newp);
1376 }
1377 READ(oldval, bool);
Jason Evans3c234352010-01-27 13:10:55 -08001378
Jason Evansd8a39002013-12-19 21:40:41 -08001379 ret = 0;
1380label_return:
1381 return (ret);
1382}
1383
1384static int
1385thread_tcache_flush_ctl(const size_t *mib, size_t miblen, void *oldp,
1386 size_t *oldlenp, void *newp, size_t newlen)
1387{
1388 int ret;
1389
Jason Evans551ebc42014-10-03 10:16:09 -07001390 if (!config_tcache)
Jason Evansd8a39002013-12-19 21:40:41 -08001391 return (ENOENT);
1392
1393 READONLY();
1394 WRITEONLY();
1395
1396 tcache_flush();
1397
1398 ret = 0;
1399label_return:
1400 return (ret);
1401}
Jason Evans3c234352010-01-27 13:10:55 -08001402
Jason Evans602c8e02014-08-18 16:22:13 -07001403static int
1404thread_prof_name_ctl(const size_t *mib, size_t miblen, void *oldp,
1405 size_t *oldlenp, void *newp, size_t newlen)
1406{
1407 int ret;
Jason Evans602c8e02014-08-18 16:22:13 -07001408
Jason Evans551ebc42014-10-03 10:16:09 -07001409 if (!config_prof)
Jason Evans602c8e02014-08-18 16:22:13 -07001410 return (ENOENT);
1411
Jason Evansfc12c0b2014-10-03 23:25:30 -07001412 READ_XOR_WRITE();
1413
Jason Evans602c8e02014-08-18 16:22:13 -07001414 if (newp != NULL) {
Jason Evans5460aa62014-09-22 21:09:23 -07001415 tsd_t *tsd;
1416
Jason Evans602c8e02014-08-18 16:22:13 -07001417 if (newlen != sizeof(const char *)) {
1418 ret = EINVAL;
1419 goto label_return;
1420 }
Jason Evans5460aa62014-09-22 21:09:23 -07001421
Jason Evans029d44c2014-10-04 11:12:53 -07001422 tsd = tsd_fetch();
Jason Evans5460aa62014-09-22 21:09:23 -07001423
Jason Evansfc12c0b2014-10-03 23:25:30 -07001424 if ((ret = prof_thread_name_set(tsd, *(const char **)newp)) !=
1425 0)
Jason Evans602c8e02014-08-18 16:22:13 -07001426 goto label_return;
Jason Evansfc12c0b2014-10-03 23:25:30 -07001427 } else {
1428 const char *oldname = prof_thread_name_get();
1429 READ(oldname, const char *);
Jason Evans602c8e02014-08-18 16:22:13 -07001430 }
Jason Evans602c8e02014-08-18 16:22:13 -07001431
1432 ret = 0;
1433label_return:
1434 return (ret);
1435}
1436
1437static int
1438thread_prof_active_ctl(const size_t *mib, size_t miblen, void *oldp,
1439 size_t *oldlenp, void *newp, size_t newlen)
1440{
1441 int ret;
1442 bool oldval;
1443
Jason Evans551ebc42014-10-03 10:16:09 -07001444 if (!config_prof)
Jason Evans602c8e02014-08-18 16:22:13 -07001445 return (ENOENT);
1446
1447 oldval = prof_thread_active_get();
1448 if (newp != NULL) {
1449 if (newlen != sizeof(bool)) {
1450 ret = EINVAL;
1451 goto label_return;
1452 }
1453 if (prof_thread_active_set(*(bool *)newp)) {
1454 ret = EAGAIN;
1455 goto label_return;
1456 }
1457 }
1458 READ(oldval, bool);
1459
1460 ret = 0;
1461label_return:
1462 return (ret);
1463}
1464
Jason Evans3c234352010-01-27 13:10:55 -08001465/******************************************************************************/
1466
Jason Evans1cb181e2015-01-29 15:30:47 -08001467static int
1468tcache_create_ctl(const size_t *mib, size_t miblen, void *oldp, size_t *oldlenp,
1469 void *newp, size_t newlen)
1470{
1471 int ret;
1472 tsd_t *tsd;
1473 unsigned tcache_ind;
1474
1475 if (!config_tcache)
1476 return (ENOENT);
1477
1478 tsd = tsd_fetch();
1479
1480 malloc_mutex_lock(&ctl_mtx);
1481 READONLY();
1482 if (tcaches_create(tsd, &tcache_ind)) {
1483 ret = EFAULT;
1484 goto label_return;
1485 }
1486 READ(tcache_ind, unsigned);
1487
1488 ret = 0;
1489label_return:
1490 malloc_mutex_unlock(&ctl_mtx);
1491 return (ret);
1492}
1493
1494static int
1495tcache_flush_ctl(const size_t *mib, size_t miblen, void *oldp, size_t *oldlenp,
1496 void *newp, size_t newlen)
1497{
1498 int ret;
1499 tsd_t *tsd;
1500 unsigned tcache_ind;
1501
1502 if (!config_tcache)
1503 return (ENOENT);
1504
1505 tsd = tsd_fetch();
1506
1507 WRITEONLY();
1508 tcache_ind = UINT_MAX;
1509 WRITE(tcache_ind, unsigned);
1510 if (tcache_ind == UINT_MAX) {
1511 ret = EFAULT;
1512 goto label_return;
1513 }
1514 tcaches_flush(tsd, tcache_ind);
1515
1516 ret = 0;
1517label_return:
1518 return (ret);
1519}
1520
1521static int
1522tcache_destroy_ctl(const size_t *mib, size_t miblen, void *oldp,
1523 size_t *oldlenp, void *newp, size_t newlen)
1524{
1525 int ret;
1526 tsd_t *tsd;
1527 unsigned tcache_ind;
1528
1529 if (!config_tcache)
1530 return (ENOENT);
1531
1532 tsd = tsd_fetch();
1533
1534 WRITEONLY();
1535 tcache_ind = UINT_MAX;
1536 WRITE(tcache_ind, unsigned);
1537 if (tcache_ind == UINT_MAX) {
1538 ret = EFAULT;
1539 goto label_return;
1540 }
1541 tcaches_destroy(tsd, tcache_ind);
1542
1543 ret = 0;
1544label_return:
1545 return (ret);
1546}
1547
1548/******************************************************************************/
1549
Jason Evans34457f52012-11-03 21:18:28 -07001550static void
Christopher Ferrise4294032016-03-02 14:33:02 -08001551arena_i_purge(unsigned arena_ind, bool all)
Jason Evans609ae592012-10-11 13:53:15 -07001552{
Jason Evans609ae592012-10-11 13:53:15 -07001553
Christopher Ferrise4294032016-03-02 14:33:02 -08001554 malloc_mutex_lock(&ctl_mtx);
1555 {
1556 unsigned narenas = ctl_stats.narenas;
Jason Evans609ae592012-10-11 13:53:15 -07001557
Christopher Ferrise4294032016-03-02 14:33:02 -08001558 if (arena_ind == narenas) {
1559 unsigned i;
1560 VARIABLE_ARRAY(arena_t *, tarenas, narenas);
1561
1562 for (i = 0; i < narenas; i++)
1563 tarenas[i] = arena_get(i, false);
1564
1565 /*
1566 * No further need to hold ctl_mtx, since narenas and
1567 * tarenas contain everything needed below.
1568 */
1569 malloc_mutex_unlock(&ctl_mtx);
1570
1571 for (i = 0; i < narenas; i++) {
1572 if (tarenas[i] != NULL)
1573 arena_purge(tarenas[i], all);
1574 }
1575 } else {
1576 arena_t *tarena;
1577
1578 assert(arena_ind < narenas);
1579
1580 tarena = arena_get(arena_ind, false);
1581
1582 /* No further need to hold ctl_mtx. */
1583 malloc_mutex_unlock(&ctl_mtx);
1584
1585 if (tarena != NULL)
1586 arena_purge(tarena, all);
Jason Evans609ae592012-10-11 13:53:15 -07001587 }
1588 }
Jason Evans609ae592012-10-11 13:53:15 -07001589}
1590
1591static int
1592arena_i_purge_ctl(const size_t *mib, size_t miblen, void *oldp, size_t *oldlenp,
1593 void *newp, size_t newlen)
1594{
1595 int ret;
1596
1597 READONLY();
1598 WRITEONLY();
Christopher Ferrise4294032016-03-02 14:33:02 -08001599 arena_i_purge((unsigned)mib[1], true);
1600
1601 ret = 0;
1602label_return:
1603 return (ret);
1604}
1605
1606static int
1607arena_i_decay_ctl(const size_t *mib, size_t miblen, void *oldp, size_t *oldlenp,
1608 void *newp, size_t newlen)
1609{
1610 int ret;
1611
1612 READONLY();
1613 WRITEONLY();
1614 arena_i_purge((unsigned)mib[1], false);
Jason Evans609ae592012-10-11 13:53:15 -07001615
Jason Evans34457f52012-11-03 21:18:28 -07001616 ret = 0;
Jason Evans609ae592012-10-11 13:53:15 -07001617label_return:
1618 return (ret);
1619}
1620
1621static int
1622arena_i_dss_ctl(const size_t *mib, size_t miblen, void *oldp, size_t *oldlenp,
1623 void *newp, size_t newlen)
1624{
Jason Evans586c8ed2014-08-15 12:20:20 -07001625 int ret;
1626 const char *dss = NULL;
Christopher Ferrise4294032016-03-02 14:33:02 -08001627 unsigned arena_ind = (unsigned)mib[1];
Jason Evans609ae592012-10-11 13:53:15 -07001628 dss_prec_t dss_prec_old = dss_prec_limit;
1629 dss_prec_t dss_prec = dss_prec_limit;
1630
Jason Evansa5c80f82012-10-15 12:48:59 -07001631 malloc_mutex_lock(&ctl_mtx);
Jason Evans609ae592012-10-11 13:53:15 -07001632 WRITE(dss, const char *);
Jason Evans586c8ed2014-08-15 12:20:20 -07001633 if (dss != NULL) {
1634 int i;
1635 bool match = false;
1636
1637 for (i = 0; i < dss_prec_limit; i++) {
1638 if (strcmp(dss_prec_names[i], dss) == 0) {
1639 dss_prec = i;
1640 match = true;
1641 break;
1642 }
Jason Evans609ae592012-10-11 13:53:15 -07001643 }
Jason Evans586c8ed2014-08-15 12:20:20 -07001644
Jason Evans551ebc42014-10-03 10:16:09 -07001645 if (!match) {
Jason Evans586c8ed2014-08-15 12:20:20 -07001646 ret = EINVAL;
1647 goto label_return;
1648 }
Jason Evans609ae592012-10-11 13:53:15 -07001649 }
1650
1651 if (arena_ind < ctl_stats.narenas) {
Christopher Ferrise4294032016-03-02 14:33:02 -08001652 arena_t *arena = arena_get(arena_ind, false);
Jason Evans586c8ed2014-08-15 12:20:20 -07001653 if (arena == NULL || (dss_prec != dss_prec_limit &&
1654 arena_dss_prec_set(arena, dss_prec))) {
1655 ret = EFAULT;
1656 goto label_return;
1657 }
1658 dss_prec_old = arena_dss_prec_get(arena);
Jason Evans609ae592012-10-11 13:53:15 -07001659 } else {
Jason Evans586c8ed2014-08-15 12:20:20 -07001660 if (dss_prec != dss_prec_limit &&
1661 chunk_dss_prec_set(dss_prec)) {
1662 ret = EFAULT;
1663 goto label_return;
1664 }
Jason Evans609ae592012-10-11 13:53:15 -07001665 dss_prec_old = chunk_dss_prec_get();
Jason Evans609ae592012-10-11 13:53:15 -07001666 }
Jason Evans586c8ed2014-08-15 12:20:20 -07001667
Jason Evans609ae592012-10-11 13:53:15 -07001668 dss = dss_prec_names[dss_prec_old];
1669 READ(dss, const char *);
Jason Evans609ae592012-10-11 13:53:15 -07001670
1671 ret = 0;
1672label_return:
Jason Evansa5c80f82012-10-15 12:48:59 -07001673 malloc_mutex_unlock(&ctl_mtx);
Jason Evans609ae592012-10-11 13:53:15 -07001674 return (ret);
1675}
1676
aravindfb7fe502014-05-05 15:16:56 -07001677static int
Jason Evans8d6a3e82015-03-18 18:55:33 -07001678arena_i_lg_dirty_mult_ctl(const size_t *mib, size_t miblen, void *oldp,
Jason Evanse2deab72014-05-15 22:22:27 -07001679 size_t *oldlenp, void *newp, size_t newlen)
aravindfb7fe502014-05-05 15:16:56 -07001680{
1681 int ret;
Christopher Ferrise4294032016-03-02 14:33:02 -08001682 unsigned arena_ind = (unsigned)mib[1];
aravindfb7fe502014-05-05 15:16:56 -07001683 arena_t *arena;
1684
Christopher Ferrise4294032016-03-02 14:33:02 -08001685 arena = arena_get(arena_ind, false);
Jason Evans8d6a3e82015-03-18 18:55:33 -07001686 if (arena == NULL) {
aravindfb7fe502014-05-05 15:16:56 -07001687 ret = EFAULT;
Jason Evans8d6a3e82015-03-18 18:55:33 -07001688 goto label_return;
aravindfb7fe502014-05-05 15:16:56 -07001689 }
Jason Evans8d6a3e82015-03-18 18:55:33 -07001690
1691 if (oldp != NULL && oldlenp != NULL) {
1692 size_t oldval = arena_lg_dirty_mult_get(arena);
1693 READ(oldval, ssize_t);
1694 }
1695 if (newp != NULL) {
1696 if (newlen != sizeof(ssize_t)) {
1697 ret = EINVAL;
1698 goto label_return;
1699 }
1700 if (arena_lg_dirty_mult_set(arena, *(ssize_t *)newp)) {
1701 ret = EFAULT;
1702 goto label_return;
1703 }
1704 }
1705
aravindfb7fe502014-05-05 15:16:56 -07001706 ret = 0;
1707label_return:
aravindfb7fe502014-05-05 15:16:56 -07001708 return (ret);
1709}
1710
Jason Evansb49a3342015-07-28 11:28:19 -04001711static int
Christopher Ferrise4294032016-03-02 14:33:02 -08001712arena_i_decay_time_ctl(const size_t *mib, size_t miblen, void *oldp,
1713 size_t *oldlenp, void *newp, size_t newlen)
1714{
1715 int ret;
1716 unsigned arena_ind = (unsigned)mib[1];
1717 arena_t *arena;
1718
1719 arena = arena_get(arena_ind, false);
1720 if (arena == NULL) {
1721 ret = EFAULT;
1722 goto label_return;
1723 }
1724
1725 if (oldp != NULL && oldlenp != NULL) {
1726 size_t oldval = arena_decay_time_get(arena);
1727 READ(oldval, ssize_t);
1728 }
1729 if (newp != NULL) {
1730 if (newlen != sizeof(ssize_t)) {
1731 ret = EINVAL;
1732 goto label_return;
1733 }
1734 if (arena_decay_time_set(arena, *(ssize_t *)newp)) {
1735 ret = EFAULT;
1736 goto label_return;
1737 }
1738 }
1739
1740 ret = 0;
1741label_return:
1742 return (ret);
1743}
1744
1745static int
Jason Evansb49a3342015-07-28 11:28:19 -04001746arena_i_chunk_hooks_ctl(const size_t *mib, size_t miblen, void *oldp,
1747 size_t *oldlenp, void *newp, size_t newlen)
1748{
1749 int ret;
Christopher Ferrise4294032016-03-02 14:33:02 -08001750 unsigned arena_ind = (unsigned)mib[1];
Jason Evansb49a3342015-07-28 11:28:19 -04001751 arena_t *arena;
1752
1753 malloc_mutex_lock(&ctl_mtx);
1754 if (arena_ind < narenas_total_get() && (arena =
Christopher Ferrise4294032016-03-02 14:33:02 -08001755 arena_get(arena_ind, false)) != NULL) {
Jason Evansb49a3342015-07-28 11:28:19 -04001756 if (newp != NULL) {
1757 chunk_hooks_t old_chunk_hooks, new_chunk_hooks;
1758 WRITE(new_chunk_hooks, chunk_hooks_t);
1759 old_chunk_hooks = chunk_hooks_set(arena,
1760 &new_chunk_hooks);
1761 READ(old_chunk_hooks, chunk_hooks_t);
1762 } else {
1763 chunk_hooks_t old_chunk_hooks = chunk_hooks_get(arena);
1764 READ(old_chunk_hooks, chunk_hooks_t);
1765 }
1766 } else {
1767 ret = EFAULT;
1768 goto label_return;
1769 }
1770 ret = 0;
1771label_return:
1772 malloc_mutex_unlock(&ctl_mtx);
1773 return (ret);
aravindfb7fe502014-05-05 15:16:56 -07001774}
1775
Jason Evans609ae592012-10-11 13:53:15 -07001776static const ctl_named_node_t *
1777arena_i_index(const size_t *mib, size_t miblen, size_t i)
1778{
1779 const ctl_named_node_t * ret;
1780
1781 malloc_mutex_lock(&ctl_mtx);
1782 if (i > ctl_stats.narenas) {
1783 ret = NULL;
1784 goto label_return;
1785 }
1786
1787 ret = super_arena_i_node;
1788label_return:
1789 malloc_mutex_unlock(&ctl_mtx);
1790 return (ret);
1791}
1792
Jason Evans609ae592012-10-11 13:53:15 -07001793/******************************************************************************/
1794
Jason Evans609ae592012-10-11 13:53:15 -07001795static int
1796arenas_narenas_ctl(const size_t *mib, size_t miblen, void *oldp,
1797 size_t *oldlenp, void *newp, size_t newlen)
1798{
1799 int ret;
1800 unsigned narenas;
1801
1802 malloc_mutex_lock(&ctl_mtx);
1803 READONLY();
1804 if (*oldlenp != sizeof(unsigned)) {
1805 ret = EINVAL;
1806 goto label_return;
1807 }
1808 narenas = ctl_stats.narenas;
1809 READ(narenas, unsigned);
1810
1811 ret = 0;
1812label_return:
1813 malloc_mutex_unlock(&ctl_mtx);
1814 return (ret);
1815}
Jason Evans3c234352010-01-27 13:10:55 -08001816
1817static int
1818arenas_initialized_ctl(const size_t *mib, size_t miblen, void *oldp,
1819 size_t *oldlenp, void *newp, size_t newlen)
1820{
1821 int ret;
1822 unsigned nread, i;
1823
Jason Evansfc4dcfa2010-11-24 15:44:21 -08001824 malloc_mutex_lock(&ctl_mtx);
Jason Evans3c234352010-01-27 13:10:55 -08001825 READONLY();
Jason Evans609ae592012-10-11 13:53:15 -07001826 if (*oldlenp != ctl_stats.narenas * sizeof(bool)) {
Jason Evans3c234352010-01-27 13:10:55 -08001827 ret = EINVAL;
Jason Evans609ae592012-10-11 13:53:15 -07001828 nread = (*oldlenp < ctl_stats.narenas * sizeof(bool))
Christopher Ferrise4294032016-03-02 14:33:02 -08001829 ? (unsigned)(*oldlenp / sizeof(bool)) : ctl_stats.narenas;
Jason Evans3c234352010-01-27 13:10:55 -08001830 } else {
1831 ret = 0;
Jason Evans609ae592012-10-11 13:53:15 -07001832 nread = ctl_stats.narenas;
Jason Evans3c234352010-01-27 13:10:55 -08001833 }
1834
1835 for (i = 0; i < nread; i++)
1836 ((bool *)oldp)[i] = ctl_stats.arenas[i].initialized;
1837
Jason Evansa1ee7832012-04-10 15:07:44 -07001838label_return:
Jason Evansfc4dcfa2010-11-24 15:44:21 -08001839 malloc_mutex_unlock(&ctl_mtx);
Jason Evans3c234352010-01-27 13:10:55 -08001840 return (ret);
1841}
1842
Jason Evans8d6a3e82015-03-18 18:55:33 -07001843static int
1844arenas_lg_dirty_mult_ctl(const size_t *mib, size_t miblen, void *oldp,
1845 size_t *oldlenp, void *newp, size_t newlen)
1846{
1847 int ret;
1848
1849 if (oldp != NULL && oldlenp != NULL) {
1850 size_t oldval = arena_lg_dirty_mult_default_get();
1851 READ(oldval, ssize_t);
1852 }
1853 if (newp != NULL) {
1854 if (newlen != sizeof(ssize_t)) {
1855 ret = EINVAL;
1856 goto label_return;
1857 }
1858 if (arena_lg_dirty_mult_default_set(*(ssize_t *)newp)) {
1859 ret = EFAULT;
1860 goto label_return;
1861 }
1862 }
1863
1864 ret = 0;
1865label_return:
1866 return (ret);
1867}
1868
Christopher Ferrise4294032016-03-02 14:33:02 -08001869static int
1870arenas_decay_time_ctl(const size_t *mib, size_t miblen, void *oldp,
1871 size_t *oldlenp, void *newp, size_t newlen)
1872{
1873 int ret;
1874
1875 if (oldp != NULL && oldlenp != NULL) {
1876 size_t oldval = arena_decay_time_default_get();
1877 READ(oldval, ssize_t);
1878 }
1879 if (newp != NULL) {
1880 if (newlen != sizeof(ssize_t)) {
1881 ret = EINVAL;
1882 goto label_return;
1883 }
1884 if (arena_decay_time_default_set(*(ssize_t *)newp)) {
1885 ret = EFAULT;
1886 goto label_return;
1887 }
1888 }
1889
1890 ret = 0;
1891label_return:
1892 return (ret);
1893}
1894
Jason Evansfc4dcfa2010-11-24 15:44:21 -08001895CTL_RO_NL_GEN(arenas_quantum, QUANTUM, size_t)
Jason Evansae4c7b42012-04-02 07:04:34 -07001896CTL_RO_NL_GEN(arenas_page, PAGE, size_t)
Jason Evans7372b152012-02-10 20:22:09 -08001897CTL_RO_NL_CGEN(config_tcache, arenas_tcache_max, tcache_maxclass, size_t)
Jason Evansb1726102012-02-28 16:50:47 -08001898CTL_RO_NL_GEN(arenas_nbins, NBINS, unsigned)
Jason Evans7372b152012-02-10 20:22:09 -08001899CTL_RO_NL_CGEN(config_tcache, arenas_nhbins, nhbins, unsigned)
Jason Evansd8a39002013-12-19 21:40:41 -08001900CTL_RO_NL_GEN(arenas_bin_i_size, arena_bin_info[mib[2]].reg_size, size_t)
1901CTL_RO_NL_GEN(arenas_bin_i_nregs, arena_bin_info[mib[2]].nregs, uint32_t)
1902CTL_RO_NL_GEN(arenas_bin_i_run_size, arena_bin_info[mib[2]].run_size, size_t)
1903static const ctl_named_node_t *
1904arenas_bin_i_index(const size_t *mib, size_t miblen, size_t i)
1905{
1906
1907 if (i > NBINS)
1908 return (NULL);
1909 return (super_arenas_bin_i_node);
1910}
1911
Jason Evans3c4d92e2014-10-12 22:53:59 -07001912CTL_RO_NL_GEN(arenas_nlruns, nlclasses, unsigned)
Christopher Ferrise4294032016-03-02 14:33:02 -08001913CTL_RO_NL_GEN(arenas_lrun_i_size, index2size(NBINS+(szind_t)mib[2]), size_t)
Jason Evansd8a39002013-12-19 21:40:41 -08001914static const ctl_named_node_t *
1915arenas_lrun_i_index(const size_t *mib, size_t miblen, size_t i)
1916{
1917
1918 if (i > nlclasses)
1919 return (NULL);
1920 return (super_arenas_lrun_i_node);
1921}
Jason Evans3c234352010-01-27 13:10:55 -08001922
Jason Evans3c4d92e2014-10-12 22:53:59 -07001923CTL_RO_NL_GEN(arenas_nhchunks, nhclasses, unsigned)
Christopher Ferrise4294032016-03-02 14:33:02 -08001924CTL_RO_NL_GEN(arenas_hchunk_i_size, index2size(NBINS+nlclasses+(szind_t)mib[2]),
1925 size_t)
Jason Evans3c4d92e2014-10-12 22:53:59 -07001926static const ctl_named_node_t *
1927arenas_hchunk_i_index(const size_t *mib, size_t miblen, size_t i)
1928{
1929
1930 if (i > nhclasses)
1931 return (NULL);
1932 return (super_arenas_hchunk_i_node);
1933}
1934
Jason Evans6005f072010-09-30 16:55:08 -07001935static int
Jason Evans609ae592012-10-11 13:53:15 -07001936arenas_extend_ctl(const size_t *mib, size_t miblen, void *oldp, size_t *oldlenp,
1937 void *newp, size_t newlen)
1938{
1939 int ret;
Jason Evans6eb84fb2012-11-29 22:13:04 -08001940 unsigned narenas;
Jason Evans609ae592012-10-11 13:53:15 -07001941
1942 malloc_mutex_lock(&ctl_mtx);
1943 READONLY();
1944 if (ctl_grow()) {
1945 ret = EAGAIN;
1946 goto label_return;
1947 }
Jason Evans6eb84fb2012-11-29 22:13:04 -08001948 narenas = ctl_stats.narenas - 1;
1949 READ(narenas, unsigned);
Jason Evans609ae592012-10-11 13:53:15 -07001950
Jason Evans6005f072010-09-30 16:55:08 -07001951 ret = 0;
Jason Evansa1ee7832012-04-10 15:07:44 -07001952label_return:
Jason Evans609ae592012-10-11 13:53:15 -07001953 malloc_mutex_unlock(&ctl_mtx);
Jason Evans6005f072010-09-30 16:55:08 -07001954 return (ret);
1955}
1956
Jason Evans3c234352010-01-27 13:10:55 -08001957/******************************************************************************/
1958
Jason Evansd34f9e72010-02-11 13:19:21 -08001959static int
Jason Evansfc12c0b2014-10-03 23:25:30 -07001960prof_thread_active_init_ctl(const size_t *mib, size_t miblen, void *oldp,
1961 size_t *oldlenp, void *newp, size_t newlen)
1962{
1963 int ret;
1964 bool oldval;
1965
1966 if (!config_prof)
1967 return (ENOENT);
1968
1969 if (newp != NULL) {
1970 if (newlen != sizeof(bool)) {
1971 ret = EINVAL;
1972 goto label_return;
1973 }
1974 oldval = prof_thread_active_init_set(*(bool *)newp);
1975 } else
1976 oldval = prof_thread_active_init_get();
1977 READ(oldval, bool);
1978
1979 ret = 0;
1980label_return:
1981 return (ret);
1982}
1983
1984static int
Jason Evansf18c9822010-03-31 18:43:24 -07001985prof_active_ctl(const size_t *mib, size_t miblen, void *oldp, size_t *oldlenp,
1986 void *newp, size_t newlen)
1987{
1988 int ret;
1989 bool oldval;
1990
Jason Evans551ebc42014-10-03 10:16:09 -07001991 if (!config_prof)
Jason Evans7372b152012-02-10 20:22:09 -08001992 return (ENOENT);
1993
Jason Evansf18c9822010-03-31 18:43:24 -07001994 if (newp != NULL) {
Jason Evansfc12c0b2014-10-03 23:25:30 -07001995 if (newlen != sizeof(bool)) {
1996 ret = EINVAL;
1997 goto label_return;
1998 }
1999 oldval = prof_active_set(*(bool *)newp);
2000 } else
2001 oldval = prof_active_get();
Jason Evansf18c9822010-03-31 18:43:24 -07002002 READ(oldval, bool);
2003
2004 ret = 0;
Jason Evansa1ee7832012-04-10 15:07:44 -07002005label_return:
Jason Evansf18c9822010-03-31 18:43:24 -07002006 return (ret);
2007}
2008
2009static int
Jason Evansd34f9e72010-02-11 13:19:21 -08002010prof_dump_ctl(const size_t *mib, size_t miblen, void *oldp, size_t *oldlenp,
2011 void *newp, size_t newlen)
2012{
2013 int ret;
Jason Evans22ca8552010-03-02 11:57:30 -08002014 const char *filename = NULL;
Jason Evansd34f9e72010-02-11 13:19:21 -08002015
Jason Evans551ebc42014-10-03 10:16:09 -07002016 if (!config_prof)
Jason Evans7372b152012-02-10 20:22:09 -08002017 return (ENOENT);
2018
Jason Evans22ca8552010-03-02 11:57:30 -08002019 WRITEONLY();
2020 WRITE(filename, const char *);
Jason Evansd34f9e72010-02-11 13:19:21 -08002021
Jason Evans22ca8552010-03-02 11:57:30 -08002022 if (prof_mdump(filename)) {
2023 ret = EFAULT;
Jason Evansa1ee7832012-04-10 15:07:44 -07002024 goto label_return;
Jason Evans22ca8552010-03-02 11:57:30 -08002025 }
Jason Evansd34f9e72010-02-11 13:19:21 -08002026
2027 ret = 0;
Jason Evansa1ee7832012-04-10 15:07:44 -07002028label_return:
Jason Evansd34f9e72010-02-11 13:19:21 -08002029 return (ret);
2030}
2031
Jason Evans602c8e02014-08-18 16:22:13 -07002032static int
Jason Evans5b8ed5b2015-01-25 21:16:57 -08002033prof_gdump_ctl(const size_t *mib, size_t miblen, void *oldp, size_t *oldlenp,
2034 void *newp, size_t newlen)
2035{
2036 int ret;
2037 bool oldval;
2038
2039 if (!config_prof)
2040 return (ENOENT);
2041
2042 if (newp != NULL) {
2043 if (newlen != sizeof(bool)) {
2044 ret = EINVAL;
2045 goto label_return;
2046 }
2047 oldval = prof_gdump_set(*(bool *)newp);
2048 } else
2049 oldval = prof_gdump_get();
2050 READ(oldval, bool);
2051
2052 ret = 0;
2053label_return:
2054 return (ret);
2055}
2056
2057static int
Jason Evans602c8e02014-08-18 16:22:13 -07002058prof_reset_ctl(const size_t *mib, size_t miblen, void *oldp, size_t *oldlenp,
2059 void *newp, size_t newlen)
2060{
2061 int ret;
2062 size_t lg_sample = lg_prof_sample;
Jason Evans5460aa62014-09-22 21:09:23 -07002063 tsd_t *tsd;
Jason Evans602c8e02014-08-18 16:22:13 -07002064
Jason Evans551ebc42014-10-03 10:16:09 -07002065 if (!config_prof)
Jason Evans602c8e02014-08-18 16:22:13 -07002066 return (ENOENT);
2067
2068 WRITEONLY();
2069 WRITE(lg_sample, size_t);
2070 if (lg_sample >= (sizeof(uint64_t) << 3))
2071 lg_sample = (sizeof(uint64_t) << 3) - 1;
2072
Jason Evans029d44c2014-10-04 11:12:53 -07002073 tsd = tsd_fetch();
Jason Evans5460aa62014-09-22 21:09:23 -07002074
2075 prof_reset(tsd, lg_sample);
Jason Evans602c8e02014-08-18 16:22:13 -07002076
2077 ret = 0;
2078label_return:
2079 return (ret);
2080}
2081
Jason Evans7372b152012-02-10 20:22:09 -08002082CTL_RO_NL_CGEN(config_prof, prof_interval, prof_interval, uint64_t)
Jason Evans602c8e02014-08-18 16:22:13 -07002083CTL_RO_NL_CGEN(config_prof, lg_prof_sample, lg_prof_sample, size_t)
Jason Evansd34f9e72010-02-11 13:19:21 -08002084
2085/******************************************************************************/
2086
Jason Evansd8a39002013-12-19 21:40:41 -08002087CTL_RO_CGEN(config_stats, stats_cactive, &stats_cactive, size_t *)
2088CTL_RO_CGEN(config_stats, stats_allocated, ctl_stats.allocated, size_t)
2089CTL_RO_CGEN(config_stats, stats_active, ctl_stats.active, size_t)
Jason Evans4581b972014-11-27 17:22:36 -02002090CTL_RO_CGEN(config_stats, stats_metadata, ctl_stats.metadata, size_t)
Jason Evans4acd75a2015-03-23 17:25:57 -07002091CTL_RO_CGEN(config_stats, stats_resident, ctl_stats.resident, size_t)
Jason Evansd8a39002013-12-19 21:40:41 -08002092CTL_RO_CGEN(config_stats, stats_mapped, ctl_stats.mapped, size_t)
2093
Jason Evansd8a39002013-12-19 21:40:41 -08002094CTL_RO_GEN(stats_arenas_i_dss, ctl_stats.arenas[mib[2]].dss, const char *)
Jason Evans562d2662015-03-24 16:36:12 -07002095CTL_RO_GEN(stats_arenas_i_lg_dirty_mult, ctl_stats.arenas[mib[2]].lg_dirty_mult,
2096 ssize_t)
Christopher Ferrise4294032016-03-02 14:33:02 -08002097CTL_RO_GEN(stats_arenas_i_decay_time, ctl_stats.arenas[mib[2]].decay_time,
2098 ssize_t)
Jason Evansd8a39002013-12-19 21:40:41 -08002099CTL_RO_GEN(stats_arenas_i_nthreads, ctl_stats.arenas[mib[2]].nthreads, unsigned)
2100CTL_RO_GEN(stats_arenas_i_pactive, ctl_stats.arenas[mib[2]].pactive, size_t)
2101CTL_RO_GEN(stats_arenas_i_pdirty, ctl_stats.arenas[mib[2]].pdirty, size_t)
2102CTL_RO_CGEN(config_stats, stats_arenas_i_mapped,
2103 ctl_stats.arenas[mib[2]].astats.mapped, size_t)
2104CTL_RO_CGEN(config_stats, stats_arenas_i_npurge,
2105 ctl_stats.arenas[mib[2]].astats.npurge, uint64_t)
2106CTL_RO_CGEN(config_stats, stats_arenas_i_nmadvise,
2107 ctl_stats.arenas[mib[2]].astats.nmadvise, uint64_t)
2108CTL_RO_CGEN(config_stats, stats_arenas_i_purged,
2109 ctl_stats.arenas[mib[2]].astats.purged, uint64_t)
Jason Evans4581b972014-11-27 17:22:36 -02002110CTL_RO_CGEN(config_stats, stats_arenas_i_metadata_mapped,
2111 ctl_stats.arenas[mib[2]].astats.metadata_mapped, size_t)
2112CTL_RO_CGEN(config_stats, stats_arenas_i_metadata_allocated,
2113 ctl_stats.arenas[mib[2]].astats.metadata_allocated, size_t)
Jason Evansd8a39002013-12-19 21:40:41 -08002114
Jason Evans7372b152012-02-10 20:22:09 -08002115CTL_RO_CGEN(config_stats, stats_arenas_i_small_allocated,
Jason Evans86815df2010-03-13 20:32:56 -08002116 ctl_stats.arenas[mib[2]].allocated_small, size_t)
Jason Evans7372b152012-02-10 20:22:09 -08002117CTL_RO_CGEN(config_stats, stats_arenas_i_small_nmalloc,
Jason Evans86815df2010-03-13 20:32:56 -08002118 ctl_stats.arenas[mib[2]].nmalloc_small, uint64_t)
Jason Evans7372b152012-02-10 20:22:09 -08002119CTL_RO_CGEN(config_stats, stats_arenas_i_small_ndalloc,
Jason Evans86815df2010-03-13 20:32:56 -08002120 ctl_stats.arenas[mib[2]].ndalloc_small, uint64_t)
Jason Evans7372b152012-02-10 20:22:09 -08002121CTL_RO_CGEN(config_stats, stats_arenas_i_small_nrequests,
Jason Evans86815df2010-03-13 20:32:56 -08002122 ctl_stats.arenas[mib[2]].nrequests_small, uint64_t)
Jason Evans7372b152012-02-10 20:22:09 -08002123CTL_RO_CGEN(config_stats, stats_arenas_i_large_allocated,
Jason Evans3c234352010-01-27 13:10:55 -08002124 ctl_stats.arenas[mib[2]].astats.allocated_large, size_t)
Jason Evans7372b152012-02-10 20:22:09 -08002125CTL_RO_CGEN(config_stats, stats_arenas_i_large_nmalloc,
Jason Evans3c234352010-01-27 13:10:55 -08002126 ctl_stats.arenas[mib[2]].astats.nmalloc_large, uint64_t)
Jason Evans7372b152012-02-10 20:22:09 -08002127CTL_RO_CGEN(config_stats, stats_arenas_i_large_ndalloc,
Jason Evans3c234352010-01-27 13:10:55 -08002128 ctl_stats.arenas[mib[2]].astats.ndalloc_large, uint64_t)
Jason Evans7372b152012-02-10 20:22:09 -08002129CTL_RO_CGEN(config_stats, stats_arenas_i_large_nrequests,
Jason Evansdafde142010-03-17 16:27:39 -07002130 ctl_stats.arenas[mib[2]].astats.nrequests_large, uint64_t)
Jason Evanse2deab72014-05-15 22:22:27 -07002131CTL_RO_CGEN(config_stats, stats_arenas_i_huge_allocated,
2132 ctl_stats.arenas[mib[2]].astats.allocated_huge, size_t)
2133CTL_RO_CGEN(config_stats, stats_arenas_i_huge_nmalloc,
2134 ctl_stats.arenas[mib[2]].astats.nmalloc_huge, uint64_t)
2135CTL_RO_CGEN(config_stats, stats_arenas_i_huge_ndalloc,
2136 ctl_stats.arenas[mib[2]].astats.ndalloc_huge, uint64_t)
2137CTL_RO_CGEN(config_stats, stats_arenas_i_huge_nrequests,
Jason Evans3c4d92e2014-10-12 22:53:59 -07002138 ctl_stats.arenas[mib[2]].astats.nmalloc_huge, uint64_t) /* Intentional. */
Jason Evans3c234352010-01-27 13:10:55 -08002139
Jason Evans7372b152012-02-10 20:22:09 -08002140CTL_RO_CGEN(config_stats, stats_arenas_i_bins_j_nmalloc,
Jason Evans86815df2010-03-13 20:32:56 -08002141 ctl_stats.arenas[mib[2]].bstats[mib[4]].nmalloc, uint64_t)
Jason Evans7372b152012-02-10 20:22:09 -08002142CTL_RO_CGEN(config_stats, stats_arenas_i_bins_j_ndalloc,
Jason Evans86815df2010-03-13 20:32:56 -08002143 ctl_stats.arenas[mib[2]].bstats[mib[4]].ndalloc, uint64_t)
Jason Evans7372b152012-02-10 20:22:09 -08002144CTL_RO_CGEN(config_stats, stats_arenas_i_bins_j_nrequests,
Jason Evans3c234352010-01-27 13:10:55 -08002145 ctl_stats.arenas[mib[2]].bstats[mib[4]].nrequests, uint64_t)
Jason Evans3c4d92e2014-10-12 22:53:59 -07002146CTL_RO_CGEN(config_stats, stats_arenas_i_bins_j_curregs,
2147 ctl_stats.arenas[mib[2]].bstats[mib[4]].curregs, size_t)
Jason Evans7372b152012-02-10 20:22:09 -08002148CTL_RO_CGEN(config_stats && config_tcache, stats_arenas_i_bins_j_nfills,
Jason Evans3c234352010-01-27 13:10:55 -08002149 ctl_stats.arenas[mib[2]].bstats[mib[4]].nfills, uint64_t)
Jason Evans7372b152012-02-10 20:22:09 -08002150CTL_RO_CGEN(config_stats && config_tcache, stats_arenas_i_bins_j_nflushes,
Jason Evans3c234352010-01-27 13:10:55 -08002151 ctl_stats.arenas[mib[2]].bstats[mib[4]].nflushes, uint64_t)
Jason Evans7372b152012-02-10 20:22:09 -08002152CTL_RO_CGEN(config_stats, stats_arenas_i_bins_j_nruns,
Jason Evans3c234352010-01-27 13:10:55 -08002153 ctl_stats.arenas[mib[2]].bstats[mib[4]].nruns, uint64_t)
Jason Evans7372b152012-02-10 20:22:09 -08002154CTL_RO_CGEN(config_stats, stats_arenas_i_bins_j_nreruns,
Jason Evans3c234352010-01-27 13:10:55 -08002155 ctl_stats.arenas[mib[2]].bstats[mib[4]].reruns, uint64_t)
Jason Evans7372b152012-02-10 20:22:09 -08002156CTL_RO_CGEN(config_stats, stats_arenas_i_bins_j_curruns,
Jason Evans3c234352010-01-27 13:10:55 -08002157 ctl_stats.arenas[mib[2]].bstats[mib[4]].curruns, size_t)
2158
Jason Evans609ae592012-10-11 13:53:15 -07002159static const ctl_named_node_t *
Jason Evans3c234352010-01-27 13:10:55 -08002160stats_arenas_i_bins_j_index(const size_t *mib, size_t miblen, size_t j)
2161{
2162
Jason Evansb1726102012-02-28 16:50:47 -08002163 if (j > NBINS)
Jason Evans3c234352010-01-27 13:10:55 -08002164 return (NULL);
2165 return (super_stats_arenas_i_bins_j_node);
2166}
2167
Jason Evans7372b152012-02-10 20:22:09 -08002168CTL_RO_CGEN(config_stats, stats_arenas_i_lruns_j_nmalloc,
Jason Evansdafde142010-03-17 16:27:39 -07002169 ctl_stats.arenas[mib[2]].lstats[mib[4]].nmalloc, uint64_t)
Jason Evans7372b152012-02-10 20:22:09 -08002170CTL_RO_CGEN(config_stats, stats_arenas_i_lruns_j_ndalloc,
Jason Evansdafde142010-03-17 16:27:39 -07002171 ctl_stats.arenas[mib[2]].lstats[mib[4]].ndalloc, uint64_t)
Jason Evans7372b152012-02-10 20:22:09 -08002172CTL_RO_CGEN(config_stats, stats_arenas_i_lruns_j_nrequests,
Jason Evans3c234352010-01-27 13:10:55 -08002173 ctl_stats.arenas[mib[2]].lstats[mib[4]].nrequests, uint64_t)
Jason Evans7372b152012-02-10 20:22:09 -08002174CTL_RO_CGEN(config_stats, stats_arenas_i_lruns_j_curruns,
Jason Evans3c234352010-01-27 13:10:55 -08002175 ctl_stats.arenas[mib[2]].lstats[mib[4]].curruns, size_t)
Jason Evans3c234352010-01-27 13:10:55 -08002176
Jason Evans609ae592012-10-11 13:53:15 -07002177static const ctl_named_node_t *
Jason Evans3c234352010-01-27 13:10:55 -08002178stats_arenas_i_lruns_j_index(const size_t *mib, size_t miblen, size_t j)
2179{
2180
2181 if (j > nlclasses)
2182 return (NULL);
2183 return (super_stats_arenas_i_lruns_j_node);
2184}
2185
Jason Evans3c4d92e2014-10-12 22:53:59 -07002186CTL_RO_CGEN(config_stats, stats_arenas_i_hchunks_j_nmalloc,
2187 ctl_stats.arenas[mib[2]].hstats[mib[4]].nmalloc, uint64_t)
2188CTL_RO_CGEN(config_stats, stats_arenas_i_hchunks_j_ndalloc,
2189 ctl_stats.arenas[mib[2]].hstats[mib[4]].ndalloc, uint64_t)
2190CTL_RO_CGEN(config_stats, stats_arenas_i_hchunks_j_nrequests,
2191 ctl_stats.arenas[mib[2]].hstats[mib[4]].nmalloc, /* Intentional. */
2192 uint64_t)
2193CTL_RO_CGEN(config_stats, stats_arenas_i_hchunks_j_curhchunks,
2194 ctl_stats.arenas[mib[2]].hstats[mib[4]].curhchunks, size_t)
2195
2196static const ctl_named_node_t *
2197stats_arenas_i_hchunks_j_index(const size_t *mib, size_t miblen, size_t j)
2198{
2199
2200 if (j > nhclasses)
2201 return (NULL);
2202 return (super_stats_arenas_i_hchunks_j_node);
2203}
2204
Jason Evans609ae592012-10-11 13:53:15 -07002205static const ctl_named_node_t *
Jason Evans3c234352010-01-27 13:10:55 -08002206stats_arenas_i_index(const size_t *mib, size_t miblen, size_t i)
2207{
Mike Hommey461ad5c2012-04-20 08:38:42 +02002208 const ctl_named_node_t * ret;
Jason Evans3c234352010-01-27 13:10:55 -08002209
Jason Evansfc4dcfa2010-11-24 15:44:21 -08002210 malloc_mutex_lock(&ctl_mtx);
Jason Evans551ebc42014-10-03 10:16:09 -07002211 if (i > ctl_stats.narenas || !ctl_stats.arenas[i].initialized) {
Jason Evansfc4dcfa2010-11-24 15:44:21 -08002212 ret = NULL;
Jason Evansa1ee7832012-04-10 15:07:44 -07002213 goto label_return;
Jason Evansfc4dcfa2010-11-24 15:44:21 -08002214 }
2215
2216 ret = super_stats_arenas_i_node;
Jason Evansa1ee7832012-04-10 15:07:44 -07002217label_return:
Jason Evansfc4dcfa2010-11-24 15:44:21 -08002218 malloc_mutex_unlock(&ctl_mtx);
2219 return (ret);
Jason Evans3c234352010-01-27 13:10:55 -08002220}