1a4bd5210SJason Evans #define JEMALLOC_CTL_C_ 2a4bd5210SJason Evans #include "jemalloc/internal/jemalloc_internal.h" 3a4bd5210SJason Evans 4a4bd5210SJason Evans /******************************************************************************/ 5a4bd5210SJason Evans /* Data. */ 6a4bd5210SJason Evans 7a4bd5210SJason Evans /* 8a4bd5210SJason Evans * ctl_mtx protects the following: 9a4bd5210SJason Evans * - ctl_stats.* 10a4bd5210SJason Evans */ 11a4bd5210SJason Evans static malloc_mutex_t ctl_mtx; 12a4bd5210SJason Evans static bool ctl_initialized; 13a4bd5210SJason Evans static uint64_t ctl_epoch; 14a4bd5210SJason Evans static ctl_stats_t ctl_stats; 15a4bd5210SJason Evans 16a4bd5210SJason Evans /******************************************************************************/ 17e722f8f8SJason Evans /* Helpers for named and indexed nodes. */ 18e722f8f8SJason Evans 19d0e79aa3SJason Evans JEMALLOC_INLINE_C const ctl_named_node_t * 20e722f8f8SJason Evans ctl_named_node(const ctl_node_t *node) 21e722f8f8SJason Evans { 22e722f8f8SJason Evans 23e722f8f8SJason Evans return ((node->named) ? (const ctl_named_node_t *)node : NULL); 24e722f8f8SJason Evans } 25e722f8f8SJason Evans 26d0e79aa3SJason Evans JEMALLOC_INLINE_C const ctl_named_node_t * 27df0d881dSJason Evans ctl_named_children(const ctl_named_node_t *node, size_t index) 28e722f8f8SJason Evans { 29e722f8f8SJason Evans const ctl_named_node_t *children = ctl_named_node(node->children); 30e722f8f8SJason Evans 31e722f8f8SJason Evans return (children ? &children[index] : NULL); 32e722f8f8SJason Evans } 33e722f8f8SJason Evans 34d0e79aa3SJason Evans JEMALLOC_INLINE_C const ctl_indexed_node_t * 35e722f8f8SJason Evans ctl_indexed_node(const ctl_node_t *node) 36e722f8f8SJason Evans { 37e722f8f8SJason Evans 38d0e79aa3SJason Evans return (!node->named ? (const ctl_indexed_node_t *)node : NULL); 39e722f8f8SJason Evans } 40e722f8f8SJason Evans 41e722f8f8SJason Evans /******************************************************************************/ 42a4bd5210SJason Evans /* Function prototypes for non-inline static functions. */ 43a4bd5210SJason Evans 44a4bd5210SJason Evans #define CTL_PROTO(n) \ 451f0a49e8SJason Evans static int n##_ctl(tsd_t *tsd, const size_t *mib, size_t miblen, \ 461f0a49e8SJason Evans void *oldp, size_t *oldlenp, void *newp, size_t newlen); 47a4bd5210SJason Evans 48a4bd5210SJason Evans #define INDEX_PROTO(n) \ 491f0a49e8SJason Evans static const ctl_named_node_t *n##_index(tsdn_t *tsdn, \ 501f0a49e8SJason Evans const size_t *mib, size_t miblen, size_t i); 51a4bd5210SJason Evans 52a4bd5210SJason Evans static bool ctl_arena_init(ctl_arena_stats_t *astats); 53a4bd5210SJason Evans static void ctl_arena_clear(ctl_arena_stats_t *astats); 541f0a49e8SJason Evans static void ctl_arena_stats_amerge(tsdn_t *tsdn, ctl_arena_stats_t *cstats, 55a4bd5210SJason Evans arena_t *arena); 56a4bd5210SJason Evans static void ctl_arena_stats_smerge(ctl_arena_stats_t *sstats, 57a4bd5210SJason Evans ctl_arena_stats_t *astats); 581f0a49e8SJason Evans static void ctl_arena_refresh(tsdn_t *tsdn, arena_t *arena, unsigned i); 591f0a49e8SJason Evans static bool ctl_grow(tsdn_t *tsdn); 601f0a49e8SJason Evans static void ctl_refresh(tsdn_t *tsdn); 611f0a49e8SJason Evans static bool ctl_init(tsdn_t *tsdn); 621f0a49e8SJason Evans static int ctl_lookup(tsdn_t *tsdn, const char *name, 631f0a49e8SJason Evans ctl_node_t const **nodesp, size_t *mibp, size_t *depthp); 64a4bd5210SJason Evans 65a4bd5210SJason Evans CTL_PROTO(version) 66a4bd5210SJason Evans CTL_PROTO(epoch) 67a4bd5210SJason Evans CTL_PROTO(thread_tcache_enabled) 68a4bd5210SJason Evans CTL_PROTO(thread_tcache_flush) 69d0e79aa3SJason Evans CTL_PROTO(thread_prof_name) 70d0e79aa3SJason Evans CTL_PROTO(thread_prof_active) 71a4bd5210SJason Evans CTL_PROTO(thread_arena) 72a4bd5210SJason Evans CTL_PROTO(thread_allocated) 73a4bd5210SJason Evans CTL_PROTO(thread_allocatedp) 74a4bd5210SJason Evans CTL_PROTO(thread_deallocated) 75a4bd5210SJason Evans CTL_PROTO(thread_deallocatedp) 76d0e79aa3SJason Evans CTL_PROTO(config_cache_oblivious) 77a4bd5210SJason Evans CTL_PROTO(config_debug) 78a4bd5210SJason Evans CTL_PROTO(config_fill) 79a4bd5210SJason Evans CTL_PROTO(config_lazy_lock) 80df0d881dSJason Evans CTL_PROTO(config_malloc_conf) 81a4bd5210SJason Evans CTL_PROTO(config_munmap) 82a4bd5210SJason Evans CTL_PROTO(config_prof) 83a4bd5210SJason Evans CTL_PROTO(config_prof_libgcc) 84a4bd5210SJason Evans CTL_PROTO(config_prof_libunwind) 85a4bd5210SJason Evans CTL_PROTO(config_stats) 86a4bd5210SJason Evans CTL_PROTO(config_tcache) 87a4bd5210SJason Evans CTL_PROTO(config_tls) 88a4bd5210SJason Evans CTL_PROTO(config_utrace) 89a4bd5210SJason Evans CTL_PROTO(config_valgrind) 90a4bd5210SJason Evans CTL_PROTO(config_xmalloc) 91a4bd5210SJason Evans CTL_PROTO(opt_abort) 9282872ac0SJason Evans CTL_PROTO(opt_dss) 93a4bd5210SJason Evans CTL_PROTO(opt_lg_chunk) 94a4bd5210SJason Evans CTL_PROTO(opt_narenas) 95df0d881dSJason Evans CTL_PROTO(opt_purge) 96a4bd5210SJason Evans CTL_PROTO(opt_lg_dirty_mult) 97df0d881dSJason Evans CTL_PROTO(opt_decay_time) 98a4bd5210SJason Evans CTL_PROTO(opt_stats_print) 99a4bd5210SJason Evans CTL_PROTO(opt_junk) 100a4bd5210SJason Evans CTL_PROTO(opt_zero) 101a4bd5210SJason Evans CTL_PROTO(opt_quarantine) 102a4bd5210SJason Evans CTL_PROTO(opt_redzone) 103a4bd5210SJason Evans CTL_PROTO(opt_utrace) 104a4bd5210SJason Evans CTL_PROTO(opt_xmalloc) 105a4bd5210SJason Evans CTL_PROTO(opt_tcache) 106a4bd5210SJason Evans CTL_PROTO(opt_lg_tcache_max) 107a4bd5210SJason Evans CTL_PROTO(opt_prof) 108a4bd5210SJason Evans CTL_PROTO(opt_prof_prefix) 109a4bd5210SJason Evans CTL_PROTO(opt_prof_active) 110d0e79aa3SJason Evans CTL_PROTO(opt_prof_thread_active_init) 111a4bd5210SJason Evans CTL_PROTO(opt_lg_prof_sample) 112a4bd5210SJason Evans CTL_PROTO(opt_lg_prof_interval) 113a4bd5210SJason Evans CTL_PROTO(opt_prof_gdump) 1148ed34ab0SJason Evans CTL_PROTO(opt_prof_final) 115a4bd5210SJason Evans CTL_PROTO(opt_prof_leak) 116a4bd5210SJason Evans CTL_PROTO(opt_prof_accum) 117d0e79aa3SJason Evans CTL_PROTO(tcache_create) 118d0e79aa3SJason Evans CTL_PROTO(tcache_flush) 119d0e79aa3SJason Evans CTL_PROTO(tcache_destroy) 1201f0a49e8SJason Evans static void arena_i_purge(tsdn_t *tsdn, unsigned arena_ind, bool all); 12182872ac0SJason Evans CTL_PROTO(arena_i_purge) 122df0d881dSJason Evans CTL_PROTO(arena_i_decay) 1231f0a49e8SJason Evans CTL_PROTO(arena_i_reset) 12482872ac0SJason Evans CTL_PROTO(arena_i_dss) 125d0e79aa3SJason Evans CTL_PROTO(arena_i_lg_dirty_mult) 126df0d881dSJason Evans CTL_PROTO(arena_i_decay_time) 127d0e79aa3SJason Evans CTL_PROTO(arena_i_chunk_hooks) 12882872ac0SJason Evans INDEX_PROTO(arena_i) 129a4bd5210SJason Evans CTL_PROTO(arenas_bin_i_size) 130a4bd5210SJason Evans CTL_PROTO(arenas_bin_i_nregs) 131a4bd5210SJason Evans CTL_PROTO(arenas_bin_i_run_size) 132a4bd5210SJason Evans INDEX_PROTO(arenas_bin_i) 133a4bd5210SJason Evans CTL_PROTO(arenas_lrun_i_size) 134a4bd5210SJason Evans INDEX_PROTO(arenas_lrun_i) 135d0e79aa3SJason Evans CTL_PROTO(arenas_hchunk_i_size) 136d0e79aa3SJason Evans INDEX_PROTO(arenas_hchunk_i) 137a4bd5210SJason Evans CTL_PROTO(arenas_narenas) 138a4bd5210SJason Evans CTL_PROTO(arenas_initialized) 139d0e79aa3SJason Evans CTL_PROTO(arenas_lg_dirty_mult) 140df0d881dSJason Evans CTL_PROTO(arenas_decay_time) 141a4bd5210SJason Evans CTL_PROTO(arenas_quantum) 142a4bd5210SJason Evans CTL_PROTO(arenas_page) 143a4bd5210SJason Evans CTL_PROTO(arenas_tcache_max) 144a4bd5210SJason Evans CTL_PROTO(arenas_nbins) 145a4bd5210SJason Evans CTL_PROTO(arenas_nhbins) 146a4bd5210SJason Evans CTL_PROTO(arenas_nlruns) 147d0e79aa3SJason Evans CTL_PROTO(arenas_nhchunks) 14882872ac0SJason Evans CTL_PROTO(arenas_extend) 149d0e79aa3SJason Evans CTL_PROTO(prof_thread_active_init) 150a4bd5210SJason Evans CTL_PROTO(prof_active) 151a4bd5210SJason Evans CTL_PROTO(prof_dump) 152d0e79aa3SJason Evans CTL_PROTO(prof_gdump) 153d0e79aa3SJason Evans CTL_PROTO(prof_reset) 154a4bd5210SJason Evans CTL_PROTO(prof_interval) 155d0e79aa3SJason Evans CTL_PROTO(lg_prof_sample) 156a4bd5210SJason Evans CTL_PROTO(stats_arenas_i_small_allocated) 157a4bd5210SJason Evans CTL_PROTO(stats_arenas_i_small_nmalloc) 158a4bd5210SJason Evans CTL_PROTO(stats_arenas_i_small_ndalloc) 159a4bd5210SJason Evans CTL_PROTO(stats_arenas_i_small_nrequests) 160a4bd5210SJason Evans CTL_PROTO(stats_arenas_i_large_allocated) 161a4bd5210SJason Evans CTL_PROTO(stats_arenas_i_large_nmalloc) 162a4bd5210SJason Evans CTL_PROTO(stats_arenas_i_large_ndalloc) 163a4bd5210SJason Evans CTL_PROTO(stats_arenas_i_large_nrequests) 164d0e79aa3SJason Evans CTL_PROTO(stats_arenas_i_huge_allocated) 165d0e79aa3SJason Evans CTL_PROTO(stats_arenas_i_huge_nmalloc) 166d0e79aa3SJason Evans CTL_PROTO(stats_arenas_i_huge_ndalloc) 167d0e79aa3SJason Evans CTL_PROTO(stats_arenas_i_huge_nrequests) 168a4bd5210SJason Evans CTL_PROTO(stats_arenas_i_bins_j_nmalloc) 169a4bd5210SJason Evans CTL_PROTO(stats_arenas_i_bins_j_ndalloc) 170a4bd5210SJason Evans CTL_PROTO(stats_arenas_i_bins_j_nrequests) 171d0e79aa3SJason Evans CTL_PROTO(stats_arenas_i_bins_j_curregs) 172a4bd5210SJason Evans CTL_PROTO(stats_arenas_i_bins_j_nfills) 173a4bd5210SJason Evans CTL_PROTO(stats_arenas_i_bins_j_nflushes) 174a4bd5210SJason Evans CTL_PROTO(stats_arenas_i_bins_j_nruns) 175a4bd5210SJason Evans CTL_PROTO(stats_arenas_i_bins_j_nreruns) 176a4bd5210SJason Evans CTL_PROTO(stats_arenas_i_bins_j_curruns) 177a4bd5210SJason Evans INDEX_PROTO(stats_arenas_i_bins_j) 178a4bd5210SJason Evans CTL_PROTO(stats_arenas_i_lruns_j_nmalloc) 179a4bd5210SJason Evans CTL_PROTO(stats_arenas_i_lruns_j_ndalloc) 180a4bd5210SJason Evans CTL_PROTO(stats_arenas_i_lruns_j_nrequests) 181a4bd5210SJason Evans CTL_PROTO(stats_arenas_i_lruns_j_curruns) 182a4bd5210SJason Evans INDEX_PROTO(stats_arenas_i_lruns_j) 183d0e79aa3SJason Evans CTL_PROTO(stats_arenas_i_hchunks_j_nmalloc) 184d0e79aa3SJason Evans CTL_PROTO(stats_arenas_i_hchunks_j_ndalloc) 185d0e79aa3SJason Evans CTL_PROTO(stats_arenas_i_hchunks_j_nrequests) 186d0e79aa3SJason Evans CTL_PROTO(stats_arenas_i_hchunks_j_curhchunks) 187d0e79aa3SJason Evans INDEX_PROTO(stats_arenas_i_hchunks_j) 188a4bd5210SJason Evans CTL_PROTO(stats_arenas_i_nthreads) 18982872ac0SJason Evans CTL_PROTO(stats_arenas_i_dss) 190d0e79aa3SJason Evans CTL_PROTO(stats_arenas_i_lg_dirty_mult) 191df0d881dSJason Evans CTL_PROTO(stats_arenas_i_decay_time) 192a4bd5210SJason Evans CTL_PROTO(stats_arenas_i_pactive) 193a4bd5210SJason Evans CTL_PROTO(stats_arenas_i_pdirty) 194a4bd5210SJason Evans CTL_PROTO(stats_arenas_i_mapped) 1951f0a49e8SJason Evans CTL_PROTO(stats_arenas_i_retained) 196a4bd5210SJason Evans CTL_PROTO(stats_arenas_i_npurge) 197a4bd5210SJason Evans CTL_PROTO(stats_arenas_i_nmadvise) 198a4bd5210SJason Evans CTL_PROTO(stats_arenas_i_purged) 199d0e79aa3SJason Evans CTL_PROTO(stats_arenas_i_metadata_mapped) 200d0e79aa3SJason Evans CTL_PROTO(stats_arenas_i_metadata_allocated) 201a4bd5210SJason Evans INDEX_PROTO(stats_arenas_i) 202a4bd5210SJason Evans CTL_PROTO(stats_cactive) 203a4bd5210SJason Evans CTL_PROTO(stats_allocated) 204a4bd5210SJason Evans CTL_PROTO(stats_active) 205d0e79aa3SJason Evans CTL_PROTO(stats_metadata) 206d0e79aa3SJason Evans CTL_PROTO(stats_resident) 207a4bd5210SJason Evans CTL_PROTO(stats_mapped) 2081f0a49e8SJason Evans CTL_PROTO(stats_retained) 209a4bd5210SJason Evans 210a4bd5210SJason Evans /******************************************************************************/ 211a4bd5210SJason Evans /* mallctl tree. */ 212a4bd5210SJason Evans 213a4bd5210SJason Evans /* Maximum tree depth. */ 214a4bd5210SJason Evans #define CTL_MAX_DEPTH 6 215a4bd5210SJason Evans 216e722f8f8SJason Evans #define NAME(n) {true}, n 217e722f8f8SJason Evans #define CHILD(t, c) \ 218e722f8f8SJason Evans sizeof(c##_node) / sizeof(ctl_##t##_node_t), \ 219e722f8f8SJason Evans (ctl_node_t *)c##_node, \ 220e722f8f8SJason Evans NULL 221e722f8f8SJason Evans #define CTL(c) 0, NULL, c##_ctl 222a4bd5210SJason Evans 223a4bd5210SJason Evans /* 224a4bd5210SJason Evans * Only handles internal indexed nodes, since there are currently no external 225a4bd5210SJason Evans * ones. 226a4bd5210SJason Evans */ 227e722f8f8SJason Evans #define INDEX(i) {false}, i##_index 228a4bd5210SJason Evans 229d0e79aa3SJason Evans static const ctl_named_node_t thread_tcache_node[] = { 230a4bd5210SJason Evans {NAME("enabled"), CTL(thread_tcache_enabled)}, 231a4bd5210SJason Evans {NAME("flush"), CTL(thread_tcache_flush)} 232a4bd5210SJason Evans }; 233a4bd5210SJason Evans 234d0e79aa3SJason Evans static const ctl_named_node_t thread_prof_node[] = { 235d0e79aa3SJason Evans {NAME("name"), CTL(thread_prof_name)}, 236d0e79aa3SJason Evans {NAME("active"), CTL(thread_prof_active)} 237d0e79aa3SJason Evans }; 238d0e79aa3SJason Evans 239e722f8f8SJason Evans static const ctl_named_node_t thread_node[] = { 240a4bd5210SJason Evans {NAME("arena"), CTL(thread_arena)}, 241a4bd5210SJason Evans {NAME("allocated"), CTL(thread_allocated)}, 242a4bd5210SJason Evans {NAME("allocatedp"), CTL(thread_allocatedp)}, 243a4bd5210SJason Evans {NAME("deallocated"), CTL(thread_deallocated)}, 244a4bd5210SJason Evans {NAME("deallocatedp"), CTL(thread_deallocatedp)}, 245d0e79aa3SJason Evans {NAME("tcache"), CHILD(named, thread_tcache)}, 246d0e79aa3SJason Evans {NAME("prof"), CHILD(named, thread_prof)} 247a4bd5210SJason Evans }; 248a4bd5210SJason Evans 249e722f8f8SJason Evans static const ctl_named_node_t config_node[] = { 250d0e79aa3SJason Evans {NAME("cache_oblivious"), CTL(config_cache_oblivious)}, 251a4bd5210SJason Evans {NAME("debug"), CTL(config_debug)}, 252a4bd5210SJason Evans {NAME("fill"), CTL(config_fill)}, 253a4bd5210SJason Evans {NAME("lazy_lock"), CTL(config_lazy_lock)}, 254df0d881dSJason Evans {NAME("malloc_conf"), CTL(config_malloc_conf)}, 255a4bd5210SJason Evans {NAME("munmap"), CTL(config_munmap)}, 256a4bd5210SJason Evans {NAME("prof"), CTL(config_prof)}, 257a4bd5210SJason Evans {NAME("prof_libgcc"), CTL(config_prof_libgcc)}, 258a4bd5210SJason Evans {NAME("prof_libunwind"), CTL(config_prof_libunwind)}, 259a4bd5210SJason Evans {NAME("stats"), CTL(config_stats)}, 260a4bd5210SJason Evans {NAME("tcache"), CTL(config_tcache)}, 261a4bd5210SJason Evans {NAME("tls"), CTL(config_tls)}, 262a4bd5210SJason Evans {NAME("utrace"), CTL(config_utrace)}, 263a4bd5210SJason Evans {NAME("valgrind"), CTL(config_valgrind)}, 264a4bd5210SJason Evans {NAME("xmalloc"), CTL(config_xmalloc)} 265a4bd5210SJason Evans }; 266a4bd5210SJason Evans 267e722f8f8SJason Evans static const ctl_named_node_t opt_node[] = { 268a4bd5210SJason Evans {NAME("abort"), CTL(opt_abort)}, 26982872ac0SJason Evans {NAME("dss"), CTL(opt_dss)}, 270a4bd5210SJason Evans {NAME("lg_chunk"), CTL(opt_lg_chunk)}, 271a4bd5210SJason Evans {NAME("narenas"), CTL(opt_narenas)}, 272df0d881dSJason Evans {NAME("purge"), CTL(opt_purge)}, 273a4bd5210SJason Evans {NAME("lg_dirty_mult"), CTL(opt_lg_dirty_mult)}, 274df0d881dSJason Evans {NAME("decay_time"), CTL(opt_decay_time)}, 275a4bd5210SJason Evans {NAME("stats_print"), CTL(opt_stats_print)}, 276a4bd5210SJason Evans {NAME("junk"), CTL(opt_junk)}, 277a4bd5210SJason Evans {NAME("zero"), CTL(opt_zero)}, 278a4bd5210SJason Evans {NAME("quarantine"), CTL(opt_quarantine)}, 279a4bd5210SJason Evans {NAME("redzone"), CTL(opt_redzone)}, 280a4bd5210SJason Evans {NAME("utrace"), CTL(opt_utrace)}, 281a4bd5210SJason Evans {NAME("xmalloc"), CTL(opt_xmalloc)}, 282a4bd5210SJason Evans {NAME("tcache"), CTL(opt_tcache)}, 283a4bd5210SJason Evans {NAME("lg_tcache_max"), CTL(opt_lg_tcache_max)}, 284a4bd5210SJason Evans {NAME("prof"), CTL(opt_prof)}, 285a4bd5210SJason Evans {NAME("prof_prefix"), CTL(opt_prof_prefix)}, 286a4bd5210SJason Evans {NAME("prof_active"), CTL(opt_prof_active)}, 287d0e79aa3SJason Evans {NAME("prof_thread_active_init"), CTL(opt_prof_thread_active_init)}, 288a4bd5210SJason Evans {NAME("lg_prof_sample"), CTL(opt_lg_prof_sample)}, 289a4bd5210SJason Evans {NAME("lg_prof_interval"), CTL(opt_lg_prof_interval)}, 290a4bd5210SJason Evans {NAME("prof_gdump"), CTL(opt_prof_gdump)}, 2918ed34ab0SJason Evans {NAME("prof_final"), CTL(opt_prof_final)}, 292a4bd5210SJason Evans {NAME("prof_leak"), CTL(opt_prof_leak)}, 293a4bd5210SJason Evans {NAME("prof_accum"), CTL(opt_prof_accum)} 294a4bd5210SJason Evans }; 295a4bd5210SJason Evans 296d0e79aa3SJason Evans static const ctl_named_node_t tcache_node[] = { 297d0e79aa3SJason Evans {NAME("create"), CTL(tcache_create)}, 298d0e79aa3SJason Evans {NAME("flush"), CTL(tcache_flush)}, 299d0e79aa3SJason Evans {NAME("destroy"), CTL(tcache_destroy)} 300d0e79aa3SJason Evans }; 301d0e79aa3SJason Evans 30282872ac0SJason Evans static const ctl_named_node_t arena_i_node[] = { 30382872ac0SJason Evans {NAME("purge"), CTL(arena_i_purge)}, 304df0d881dSJason Evans {NAME("decay"), CTL(arena_i_decay)}, 3051f0a49e8SJason Evans {NAME("reset"), CTL(arena_i_reset)}, 306d0e79aa3SJason Evans {NAME("dss"), CTL(arena_i_dss)}, 307d0e79aa3SJason Evans {NAME("lg_dirty_mult"), CTL(arena_i_lg_dirty_mult)}, 308df0d881dSJason Evans {NAME("decay_time"), CTL(arena_i_decay_time)}, 309d0e79aa3SJason Evans {NAME("chunk_hooks"), CTL(arena_i_chunk_hooks)} 31082872ac0SJason Evans }; 31182872ac0SJason Evans static const ctl_named_node_t super_arena_i_node[] = { 31282872ac0SJason Evans {NAME(""), CHILD(named, arena_i)} 31382872ac0SJason Evans }; 31482872ac0SJason Evans 31582872ac0SJason Evans static const ctl_indexed_node_t arena_node[] = { 31682872ac0SJason Evans {INDEX(arena_i)} 31782872ac0SJason Evans }; 31882872ac0SJason Evans 319e722f8f8SJason Evans static const ctl_named_node_t arenas_bin_i_node[] = { 320a4bd5210SJason Evans {NAME("size"), CTL(arenas_bin_i_size)}, 321a4bd5210SJason Evans {NAME("nregs"), CTL(arenas_bin_i_nregs)}, 322a4bd5210SJason Evans {NAME("run_size"), CTL(arenas_bin_i_run_size)} 323a4bd5210SJason Evans }; 324e722f8f8SJason Evans static const ctl_named_node_t super_arenas_bin_i_node[] = { 325e722f8f8SJason Evans {NAME(""), CHILD(named, arenas_bin_i)} 326a4bd5210SJason Evans }; 327a4bd5210SJason Evans 328e722f8f8SJason Evans static const ctl_indexed_node_t arenas_bin_node[] = { 329a4bd5210SJason Evans {INDEX(arenas_bin_i)} 330a4bd5210SJason Evans }; 331a4bd5210SJason Evans 332e722f8f8SJason Evans static const ctl_named_node_t arenas_lrun_i_node[] = { 333a4bd5210SJason Evans {NAME("size"), CTL(arenas_lrun_i_size)} 334a4bd5210SJason Evans }; 335e722f8f8SJason Evans static const ctl_named_node_t super_arenas_lrun_i_node[] = { 336e722f8f8SJason Evans {NAME(""), CHILD(named, arenas_lrun_i)} 337a4bd5210SJason Evans }; 338a4bd5210SJason Evans 339e722f8f8SJason Evans static const ctl_indexed_node_t arenas_lrun_node[] = { 340a4bd5210SJason Evans {INDEX(arenas_lrun_i)} 341a4bd5210SJason Evans }; 342a4bd5210SJason Evans 343d0e79aa3SJason Evans static const ctl_named_node_t arenas_hchunk_i_node[] = { 344d0e79aa3SJason Evans {NAME("size"), CTL(arenas_hchunk_i_size)} 345d0e79aa3SJason Evans }; 346d0e79aa3SJason Evans static const ctl_named_node_t super_arenas_hchunk_i_node[] = { 347d0e79aa3SJason Evans {NAME(""), CHILD(named, arenas_hchunk_i)} 348d0e79aa3SJason Evans }; 349d0e79aa3SJason Evans 350d0e79aa3SJason Evans static const ctl_indexed_node_t arenas_hchunk_node[] = { 351d0e79aa3SJason Evans {INDEX(arenas_hchunk_i)} 352d0e79aa3SJason Evans }; 353d0e79aa3SJason Evans 354e722f8f8SJason Evans static const ctl_named_node_t arenas_node[] = { 355a4bd5210SJason Evans {NAME("narenas"), CTL(arenas_narenas)}, 356a4bd5210SJason Evans {NAME("initialized"), CTL(arenas_initialized)}, 357d0e79aa3SJason Evans {NAME("lg_dirty_mult"), CTL(arenas_lg_dirty_mult)}, 358df0d881dSJason Evans {NAME("decay_time"), CTL(arenas_decay_time)}, 359a4bd5210SJason Evans {NAME("quantum"), CTL(arenas_quantum)}, 360a4bd5210SJason Evans {NAME("page"), CTL(arenas_page)}, 361a4bd5210SJason Evans {NAME("tcache_max"), CTL(arenas_tcache_max)}, 362a4bd5210SJason Evans {NAME("nbins"), CTL(arenas_nbins)}, 363a4bd5210SJason Evans {NAME("nhbins"), CTL(arenas_nhbins)}, 364e722f8f8SJason Evans {NAME("bin"), CHILD(indexed, arenas_bin)}, 365a4bd5210SJason Evans {NAME("nlruns"), CTL(arenas_nlruns)}, 366e722f8f8SJason Evans {NAME("lrun"), CHILD(indexed, arenas_lrun)}, 367d0e79aa3SJason Evans {NAME("nhchunks"), CTL(arenas_nhchunks)}, 368d0e79aa3SJason Evans {NAME("hchunk"), CHILD(indexed, arenas_hchunk)}, 36982872ac0SJason Evans {NAME("extend"), CTL(arenas_extend)} 370a4bd5210SJason Evans }; 371a4bd5210SJason Evans 372e722f8f8SJason Evans static const ctl_named_node_t prof_node[] = { 373d0e79aa3SJason Evans {NAME("thread_active_init"), CTL(prof_thread_active_init)}, 374a4bd5210SJason Evans {NAME("active"), CTL(prof_active)}, 375a4bd5210SJason Evans {NAME("dump"), CTL(prof_dump)}, 376d0e79aa3SJason Evans {NAME("gdump"), CTL(prof_gdump)}, 377d0e79aa3SJason Evans {NAME("reset"), CTL(prof_reset)}, 378d0e79aa3SJason Evans {NAME("interval"), CTL(prof_interval)}, 379d0e79aa3SJason Evans {NAME("lg_sample"), CTL(lg_prof_sample)} 380a4bd5210SJason Evans }; 381a4bd5210SJason Evans 382d0e79aa3SJason Evans static const ctl_named_node_t stats_arenas_i_metadata_node[] = { 383d0e79aa3SJason Evans {NAME("mapped"), CTL(stats_arenas_i_metadata_mapped)}, 384d0e79aa3SJason Evans {NAME("allocated"), CTL(stats_arenas_i_metadata_allocated)} 385a4bd5210SJason Evans }; 386a4bd5210SJason Evans 387e722f8f8SJason Evans static const ctl_named_node_t stats_arenas_i_small_node[] = { 388a4bd5210SJason Evans {NAME("allocated"), CTL(stats_arenas_i_small_allocated)}, 389a4bd5210SJason Evans {NAME("nmalloc"), CTL(stats_arenas_i_small_nmalloc)}, 390a4bd5210SJason Evans {NAME("ndalloc"), CTL(stats_arenas_i_small_ndalloc)}, 391a4bd5210SJason Evans {NAME("nrequests"), CTL(stats_arenas_i_small_nrequests)} 392a4bd5210SJason Evans }; 393a4bd5210SJason Evans 394e722f8f8SJason Evans static const ctl_named_node_t stats_arenas_i_large_node[] = { 395a4bd5210SJason Evans {NAME("allocated"), CTL(stats_arenas_i_large_allocated)}, 396a4bd5210SJason Evans {NAME("nmalloc"), CTL(stats_arenas_i_large_nmalloc)}, 397a4bd5210SJason Evans {NAME("ndalloc"), CTL(stats_arenas_i_large_ndalloc)}, 398a4bd5210SJason Evans {NAME("nrequests"), CTL(stats_arenas_i_large_nrequests)} 399a4bd5210SJason Evans }; 400a4bd5210SJason Evans 401d0e79aa3SJason Evans static const ctl_named_node_t stats_arenas_i_huge_node[] = { 402d0e79aa3SJason Evans {NAME("allocated"), CTL(stats_arenas_i_huge_allocated)}, 403d0e79aa3SJason Evans {NAME("nmalloc"), CTL(stats_arenas_i_huge_nmalloc)}, 404d0e79aa3SJason Evans {NAME("ndalloc"), CTL(stats_arenas_i_huge_ndalloc)}, 405d0e79aa3SJason Evans {NAME("nrequests"), CTL(stats_arenas_i_huge_nrequests)} 406d0e79aa3SJason Evans }; 407d0e79aa3SJason Evans 408e722f8f8SJason Evans static const ctl_named_node_t stats_arenas_i_bins_j_node[] = { 409a4bd5210SJason Evans {NAME("nmalloc"), CTL(stats_arenas_i_bins_j_nmalloc)}, 410a4bd5210SJason Evans {NAME("ndalloc"), CTL(stats_arenas_i_bins_j_ndalloc)}, 411a4bd5210SJason Evans {NAME("nrequests"), CTL(stats_arenas_i_bins_j_nrequests)}, 412d0e79aa3SJason Evans {NAME("curregs"), CTL(stats_arenas_i_bins_j_curregs)}, 413a4bd5210SJason Evans {NAME("nfills"), CTL(stats_arenas_i_bins_j_nfills)}, 414a4bd5210SJason Evans {NAME("nflushes"), CTL(stats_arenas_i_bins_j_nflushes)}, 415a4bd5210SJason Evans {NAME("nruns"), CTL(stats_arenas_i_bins_j_nruns)}, 416a4bd5210SJason Evans {NAME("nreruns"), CTL(stats_arenas_i_bins_j_nreruns)}, 417a4bd5210SJason Evans {NAME("curruns"), CTL(stats_arenas_i_bins_j_curruns)} 418a4bd5210SJason Evans }; 419e722f8f8SJason Evans static const ctl_named_node_t super_stats_arenas_i_bins_j_node[] = { 420e722f8f8SJason Evans {NAME(""), CHILD(named, stats_arenas_i_bins_j)} 421a4bd5210SJason Evans }; 422a4bd5210SJason Evans 423e722f8f8SJason Evans static const ctl_indexed_node_t stats_arenas_i_bins_node[] = { 424a4bd5210SJason Evans {INDEX(stats_arenas_i_bins_j)} 425a4bd5210SJason Evans }; 426a4bd5210SJason Evans 427e722f8f8SJason Evans static const ctl_named_node_t stats_arenas_i_lruns_j_node[] = { 428a4bd5210SJason Evans {NAME("nmalloc"), CTL(stats_arenas_i_lruns_j_nmalloc)}, 429a4bd5210SJason Evans {NAME("ndalloc"), CTL(stats_arenas_i_lruns_j_ndalloc)}, 430a4bd5210SJason Evans {NAME("nrequests"), CTL(stats_arenas_i_lruns_j_nrequests)}, 431a4bd5210SJason Evans {NAME("curruns"), CTL(stats_arenas_i_lruns_j_curruns)} 432a4bd5210SJason Evans }; 433e722f8f8SJason Evans static const ctl_named_node_t super_stats_arenas_i_lruns_j_node[] = { 434e722f8f8SJason Evans {NAME(""), CHILD(named, stats_arenas_i_lruns_j)} 435a4bd5210SJason Evans }; 436a4bd5210SJason Evans 437e722f8f8SJason Evans static const ctl_indexed_node_t stats_arenas_i_lruns_node[] = { 438a4bd5210SJason Evans {INDEX(stats_arenas_i_lruns_j)} 439a4bd5210SJason Evans }; 440a4bd5210SJason Evans 441d0e79aa3SJason Evans static const ctl_named_node_t stats_arenas_i_hchunks_j_node[] = { 442d0e79aa3SJason Evans {NAME("nmalloc"), CTL(stats_arenas_i_hchunks_j_nmalloc)}, 443d0e79aa3SJason Evans {NAME("ndalloc"), CTL(stats_arenas_i_hchunks_j_ndalloc)}, 444d0e79aa3SJason Evans {NAME("nrequests"), CTL(stats_arenas_i_hchunks_j_nrequests)}, 445d0e79aa3SJason Evans {NAME("curhchunks"), CTL(stats_arenas_i_hchunks_j_curhchunks)} 446d0e79aa3SJason Evans }; 447d0e79aa3SJason Evans static const ctl_named_node_t super_stats_arenas_i_hchunks_j_node[] = { 448d0e79aa3SJason Evans {NAME(""), CHILD(named, stats_arenas_i_hchunks_j)} 449d0e79aa3SJason Evans }; 450d0e79aa3SJason Evans 451d0e79aa3SJason Evans static const ctl_indexed_node_t stats_arenas_i_hchunks_node[] = { 452d0e79aa3SJason Evans {INDEX(stats_arenas_i_hchunks_j)} 453d0e79aa3SJason Evans }; 454d0e79aa3SJason Evans 455e722f8f8SJason Evans static const ctl_named_node_t stats_arenas_i_node[] = { 456a4bd5210SJason Evans {NAME("nthreads"), CTL(stats_arenas_i_nthreads)}, 45782872ac0SJason Evans {NAME("dss"), CTL(stats_arenas_i_dss)}, 458d0e79aa3SJason Evans {NAME("lg_dirty_mult"), CTL(stats_arenas_i_lg_dirty_mult)}, 459df0d881dSJason Evans {NAME("decay_time"), CTL(stats_arenas_i_decay_time)}, 460a4bd5210SJason Evans {NAME("pactive"), CTL(stats_arenas_i_pactive)}, 461a4bd5210SJason Evans {NAME("pdirty"), CTL(stats_arenas_i_pdirty)}, 462a4bd5210SJason Evans {NAME("mapped"), CTL(stats_arenas_i_mapped)}, 4631f0a49e8SJason Evans {NAME("retained"), CTL(stats_arenas_i_retained)}, 464a4bd5210SJason Evans {NAME("npurge"), CTL(stats_arenas_i_npurge)}, 465a4bd5210SJason Evans {NAME("nmadvise"), CTL(stats_arenas_i_nmadvise)}, 466a4bd5210SJason Evans {NAME("purged"), CTL(stats_arenas_i_purged)}, 467d0e79aa3SJason Evans {NAME("metadata"), CHILD(named, stats_arenas_i_metadata)}, 468e722f8f8SJason Evans {NAME("small"), CHILD(named, stats_arenas_i_small)}, 469e722f8f8SJason Evans {NAME("large"), CHILD(named, stats_arenas_i_large)}, 470d0e79aa3SJason Evans {NAME("huge"), CHILD(named, stats_arenas_i_huge)}, 471e722f8f8SJason Evans {NAME("bins"), CHILD(indexed, stats_arenas_i_bins)}, 472d0e79aa3SJason Evans {NAME("lruns"), CHILD(indexed, stats_arenas_i_lruns)}, 473d0e79aa3SJason Evans {NAME("hchunks"), CHILD(indexed, stats_arenas_i_hchunks)} 474a4bd5210SJason Evans }; 475e722f8f8SJason Evans static const ctl_named_node_t super_stats_arenas_i_node[] = { 476e722f8f8SJason Evans {NAME(""), CHILD(named, stats_arenas_i)} 477a4bd5210SJason Evans }; 478a4bd5210SJason Evans 479e722f8f8SJason Evans static const ctl_indexed_node_t stats_arenas_node[] = { 480a4bd5210SJason Evans {INDEX(stats_arenas_i)} 481a4bd5210SJason Evans }; 482a4bd5210SJason Evans 483e722f8f8SJason Evans static const ctl_named_node_t stats_node[] = { 484a4bd5210SJason Evans {NAME("cactive"), CTL(stats_cactive)}, 485a4bd5210SJason Evans {NAME("allocated"), CTL(stats_allocated)}, 486a4bd5210SJason Evans {NAME("active"), CTL(stats_active)}, 487d0e79aa3SJason Evans {NAME("metadata"), CTL(stats_metadata)}, 488d0e79aa3SJason Evans {NAME("resident"), CTL(stats_resident)}, 489a4bd5210SJason Evans {NAME("mapped"), CTL(stats_mapped)}, 4901f0a49e8SJason Evans {NAME("retained"), CTL(stats_retained)}, 491e722f8f8SJason Evans {NAME("arenas"), CHILD(indexed, stats_arenas)} 492a4bd5210SJason Evans }; 493a4bd5210SJason Evans 494e722f8f8SJason Evans static const ctl_named_node_t root_node[] = { 495a4bd5210SJason Evans {NAME("version"), CTL(version)}, 496a4bd5210SJason Evans {NAME("epoch"), CTL(epoch)}, 497e722f8f8SJason Evans {NAME("thread"), CHILD(named, thread)}, 498e722f8f8SJason Evans {NAME("config"), CHILD(named, config)}, 499e722f8f8SJason Evans {NAME("opt"), CHILD(named, opt)}, 500d0e79aa3SJason Evans {NAME("tcache"), CHILD(named, tcache)}, 50182872ac0SJason Evans {NAME("arena"), CHILD(indexed, arena)}, 502e722f8f8SJason Evans {NAME("arenas"), CHILD(named, arenas)}, 503e722f8f8SJason Evans {NAME("prof"), CHILD(named, prof)}, 504e722f8f8SJason Evans {NAME("stats"), CHILD(named, stats)} 505a4bd5210SJason Evans }; 506e722f8f8SJason Evans static const ctl_named_node_t super_root_node[] = { 507e722f8f8SJason Evans {NAME(""), CHILD(named, root)} 508a4bd5210SJason Evans }; 509a4bd5210SJason Evans 510a4bd5210SJason Evans #undef NAME 511a4bd5210SJason Evans #undef CHILD 512a4bd5210SJason Evans #undef CTL 513a4bd5210SJason Evans #undef INDEX 514a4bd5210SJason Evans 515a4bd5210SJason Evans /******************************************************************************/ 516a4bd5210SJason Evans 517a4bd5210SJason Evans static bool 518a4bd5210SJason Evans ctl_arena_init(ctl_arena_stats_t *astats) 519a4bd5210SJason Evans { 520a4bd5210SJason Evans 521a4bd5210SJason Evans if (astats->lstats == NULL) { 522d0e79aa3SJason Evans astats->lstats = (malloc_large_stats_t *)a0malloc(nlclasses * 523a4bd5210SJason Evans sizeof(malloc_large_stats_t)); 524a4bd5210SJason Evans if (astats->lstats == NULL) 525a4bd5210SJason Evans return (true); 526a4bd5210SJason Evans } 527a4bd5210SJason Evans 528d0e79aa3SJason Evans if (astats->hstats == NULL) { 529d0e79aa3SJason Evans astats->hstats = (malloc_huge_stats_t *)a0malloc(nhclasses * 530d0e79aa3SJason Evans sizeof(malloc_huge_stats_t)); 531d0e79aa3SJason Evans if (astats->hstats == NULL) 532d0e79aa3SJason Evans return (true); 533d0e79aa3SJason Evans } 534d0e79aa3SJason Evans 535a4bd5210SJason Evans return (false); 536a4bd5210SJason Evans } 537a4bd5210SJason Evans 538a4bd5210SJason Evans static void 539a4bd5210SJason Evans ctl_arena_clear(ctl_arena_stats_t *astats) 540a4bd5210SJason Evans { 541a4bd5210SJason Evans 542df0d881dSJason Evans astats->nthreads = 0; 54382872ac0SJason Evans astats->dss = dss_prec_names[dss_prec_limit]; 544d0e79aa3SJason Evans astats->lg_dirty_mult = -1; 545df0d881dSJason Evans astats->decay_time = -1; 546a4bd5210SJason Evans astats->pactive = 0; 547a4bd5210SJason Evans astats->pdirty = 0; 548a4bd5210SJason Evans if (config_stats) { 549a4bd5210SJason Evans memset(&astats->astats, 0, sizeof(arena_stats_t)); 550a4bd5210SJason Evans astats->allocated_small = 0; 551a4bd5210SJason Evans astats->nmalloc_small = 0; 552a4bd5210SJason Evans astats->ndalloc_small = 0; 553a4bd5210SJason Evans astats->nrequests_small = 0; 554a4bd5210SJason Evans memset(astats->bstats, 0, NBINS * sizeof(malloc_bin_stats_t)); 555a4bd5210SJason Evans memset(astats->lstats, 0, nlclasses * 556a4bd5210SJason Evans sizeof(malloc_large_stats_t)); 557d0e79aa3SJason Evans memset(astats->hstats, 0, nhclasses * 558d0e79aa3SJason Evans sizeof(malloc_huge_stats_t)); 559a4bd5210SJason Evans } 560a4bd5210SJason Evans } 561a4bd5210SJason Evans 562a4bd5210SJason Evans static void 5631f0a49e8SJason Evans ctl_arena_stats_amerge(tsdn_t *tsdn, ctl_arena_stats_t *cstats, arena_t *arena) 564a4bd5210SJason Evans { 565a4bd5210SJason Evans unsigned i; 566a4bd5210SJason Evans 567df0d881dSJason Evans if (config_stats) { 5681f0a49e8SJason Evans arena_stats_merge(tsdn, arena, &cstats->nthreads, &cstats->dss, 569df0d881dSJason Evans &cstats->lg_dirty_mult, &cstats->decay_time, 570df0d881dSJason Evans &cstats->pactive, &cstats->pdirty, &cstats->astats, 571df0d881dSJason Evans cstats->bstats, cstats->lstats, cstats->hstats); 572a4bd5210SJason Evans 573a4bd5210SJason Evans for (i = 0; i < NBINS; i++) { 574d0e79aa3SJason Evans cstats->allocated_small += cstats->bstats[i].curregs * 575d0e79aa3SJason Evans index2size(i); 576a4bd5210SJason Evans cstats->nmalloc_small += cstats->bstats[i].nmalloc; 577a4bd5210SJason Evans cstats->ndalloc_small += cstats->bstats[i].ndalloc; 578a4bd5210SJason Evans cstats->nrequests_small += cstats->bstats[i].nrequests; 579a4bd5210SJason Evans } 580df0d881dSJason Evans } else { 5811f0a49e8SJason Evans arena_basic_stats_merge(tsdn, arena, &cstats->nthreads, 5821f0a49e8SJason Evans &cstats->dss, &cstats->lg_dirty_mult, &cstats->decay_time, 583df0d881dSJason Evans &cstats->pactive, &cstats->pdirty); 584df0d881dSJason Evans } 585a4bd5210SJason Evans } 586a4bd5210SJason Evans 587a4bd5210SJason Evans static void 588a4bd5210SJason Evans ctl_arena_stats_smerge(ctl_arena_stats_t *sstats, ctl_arena_stats_t *astats) 589a4bd5210SJason Evans { 590a4bd5210SJason Evans unsigned i; 591a4bd5210SJason Evans 592df0d881dSJason Evans sstats->nthreads += astats->nthreads; 593a4bd5210SJason Evans sstats->pactive += astats->pactive; 594a4bd5210SJason Evans sstats->pdirty += astats->pdirty; 595a4bd5210SJason Evans 596df0d881dSJason Evans if (config_stats) { 597a4bd5210SJason Evans sstats->astats.mapped += astats->astats.mapped; 5981f0a49e8SJason Evans sstats->astats.retained += astats->astats.retained; 599a4bd5210SJason Evans sstats->astats.npurge += astats->astats.npurge; 600a4bd5210SJason Evans sstats->astats.nmadvise += astats->astats.nmadvise; 601a4bd5210SJason Evans sstats->astats.purged += astats->astats.purged; 602a4bd5210SJason Evans 603df0d881dSJason Evans sstats->astats.metadata_mapped += 604df0d881dSJason Evans astats->astats.metadata_mapped; 605df0d881dSJason Evans sstats->astats.metadata_allocated += 606df0d881dSJason Evans astats->astats.metadata_allocated; 607d0e79aa3SJason Evans 608a4bd5210SJason Evans sstats->allocated_small += astats->allocated_small; 609a4bd5210SJason Evans sstats->nmalloc_small += astats->nmalloc_small; 610a4bd5210SJason Evans sstats->ndalloc_small += astats->ndalloc_small; 611a4bd5210SJason Evans sstats->nrequests_small += astats->nrequests_small; 612a4bd5210SJason Evans 613df0d881dSJason Evans sstats->astats.allocated_large += 614df0d881dSJason Evans astats->astats.allocated_large; 615a4bd5210SJason Evans sstats->astats.nmalloc_large += astats->astats.nmalloc_large; 616a4bd5210SJason Evans sstats->astats.ndalloc_large += astats->astats.ndalloc_large; 617df0d881dSJason Evans sstats->astats.nrequests_large += 618df0d881dSJason Evans astats->astats.nrequests_large; 619a4bd5210SJason Evans 620d0e79aa3SJason Evans sstats->astats.allocated_huge += astats->astats.allocated_huge; 621d0e79aa3SJason Evans sstats->astats.nmalloc_huge += astats->astats.nmalloc_huge; 622d0e79aa3SJason Evans sstats->astats.ndalloc_huge += astats->astats.ndalloc_huge; 623a4bd5210SJason Evans 624a4bd5210SJason Evans for (i = 0; i < NBINS; i++) { 625a4bd5210SJason Evans sstats->bstats[i].nmalloc += astats->bstats[i].nmalloc; 626a4bd5210SJason Evans sstats->bstats[i].ndalloc += astats->bstats[i].ndalloc; 627df0d881dSJason Evans sstats->bstats[i].nrequests += 628df0d881dSJason Evans astats->bstats[i].nrequests; 629d0e79aa3SJason Evans sstats->bstats[i].curregs += astats->bstats[i].curregs; 630a4bd5210SJason Evans if (config_tcache) { 631df0d881dSJason Evans sstats->bstats[i].nfills += 632df0d881dSJason Evans astats->bstats[i].nfills; 633a4bd5210SJason Evans sstats->bstats[i].nflushes += 634a4bd5210SJason Evans astats->bstats[i].nflushes; 635a4bd5210SJason Evans } 636a4bd5210SJason Evans sstats->bstats[i].nruns += astats->bstats[i].nruns; 637a4bd5210SJason Evans sstats->bstats[i].reruns += astats->bstats[i].reruns; 638a4bd5210SJason Evans sstats->bstats[i].curruns += astats->bstats[i].curruns; 639a4bd5210SJason Evans } 640d0e79aa3SJason Evans 641d0e79aa3SJason Evans for (i = 0; i < nlclasses; i++) { 642d0e79aa3SJason Evans sstats->lstats[i].nmalloc += astats->lstats[i].nmalloc; 643d0e79aa3SJason Evans sstats->lstats[i].ndalloc += astats->lstats[i].ndalloc; 644df0d881dSJason Evans sstats->lstats[i].nrequests += 645df0d881dSJason Evans astats->lstats[i].nrequests; 646d0e79aa3SJason Evans sstats->lstats[i].curruns += astats->lstats[i].curruns; 647d0e79aa3SJason Evans } 648d0e79aa3SJason Evans 649d0e79aa3SJason Evans for (i = 0; i < nhclasses; i++) { 650d0e79aa3SJason Evans sstats->hstats[i].nmalloc += astats->hstats[i].nmalloc; 651d0e79aa3SJason Evans sstats->hstats[i].ndalloc += astats->hstats[i].ndalloc; 652df0d881dSJason Evans sstats->hstats[i].curhchunks += 653df0d881dSJason Evans astats->hstats[i].curhchunks; 654df0d881dSJason Evans } 655d0e79aa3SJason Evans } 656a4bd5210SJason Evans } 657a4bd5210SJason Evans 658a4bd5210SJason Evans static void 6591f0a49e8SJason Evans ctl_arena_refresh(tsdn_t *tsdn, arena_t *arena, unsigned i) 660a4bd5210SJason Evans { 661a4bd5210SJason Evans ctl_arena_stats_t *astats = &ctl_stats.arenas[i]; 66282872ac0SJason Evans ctl_arena_stats_t *sstats = &ctl_stats.arenas[ctl_stats.narenas]; 663a4bd5210SJason Evans 664a4bd5210SJason Evans ctl_arena_clear(astats); 6651f0a49e8SJason Evans ctl_arena_stats_amerge(tsdn, astats, arena); 666a4bd5210SJason Evans /* Merge into sum stats as well. */ 667a4bd5210SJason Evans ctl_arena_stats_smerge(sstats, astats); 668a4bd5210SJason Evans } 669a4bd5210SJason Evans 67082872ac0SJason Evans static bool 6711f0a49e8SJason Evans ctl_grow(tsdn_t *tsdn) 67282872ac0SJason Evans { 67382872ac0SJason Evans ctl_arena_stats_t *astats; 67482872ac0SJason Evans 675d0e79aa3SJason Evans /* Initialize new arena. */ 6761f0a49e8SJason Evans if (arena_init(tsdn, ctl_stats.narenas) == NULL) 677d0e79aa3SJason Evans return (true); 678d0e79aa3SJason Evans 679d0e79aa3SJason Evans /* Allocate extended arena stats. */ 680d0e79aa3SJason Evans astats = (ctl_arena_stats_t *)a0malloc((ctl_stats.narenas + 2) * 6812b06b201SJason Evans sizeof(ctl_arena_stats_t)); 68282872ac0SJason Evans if (astats == NULL) 68382872ac0SJason Evans return (true); 68482872ac0SJason Evans 6852b06b201SJason Evans /* Initialize the new astats element. */ 6862b06b201SJason Evans memcpy(astats, ctl_stats.arenas, (ctl_stats.narenas + 1) * 6872b06b201SJason Evans sizeof(ctl_arena_stats_t)); 6882b06b201SJason Evans memset(&astats[ctl_stats.narenas + 1], 0, sizeof(ctl_arena_stats_t)); 6892b06b201SJason Evans if (ctl_arena_init(&astats[ctl_stats.narenas + 1])) { 690d0e79aa3SJason Evans a0dalloc(astats); 69182872ac0SJason Evans return (true); 69282872ac0SJason Evans } 69382872ac0SJason Evans /* Swap merged stats to their new location. */ 69482872ac0SJason Evans { 69582872ac0SJason Evans ctl_arena_stats_t tstats; 69682872ac0SJason Evans memcpy(&tstats, &astats[ctl_stats.narenas], 69782872ac0SJason Evans sizeof(ctl_arena_stats_t)); 69882872ac0SJason Evans memcpy(&astats[ctl_stats.narenas], 69982872ac0SJason Evans &astats[ctl_stats.narenas + 1], sizeof(ctl_arena_stats_t)); 70082872ac0SJason Evans memcpy(&astats[ctl_stats.narenas + 1], &tstats, 70182872ac0SJason Evans sizeof(ctl_arena_stats_t)); 70282872ac0SJason Evans } 703d0e79aa3SJason Evans a0dalloc(ctl_stats.arenas); 7042b06b201SJason Evans ctl_stats.arenas = astats; 7052b06b201SJason Evans ctl_stats.narenas++; 70682872ac0SJason Evans 70782872ac0SJason Evans return (false); 70882872ac0SJason Evans } 70982872ac0SJason Evans 710a4bd5210SJason Evans static void 7111f0a49e8SJason Evans ctl_refresh(tsdn_t *tsdn) 712a4bd5210SJason Evans { 713a4bd5210SJason Evans unsigned i; 71482872ac0SJason Evans VARIABLE_ARRAY(arena_t *, tarenas, ctl_stats.narenas); 715a4bd5210SJason Evans 716a4bd5210SJason Evans /* 717a4bd5210SJason Evans * Clear sum stats, since they will be merged into by 718a4bd5210SJason Evans * ctl_arena_refresh(). 719a4bd5210SJason Evans */ 72082872ac0SJason Evans ctl_arena_clear(&ctl_stats.arenas[ctl_stats.narenas]); 721a4bd5210SJason Evans 722df0d881dSJason Evans for (i = 0; i < ctl_stats.narenas; i++) 7231f0a49e8SJason Evans tarenas[i] = arena_get(tsdn, i, false); 724d0e79aa3SJason Evans 72582872ac0SJason Evans for (i = 0; i < ctl_stats.narenas; i++) { 726a4bd5210SJason Evans bool initialized = (tarenas[i] != NULL); 727a4bd5210SJason Evans 728a4bd5210SJason Evans ctl_stats.arenas[i].initialized = initialized; 729a4bd5210SJason Evans if (initialized) 7301f0a49e8SJason Evans ctl_arena_refresh(tsdn, tarenas[i], i); 731a4bd5210SJason Evans } 732a4bd5210SJason Evans 733a4bd5210SJason Evans if (config_stats) { 734d0e79aa3SJason Evans size_t base_allocated, base_resident, base_mapped; 7351f0a49e8SJason Evans base_stats_get(tsdn, &base_allocated, &base_resident, 7361f0a49e8SJason Evans &base_mapped); 73782872ac0SJason Evans ctl_stats.allocated = 738d0e79aa3SJason Evans ctl_stats.arenas[ctl_stats.narenas].allocated_small + 739d0e79aa3SJason Evans ctl_stats.arenas[ctl_stats.narenas].astats.allocated_large + 740d0e79aa3SJason Evans ctl_stats.arenas[ctl_stats.narenas].astats.allocated_huge; 74182872ac0SJason Evans ctl_stats.active = 742d0e79aa3SJason Evans (ctl_stats.arenas[ctl_stats.narenas].pactive << LG_PAGE); 743d0e79aa3SJason Evans ctl_stats.metadata = base_allocated + 744d0e79aa3SJason Evans ctl_stats.arenas[ctl_stats.narenas].astats.metadata_mapped + 745d0e79aa3SJason Evans ctl_stats.arenas[ctl_stats.narenas].astats 746d0e79aa3SJason Evans .metadata_allocated; 747d0e79aa3SJason Evans ctl_stats.resident = base_resident + 748d0e79aa3SJason Evans ctl_stats.arenas[ctl_stats.narenas].astats.metadata_mapped + 749d0e79aa3SJason Evans ((ctl_stats.arenas[ctl_stats.narenas].pactive + 750d0e79aa3SJason Evans ctl_stats.arenas[ctl_stats.narenas].pdirty) << LG_PAGE); 751d0e79aa3SJason Evans ctl_stats.mapped = base_mapped + 752d0e79aa3SJason Evans ctl_stats.arenas[ctl_stats.narenas].astats.mapped; 7531f0a49e8SJason Evans ctl_stats.retained = 7541f0a49e8SJason Evans ctl_stats.arenas[ctl_stats.narenas].astats.retained; 755a4bd5210SJason Evans } 756a4bd5210SJason Evans 757a4bd5210SJason Evans ctl_epoch++; 758a4bd5210SJason Evans } 759a4bd5210SJason Evans 760a4bd5210SJason Evans static bool 7611f0a49e8SJason Evans ctl_init(tsdn_t *tsdn) 762a4bd5210SJason Evans { 763a4bd5210SJason Evans bool ret; 764a4bd5210SJason Evans 7651f0a49e8SJason Evans malloc_mutex_lock(tsdn, &ctl_mtx); 766d0e79aa3SJason Evans if (!ctl_initialized) { 767a4bd5210SJason Evans /* 768a4bd5210SJason Evans * Allocate space for one extra arena stats element, which 769a4bd5210SJason Evans * contains summed stats across all arenas. 770a4bd5210SJason Evans */ 771d0e79aa3SJason Evans ctl_stats.narenas = narenas_total_get(); 772d0e79aa3SJason Evans ctl_stats.arenas = (ctl_arena_stats_t *)a0malloc( 77382872ac0SJason Evans (ctl_stats.narenas + 1) * sizeof(ctl_arena_stats_t)); 774a4bd5210SJason Evans if (ctl_stats.arenas == NULL) { 775a4bd5210SJason Evans ret = true; 776a4bd5210SJason Evans goto label_return; 777a4bd5210SJason Evans } 77882872ac0SJason Evans memset(ctl_stats.arenas, 0, (ctl_stats.narenas + 1) * 779a4bd5210SJason Evans sizeof(ctl_arena_stats_t)); 780a4bd5210SJason Evans 781a4bd5210SJason Evans /* 782a4bd5210SJason Evans * Initialize all stats structures, regardless of whether they 783a4bd5210SJason Evans * ever get used. Lazy initialization would allow errors to 784a4bd5210SJason Evans * cause inconsistent state to be viewable by the application. 785a4bd5210SJason Evans */ 786a4bd5210SJason Evans if (config_stats) { 787a4bd5210SJason Evans unsigned i; 78882872ac0SJason Evans for (i = 0; i <= ctl_stats.narenas; i++) { 789a4bd5210SJason Evans if (ctl_arena_init(&ctl_stats.arenas[i])) { 790d0e79aa3SJason Evans unsigned j; 791d0e79aa3SJason Evans for (j = 0; j < i; j++) { 792d0e79aa3SJason Evans a0dalloc( 793d0e79aa3SJason Evans ctl_stats.arenas[j].lstats); 794d0e79aa3SJason Evans a0dalloc( 795d0e79aa3SJason Evans ctl_stats.arenas[j].hstats); 796d0e79aa3SJason Evans } 797d0e79aa3SJason Evans a0dalloc(ctl_stats.arenas); 798d0e79aa3SJason Evans ctl_stats.arenas = NULL; 799a4bd5210SJason Evans ret = true; 800a4bd5210SJason Evans goto label_return; 801a4bd5210SJason Evans } 802a4bd5210SJason Evans } 803a4bd5210SJason Evans } 80482872ac0SJason Evans ctl_stats.arenas[ctl_stats.narenas].initialized = true; 805a4bd5210SJason Evans 806a4bd5210SJason Evans ctl_epoch = 0; 8071f0a49e8SJason Evans ctl_refresh(tsdn); 808a4bd5210SJason Evans ctl_initialized = true; 809a4bd5210SJason Evans } 810a4bd5210SJason Evans 811a4bd5210SJason Evans ret = false; 812a4bd5210SJason Evans label_return: 8131f0a49e8SJason Evans malloc_mutex_unlock(tsdn, &ctl_mtx); 814a4bd5210SJason Evans return (ret); 815a4bd5210SJason Evans } 816a4bd5210SJason Evans 817a4bd5210SJason Evans static int 8181f0a49e8SJason Evans ctl_lookup(tsdn_t *tsdn, const char *name, ctl_node_t const **nodesp, 8191f0a49e8SJason Evans size_t *mibp, size_t *depthp) 820a4bd5210SJason Evans { 821a4bd5210SJason Evans int ret; 822a4bd5210SJason Evans const char *elm, *tdot, *dot; 823a4bd5210SJason Evans size_t elen, i, j; 824e722f8f8SJason Evans const ctl_named_node_t *node; 825a4bd5210SJason Evans 826a4bd5210SJason Evans elm = name; 827a4bd5210SJason Evans /* Equivalent to strchrnul(). */ 828a4bd5210SJason Evans dot = ((tdot = strchr(elm, '.')) != NULL) ? tdot : strchr(elm, '\0'); 829a4bd5210SJason Evans elen = (size_t)((uintptr_t)dot - (uintptr_t)elm); 830a4bd5210SJason Evans if (elen == 0) { 831a4bd5210SJason Evans ret = ENOENT; 832a4bd5210SJason Evans goto label_return; 833a4bd5210SJason Evans } 834a4bd5210SJason Evans node = super_root_node; 835a4bd5210SJason Evans for (i = 0; i < *depthp; i++) { 836e722f8f8SJason Evans assert(node); 837e722f8f8SJason Evans assert(node->nchildren > 0); 838e722f8f8SJason Evans if (ctl_named_node(node->children) != NULL) { 839e722f8f8SJason Evans const ctl_named_node_t *pnode = node; 840a4bd5210SJason Evans 841a4bd5210SJason Evans /* Children are named. */ 842e722f8f8SJason Evans for (j = 0; j < node->nchildren; j++) { 843e722f8f8SJason Evans const ctl_named_node_t *child = 844e722f8f8SJason Evans ctl_named_children(node, j); 845e722f8f8SJason Evans if (strlen(child->name) == elen && 846e722f8f8SJason Evans strncmp(elm, child->name, elen) == 0) { 847a4bd5210SJason Evans node = child; 848a4bd5210SJason Evans if (nodesp != NULL) 849e722f8f8SJason Evans nodesp[i] = 850e722f8f8SJason Evans (const ctl_node_t *)node; 851a4bd5210SJason Evans mibp[i] = j; 852a4bd5210SJason Evans break; 853a4bd5210SJason Evans } 854a4bd5210SJason Evans } 855a4bd5210SJason Evans if (node == pnode) { 856a4bd5210SJason Evans ret = ENOENT; 857a4bd5210SJason Evans goto label_return; 858a4bd5210SJason Evans } 859a4bd5210SJason Evans } else { 860a4bd5210SJason Evans uintmax_t index; 861e722f8f8SJason Evans const ctl_indexed_node_t *inode; 862a4bd5210SJason Evans 863a4bd5210SJason Evans /* Children are indexed. */ 864a4bd5210SJason Evans index = malloc_strtoumax(elm, NULL, 10); 865a4bd5210SJason Evans if (index == UINTMAX_MAX || index > SIZE_T_MAX) { 866a4bd5210SJason Evans ret = ENOENT; 867a4bd5210SJason Evans goto label_return; 868a4bd5210SJason Evans } 869a4bd5210SJason Evans 870e722f8f8SJason Evans inode = ctl_indexed_node(node->children); 8711f0a49e8SJason Evans node = inode->index(tsdn, mibp, *depthp, (size_t)index); 872a4bd5210SJason Evans if (node == NULL) { 873a4bd5210SJason Evans ret = ENOENT; 874a4bd5210SJason Evans goto label_return; 875a4bd5210SJason Evans } 876a4bd5210SJason Evans 877a4bd5210SJason Evans if (nodesp != NULL) 878e722f8f8SJason Evans nodesp[i] = (const ctl_node_t *)node; 879a4bd5210SJason Evans mibp[i] = (size_t)index; 880a4bd5210SJason Evans } 881a4bd5210SJason Evans 882a4bd5210SJason Evans if (node->ctl != NULL) { 883a4bd5210SJason Evans /* Terminal node. */ 884a4bd5210SJason Evans if (*dot != '\0') { 885a4bd5210SJason Evans /* 886a4bd5210SJason Evans * The name contains more elements than are 887a4bd5210SJason Evans * in this path through the tree. 888a4bd5210SJason Evans */ 889a4bd5210SJason Evans ret = ENOENT; 890a4bd5210SJason Evans goto label_return; 891a4bd5210SJason Evans } 892a4bd5210SJason Evans /* Complete lookup successful. */ 893a4bd5210SJason Evans *depthp = i + 1; 894a4bd5210SJason Evans break; 895a4bd5210SJason Evans } 896a4bd5210SJason Evans 897a4bd5210SJason Evans /* Update elm. */ 898a4bd5210SJason Evans if (*dot == '\0') { 899a4bd5210SJason Evans /* No more elements. */ 900a4bd5210SJason Evans ret = ENOENT; 901a4bd5210SJason Evans goto label_return; 902a4bd5210SJason Evans } 903a4bd5210SJason Evans elm = &dot[1]; 904a4bd5210SJason Evans dot = ((tdot = strchr(elm, '.')) != NULL) ? tdot : 905a4bd5210SJason Evans strchr(elm, '\0'); 906a4bd5210SJason Evans elen = (size_t)((uintptr_t)dot - (uintptr_t)elm); 907a4bd5210SJason Evans } 908a4bd5210SJason Evans 909a4bd5210SJason Evans ret = 0; 910a4bd5210SJason Evans label_return: 911a4bd5210SJason Evans return (ret); 912a4bd5210SJason Evans } 913a4bd5210SJason Evans 914a4bd5210SJason Evans int 9151f0a49e8SJason Evans ctl_byname(tsd_t *tsd, const char *name, void *oldp, size_t *oldlenp, 9161f0a49e8SJason Evans void *newp, size_t newlen) 917a4bd5210SJason Evans { 918a4bd5210SJason Evans int ret; 919a4bd5210SJason Evans size_t depth; 920a4bd5210SJason Evans ctl_node_t const *nodes[CTL_MAX_DEPTH]; 921a4bd5210SJason Evans size_t mib[CTL_MAX_DEPTH]; 922e722f8f8SJason Evans const ctl_named_node_t *node; 923a4bd5210SJason Evans 9241f0a49e8SJason Evans if (!ctl_initialized && ctl_init(tsd_tsdn(tsd))) { 925a4bd5210SJason Evans ret = EAGAIN; 926a4bd5210SJason Evans goto label_return; 927a4bd5210SJason Evans } 928a4bd5210SJason Evans 929a4bd5210SJason Evans depth = CTL_MAX_DEPTH; 9301f0a49e8SJason Evans ret = ctl_lookup(tsd_tsdn(tsd), name, nodes, mib, &depth); 931a4bd5210SJason Evans if (ret != 0) 932a4bd5210SJason Evans goto label_return; 933a4bd5210SJason Evans 934e722f8f8SJason Evans node = ctl_named_node(nodes[depth-1]); 935e722f8f8SJason Evans if (node != NULL && node->ctl) 9361f0a49e8SJason Evans ret = node->ctl(tsd, mib, depth, oldp, oldlenp, newp, newlen); 937e722f8f8SJason Evans else { 938a4bd5210SJason Evans /* The name refers to a partial path through the ctl tree. */ 939a4bd5210SJason Evans ret = ENOENT; 940a4bd5210SJason Evans } 941a4bd5210SJason Evans 942a4bd5210SJason Evans label_return: 943a4bd5210SJason Evans return(ret); 944a4bd5210SJason Evans } 945a4bd5210SJason Evans 946a4bd5210SJason Evans int 9471f0a49e8SJason Evans ctl_nametomib(tsdn_t *tsdn, const char *name, size_t *mibp, size_t *miblenp) 948a4bd5210SJason Evans { 949a4bd5210SJason Evans int ret; 950a4bd5210SJason Evans 9511f0a49e8SJason Evans if (!ctl_initialized && ctl_init(tsdn)) { 952a4bd5210SJason Evans ret = EAGAIN; 953a4bd5210SJason Evans goto label_return; 954a4bd5210SJason Evans } 955a4bd5210SJason Evans 9561f0a49e8SJason Evans ret = ctl_lookup(tsdn, name, NULL, mibp, miblenp); 957a4bd5210SJason Evans label_return: 958a4bd5210SJason Evans return(ret); 959a4bd5210SJason Evans } 960a4bd5210SJason Evans 961a4bd5210SJason Evans int 9621f0a49e8SJason Evans ctl_bymib(tsd_t *tsd, const size_t *mib, size_t miblen, void *oldp, 9631f0a49e8SJason Evans size_t *oldlenp, void *newp, size_t newlen) 964a4bd5210SJason Evans { 965a4bd5210SJason Evans int ret; 966e722f8f8SJason Evans const ctl_named_node_t *node; 967a4bd5210SJason Evans size_t i; 968a4bd5210SJason Evans 9691f0a49e8SJason Evans if (!ctl_initialized && ctl_init(tsd_tsdn(tsd))) { 970a4bd5210SJason Evans ret = EAGAIN; 971a4bd5210SJason Evans goto label_return; 972a4bd5210SJason Evans } 973a4bd5210SJason Evans 974a4bd5210SJason Evans /* Iterate down the tree. */ 975a4bd5210SJason Evans node = super_root_node; 976a4bd5210SJason Evans for (i = 0; i < miblen; i++) { 977e722f8f8SJason Evans assert(node); 978e722f8f8SJason Evans assert(node->nchildren > 0); 979e722f8f8SJason Evans if (ctl_named_node(node->children) != NULL) { 980a4bd5210SJason Evans /* Children are named. */ 981df0d881dSJason Evans if (node->nchildren <= (unsigned)mib[i]) { 982a4bd5210SJason Evans ret = ENOENT; 983a4bd5210SJason Evans goto label_return; 984a4bd5210SJason Evans } 985e722f8f8SJason Evans node = ctl_named_children(node, mib[i]); 986a4bd5210SJason Evans } else { 987e722f8f8SJason Evans const ctl_indexed_node_t *inode; 988a4bd5210SJason Evans 989a4bd5210SJason Evans /* Indexed element. */ 990e722f8f8SJason Evans inode = ctl_indexed_node(node->children); 9911f0a49e8SJason Evans node = inode->index(tsd_tsdn(tsd), mib, miblen, mib[i]); 992a4bd5210SJason Evans if (node == NULL) { 993a4bd5210SJason Evans ret = ENOENT; 994a4bd5210SJason Evans goto label_return; 995a4bd5210SJason Evans } 996a4bd5210SJason Evans } 997a4bd5210SJason Evans } 998a4bd5210SJason Evans 999a4bd5210SJason Evans /* Call the ctl function. */ 1000e722f8f8SJason Evans if (node && node->ctl) 10011f0a49e8SJason Evans ret = node->ctl(tsd, mib, miblen, oldp, oldlenp, newp, newlen); 1002e722f8f8SJason Evans else { 1003a4bd5210SJason Evans /* Partial MIB. */ 1004a4bd5210SJason Evans ret = ENOENT; 1005a4bd5210SJason Evans } 1006a4bd5210SJason Evans 1007a4bd5210SJason Evans label_return: 1008a4bd5210SJason Evans return(ret); 1009a4bd5210SJason Evans } 1010a4bd5210SJason Evans 1011a4bd5210SJason Evans bool 1012a4bd5210SJason Evans ctl_boot(void) 1013a4bd5210SJason Evans { 1014a4bd5210SJason Evans 10151f0a49e8SJason Evans if (malloc_mutex_init(&ctl_mtx, "ctl", WITNESS_RANK_CTL)) 1016a4bd5210SJason Evans return (true); 1017a4bd5210SJason Evans 1018a4bd5210SJason Evans ctl_initialized = false; 1019a4bd5210SJason Evans 1020a4bd5210SJason Evans return (false); 1021a4bd5210SJason Evans } 1022a4bd5210SJason Evans 102382872ac0SJason Evans void 10241f0a49e8SJason Evans ctl_prefork(tsdn_t *tsdn) 102582872ac0SJason Evans { 102682872ac0SJason Evans 10271f0a49e8SJason Evans malloc_mutex_prefork(tsdn, &ctl_mtx); 102882872ac0SJason Evans } 102982872ac0SJason Evans 103082872ac0SJason Evans void 10311f0a49e8SJason Evans ctl_postfork_parent(tsdn_t *tsdn) 103282872ac0SJason Evans { 103382872ac0SJason Evans 10341f0a49e8SJason Evans malloc_mutex_postfork_parent(tsdn, &ctl_mtx); 103582872ac0SJason Evans } 103682872ac0SJason Evans 103782872ac0SJason Evans void 10381f0a49e8SJason Evans ctl_postfork_child(tsdn_t *tsdn) 103982872ac0SJason Evans { 104082872ac0SJason Evans 10411f0a49e8SJason Evans malloc_mutex_postfork_child(tsdn, &ctl_mtx); 104282872ac0SJason Evans } 104382872ac0SJason Evans 1044a4bd5210SJason Evans /******************************************************************************/ 1045a4bd5210SJason Evans /* *_ctl() functions. */ 1046a4bd5210SJason Evans 1047a4bd5210SJason Evans #define READONLY() do { \ 1048a4bd5210SJason Evans if (newp != NULL || newlen != 0) { \ 1049a4bd5210SJason Evans ret = EPERM; \ 1050a4bd5210SJason Evans goto label_return; \ 1051a4bd5210SJason Evans } \ 1052a4bd5210SJason Evans } while (0) 1053a4bd5210SJason Evans 1054a4bd5210SJason Evans #define WRITEONLY() do { \ 1055a4bd5210SJason Evans if (oldp != NULL || oldlenp != NULL) { \ 1056a4bd5210SJason Evans ret = EPERM; \ 1057a4bd5210SJason Evans goto label_return; \ 1058a4bd5210SJason Evans } \ 1059a4bd5210SJason Evans } while (0) 1060a4bd5210SJason Evans 1061d0e79aa3SJason Evans #define READ_XOR_WRITE() do { \ 1062d0e79aa3SJason Evans if ((oldp != NULL && oldlenp != NULL) && (newp != NULL || \ 1063d0e79aa3SJason Evans newlen != 0)) { \ 1064d0e79aa3SJason Evans ret = EPERM; \ 1065d0e79aa3SJason Evans goto label_return; \ 1066d0e79aa3SJason Evans } \ 1067d0e79aa3SJason Evans } while (0) 1068d0e79aa3SJason Evans 1069a4bd5210SJason Evans #define READ(v, t) do { \ 1070a4bd5210SJason Evans if (oldp != NULL && oldlenp != NULL) { \ 1071a4bd5210SJason Evans if (*oldlenp != sizeof(t)) { \ 1072a4bd5210SJason Evans size_t copylen = (sizeof(t) <= *oldlenp) \ 1073a4bd5210SJason Evans ? sizeof(t) : *oldlenp; \ 107488ad2f8dSJason Evans memcpy(oldp, (void *)&(v), copylen); \ 1075a4bd5210SJason Evans ret = EINVAL; \ 1076a4bd5210SJason Evans goto label_return; \ 1077d0e79aa3SJason Evans } \ 107888ad2f8dSJason Evans *(t *)oldp = (v); \ 1079a4bd5210SJason Evans } \ 1080a4bd5210SJason Evans } while (0) 1081a4bd5210SJason Evans 1082a4bd5210SJason Evans #define WRITE(v, t) do { \ 1083a4bd5210SJason Evans if (newp != NULL) { \ 1084a4bd5210SJason Evans if (newlen != sizeof(t)) { \ 1085a4bd5210SJason Evans ret = EINVAL; \ 1086a4bd5210SJason Evans goto label_return; \ 1087a4bd5210SJason Evans } \ 108888ad2f8dSJason Evans (v) = *(t *)newp; \ 1089a4bd5210SJason Evans } \ 1090a4bd5210SJason Evans } while (0) 1091a4bd5210SJason Evans 1092a4bd5210SJason Evans /* 1093a4bd5210SJason Evans * There's a lot of code duplication in the following macros due to limitations 1094a4bd5210SJason Evans * in how nested cpp macros are expanded. 1095a4bd5210SJason Evans */ 1096a4bd5210SJason Evans #define CTL_RO_CLGEN(c, l, n, v, t) \ 1097a4bd5210SJason Evans static int \ 10981f0a49e8SJason Evans n##_ctl(tsd_t *tsd, const size_t *mib, size_t miblen, void *oldp, \ 10991f0a49e8SJason Evans size_t *oldlenp, void *newp, size_t newlen) \ 1100a4bd5210SJason Evans { \ 1101a4bd5210SJason Evans int ret; \ 1102a4bd5210SJason Evans t oldval; \ 1103a4bd5210SJason Evans \ 1104d0e79aa3SJason Evans if (!(c)) \ 1105a4bd5210SJason Evans return (ENOENT); \ 1106a4bd5210SJason Evans if (l) \ 11071f0a49e8SJason Evans malloc_mutex_lock(tsd_tsdn(tsd), &ctl_mtx); \ 1108a4bd5210SJason Evans READONLY(); \ 110988ad2f8dSJason Evans oldval = (v); \ 1110a4bd5210SJason Evans READ(oldval, t); \ 1111a4bd5210SJason Evans \ 1112a4bd5210SJason Evans ret = 0; \ 1113a4bd5210SJason Evans label_return: \ 1114a4bd5210SJason Evans if (l) \ 11151f0a49e8SJason Evans malloc_mutex_unlock(tsd_tsdn(tsd), &ctl_mtx); \ 1116a4bd5210SJason Evans return (ret); \ 1117a4bd5210SJason Evans } 1118a4bd5210SJason Evans 1119a4bd5210SJason Evans #define CTL_RO_CGEN(c, n, v, t) \ 1120a4bd5210SJason Evans static int \ 11211f0a49e8SJason Evans n##_ctl(tsd_t *tsd, const size_t *mib, size_t miblen, void *oldp, \ 11221f0a49e8SJason Evans size_t *oldlenp, void *newp, size_t newlen) \ 1123a4bd5210SJason Evans { \ 1124a4bd5210SJason Evans int ret; \ 1125a4bd5210SJason Evans t oldval; \ 1126a4bd5210SJason Evans \ 1127d0e79aa3SJason Evans if (!(c)) \ 1128a4bd5210SJason Evans return (ENOENT); \ 11291f0a49e8SJason Evans malloc_mutex_lock(tsd_tsdn(tsd), &ctl_mtx); \ 1130a4bd5210SJason Evans READONLY(); \ 113188ad2f8dSJason Evans oldval = (v); \ 1132a4bd5210SJason Evans READ(oldval, t); \ 1133a4bd5210SJason Evans \ 1134a4bd5210SJason Evans ret = 0; \ 1135a4bd5210SJason Evans label_return: \ 11361f0a49e8SJason Evans malloc_mutex_unlock(tsd_tsdn(tsd), &ctl_mtx); \ 1137a4bd5210SJason Evans return (ret); \ 1138a4bd5210SJason Evans } 1139a4bd5210SJason Evans 1140a4bd5210SJason Evans #define CTL_RO_GEN(n, v, t) \ 1141a4bd5210SJason Evans static int \ 11421f0a49e8SJason Evans n##_ctl(tsd_t *tsd, const size_t *mib, size_t miblen, void *oldp, \ 11431f0a49e8SJason Evans size_t *oldlenp, void *newp, size_t newlen) \ 1144a4bd5210SJason Evans { \ 1145a4bd5210SJason Evans int ret; \ 1146a4bd5210SJason Evans t oldval; \ 1147a4bd5210SJason Evans \ 11481f0a49e8SJason Evans malloc_mutex_lock(tsd_tsdn(tsd), &ctl_mtx); \ 1149a4bd5210SJason Evans READONLY(); \ 115088ad2f8dSJason Evans oldval = (v); \ 1151a4bd5210SJason Evans READ(oldval, t); \ 1152a4bd5210SJason Evans \ 1153a4bd5210SJason Evans ret = 0; \ 1154a4bd5210SJason Evans label_return: \ 11551f0a49e8SJason Evans malloc_mutex_unlock(tsd_tsdn(tsd), &ctl_mtx); \ 1156a4bd5210SJason Evans return (ret); \ 1157a4bd5210SJason Evans } 1158a4bd5210SJason Evans 1159a4bd5210SJason Evans /* 1160a4bd5210SJason Evans * ctl_mtx is not acquired, under the assumption that no pertinent data will 1161a4bd5210SJason Evans * mutate during the call. 1162a4bd5210SJason Evans */ 1163a4bd5210SJason Evans #define CTL_RO_NL_CGEN(c, n, v, t) \ 1164a4bd5210SJason Evans static int \ 11651f0a49e8SJason Evans n##_ctl(tsd_t *tsd, const size_t *mib, size_t miblen, void *oldp, \ 11661f0a49e8SJason Evans size_t *oldlenp, void *newp, size_t newlen) \ 1167a4bd5210SJason Evans { \ 1168a4bd5210SJason Evans int ret; \ 1169a4bd5210SJason Evans t oldval; \ 1170a4bd5210SJason Evans \ 1171d0e79aa3SJason Evans if (!(c)) \ 1172a4bd5210SJason Evans return (ENOENT); \ 1173a4bd5210SJason Evans READONLY(); \ 117488ad2f8dSJason Evans oldval = (v); \ 1175a4bd5210SJason Evans READ(oldval, t); \ 1176a4bd5210SJason Evans \ 1177a4bd5210SJason Evans ret = 0; \ 1178a4bd5210SJason Evans label_return: \ 1179a4bd5210SJason Evans return (ret); \ 1180a4bd5210SJason Evans } 1181a4bd5210SJason Evans 1182a4bd5210SJason Evans #define CTL_RO_NL_GEN(n, v, t) \ 1183a4bd5210SJason Evans static int \ 11841f0a49e8SJason Evans n##_ctl(tsd_t *tsd, const size_t *mib, size_t miblen, void *oldp, \ 11851f0a49e8SJason Evans size_t *oldlenp, void *newp, size_t newlen) \ 1186a4bd5210SJason Evans { \ 1187a4bd5210SJason Evans int ret; \ 1188a4bd5210SJason Evans t oldval; \ 1189a4bd5210SJason Evans \ 1190a4bd5210SJason Evans READONLY(); \ 119188ad2f8dSJason Evans oldval = (v); \ 1192a4bd5210SJason Evans READ(oldval, t); \ 1193a4bd5210SJason Evans \ 1194a4bd5210SJason Evans ret = 0; \ 1195a4bd5210SJason Evans label_return: \ 1196a4bd5210SJason Evans return (ret); \ 1197a4bd5210SJason Evans } 1198a4bd5210SJason Evans 1199d0e79aa3SJason Evans #define CTL_TSD_RO_NL_CGEN(c, n, m, t) \ 1200d0e79aa3SJason Evans static int \ 12011f0a49e8SJason Evans n##_ctl(tsd_t *tsd, const size_t *mib, size_t miblen, void *oldp, \ 12021f0a49e8SJason Evans size_t *oldlenp, void *newp, size_t newlen) \ 1203d0e79aa3SJason Evans { \ 1204d0e79aa3SJason Evans int ret; \ 1205d0e79aa3SJason Evans t oldval; \ 1206d0e79aa3SJason Evans \ 1207d0e79aa3SJason Evans if (!(c)) \ 1208d0e79aa3SJason Evans return (ENOENT); \ 1209d0e79aa3SJason Evans READONLY(); \ 1210d0e79aa3SJason Evans oldval = (m(tsd)); \ 1211d0e79aa3SJason Evans READ(oldval, t); \ 1212d0e79aa3SJason Evans \ 1213d0e79aa3SJason Evans ret = 0; \ 1214d0e79aa3SJason Evans label_return: \ 1215d0e79aa3SJason Evans return (ret); \ 1216d0e79aa3SJason Evans } 1217d0e79aa3SJason Evans 1218df0d881dSJason Evans #define CTL_RO_CONFIG_GEN(n, t) \ 1219a4bd5210SJason Evans static int \ 12201f0a49e8SJason Evans n##_ctl(tsd_t *tsd, const size_t *mib, size_t miblen, void *oldp, \ 12211f0a49e8SJason Evans size_t *oldlenp, void *newp, size_t newlen) \ 1222a4bd5210SJason Evans { \ 1223a4bd5210SJason Evans int ret; \ 1224df0d881dSJason Evans t oldval; \ 1225a4bd5210SJason Evans \ 1226a4bd5210SJason Evans READONLY(); \ 1227a4bd5210SJason Evans oldval = n; \ 1228df0d881dSJason Evans READ(oldval, t); \ 1229a4bd5210SJason Evans \ 1230a4bd5210SJason Evans ret = 0; \ 1231a4bd5210SJason Evans label_return: \ 1232a4bd5210SJason Evans return (ret); \ 1233a4bd5210SJason Evans } 1234a4bd5210SJason Evans 1235f921d10fSJason Evans /******************************************************************************/ 1236f921d10fSJason Evans 1237a4bd5210SJason Evans CTL_RO_NL_GEN(version, JEMALLOC_VERSION, const char *) 1238a4bd5210SJason Evans 1239a4bd5210SJason Evans static int 12401f0a49e8SJason Evans epoch_ctl(tsd_t *tsd, const size_t *mib, size_t miblen, void *oldp, 12411f0a49e8SJason Evans size_t *oldlenp, void *newp, size_t newlen) 1242a4bd5210SJason Evans { 1243a4bd5210SJason Evans int ret; 12442b06b201SJason Evans UNUSED uint64_t newval; 1245a4bd5210SJason Evans 12461f0a49e8SJason Evans malloc_mutex_lock(tsd_tsdn(tsd), &ctl_mtx); 1247a4bd5210SJason Evans WRITE(newval, uint64_t); 1248e722f8f8SJason Evans if (newp != NULL) 12491f0a49e8SJason Evans ctl_refresh(tsd_tsdn(tsd)); 1250a4bd5210SJason Evans READ(ctl_epoch, uint64_t); 1251a4bd5210SJason Evans 1252a4bd5210SJason Evans ret = 0; 1253a4bd5210SJason Evans label_return: 12541f0a49e8SJason Evans malloc_mutex_unlock(tsd_tsdn(tsd), &ctl_mtx); 1255a4bd5210SJason Evans return (ret); 1256a4bd5210SJason Evans } 1257a4bd5210SJason Evans 1258f921d10fSJason Evans /******************************************************************************/ 1259a4bd5210SJason Evans 1260df0d881dSJason Evans CTL_RO_CONFIG_GEN(config_cache_oblivious, bool) 1261df0d881dSJason Evans CTL_RO_CONFIG_GEN(config_debug, bool) 1262df0d881dSJason Evans CTL_RO_CONFIG_GEN(config_fill, bool) 1263df0d881dSJason Evans CTL_RO_CONFIG_GEN(config_lazy_lock, bool) 1264df0d881dSJason Evans CTL_RO_CONFIG_GEN(config_malloc_conf, const char *) 1265df0d881dSJason Evans CTL_RO_CONFIG_GEN(config_munmap, bool) 1266df0d881dSJason Evans CTL_RO_CONFIG_GEN(config_prof, bool) 1267df0d881dSJason Evans CTL_RO_CONFIG_GEN(config_prof_libgcc, bool) 1268df0d881dSJason Evans CTL_RO_CONFIG_GEN(config_prof_libunwind, bool) 1269df0d881dSJason Evans CTL_RO_CONFIG_GEN(config_stats, bool) 1270df0d881dSJason Evans CTL_RO_CONFIG_GEN(config_tcache, bool) 1271df0d881dSJason Evans CTL_RO_CONFIG_GEN(config_tls, bool) 1272df0d881dSJason Evans CTL_RO_CONFIG_GEN(config_utrace, bool) 1273df0d881dSJason Evans CTL_RO_CONFIG_GEN(config_valgrind, bool) 1274df0d881dSJason Evans CTL_RO_CONFIG_GEN(config_xmalloc, bool) 1275a4bd5210SJason Evans 1276f921d10fSJason Evans /******************************************************************************/ 1277a4bd5210SJason Evans 1278f921d10fSJason Evans CTL_RO_NL_GEN(opt_abort, opt_abort, bool) 1279f921d10fSJason Evans CTL_RO_NL_GEN(opt_dss, opt_dss, const char *) 1280f921d10fSJason Evans CTL_RO_NL_GEN(opt_lg_chunk, opt_lg_chunk, size_t) 1281df0d881dSJason Evans CTL_RO_NL_GEN(opt_narenas, opt_narenas, unsigned) 1282df0d881dSJason Evans CTL_RO_NL_GEN(opt_purge, purge_mode_names[opt_purge], const char *) 1283f921d10fSJason Evans CTL_RO_NL_GEN(opt_lg_dirty_mult, opt_lg_dirty_mult, ssize_t) 1284df0d881dSJason Evans CTL_RO_NL_GEN(opt_decay_time, opt_decay_time, ssize_t) 1285f921d10fSJason Evans CTL_RO_NL_GEN(opt_stats_print, opt_stats_print, bool) 1286d0e79aa3SJason Evans CTL_RO_NL_CGEN(config_fill, opt_junk, opt_junk, const char *) 1287f921d10fSJason Evans CTL_RO_NL_CGEN(config_fill, opt_quarantine, opt_quarantine, size_t) 1288f921d10fSJason Evans CTL_RO_NL_CGEN(config_fill, opt_redzone, opt_redzone, bool) 1289f921d10fSJason Evans CTL_RO_NL_CGEN(config_fill, opt_zero, opt_zero, bool) 1290f921d10fSJason Evans CTL_RO_NL_CGEN(config_utrace, opt_utrace, opt_utrace, bool) 1291f921d10fSJason Evans CTL_RO_NL_CGEN(config_xmalloc, opt_xmalloc, opt_xmalloc, bool) 1292f921d10fSJason Evans CTL_RO_NL_CGEN(config_tcache, opt_tcache, opt_tcache, bool) 1293f921d10fSJason Evans CTL_RO_NL_CGEN(config_tcache, opt_lg_tcache_max, opt_lg_tcache_max, ssize_t) 1294f921d10fSJason Evans CTL_RO_NL_CGEN(config_prof, opt_prof, opt_prof, bool) 1295f921d10fSJason Evans CTL_RO_NL_CGEN(config_prof, opt_prof_prefix, opt_prof_prefix, const char *) 1296d0e79aa3SJason Evans CTL_RO_NL_CGEN(config_prof, opt_prof_active, opt_prof_active, bool) 1297d0e79aa3SJason Evans CTL_RO_NL_CGEN(config_prof, opt_prof_thread_active_init, 1298d0e79aa3SJason Evans opt_prof_thread_active_init, bool) 1299f921d10fSJason Evans CTL_RO_NL_CGEN(config_prof, opt_lg_prof_sample, opt_lg_prof_sample, size_t) 1300f921d10fSJason Evans CTL_RO_NL_CGEN(config_prof, opt_prof_accum, opt_prof_accum, bool) 1301f921d10fSJason Evans CTL_RO_NL_CGEN(config_prof, opt_lg_prof_interval, opt_lg_prof_interval, ssize_t) 1302f921d10fSJason Evans CTL_RO_NL_CGEN(config_prof, opt_prof_gdump, opt_prof_gdump, bool) 1303f921d10fSJason Evans CTL_RO_NL_CGEN(config_prof, opt_prof_final, opt_prof_final, bool) 1304f921d10fSJason Evans CTL_RO_NL_CGEN(config_prof, opt_prof_leak, opt_prof_leak, bool) 1305a4bd5210SJason Evans 1306f921d10fSJason Evans /******************************************************************************/ 1307a4bd5210SJason Evans 1308a4bd5210SJason Evans static int 13091f0a49e8SJason Evans thread_arena_ctl(tsd_t *tsd, const size_t *mib, size_t miblen, void *oldp, 13101f0a49e8SJason Evans size_t *oldlenp, void *newp, size_t newlen) 1311a4bd5210SJason Evans { 1312a4bd5210SJason Evans int ret; 1313d0e79aa3SJason Evans arena_t *oldarena; 1314a4bd5210SJason Evans unsigned newind, oldind; 1315a4bd5210SJason Evans 1316d0e79aa3SJason Evans oldarena = arena_choose(tsd, NULL); 1317d0e79aa3SJason Evans if (oldarena == NULL) 1318d0e79aa3SJason Evans return (EAGAIN); 1319d0e79aa3SJason Evans 13201f0a49e8SJason Evans malloc_mutex_lock(tsd_tsdn(tsd), &ctl_mtx); 1321d0e79aa3SJason Evans newind = oldind = oldarena->ind; 1322a4bd5210SJason Evans WRITE(newind, unsigned); 1323a4bd5210SJason Evans READ(oldind, unsigned); 1324a4bd5210SJason Evans if (newind != oldind) { 1325d0e79aa3SJason Evans arena_t *newarena; 1326a4bd5210SJason Evans 132782872ac0SJason Evans if (newind >= ctl_stats.narenas) { 1328a4bd5210SJason Evans /* New arena index is out of range. */ 1329a4bd5210SJason Evans ret = EFAULT; 1330a4bd5210SJason Evans goto label_return; 1331a4bd5210SJason Evans } 1332a4bd5210SJason Evans 1333a4bd5210SJason Evans /* Initialize arena if necessary. */ 13341f0a49e8SJason Evans newarena = arena_get(tsd_tsdn(tsd), newind, true); 1335d0e79aa3SJason Evans if (newarena == NULL) { 1336a4bd5210SJason Evans ret = EAGAIN; 1337a4bd5210SJason Evans goto label_return; 1338a4bd5210SJason Evans } 1339d0e79aa3SJason Evans /* Set new arena/tcache associations. */ 1340d0e79aa3SJason Evans arena_migrate(tsd, oldind, newind); 1341a4bd5210SJason Evans if (config_tcache) { 1342d0e79aa3SJason Evans tcache_t *tcache = tsd_tcache_get(tsd); 1343d0e79aa3SJason Evans if (tcache != NULL) { 13441f0a49e8SJason Evans tcache_arena_reassociate(tsd_tsdn(tsd), tcache, 13451f0a49e8SJason Evans oldarena, newarena); 1346a4bd5210SJason Evans } 1347a4bd5210SJason Evans } 1348a4bd5210SJason Evans } 1349a4bd5210SJason Evans 1350a4bd5210SJason Evans ret = 0; 1351a4bd5210SJason Evans label_return: 13521f0a49e8SJason Evans malloc_mutex_unlock(tsd_tsdn(tsd), &ctl_mtx); 1353a4bd5210SJason Evans return (ret); 1354a4bd5210SJason Evans } 1355a4bd5210SJason Evans 1356d0e79aa3SJason Evans CTL_TSD_RO_NL_CGEN(config_stats, thread_allocated, tsd_thread_allocated_get, 1357d0e79aa3SJason Evans uint64_t) 1358d0e79aa3SJason Evans CTL_TSD_RO_NL_CGEN(config_stats, thread_allocatedp, tsd_thread_allocatedp_get, 1359d0e79aa3SJason Evans uint64_t *) 1360d0e79aa3SJason Evans CTL_TSD_RO_NL_CGEN(config_stats, thread_deallocated, tsd_thread_deallocated_get, 1361d0e79aa3SJason Evans uint64_t) 1362d0e79aa3SJason Evans CTL_TSD_RO_NL_CGEN(config_stats, thread_deallocatedp, 1363d0e79aa3SJason Evans tsd_thread_deallocatedp_get, uint64_t *) 1364a4bd5210SJason Evans 1365f921d10fSJason Evans static int 13661f0a49e8SJason Evans thread_tcache_enabled_ctl(tsd_t *tsd, const size_t *mib, size_t miblen, 13671f0a49e8SJason Evans void *oldp, size_t *oldlenp, void *newp, size_t newlen) 1368f921d10fSJason Evans { 1369f921d10fSJason Evans int ret; 1370f921d10fSJason Evans bool oldval; 1371a4bd5210SJason Evans 1372d0e79aa3SJason Evans if (!config_tcache) 1373f921d10fSJason Evans return (ENOENT); 1374a4bd5210SJason Evans 1375f921d10fSJason Evans oldval = tcache_enabled_get(); 1376f921d10fSJason Evans if (newp != NULL) { 1377f921d10fSJason Evans if (newlen != sizeof(bool)) { 1378f921d10fSJason Evans ret = EINVAL; 1379f921d10fSJason Evans goto label_return; 1380f921d10fSJason Evans } 1381f921d10fSJason Evans tcache_enabled_set(*(bool *)newp); 1382f921d10fSJason Evans } 1383f921d10fSJason Evans READ(oldval, bool); 1384a4bd5210SJason Evans 1385f921d10fSJason Evans ret = 0; 1386f921d10fSJason Evans label_return: 1387f921d10fSJason Evans return (ret); 1388f921d10fSJason Evans } 1389f921d10fSJason Evans 1390f921d10fSJason Evans static int 13911f0a49e8SJason Evans thread_tcache_flush_ctl(tsd_t *tsd, const size_t *mib, size_t miblen, 13921f0a49e8SJason Evans void *oldp, size_t *oldlenp, void *newp, size_t newlen) 1393f921d10fSJason Evans { 1394f921d10fSJason Evans int ret; 1395f921d10fSJason Evans 1396d0e79aa3SJason Evans if (!config_tcache) 1397f921d10fSJason Evans return (ENOENT); 1398f921d10fSJason Evans 1399f921d10fSJason Evans READONLY(); 1400f921d10fSJason Evans WRITEONLY(); 1401f921d10fSJason Evans 1402f921d10fSJason Evans tcache_flush(); 1403f921d10fSJason Evans 1404f921d10fSJason Evans ret = 0; 1405f921d10fSJason Evans label_return: 1406f921d10fSJason Evans return (ret); 1407f921d10fSJason Evans } 1408a4bd5210SJason Evans 1409d0e79aa3SJason Evans static int 14101f0a49e8SJason Evans thread_prof_name_ctl(tsd_t *tsd, const size_t *mib, size_t miblen, void *oldp, 1411d0e79aa3SJason Evans size_t *oldlenp, void *newp, size_t newlen) 1412d0e79aa3SJason Evans { 1413d0e79aa3SJason Evans int ret; 1414d0e79aa3SJason Evans 1415d0e79aa3SJason Evans if (!config_prof) 1416d0e79aa3SJason Evans return (ENOENT); 1417d0e79aa3SJason Evans 1418d0e79aa3SJason Evans READ_XOR_WRITE(); 1419d0e79aa3SJason Evans 1420d0e79aa3SJason Evans if (newp != NULL) { 1421d0e79aa3SJason Evans if (newlen != sizeof(const char *)) { 1422d0e79aa3SJason Evans ret = EINVAL; 1423d0e79aa3SJason Evans goto label_return; 1424d0e79aa3SJason Evans } 1425d0e79aa3SJason Evans 1426d0e79aa3SJason Evans if ((ret = prof_thread_name_set(tsd, *(const char **)newp)) != 1427d0e79aa3SJason Evans 0) 1428d0e79aa3SJason Evans goto label_return; 1429d0e79aa3SJason Evans } else { 14301f0a49e8SJason Evans const char *oldname = prof_thread_name_get(tsd); 1431d0e79aa3SJason Evans READ(oldname, const char *); 1432d0e79aa3SJason Evans } 1433d0e79aa3SJason Evans 1434d0e79aa3SJason Evans ret = 0; 1435d0e79aa3SJason Evans label_return: 1436d0e79aa3SJason Evans return (ret); 1437d0e79aa3SJason Evans } 1438d0e79aa3SJason Evans 1439d0e79aa3SJason Evans static int 14401f0a49e8SJason Evans thread_prof_active_ctl(tsd_t *tsd, const size_t *mib, size_t miblen, void *oldp, 1441d0e79aa3SJason Evans size_t *oldlenp, void *newp, size_t newlen) 1442d0e79aa3SJason Evans { 1443d0e79aa3SJason Evans int ret; 1444d0e79aa3SJason Evans bool oldval; 1445d0e79aa3SJason Evans 1446d0e79aa3SJason Evans if (!config_prof) 1447d0e79aa3SJason Evans return (ENOENT); 1448d0e79aa3SJason Evans 14491f0a49e8SJason Evans oldval = prof_thread_active_get(tsd); 1450d0e79aa3SJason Evans if (newp != NULL) { 1451d0e79aa3SJason Evans if (newlen != sizeof(bool)) { 1452d0e79aa3SJason Evans ret = EINVAL; 1453d0e79aa3SJason Evans goto label_return; 1454d0e79aa3SJason Evans } 14551f0a49e8SJason Evans if (prof_thread_active_set(tsd, *(bool *)newp)) { 1456d0e79aa3SJason Evans ret = EAGAIN; 1457d0e79aa3SJason Evans goto label_return; 1458d0e79aa3SJason Evans } 1459d0e79aa3SJason Evans } 1460d0e79aa3SJason Evans READ(oldval, bool); 1461d0e79aa3SJason Evans 1462d0e79aa3SJason Evans ret = 0; 1463d0e79aa3SJason Evans label_return: 1464d0e79aa3SJason Evans return (ret); 1465d0e79aa3SJason Evans } 1466d0e79aa3SJason Evans 1467d0e79aa3SJason Evans /******************************************************************************/ 1468d0e79aa3SJason Evans 1469d0e79aa3SJason Evans static int 14701f0a49e8SJason Evans tcache_create_ctl(tsd_t *tsd, const size_t *mib, size_t miblen, void *oldp, 14711f0a49e8SJason Evans size_t *oldlenp, void *newp, size_t newlen) 1472d0e79aa3SJason Evans { 1473d0e79aa3SJason Evans int ret; 1474d0e79aa3SJason Evans unsigned tcache_ind; 1475d0e79aa3SJason Evans 1476d0e79aa3SJason Evans if (!config_tcache) 1477d0e79aa3SJason Evans return (ENOENT); 1478d0e79aa3SJason Evans 14791f0a49e8SJason Evans malloc_mutex_lock(tsd_tsdn(tsd), &ctl_mtx); 1480d0e79aa3SJason Evans READONLY(); 1481*bde95144SJason Evans if (tcaches_create(tsd, &tcache_ind)) { 1482d0e79aa3SJason Evans ret = EFAULT; 1483d0e79aa3SJason Evans goto label_return; 1484d0e79aa3SJason Evans } 1485d0e79aa3SJason Evans READ(tcache_ind, unsigned); 1486d0e79aa3SJason Evans 1487d0e79aa3SJason Evans ret = 0; 1488d0e79aa3SJason Evans label_return: 14891f0a49e8SJason Evans malloc_mutex_unlock(tsd_tsdn(tsd), &ctl_mtx); 1490d0e79aa3SJason Evans return (ret); 1491d0e79aa3SJason Evans } 1492d0e79aa3SJason Evans 1493d0e79aa3SJason Evans static int 14941f0a49e8SJason Evans tcache_flush_ctl(tsd_t *tsd, const size_t *mib, size_t miblen, void *oldp, 14951f0a49e8SJason Evans size_t *oldlenp, void *newp, size_t newlen) 1496d0e79aa3SJason Evans { 1497d0e79aa3SJason Evans int ret; 1498d0e79aa3SJason Evans unsigned tcache_ind; 1499d0e79aa3SJason Evans 1500d0e79aa3SJason Evans if (!config_tcache) 1501d0e79aa3SJason Evans return (ENOENT); 1502d0e79aa3SJason Evans 1503d0e79aa3SJason Evans WRITEONLY(); 1504d0e79aa3SJason Evans tcache_ind = UINT_MAX; 1505d0e79aa3SJason Evans WRITE(tcache_ind, unsigned); 1506d0e79aa3SJason Evans if (tcache_ind == UINT_MAX) { 1507d0e79aa3SJason Evans ret = EFAULT; 1508d0e79aa3SJason Evans goto label_return; 1509d0e79aa3SJason Evans } 1510d0e79aa3SJason Evans tcaches_flush(tsd, tcache_ind); 1511d0e79aa3SJason Evans 1512d0e79aa3SJason Evans ret = 0; 1513d0e79aa3SJason Evans label_return: 1514d0e79aa3SJason Evans return (ret); 1515d0e79aa3SJason Evans } 1516d0e79aa3SJason Evans 1517d0e79aa3SJason Evans static int 15181f0a49e8SJason Evans tcache_destroy_ctl(tsd_t *tsd, const size_t *mib, size_t miblen, void *oldp, 1519d0e79aa3SJason Evans size_t *oldlenp, void *newp, size_t newlen) 1520d0e79aa3SJason Evans { 1521d0e79aa3SJason Evans int ret; 1522d0e79aa3SJason Evans unsigned tcache_ind; 1523d0e79aa3SJason Evans 1524d0e79aa3SJason Evans if (!config_tcache) 1525d0e79aa3SJason Evans return (ENOENT); 1526d0e79aa3SJason Evans 1527d0e79aa3SJason Evans WRITEONLY(); 1528d0e79aa3SJason Evans tcache_ind = UINT_MAX; 1529d0e79aa3SJason Evans WRITE(tcache_ind, unsigned); 1530d0e79aa3SJason Evans if (tcache_ind == UINT_MAX) { 1531d0e79aa3SJason Evans ret = EFAULT; 1532d0e79aa3SJason Evans goto label_return; 1533d0e79aa3SJason Evans } 1534d0e79aa3SJason Evans tcaches_destroy(tsd, tcache_ind); 1535d0e79aa3SJason Evans 1536d0e79aa3SJason Evans ret = 0; 1537d0e79aa3SJason Evans label_return: 1538d0e79aa3SJason Evans return (ret); 1539d0e79aa3SJason Evans } 1540d0e79aa3SJason Evans 1541a4bd5210SJason Evans /******************************************************************************/ 1542a4bd5210SJason Evans 154382872ac0SJason Evans static void 15441f0a49e8SJason Evans arena_i_purge(tsdn_t *tsdn, unsigned arena_ind, bool all) 154582872ac0SJason Evans { 154682872ac0SJason Evans 15471f0a49e8SJason Evans malloc_mutex_lock(tsdn, &ctl_mtx); 1548df0d881dSJason Evans { 1549df0d881dSJason Evans unsigned narenas = ctl_stats.narenas; 155082872ac0SJason Evans 1551df0d881dSJason Evans if (arena_ind == narenas) { 155282872ac0SJason Evans unsigned i; 1553df0d881dSJason Evans VARIABLE_ARRAY(arena_t *, tarenas, narenas); 1554df0d881dSJason Evans 1555df0d881dSJason Evans for (i = 0; i < narenas; i++) 15561f0a49e8SJason Evans tarenas[i] = arena_get(tsdn, i, false); 1557df0d881dSJason Evans 1558df0d881dSJason Evans /* 1559df0d881dSJason Evans * No further need to hold ctl_mtx, since narenas and 1560df0d881dSJason Evans * tarenas contain everything needed below. 1561df0d881dSJason Evans */ 15621f0a49e8SJason Evans malloc_mutex_unlock(tsdn, &ctl_mtx); 1563df0d881dSJason Evans 1564df0d881dSJason Evans for (i = 0; i < narenas; i++) { 156582872ac0SJason Evans if (tarenas[i] != NULL) 15661f0a49e8SJason Evans arena_purge(tsdn, tarenas[i], all); 156782872ac0SJason Evans } 156882872ac0SJason Evans } else { 1569df0d881dSJason Evans arena_t *tarena; 1570df0d881dSJason Evans 1571df0d881dSJason Evans assert(arena_ind < narenas); 1572df0d881dSJason Evans 15731f0a49e8SJason Evans tarena = arena_get(tsdn, arena_ind, false); 1574df0d881dSJason Evans 1575df0d881dSJason Evans /* No further need to hold ctl_mtx. */ 15761f0a49e8SJason Evans malloc_mutex_unlock(tsdn, &ctl_mtx); 1577df0d881dSJason Evans 1578df0d881dSJason Evans if (tarena != NULL) 15791f0a49e8SJason Evans arena_purge(tsdn, tarena, all); 1580df0d881dSJason Evans } 158182872ac0SJason Evans } 158282872ac0SJason Evans } 158382872ac0SJason Evans 158482872ac0SJason Evans static int 15851f0a49e8SJason Evans arena_i_purge_ctl(tsd_t *tsd, const size_t *mib, size_t miblen, void *oldp, 15861f0a49e8SJason Evans size_t *oldlenp, void *newp, size_t newlen) 158782872ac0SJason Evans { 158882872ac0SJason Evans int ret; 158982872ac0SJason Evans 159082872ac0SJason Evans READONLY(); 159182872ac0SJason Evans WRITEONLY(); 15921f0a49e8SJason Evans arena_i_purge(tsd_tsdn(tsd), (unsigned)mib[1], true); 1593df0d881dSJason Evans 1594df0d881dSJason Evans ret = 0; 1595df0d881dSJason Evans label_return: 1596df0d881dSJason Evans return (ret); 1597df0d881dSJason Evans } 1598df0d881dSJason Evans 1599df0d881dSJason Evans static int 16001f0a49e8SJason Evans arena_i_decay_ctl(tsd_t *tsd, const size_t *mib, size_t miblen, void *oldp, 16011f0a49e8SJason Evans size_t *oldlenp, void *newp, size_t newlen) 1602df0d881dSJason Evans { 1603df0d881dSJason Evans int ret; 1604df0d881dSJason Evans 1605df0d881dSJason Evans READONLY(); 1606df0d881dSJason Evans WRITEONLY(); 16071f0a49e8SJason Evans arena_i_purge(tsd_tsdn(tsd), (unsigned)mib[1], false); 160882872ac0SJason Evans 160982872ac0SJason Evans ret = 0; 161082872ac0SJason Evans label_return: 161182872ac0SJason Evans return (ret); 161282872ac0SJason Evans } 161382872ac0SJason Evans 161482872ac0SJason Evans static int 16151f0a49e8SJason Evans arena_i_reset_ctl(tsd_t *tsd, const size_t *mib, size_t miblen, void *oldp, 16161f0a49e8SJason Evans size_t *oldlenp, void *newp, size_t newlen) 16171f0a49e8SJason Evans { 16181f0a49e8SJason Evans int ret; 16191f0a49e8SJason Evans unsigned arena_ind; 16201f0a49e8SJason Evans arena_t *arena; 16211f0a49e8SJason Evans 16221f0a49e8SJason Evans READONLY(); 16231f0a49e8SJason Evans WRITEONLY(); 16241f0a49e8SJason Evans 16251f0a49e8SJason Evans if ((config_valgrind && unlikely(in_valgrind)) || (config_fill && 16261f0a49e8SJason Evans unlikely(opt_quarantine))) { 16271f0a49e8SJason Evans ret = EFAULT; 16281f0a49e8SJason Evans goto label_return; 16291f0a49e8SJason Evans } 16301f0a49e8SJason Evans 16311f0a49e8SJason Evans arena_ind = (unsigned)mib[1]; 16321f0a49e8SJason Evans if (config_debug) { 16331f0a49e8SJason Evans malloc_mutex_lock(tsd_tsdn(tsd), &ctl_mtx); 16341f0a49e8SJason Evans assert(arena_ind < ctl_stats.narenas); 16351f0a49e8SJason Evans malloc_mutex_unlock(tsd_tsdn(tsd), &ctl_mtx); 16361f0a49e8SJason Evans } 16371f0a49e8SJason Evans assert(arena_ind >= opt_narenas); 16381f0a49e8SJason Evans 16391f0a49e8SJason Evans arena = arena_get(tsd_tsdn(tsd), arena_ind, false); 16401f0a49e8SJason Evans 16411f0a49e8SJason Evans arena_reset(tsd, arena); 16421f0a49e8SJason Evans 16431f0a49e8SJason Evans ret = 0; 16441f0a49e8SJason Evans label_return: 16451f0a49e8SJason Evans return (ret); 16461f0a49e8SJason Evans } 16471f0a49e8SJason Evans 16481f0a49e8SJason Evans static int 16491f0a49e8SJason Evans arena_i_dss_ctl(tsd_t *tsd, const size_t *mib, size_t miblen, void *oldp, 16501f0a49e8SJason Evans size_t *oldlenp, void *newp, size_t newlen) 165182872ac0SJason Evans { 1652d0e79aa3SJason Evans int ret; 1653d0e79aa3SJason Evans const char *dss = NULL; 1654df0d881dSJason Evans unsigned arena_ind = (unsigned)mib[1]; 165582872ac0SJason Evans dss_prec_t dss_prec_old = dss_prec_limit; 165682872ac0SJason Evans dss_prec_t dss_prec = dss_prec_limit; 165782872ac0SJason Evans 16581f0a49e8SJason Evans malloc_mutex_lock(tsd_tsdn(tsd), &ctl_mtx); 165982872ac0SJason Evans WRITE(dss, const char *); 1660d0e79aa3SJason Evans if (dss != NULL) { 1661d0e79aa3SJason Evans int i; 1662d0e79aa3SJason Evans bool match = false; 1663d0e79aa3SJason Evans 166482872ac0SJason Evans for (i = 0; i < dss_prec_limit; i++) { 166582872ac0SJason Evans if (strcmp(dss_prec_names[i], dss) == 0) { 166682872ac0SJason Evans dss_prec = i; 166782872ac0SJason Evans match = true; 166882872ac0SJason Evans break; 166982872ac0SJason Evans } 167082872ac0SJason Evans } 1671d0e79aa3SJason Evans 1672d0e79aa3SJason Evans if (!match) { 167382872ac0SJason Evans ret = EINVAL; 167482872ac0SJason Evans goto label_return; 167582872ac0SJason Evans } 1676d0e79aa3SJason Evans } 167782872ac0SJason Evans 167882872ac0SJason Evans if (arena_ind < ctl_stats.narenas) { 16791f0a49e8SJason Evans arena_t *arena = arena_get(tsd_tsdn(tsd), arena_ind, false); 1680d0e79aa3SJason Evans if (arena == NULL || (dss_prec != dss_prec_limit && 16811f0a49e8SJason Evans arena_dss_prec_set(tsd_tsdn(tsd), arena, dss_prec))) { 1682d0e79aa3SJason Evans ret = EFAULT; 1683d0e79aa3SJason Evans goto label_return; 168482872ac0SJason Evans } 16851f0a49e8SJason Evans dss_prec_old = arena_dss_prec_get(tsd_tsdn(tsd), arena); 1686d0e79aa3SJason Evans } else { 1687d0e79aa3SJason Evans if (dss_prec != dss_prec_limit && 1688*bde95144SJason Evans chunk_dss_prec_set(dss_prec)) { 1689d0e79aa3SJason Evans ret = EFAULT; 1690d0e79aa3SJason Evans goto label_return; 1691d0e79aa3SJason Evans } 1692*bde95144SJason Evans dss_prec_old = chunk_dss_prec_get(); 1693d0e79aa3SJason Evans } 1694d0e79aa3SJason Evans 169582872ac0SJason Evans dss = dss_prec_names[dss_prec_old]; 169682872ac0SJason Evans READ(dss, const char *); 1697d0e79aa3SJason Evans 1698d0e79aa3SJason Evans ret = 0; 1699d0e79aa3SJason Evans label_return: 17001f0a49e8SJason Evans malloc_mutex_unlock(tsd_tsdn(tsd), &ctl_mtx); 1701d0e79aa3SJason Evans return (ret); 1702d0e79aa3SJason Evans } 1703d0e79aa3SJason Evans 1704d0e79aa3SJason Evans static int 17051f0a49e8SJason Evans arena_i_lg_dirty_mult_ctl(tsd_t *tsd, const size_t *mib, size_t miblen, 17061f0a49e8SJason Evans void *oldp, size_t *oldlenp, void *newp, size_t newlen) 1707d0e79aa3SJason Evans { 1708d0e79aa3SJason Evans int ret; 1709df0d881dSJason Evans unsigned arena_ind = (unsigned)mib[1]; 1710d0e79aa3SJason Evans arena_t *arena; 1711d0e79aa3SJason Evans 17121f0a49e8SJason Evans arena = arena_get(tsd_tsdn(tsd), arena_ind, false); 1713d0e79aa3SJason Evans if (arena == NULL) { 171482872ac0SJason Evans ret = EFAULT; 171582872ac0SJason Evans goto label_return; 171682872ac0SJason Evans } 171782872ac0SJason Evans 1718d0e79aa3SJason Evans if (oldp != NULL && oldlenp != NULL) { 17191f0a49e8SJason Evans size_t oldval = arena_lg_dirty_mult_get(tsd_tsdn(tsd), arena); 1720d0e79aa3SJason Evans READ(oldval, ssize_t); 1721d0e79aa3SJason Evans } 1722d0e79aa3SJason Evans if (newp != NULL) { 1723d0e79aa3SJason Evans if (newlen != sizeof(ssize_t)) { 1724d0e79aa3SJason Evans ret = EINVAL; 1725d0e79aa3SJason Evans goto label_return; 1726d0e79aa3SJason Evans } 17271f0a49e8SJason Evans if (arena_lg_dirty_mult_set(tsd_tsdn(tsd), arena, 17281f0a49e8SJason Evans *(ssize_t *)newp)) { 1729d0e79aa3SJason Evans ret = EFAULT; 1730d0e79aa3SJason Evans goto label_return; 1731d0e79aa3SJason Evans } 1732d0e79aa3SJason Evans } 1733d0e79aa3SJason Evans 1734d0e79aa3SJason Evans ret = 0; 1735d0e79aa3SJason Evans label_return: 1736d0e79aa3SJason Evans return (ret); 1737d0e79aa3SJason Evans } 1738d0e79aa3SJason Evans 1739d0e79aa3SJason Evans static int 17401f0a49e8SJason Evans arena_i_decay_time_ctl(tsd_t *tsd, const size_t *mib, size_t miblen, void *oldp, 1741df0d881dSJason Evans size_t *oldlenp, void *newp, size_t newlen) 1742df0d881dSJason Evans { 1743df0d881dSJason Evans int ret; 1744df0d881dSJason Evans unsigned arena_ind = (unsigned)mib[1]; 1745df0d881dSJason Evans arena_t *arena; 1746df0d881dSJason Evans 17471f0a49e8SJason Evans arena = arena_get(tsd_tsdn(tsd), arena_ind, false); 1748df0d881dSJason Evans if (arena == NULL) { 1749df0d881dSJason Evans ret = EFAULT; 1750df0d881dSJason Evans goto label_return; 1751df0d881dSJason Evans } 1752df0d881dSJason Evans 1753df0d881dSJason Evans if (oldp != NULL && oldlenp != NULL) { 17541f0a49e8SJason Evans size_t oldval = arena_decay_time_get(tsd_tsdn(tsd), arena); 1755df0d881dSJason Evans READ(oldval, ssize_t); 1756df0d881dSJason Evans } 1757df0d881dSJason Evans if (newp != NULL) { 1758df0d881dSJason Evans if (newlen != sizeof(ssize_t)) { 1759df0d881dSJason Evans ret = EINVAL; 1760df0d881dSJason Evans goto label_return; 1761df0d881dSJason Evans } 17621f0a49e8SJason Evans if (arena_decay_time_set(tsd_tsdn(tsd), arena, 17631f0a49e8SJason Evans *(ssize_t *)newp)) { 1764df0d881dSJason Evans ret = EFAULT; 1765df0d881dSJason Evans goto label_return; 1766df0d881dSJason Evans } 1767df0d881dSJason Evans } 1768df0d881dSJason Evans 1769df0d881dSJason Evans ret = 0; 1770df0d881dSJason Evans label_return: 1771df0d881dSJason Evans return (ret); 1772df0d881dSJason Evans } 1773df0d881dSJason Evans 1774df0d881dSJason Evans static int 17751f0a49e8SJason Evans arena_i_chunk_hooks_ctl(tsd_t *tsd, const size_t *mib, size_t miblen, 17761f0a49e8SJason Evans void *oldp, size_t *oldlenp, void *newp, size_t newlen) 1777d0e79aa3SJason Evans { 1778d0e79aa3SJason Evans int ret; 1779df0d881dSJason Evans unsigned arena_ind = (unsigned)mib[1]; 1780d0e79aa3SJason Evans arena_t *arena; 1781d0e79aa3SJason Evans 17821f0a49e8SJason Evans malloc_mutex_lock(tsd_tsdn(tsd), &ctl_mtx); 1783d0e79aa3SJason Evans if (arena_ind < narenas_total_get() && (arena = 17841f0a49e8SJason Evans arena_get(tsd_tsdn(tsd), arena_ind, false)) != NULL) { 1785d0e79aa3SJason Evans if (newp != NULL) { 1786d0e79aa3SJason Evans chunk_hooks_t old_chunk_hooks, new_chunk_hooks; 1787d0e79aa3SJason Evans WRITE(new_chunk_hooks, chunk_hooks_t); 17881f0a49e8SJason Evans old_chunk_hooks = chunk_hooks_set(tsd_tsdn(tsd), arena, 1789d0e79aa3SJason Evans &new_chunk_hooks); 1790d0e79aa3SJason Evans READ(old_chunk_hooks, chunk_hooks_t); 1791d0e79aa3SJason Evans } else { 17921f0a49e8SJason Evans chunk_hooks_t old_chunk_hooks = 17931f0a49e8SJason Evans chunk_hooks_get(tsd_tsdn(tsd), arena); 1794d0e79aa3SJason Evans READ(old_chunk_hooks, chunk_hooks_t); 1795d0e79aa3SJason Evans } 1796d0e79aa3SJason Evans } else { 1797d0e79aa3SJason Evans ret = EFAULT; 1798d0e79aa3SJason Evans goto label_return; 1799d0e79aa3SJason Evans } 180082872ac0SJason Evans ret = 0; 180182872ac0SJason Evans label_return: 18021f0a49e8SJason Evans malloc_mutex_unlock(tsd_tsdn(tsd), &ctl_mtx); 180382872ac0SJason Evans return (ret); 180482872ac0SJason Evans } 180582872ac0SJason Evans 180682872ac0SJason Evans static const ctl_named_node_t * 18071f0a49e8SJason Evans arena_i_index(tsdn_t *tsdn, const size_t *mib, size_t miblen, size_t i) 180882872ac0SJason Evans { 180982872ac0SJason Evans const ctl_named_node_t *ret; 181082872ac0SJason Evans 18111f0a49e8SJason Evans malloc_mutex_lock(tsdn, &ctl_mtx); 181282872ac0SJason Evans if (i > ctl_stats.narenas) { 181382872ac0SJason Evans ret = NULL; 181482872ac0SJason Evans goto label_return; 181582872ac0SJason Evans } 181682872ac0SJason Evans 181782872ac0SJason Evans ret = super_arena_i_node; 181882872ac0SJason Evans label_return: 18191f0a49e8SJason Evans malloc_mutex_unlock(tsdn, &ctl_mtx); 182082872ac0SJason Evans return (ret); 182182872ac0SJason Evans } 182282872ac0SJason Evans 182382872ac0SJason Evans /******************************************************************************/ 182482872ac0SJason Evans 182582872ac0SJason Evans static int 18261f0a49e8SJason Evans arenas_narenas_ctl(tsd_t *tsd, const size_t *mib, size_t miblen, void *oldp, 182782872ac0SJason Evans size_t *oldlenp, void *newp, size_t newlen) 182882872ac0SJason Evans { 182982872ac0SJason Evans int ret; 183082872ac0SJason Evans unsigned narenas; 183182872ac0SJason Evans 18321f0a49e8SJason Evans malloc_mutex_lock(tsd_tsdn(tsd), &ctl_mtx); 183382872ac0SJason Evans READONLY(); 183482872ac0SJason Evans if (*oldlenp != sizeof(unsigned)) { 183582872ac0SJason Evans ret = EINVAL; 183682872ac0SJason Evans goto label_return; 183782872ac0SJason Evans } 183882872ac0SJason Evans narenas = ctl_stats.narenas; 183982872ac0SJason Evans READ(narenas, unsigned); 184082872ac0SJason Evans 184182872ac0SJason Evans ret = 0; 184282872ac0SJason Evans label_return: 18431f0a49e8SJason Evans malloc_mutex_unlock(tsd_tsdn(tsd), &ctl_mtx); 184482872ac0SJason Evans return (ret); 184582872ac0SJason Evans } 1846a4bd5210SJason Evans 1847a4bd5210SJason Evans static int 18481f0a49e8SJason Evans arenas_initialized_ctl(tsd_t *tsd, const size_t *mib, size_t miblen, void *oldp, 1849a4bd5210SJason Evans size_t *oldlenp, void *newp, size_t newlen) 1850a4bd5210SJason Evans { 1851a4bd5210SJason Evans int ret; 1852a4bd5210SJason Evans unsigned nread, i; 1853a4bd5210SJason Evans 18541f0a49e8SJason Evans malloc_mutex_lock(tsd_tsdn(tsd), &ctl_mtx); 1855a4bd5210SJason Evans READONLY(); 185682872ac0SJason Evans if (*oldlenp != ctl_stats.narenas * sizeof(bool)) { 1857a4bd5210SJason Evans ret = EINVAL; 185882872ac0SJason Evans nread = (*oldlenp < ctl_stats.narenas * sizeof(bool)) 1859df0d881dSJason Evans ? (unsigned)(*oldlenp / sizeof(bool)) : ctl_stats.narenas; 1860a4bd5210SJason Evans } else { 1861a4bd5210SJason Evans ret = 0; 186282872ac0SJason Evans nread = ctl_stats.narenas; 1863a4bd5210SJason Evans } 1864a4bd5210SJason Evans 1865a4bd5210SJason Evans for (i = 0; i < nread; i++) 1866a4bd5210SJason Evans ((bool *)oldp)[i] = ctl_stats.arenas[i].initialized; 1867a4bd5210SJason Evans 1868a4bd5210SJason Evans label_return: 18691f0a49e8SJason Evans malloc_mutex_unlock(tsd_tsdn(tsd), &ctl_mtx); 1870a4bd5210SJason Evans return (ret); 1871a4bd5210SJason Evans } 1872a4bd5210SJason Evans 1873d0e79aa3SJason Evans static int 18741f0a49e8SJason Evans arenas_lg_dirty_mult_ctl(tsd_t *tsd, const size_t *mib, size_t miblen, 18751f0a49e8SJason Evans void *oldp, size_t *oldlenp, void *newp, size_t newlen) 1876d0e79aa3SJason Evans { 1877d0e79aa3SJason Evans int ret; 1878d0e79aa3SJason Evans 1879d0e79aa3SJason Evans if (oldp != NULL && oldlenp != NULL) { 1880d0e79aa3SJason Evans size_t oldval = arena_lg_dirty_mult_default_get(); 1881d0e79aa3SJason Evans READ(oldval, ssize_t); 1882d0e79aa3SJason Evans } 1883d0e79aa3SJason Evans if (newp != NULL) { 1884d0e79aa3SJason Evans if (newlen != sizeof(ssize_t)) { 1885d0e79aa3SJason Evans ret = EINVAL; 1886d0e79aa3SJason Evans goto label_return; 1887d0e79aa3SJason Evans } 1888d0e79aa3SJason Evans if (arena_lg_dirty_mult_default_set(*(ssize_t *)newp)) { 1889d0e79aa3SJason Evans ret = EFAULT; 1890d0e79aa3SJason Evans goto label_return; 1891d0e79aa3SJason Evans } 1892d0e79aa3SJason Evans } 1893d0e79aa3SJason Evans 1894d0e79aa3SJason Evans ret = 0; 1895d0e79aa3SJason Evans label_return: 1896d0e79aa3SJason Evans return (ret); 1897d0e79aa3SJason Evans } 1898d0e79aa3SJason Evans 1899df0d881dSJason Evans static int 19001f0a49e8SJason Evans arenas_decay_time_ctl(tsd_t *tsd, const size_t *mib, size_t miblen, void *oldp, 1901df0d881dSJason Evans size_t *oldlenp, void *newp, size_t newlen) 1902df0d881dSJason Evans { 1903df0d881dSJason Evans int ret; 1904df0d881dSJason Evans 1905df0d881dSJason Evans if (oldp != NULL && oldlenp != NULL) { 1906df0d881dSJason Evans size_t oldval = arena_decay_time_default_get(); 1907df0d881dSJason Evans READ(oldval, ssize_t); 1908df0d881dSJason Evans } 1909df0d881dSJason Evans if (newp != NULL) { 1910df0d881dSJason Evans if (newlen != sizeof(ssize_t)) { 1911df0d881dSJason Evans ret = EINVAL; 1912df0d881dSJason Evans goto label_return; 1913df0d881dSJason Evans } 1914df0d881dSJason Evans if (arena_decay_time_default_set(*(ssize_t *)newp)) { 1915df0d881dSJason Evans ret = EFAULT; 1916df0d881dSJason Evans goto label_return; 1917df0d881dSJason Evans } 1918df0d881dSJason Evans } 1919df0d881dSJason Evans 1920df0d881dSJason Evans ret = 0; 1921df0d881dSJason Evans label_return: 1922df0d881dSJason Evans return (ret); 1923df0d881dSJason Evans } 1924df0d881dSJason Evans 1925a4bd5210SJason Evans CTL_RO_NL_GEN(arenas_quantum, QUANTUM, size_t) 1926a4bd5210SJason Evans CTL_RO_NL_GEN(arenas_page, PAGE, size_t) 1927a4bd5210SJason Evans CTL_RO_NL_CGEN(config_tcache, arenas_tcache_max, tcache_maxclass, size_t) 1928a4bd5210SJason Evans CTL_RO_NL_GEN(arenas_nbins, NBINS, unsigned) 1929a4bd5210SJason Evans CTL_RO_NL_CGEN(config_tcache, arenas_nhbins, nhbins, unsigned) 1930f921d10fSJason Evans CTL_RO_NL_GEN(arenas_bin_i_size, arena_bin_info[mib[2]].reg_size, size_t) 1931f921d10fSJason Evans CTL_RO_NL_GEN(arenas_bin_i_nregs, arena_bin_info[mib[2]].nregs, uint32_t) 1932f921d10fSJason Evans CTL_RO_NL_GEN(arenas_bin_i_run_size, arena_bin_info[mib[2]].run_size, size_t) 1933f921d10fSJason Evans static const ctl_named_node_t * 19341f0a49e8SJason Evans arenas_bin_i_index(tsdn_t *tsdn, const size_t *mib, size_t miblen, size_t i) 1935f921d10fSJason Evans { 1936f921d10fSJason Evans 1937f921d10fSJason Evans if (i > NBINS) 1938f921d10fSJason Evans return (NULL); 1939f921d10fSJason Evans return (super_arenas_bin_i_node); 1940f921d10fSJason Evans } 1941f921d10fSJason Evans 1942d0e79aa3SJason Evans CTL_RO_NL_GEN(arenas_nlruns, nlclasses, unsigned) 1943df0d881dSJason Evans CTL_RO_NL_GEN(arenas_lrun_i_size, index2size(NBINS+(szind_t)mib[2]), size_t) 1944f921d10fSJason Evans static const ctl_named_node_t * 19451f0a49e8SJason Evans arenas_lrun_i_index(tsdn_t *tsdn, const size_t *mib, size_t miblen, size_t i) 1946f921d10fSJason Evans { 1947f921d10fSJason Evans 1948f921d10fSJason Evans if (i > nlclasses) 1949f921d10fSJason Evans return (NULL); 1950f921d10fSJason Evans return (super_arenas_lrun_i_node); 1951f921d10fSJason Evans } 1952a4bd5210SJason Evans 1953d0e79aa3SJason Evans CTL_RO_NL_GEN(arenas_nhchunks, nhclasses, unsigned) 1954df0d881dSJason Evans CTL_RO_NL_GEN(arenas_hchunk_i_size, index2size(NBINS+nlclasses+(szind_t)mib[2]), 1955df0d881dSJason Evans size_t) 1956d0e79aa3SJason Evans static const ctl_named_node_t * 19571f0a49e8SJason Evans arenas_hchunk_i_index(tsdn_t *tsdn, const size_t *mib, size_t miblen, size_t i) 1958a4bd5210SJason Evans { 1959a4bd5210SJason Evans 1960d0e79aa3SJason Evans if (i > nhclasses) 1961d0e79aa3SJason Evans return (NULL); 1962d0e79aa3SJason Evans return (super_arenas_hchunk_i_node); 196382872ac0SJason Evans } 196482872ac0SJason Evans 196582872ac0SJason Evans static int 19661f0a49e8SJason Evans arenas_extend_ctl(tsd_t *tsd, const size_t *mib, size_t miblen, void *oldp, 19671f0a49e8SJason Evans size_t *oldlenp, void *newp, size_t newlen) 196882872ac0SJason Evans { 196982872ac0SJason Evans int ret; 197088ad2f8dSJason Evans unsigned narenas; 197182872ac0SJason Evans 19721f0a49e8SJason Evans malloc_mutex_lock(tsd_tsdn(tsd), &ctl_mtx); 197382872ac0SJason Evans READONLY(); 19741f0a49e8SJason Evans if (ctl_grow(tsd_tsdn(tsd))) { 197582872ac0SJason Evans ret = EAGAIN; 1976a4bd5210SJason Evans goto label_return; 1977a4bd5210SJason Evans } 197888ad2f8dSJason Evans narenas = ctl_stats.narenas - 1; 197988ad2f8dSJason Evans READ(narenas, unsigned); 1980a4bd5210SJason Evans 1981a4bd5210SJason Evans ret = 0; 1982a4bd5210SJason Evans label_return: 19831f0a49e8SJason Evans malloc_mutex_unlock(tsd_tsdn(tsd), &ctl_mtx); 1984a4bd5210SJason Evans return (ret); 1985a4bd5210SJason Evans } 1986a4bd5210SJason Evans 1987a4bd5210SJason Evans /******************************************************************************/ 1988a4bd5210SJason Evans 1989a4bd5210SJason Evans static int 19901f0a49e8SJason Evans prof_thread_active_init_ctl(tsd_t *tsd, const size_t *mib, size_t miblen, 19911f0a49e8SJason Evans void *oldp, size_t *oldlenp, void *newp, size_t newlen) 19921f0a49e8SJason Evans { 19931f0a49e8SJason Evans int ret; 19941f0a49e8SJason Evans bool oldval; 19951f0a49e8SJason Evans 19961f0a49e8SJason Evans if (!config_prof) 19971f0a49e8SJason Evans return (ENOENT); 19981f0a49e8SJason Evans 19991f0a49e8SJason Evans if (newp != NULL) { 20001f0a49e8SJason Evans if (newlen != sizeof(bool)) { 20011f0a49e8SJason Evans ret = EINVAL; 20021f0a49e8SJason Evans goto label_return; 20031f0a49e8SJason Evans } 20041f0a49e8SJason Evans oldval = prof_thread_active_init_set(tsd_tsdn(tsd), 20051f0a49e8SJason Evans *(bool *)newp); 20061f0a49e8SJason Evans } else 20071f0a49e8SJason Evans oldval = prof_thread_active_init_get(tsd_tsdn(tsd)); 20081f0a49e8SJason Evans READ(oldval, bool); 20091f0a49e8SJason Evans 20101f0a49e8SJason Evans ret = 0; 20111f0a49e8SJason Evans label_return: 20121f0a49e8SJason Evans return (ret); 20131f0a49e8SJason Evans } 20141f0a49e8SJason Evans 20151f0a49e8SJason Evans static int 20161f0a49e8SJason Evans prof_active_ctl(tsd_t *tsd, const size_t *mib, size_t miblen, void *oldp, 2017d0e79aa3SJason Evans size_t *oldlenp, void *newp, size_t newlen) 2018d0e79aa3SJason Evans { 2019d0e79aa3SJason Evans int ret; 2020d0e79aa3SJason Evans bool oldval; 2021d0e79aa3SJason Evans 2022d0e79aa3SJason Evans if (!config_prof) 2023d0e79aa3SJason Evans return (ENOENT); 2024d0e79aa3SJason Evans 2025d0e79aa3SJason Evans if (newp != NULL) { 2026d0e79aa3SJason Evans if (newlen != sizeof(bool)) { 2027d0e79aa3SJason Evans ret = EINVAL; 2028d0e79aa3SJason Evans goto label_return; 2029d0e79aa3SJason Evans } 20301f0a49e8SJason Evans oldval = prof_active_set(tsd_tsdn(tsd), *(bool *)newp); 2031d0e79aa3SJason Evans } else 20321f0a49e8SJason Evans oldval = prof_active_get(tsd_tsdn(tsd)); 2033d0e79aa3SJason Evans READ(oldval, bool); 2034d0e79aa3SJason Evans 2035d0e79aa3SJason Evans ret = 0; 2036d0e79aa3SJason Evans label_return: 2037d0e79aa3SJason Evans return (ret); 2038d0e79aa3SJason Evans } 2039d0e79aa3SJason Evans 2040d0e79aa3SJason Evans static int 20411f0a49e8SJason Evans prof_dump_ctl(tsd_t *tsd, const size_t *mib, size_t miblen, void *oldp, 20421f0a49e8SJason Evans size_t *oldlenp, void *newp, size_t newlen) 2043a4bd5210SJason Evans { 2044a4bd5210SJason Evans int ret; 2045a4bd5210SJason Evans const char *filename = NULL; 2046a4bd5210SJason Evans 2047d0e79aa3SJason Evans if (!config_prof) 2048a4bd5210SJason Evans return (ENOENT); 2049a4bd5210SJason Evans 2050a4bd5210SJason Evans WRITEONLY(); 2051a4bd5210SJason Evans WRITE(filename, const char *); 2052a4bd5210SJason Evans 20531f0a49e8SJason Evans if (prof_mdump(tsd, filename)) { 2054a4bd5210SJason Evans ret = EFAULT; 2055a4bd5210SJason Evans goto label_return; 2056a4bd5210SJason Evans } 2057a4bd5210SJason Evans 2058a4bd5210SJason Evans ret = 0; 2059a4bd5210SJason Evans label_return: 2060a4bd5210SJason Evans return (ret); 2061a4bd5210SJason Evans } 2062a4bd5210SJason Evans 2063d0e79aa3SJason Evans static int 20641f0a49e8SJason Evans prof_gdump_ctl(tsd_t *tsd, const size_t *mib, size_t miblen, void *oldp, 20651f0a49e8SJason Evans size_t *oldlenp, void *newp, size_t newlen) 2066d0e79aa3SJason Evans { 2067d0e79aa3SJason Evans int ret; 2068d0e79aa3SJason Evans bool oldval; 2069d0e79aa3SJason Evans 2070d0e79aa3SJason Evans if (!config_prof) 2071d0e79aa3SJason Evans return (ENOENT); 2072d0e79aa3SJason Evans 2073d0e79aa3SJason Evans if (newp != NULL) { 2074d0e79aa3SJason Evans if (newlen != sizeof(bool)) { 2075d0e79aa3SJason Evans ret = EINVAL; 2076d0e79aa3SJason Evans goto label_return; 2077d0e79aa3SJason Evans } 20781f0a49e8SJason Evans oldval = prof_gdump_set(tsd_tsdn(tsd), *(bool *)newp); 2079d0e79aa3SJason Evans } else 20801f0a49e8SJason Evans oldval = prof_gdump_get(tsd_tsdn(tsd)); 2081d0e79aa3SJason Evans READ(oldval, bool); 2082d0e79aa3SJason Evans 2083d0e79aa3SJason Evans ret = 0; 2084d0e79aa3SJason Evans label_return: 2085d0e79aa3SJason Evans return (ret); 2086d0e79aa3SJason Evans } 2087d0e79aa3SJason Evans 2088d0e79aa3SJason Evans static int 20891f0a49e8SJason Evans prof_reset_ctl(tsd_t *tsd, const size_t *mib, size_t miblen, void *oldp, 20901f0a49e8SJason Evans size_t *oldlenp, void *newp, size_t newlen) 2091d0e79aa3SJason Evans { 2092d0e79aa3SJason Evans int ret; 2093d0e79aa3SJason Evans size_t lg_sample = lg_prof_sample; 2094d0e79aa3SJason Evans 2095d0e79aa3SJason Evans if (!config_prof) 2096d0e79aa3SJason Evans return (ENOENT); 2097d0e79aa3SJason Evans 2098d0e79aa3SJason Evans WRITEONLY(); 2099d0e79aa3SJason Evans WRITE(lg_sample, size_t); 2100d0e79aa3SJason Evans if (lg_sample >= (sizeof(uint64_t) << 3)) 2101d0e79aa3SJason Evans lg_sample = (sizeof(uint64_t) << 3) - 1; 2102d0e79aa3SJason Evans 2103*bde95144SJason Evans prof_reset(tsd, lg_sample); 2104d0e79aa3SJason Evans 2105d0e79aa3SJason Evans ret = 0; 2106d0e79aa3SJason Evans label_return: 2107d0e79aa3SJason Evans return (ret); 2108d0e79aa3SJason Evans } 2109d0e79aa3SJason Evans 2110a4bd5210SJason Evans CTL_RO_NL_CGEN(config_prof, prof_interval, prof_interval, uint64_t) 2111d0e79aa3SJason Evans CTL_RO_NL_CGEN(config_prof, lg_prof_sample, lg_prof_sample, size_t) 2112a4bd5210SJason Evans 2113a4bd5210SJason Evans /******************************************************************************/ 2114a4bd5210SJason Evans 2115f921d10fSJason Evans CTL_RO_CGEN(config_stats, stats_cactive, &stats_cactive, size_t *) 2116f921d10fSJason Evans CTL_RO_CGEN(config_stats, stats_allocated, ctl_stats.allocated, size_t) 2117f921d10fSJason Evans CTL_RO_CGEN(config_stats, stats_active, ctl_stats.active, size_t) 2118d0e79aa3SJason Evans CTL_RO_CGEN(config_stats, stats_metadata, ctl_stats.metadata, size_t) 2119d0e79aa3SJason Evans CTL_RO_CGEN(config_stats, stats_resident, ctl_stats.resident, size_t) 2120f921d10fSJason Evans CTL_RO_CGEN(config_stats, stats_mapped, ctl_stats.mapped, size_t) 21211f0a49e8SJason Evans CTL_RO_CGEN(config_stats, stats_retained, ctl_stats.retained, size_t) 2122f921d10fSJason Evans 2123f921d10fSJason Evans CTL_RO_GEN(stats_arenas_i_dss, ctl_stats.arenas[mib[2]].dss, const char *) 2124d0e79aa3SJason Evans CTL_RO_GEN(stats_arenas_i_lg_dirty_mult, ctl_stats.arenas[mib[2]].lg_dirty_mult, 2125d0e79aa3SJason Evans ssize_t) 2126df0d881dSJason Evans CTL_RO_GEN(stats_arenas_i_decay_time, ctl_stats.arenas[mib[2]].decay_time, 2127df0d881dSJason Evans ssize_t) 2128f921d10fSJason Evans CTL_RO_GEN(stats_arenas_i_nthreads, ctl_stats.arenas[mib[2]].nthreads, unsigned) 2129f921d10fSJason Evans CTL_RO_GEN(stats_arenas_i_pactive, ctl_stats.arenas[mib[2]].pactive, size_t) 2130f921d10fSJason Evans CTL_RO_GEN(stats_arenas_i_pdirty, ctl_stats.arenas[mib[2]].pdirty, size_t) 2131f921d10fSJason Evans CTL_RO_CGEN(config_stats, stats_arenas_i_mapped, 2132f921d10fSJason Evans ctl_stats.arenas[mib[2]].astats.mapped, size_t) 21331f0a49e8SJason Evans CTL_RO_CGEN(config_stats, stats_arenas_i_retained, 21341f0a49e8SJason Evans ctl_stats.arenas[mib[2]].astats.retained, size_t) 2135f921d10fSJason Evans CTL_RO_CGEN(config_stats, stats_arenas_i_npurge, 2136f921d10fSJason Evans ctl_stats.arenas[mib[2]].astats.npurge, uint64_t) 2137f921d10fSJason Evans CTL_RO_CGEN(config_stats, stats_arenas_i_nmadvise, 2138f921d10fSJason Evans ctl_stats.arenas[mib[2]].astats.nmadvise, uint64_t) 2139f921d10fSJason Evans CTL_RO_CGEN(config_stats, stats_arenas_i_purged, 2140f921d10fSJason Evans ctl_stats.arenas[mib[2]].astats.purged, uint64_t) 2141d0e79aa3SJason Evans CTL_RO_CGEN(config_stats, stats_arenas_i_metadata_mapped, 2142d0e79aa3SJason Evans ctl_stats.arenas[mib[2]].astats.metadata_mapped, size_t) 2143d0e79aa3SJason Evans CTL_RO_CGEN(config_stats, stats_arenas_i_metadata_allocated, 2144d0e79aa3SJason Evans ctl_stats.arenas[mib[2]].astats.metadata_allocated, size_t) 2145f921d10fSJason Evans 2146a4bd5210SJason Evans CTL_RO_CGEN(config_stats, stats_arenas_i_small_allocated, 2147a4bd5210SJason Evans ctl_stats.arenas[mib[2]].allocated_small, size_t) 2148a4bd5210SJason Evans CTL_RO_CGEN(config_stats, stats_arenas_i_small_nmalloc, 2149a4bd5210SJason Evans ctl_stats.arenas[mib[2]].nmalloc_small, uint64_t) 2150a4bd5210SJason Evans CTL_RO_CGEN(config_stats, stats_arenas_i_small_ndalloc, 2151a4bd5210SJason Evans ctl_stats.arenas[mib[2]].ndalloc_small, uint64_t) 2152a4bd5210SJason Evans CTL_RO_CGEN(config_stats, stats_arenas_i_small_nrequests, 2153a4bd5210SJason Evans ctl_stats.arenas[mib[2]].nrequests_small, uint64_t) 2154a4bd5210SJason Evans CTL_RO_CGEN(config_stats, stats_arenas_i_large_allocated, 2155a4bd5210SJason Evans ctl_stats.arenas[mib[2]].astats.allocated_large, size_t) 2156a4bd5210SJason Evans CTL_RO_CGEN(config_stats, stats_arenas_i_large_nmalloc, 2157a4bd5210SJason Evans ctl_stats.arenas[mib[2]].astats.nmalloc_large, uint64_t) 2158a4bd5210SJason Evans CTL_RO_CGEN(config_stats, stats_arenas_i_large_ndalloc, 2159a4bd5210SJason Evans ctl_stats.arenas[mib[2]].astats.ndalloc_large, uint64_t) 2160a4bd5210SJason Evans CTL_RO_CGEN(config_stats, stats_arenas_i_large_nrequests, 2161a4bd5210SJason Evans ctl_stats.arenas[mib[2]].astats.nrequests_large, uint64_t) 2162d0e79aa3SJason Evans CTL_RO_CGEN(config_stats, stats_arenas_i_huge_allocated, 2163d0e79aa3SJason Evans ctl_stats.arenas[mib[2]].astats.allocated_huge, size_t) 2164d0e79aa3SJason Evans CTL_RO_CGEN(config_stats, stats_arenas_i_huge_nmalloc, 2165d0e79aa3SJason Evans ctl_stats.arenas[mib[2]].astats.nmalloc_huge, uint64_t) 2166d0e79aa3SJason Evans CTL_RO_CGEN(config_stats, stats_arenas_i_huge_ndalloc, 2167d0e79aa3SJason Evans ctl_stats.arenas[mib[2]].astats.ndalloc_huge, uint64_t) 2168d0e79aa3SJason Evans CTL_RO_CGEN(config_stats, stats_arenas_i_huge_nrequests, 2169d0e79aa3SJason Evans ctl_stats.arenas[mib[2]].astats.nmalloc_huge, uint64_t) /* Intentional. */ 2170a4bd5210SJason Evans 2171a4bd5210SJason Evans CTL_RO_CGEN(config_stats, stats_arenas_i_bins_j_nmalloc, 2172a4bd5210SJason Evans ctl_stats.arenas[mib[2]].bstats[mib[4]].nmalloc, uint64_t) 2173a4bd5210SJason Evans CTL_RO_CGEN(config_stats, stats_arenas_i_bins_j_ndalloc, 2174a4bd5210SJason Evans ctl_stats.arenas[mib[2]].bstats[mib[4]].ndalloc, uint64_t) 2175a4bd5210SJason Evans CTL_RO_CGEN(config_stats, stats_arenas_i_bins_j_nrequests, 2176a4bd5210SJason Evans ctl_stats.arenas[mib[2]].bstats[mib[4]].nrequests, uint64_t) 2177d0e79aa3SJason Evans CTL_RO_CGEN(config_stats, stats_arenas_i_bins_j_curregs, 2178d0e79aa3SJason Evans ctl_stats.arenas[mib[2]].bstats[mib[4]].curregs, size_t) 2179a4bd5210SJason Evans CTL_RO_CGEN(config_stats && config_tcache, stats_arenas_i_bins_j_nfills, 2180a4bd5210SJason Evans ctl_stats.arenas[mib[2]].bstats[mib[4]].nfills, uint64_t) 2181a4bd5210SJason Evans CTL_RO_CGEN(config_stats && config_tcache, stats_arenas_i_bins_j_nflushes, 2182a4bd5210SJason Evans ctl_stats.arenas[mib[2]].bstats[mib[4]].nflushes, uint64_t) 2183a4bd5210SJason Evans CTL_RO_CGEN(config_stats, stats_arenas_i_bins_j_nruns, 2184a4bd5210SJason Evans ctl_stats.arenas[mib[2]].bstats[mib[4]].nruns, uint64_t) 2185a4bd5210SJason Evans CTL_RO_CGEN(config_stats, stats_arenas_i_bins_j_nreruns, 2186a4bd5210SJason Evans ctl_stats.arenas[mib[2]].bstats[mib[4]].reruns, uint64_t) 2187a4bd5210SJason Evans CTL_RO_CGEN(config_stats, stats_arenas_i_bins_j_curruns, 2188a4bd5210SJason Evans ctl_stats.arenas[mib[2]].bstats[mib[4]].curruns, size_t) 2189a4bd5210SJason Evans 219082872ac0SJason Evans static const ctl_named_node_t * 21911f0a49e8SJason Evans stats_arenas_i_bins_j_index(tsdn_t *tsdn, const size_t *mib, size_t miblen, 21921f0a49e8SJason Evans size_t j) 2193a4bd5210SJason Evans { 2194a4bd5210SJason Evans 2195a4bd5210SJason Evans if (j > NBINS) 2196a4bd5210SJason Evans return (NULL); 2197a4bd5210SJason Evans return (super_stats_arenas_i_bins_j_node); 2198a4bd5210SJason Evans } 2199a4bd5210SJason Evans 2200a4bd5210SJason Evans CTL_RO_CGEN(config_stats, stats_arenas_i_lruns_j_nmalloc, 2201a4bd5210SJason Evans ctl_stats.arenas[mib[2]].lstats[mib[4]].nmalloc, uint64_t) 2202a4bd5210SJason Evans CTL_RO_CGEN(config_stats, stats_arenas_i_lruns_j_ndalloc, 2203a4bd5210SJason Evans ctl_stats.arenas[mib[2]].lstats[mib[4]].ndalloc, uint64_t) 2204a4bd5210SJason Evans CTL_RO_CGEN(config_stats, stats_arenas_i_lruns_j_nrequests, 2205a4bd5210SJason Evans ctl_stats.arenas[mib[2]].lstats[mib[4]].nrequests, uint64_t) 2206a4bd5210SJason Evans CTL_RO_CGEN(config_stats, stats_arenas_i_lruns_j_curruns, 2207a4bd5210SJason Evans ctl_stats.arenas[mib[2]].lstats[mib[4]].curruns, size_t) 2208a4bd5210SJason Evans 220982872ac0SJason Evans static const ctl_named_node_t * 22101f0a49e8SJason Evans stats_arenas_i_lruns_j_index(tsdn_t *tsdn, const size_t *mib, size_t miblen, 22111f0a49e8SJason Evans size_t j) 2212a4bd5210SJason Evans { 2213a4bd5210SJason Evans 2214a4bd5210SJason Evans if (j > nlclasses) 2215a4bd5210SJason Evans return (NULL); 2216a4bd5210SJason Evans return (super_stats_arenas_i_lruns_j_node); 2217a4bd5210SJason Evans } 2218a4bd5210SJason Evans 2219d0e79aa3SJason Evans CTL_RO_CGEN(config_stats, stats_arenas_i_hchunks_j_nmalloc, 2220d0e79aa3SJason Evans ctl_stats.arenas[mib[2]].hstats[mib[4]].nmalloc, uint64_t) 2221d0e79aa3SJason Evans CTL_RO_CGEN(config_stats, stats_arenas_i_hchunks_j_ndalloc, 2222d0e79aa3SJason Evans ctl_stats.arenas[mib[2]].hstats[mib[4]].ndalloc, uint64_t) 2223d0e79aa3SJason Evans CTL_RO_CGEN(config_stats, stats_arenas_i_hchunks_j_nrequests, 2224d0e79aa3SJason Evans ctl_stats.arenas[mib[2]].hstats[mib[4]].nmalloc, /* Intentional. */ 2225d0e79aa3SJason Evans uint64_t) 2226d0e79aa3SJason Evans CTL_RO_CGEN(config_stats, stats_arenas_i_hchunks_j_curhchunks, 2227d0e79aa3SJason Evans ctl_stats.arenas[mib[2]].hstats[mib[4]].curhchunks, size_t) 2228d0e79aa3SJason Evans 2229d0e79aa3SJason Evans static const ctl_named_node_t * 22301f0a49e8SJason Evans stats_arenas_i_hchunks_j_index(tsdn_t *tsdn, const size_t *mib, size_t miblen, 22311f0a49e8SJason Evans size_t j) 2232d0e79aa3SJason Evans { 2233d0e79aa3SJason Evans 2234d0e79aa3SJason Evans if (j > nhclasses) 2235d0e79aa3SJason Evans return (NULL); 2236d0e79aa3SJason Evans return (super_stats_arenas_i_hchunks_j_node); 2237d0e79aa3SJason Evans } 2238d0e79aa3SJason Evans 223982872ac0SJason Evans static const ctl_named_node_t * 22401f0a49e8SJason Evans stats_arenas_i_index(tsdn_t *tsdn, const size_t *mib, size_t miblen, size_t i) 2241a4bd5210SJason Evans { 2242e722f8f8SJason Evans const ctl_named_node_t * ret; 2243a4bd5210SJason Evans 22441f0a49e8SJason Evans malloc_mutex_lock(tsdn, &ctl_mtx); 2245d0e79aa3SJason Evans if (i > ctl_stats.narenas || !ctl_stats.arenas[i].initialized) { 2246a4bd5210SJason Evans ret = NULL; 2247a4bd5210SJason Evans goto label_return; 2248a4bd5210SJason Evans } 2249a4bd5210SJason Evans 2250a4bd5210SJason Evans ret = super_stats_arenas_i_node; 2251a4bd5210SJason Evans label_return: 22521f0a49e8SJason Evans malloc_mutex_unlock(tsdn, &ctl_mtx); 2253a4bd5210SJason Evans return (ret); 2254a4bd5210SJason Evans } 2255