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) 87*8244f2aaSJason Evans CTL_PROTO(config_thp) 88a4bd5210SJason Evans CTL_PROTO(config_tls) 89a4bd5210SJason Evans CTL_PROTO(config_utrace) 90a4bd5210SJason Evans CTL_PROTO(config_valgrind) 91a4bd5210SJason Evans CTL_PROTO(config_xmalloc) 92a4bd5210SJason Evans CTL_PROTO(opt_abort) 9382872ac0SJason Evans CTL_PROTO(opt_dss) 94a4bd5210SJason Evans CTL_PROTO(opt_lg_chunk) 95a4bd5210SJason Evans CTL_PROTO(opt_narenas) 96df0d881dSJason Evans CTL_PROTO(opt_purge) 97a4bd5210SJason Evans CTL_PROTO(opt_lg_dirty_mult) 98df0d881dSJason Evans CTL_PROTO(opt_decay_time) 99a4bd5210SJason Evans CTL_PROTO(opt_stats_print) 100a4bd5210SJason Evans CTL_PROTO(opt_junk) 101a4bd5210SJason Evans CTL_PROTO(opt_zero) 102a4bd5210SJason Evans CTL_PROTO(opt_quarantine) 103a4bd5210SJason Evans CTL_PROTO(opt_redzone) 104a4bd5210SJason Evans CTL_PROTO(opt_utrace) 105a4bd5210SJason Evans CTL_PROTO(opt_xmalloc) 106a4bd5210SJason Evans CTL_PROTO(opt_tcache) 107a4bd5210SJason Evans CTL_PROTO(opt_lg_tcache_max) 108*8244f2aaSJason Evans CTL_PROTO(opt_thp) 109a4bd5210SJason Evans CTL_PROTO(opt_prof) 110a4bd5210SJason Evans CTL_PROTO(opt_prof_prefix) 111a4bd5210SJason Evans CTL_PROTO(opt_prof_active) 112d0e79aa3SJason Evans CTL_PROTO(opt_prof_thread_active_init) 113a4bd5210SJason Evans CTL_PROTO(opt_lg_prof_sample) 114a4bd5210SJason Evans CTL_PROTO(opt_lg_prof_interval) 115a4bd5210SJason Evans CTL_PROTO(opt_prof_gdump) 1168ed34ab0SJason Evans CTL_PROTO(opt_prof_final) 117a4bd5210SJason Evans CTL_PROTO(opt_prof_leak) 118a4bd5210SJason Evans CTL_PROTO(opt_prof_accum) 119d0e79aa3SJason Evans CTL_PROTO(tcache_create) 120d0e79aa3SJason Evans CTL_PROTO(tcache_flush) 121d0e79aa3SJason Evans CTL_PROTO(tcache_destroy) 1221f0a49e8SJason Evans static void arena_i_purge(tsdn_t *tsdn, unsigned arena_ind, bool all); 12382872ac0SJason Evans CTL_PROTO(arena_i_purge) 124df0d881dSJason Evans CTL_PROTO(arena_i_decay) 1251f0a49e8SJason Evans CTL_PROTO(arena_i_reset) 12682872ac0SJason Evans CTL_PROTO(arena_i_dss) 127d0e79aa3SJason Evans CTL_PROTO(arena_i_lg_dirty_mult) 128df0d881dSJason Evans CTL_PROTO(arena_i_decay_time) 129d0e79aa3SJason Evans CTL_PROTO(arena_i_chunk_hooks) 13082872ac0SJason Evans INDEX_PROTO(arena_i) 131a4bd5210SJason Evans CTL_PROTO(arenas_bin_i_size) 132a4bd5210SJason Evans CTL_PROTO(arenas_bin_i_nregs) 133a4bd5210SJason Evans CTL_PROTO(arenas_bin_i_run_size) 134a4bd5210SJason Evans INDEX_PROTO(arenas_bin_i) 135a4bd5210SJason Evans CTL_PROTO(arenas_lrun_i_size) 136a4bd5210SJason Evans INDEX_PROTO(arenas_lrun_i) 137d0e79aa3SJason Evans CTL_PROTO(arenas_hchunk_i_size) 138d0e79aa3SJason Evans INDEX_PROTO(arenas_hchunk_i) 139a4bd5210SJason Evans CTL_PROTO(arenas_narenas) 140a4bd5210SJason Evans CTL_PROTO(arenas_initialized) 141d0e79aa3SJason Evans CTL_PROTO(arenas_lg_dirty_mult) 142df0d881dSJason Evans CTL_PROTO(arenas_decay_time) 143a4bd5210SJason Evans CTL_PROTO(arenas_quantum) 144a4bd5210SJason Evans CTL_PROTO(arenas_page) 145a4bd5210SJason Evans CTL_PROTO(arenas_tcache_max) 146a4bd5210SJason Evans CTL_PROTO(arenas_nbins) 147a4bd5210SJason Evans CTL_PROTO(arenas_nhbins) 148a4bd5210SJason Evans CTL_PROTO(arenas_nlruns) 149d0e79aa3SJason Evans CTL_PROTO(arenas_nhchunks) 15082872ac0SJason Evans CTL_PROTO(arenas_extend) 151d0e79aa3SJason Evans CTL_PROTO(prof_thread_active_init) 152a4bd5210SJason Evans CTL_PROTO(prof_active) 153a4bd5210SJason Evans CTL_PROTO(prof_dump) 154d0e79aa3SJason Evans CTL_PROTO(prof_gdump) 155d0e79aa3SJason Evans CTL_PROTO(prof_reset) 156a4bd5210SJason Evans CTL_PROTO(prof_interval) 157d0e79aa3SJason Evans CTL_PROTO(lg_prof_sample) 158a4bd5210SJason Evans CTL_PROTO(stats_arenas_i_small_allocated) 159a4bd5210SJason Evans CTL_PROTO(stats_arenas_i_small_nmalloc) 160a4bd5210SJason Evans CTL_PROTO(stats_arenas_i_small_ndalloc) 161a4bd5210SJason Evans CTL_PROTO(stats_arenas_i_small_nrequests) 162a4bd5210SJason Evans CTL_PROTO(stats_arenas_i_large_allocated) 163a4bd5210SJason Evans CTL_PROTO(stats_arenas_i_large_nmalloc) 164a4bd5210SJason Evans CTL_PROTO(stats_arenas_i_large_ndalloc) 165a4bd5210SJason Evans CTL_PROTO(stats_arenas_i_large_nrequests) 166d0e79aa3SJason Evans CTL_PROTO(stats_arenas_i_huge_allocated) 167d0e79aa3SJason Evans CTL_PROTO(stats_arenas_i_huge_nmalloc) 168d0e79aa3SJason Evans CTL_PROTO(stats_arenas_i_huge_ndalloc) 169d0e79aa3SJason Evans CTL_PROTO(stats_arenas_i_huge_nrequests) 170a4bd5210SJason Evans CTL_PROTO(stats_arenas_i_bins_j_nmalloc) 171a4bd5210SJason Evans CTL_PROTO(stats_arenas_i_bins_j_ndalloc) 172a4bd5210SJason Evans CTL_PROTO(stats_arenas_i_bins_j_nrequests) 173d0e79aa3SJason Evans CTL_PROTO(stats_arenas_i_bins_j_curregs) 174a4bd5210SJason Evans CTL_PROTO(stats_arenas_i_bins_j_nfills) 175a4bd5210SJason Evans CTL_PROTO(stats_arenas_i_bins_j_nflushes) 176a4bd5210SJason Evans CTL_PROTO(stats_arenas_i_bins_j_nruns) 177a4bd5210SJason Evans CTL_PROTO(stats_arenas_i_bins_j_nreruns) 178a4bd5210SJason Evans CTL_PROTO(stats_arenas_i_bins_j_curruns) 179a4bd5210SJason Evans INDEX_PROTO(stats_arenas_i_bins_j) 180a4bd5210SJason Evans CTL_PROTO(stats_arenas_i_lruns_j_nmalloc) 181a4bd5210SJason Evans CTL_PROTO(stats_arenas_i_lruns_j_ndalloc) 182a4bd5210SJason Evans CTL_PROTO(stats_arenas_i_lruns_j_nrequests) 183a4bd5210SJason Evans CTL_PROTO(stats_arenas_i_lruns_j_curruns) 184a4bd5210SJason Evans INDEX_PROTO(stats_arenas_i_lruns_j) 185d0e79aa3SJason Evans CTL_PROTO(stats_arenas_i_hchunks_j_nmalloc) 186d0e79aa3SJason Evans CTL_PROTO(stats_arenas_i_hchunks_j_ndalloc) 187d0e79aa3SJason Evans CTL_PROTO(stats_arenas_i_hchunks_j_nrequests) 188d0e79aa3SJason Evans CTL_PROTO(stats_arenas_i_hchunks_j_curhchunks) 189d0e79aa3SJason Evans INDEX_PROTO(stats_arenas_i_hchunks_j) 190a4bd5210SJason Evans CTL_PROTO(stats_arenas_i_nthreads) 19182872ac0SJason Evans CTL_PROTO(stats_arenas_i_dss) 192d0e79aa3SJason Evans CTL_PROTO(stats_arenas_i_lg_dirty_mult) 193df0d881dSJason Evans CTL_PROTO(stats_arenas_i_decay_time) 194a4bd5210SJason Evans CTL_PROTO(stats_arenas_i_pactive) 195a4bd5210SJason Evans CTL_PROTO(stats_arenas_i_pdirty) 196a4bd5210SJason Evans CTL_PROTO(stats_arenas_i_mapped) 1971f0a49e8SJason Evans CTL_PROTO(stats_arenas_i_retained) 198a4bd5210SJason Evans CTL_PROTO(stats_arenas_i_npurge) 199a4bd5210SJason Evans CTL_PROTO(stats_arenas_i_nmadvise) 200a4bd5210SJason Evans CTL_PROTO(stats_arenas_i_purged) 201d0e79aa3SJason Evans CTL_PROTO(stats_arenas_i_metadata_mapped) 202d0e79aa3SJason Evans CTL_PROTO(stats_arenas_i_metadata_allocated) 203a4bd5210SJason Evans INDEX_PROTO(stats_arenas_i) 204a4bd5210SJason Evans CTL_PROTO(stats_cactive) 205a4bd5210SJason Evans CTL_PROTO(stats_allocated) 206a4bd5210SJason Evans CTL_PROTO(stats_active) 207d0e79aa3SJason Evans CTL_PROTO(stats_metadata) 208d0e79aa3SJason Evans CTL_PROTO(stats_resident) 209a4bd5210SJason Evans CTL_PROTO(stats_mapped) 2101f0a49e8SJason Evans CTL_PROTO(stats_retained) 211a4bd5210SJason Evans 212a4bd5210SJason Evans /******************************************************************************/ 213a4bd5210SJason Evans /* mallctl tree. */ 214a4bd5210SJason Evans 215a4bd5210SJason Evans /* Maximum tree depth. */ 216a4bd5210SJason Evans #define CTL_MAX_DEPTH 6 217a4bd5210SJason Evans 218e722f8f8SJason Evans #define NAME(n) {true}, n 219e722f8f8SJason Evans #define CHILD(t, c) \ 220e722f8f8SJason Evans sizeof(c##_node) / sizeof(ctl_##t##_node_t), \ 221e722f8f8SJason Evans (ctl_node_t *)c##_node, \ 222e722f8f8SJason Evans NULL 223e722f8f8SJason Evans #define CTL(c) 0, NULL, c##_ctl 224a4bd5210SJason Evans 225a4bd5210SJason Evans /* 226a4bd5210SJason Evans * Only handles internal indexed nodes, since there are currently no external 227a4bd5210SJason Evans * ones. 228a4bd5210SJason Evans */ 229e722f8f8SJason Evans #define INDEX(i) {false}, i##_index 230a4bd5210SJason Evans 231d0e79aa3SJason Evans static const ctl_named_node_t thread_tcache_node[] = { 232a4bd5210SJason Evans {NAME("enabled"), CTL(thread_tcache_enabled)}, 233a4bd5210SJason Evans {NAME("flush"), CTL(thread_tcache_flush)} 234a4bd5210SJason Evans }; 235a4bd5210SJason Evans 236d0e79aa3SJason Evans static const ctl_named_node_t thread_prof_node[] = { 237d0e79aa3SJason Evans {NAME("name"), CTL(thread_prof_name)}, 238d0e79aa3SJason Evans {NAME("active"), CTL(thread_prof_active)} 239d0e79aa3SJason Evans }; 240d0e79aa3SJason Evans 241e722f8f8SJason Evans static const ctl_named_node_t thread_node[] = { 242a4bd5210SJason Evans {NAME("arena"), CTL(thread_arena)}, 243a4bd5210SJason Evans {NAME("allocated"), CTL(thread_allocated)}, 244a4bd5210SJason Evans {NAME("allocatedp"), CTL(thread_allocatedp)}, 245a4bd5210SJason Evans {NAME("deallocated"), CTL(thread_deallocated)}, 246a4bd5210SJason Evans {NAME("deallocatedp"), CTL(thread_deallocatedp)}, 247d0e79aa3SJason Evans {NAME("tcache"), CHILD(named, thread_tcache)}, 248d0e79aa3SJason Evans {NAME("prof"), CHILD(named, thread_prof)} 249a4bd5210SJason Evans }; 250a4bd5210SJason Evans 251e722f8f8SJason Evans static const ctl_named_node_t config_node[] = { 252d0e79aa3SJason Evans {NAME("cache_oblivious"), CTL(config_cache_oblivious)}, 253a4bd5210SJason Evans {NAME("debug"), CTL(config_debug)}, 254a4bd5210SJason Evans {NAME("fill"), CTL(config_fill)}, 255a4bd5210SJason Evans {NAME("lazy_lock"), CTL(config_lazy_lock)}, 256df0d881dSJason Evans {NAME("malloc_conf"), CTL(config_malloc_conf)}, 257a4bd5210SJason Evans {NAME("munmap"), CTL(config_munmap)}, 258a4bd5210SJason Evans {NAME("prof"), CTL(config_prof)}, 259a4bd5210SJason Evans {NAME("prof_libgcc"), CTL(config_prof_libgcc)}, 260a4bd5210SJason Evans {NAME("prof_libunwind"), CTL(config_prof_libunwind)}, 261a4bd5210SJason Evans {NAME("stats"), CTL(config_stats)}, 262a4bd5210SJason Evans {NAME("tcache"), CTL(config_tcache)}, 263*8244f2aaSJason Evans {NAME("thp"), CTL(config_thp)}, 264a4bd5210SJason Evans {NAME("tls"), CTL(config_tls)}, 265a4bd5210SJason Evans {NAME("utrace"), CTL(config_utrace)}, 266a4bd5210SJason Evans {NAME("valgrind"), CTL(config_valgrind)}, 267a4bd5210SJason Evans {NAME("xmalloc"), CTL(config_xmalloc)} 268a4bd5210SJason Evans }; 269a4bd5210SJason Evans 270e722f8f8SJason Evans static const ctl_named_node_t opt_node[] = { 271a4bd5210SJason Evans {NAME("abort"), CTL(opt_abort)}, 27282872ac0SJason Evans {NAME("dss"), CTL(opt_dss)}, 273a4bd5210SJason Evans {NAME("lg_chunk"), CTL(opt_lg_chunk)}, 274a4bd5210SJason Evans {NAME("narenas"), CTL(opt_narenas)}, 275df0d881dSJason Evans {NAME("purge"), CTL(opt_purge)}, 276a4bd5210SJason Evans {NAME("lg_dirty_mult"), CTL(opt_lg_dirty_mult)}, 277df0d881dSJason Evans {NAME("decay_time"), CTL(opt_decay_time)}, 278a4bd5210SJason Evans {NAME("stats_print"), CTL(opt_stats_print)}, 279a4bd5210SJason Evans {NAME("junk"), CTL(opt_junk)}, 280a4bd5210SJason Evans {NAME("zero"), CTL(opt_zero)}, 281a4bd5210SJason Evans {NAME("quarantine"), CTL(opt_quarantine)}, 282a4bd5210SJason Evans {NAME("redzone"), CTL(opt_redzone)}, 283a4bd5210SJason Evans {NAME("utrace"), CTL(opt_utrace)}, 284a4bd5210SJason Evans {NAME("xmalloc"), CTL(opt_xmalloc)}, 285a4bd5210SJason Evans {NAME("tcache"), CTL(opt_tcache)}, 286a4bd5210SJason Evans {NAME("lg_tcache_max"), CTL(opt_lg_tcache_max)}, 287*8244f2aaSJason Evans {NAME("thp"), CTL(opt_thp)}, 288a4bd5210SJason Evans {NAME("prof"), CTL(opt_prof)}, 289a4bd5210SJason Evans {NAME("prof_prefix"), CTL(opt_prof_prefix)}, 290a4bd5210SJason Evans {NAME("prof_active"), CTL(opt_prof_active)}, 291d0e79aa3SJason Evans {NAME("prof_thread_active_init"), CTL(opt_prof_thread_active_init)}, 292a4bd5210SJason Evans {NAME("lg_prof_sample"), CTL(opt_lg_prof_sample)}, 293a4bd5210SJason Evans {NAME("lg_prof_interval"), CTL(opt_lg_prof_interval)}, 294a4bd5210SJason Evans {NAME("prof_gdump"), CTL(opt_prof_gdump)}, 2958ed34ab0SJason Evans {NAME("prof_final"), CTL(opt_prof_final)}, 296a4bd5210SJason Evans {NAME("prof_leak"), CTL(opt_prof_leak)}, 297a4bd5210SJason Evans {NAME("prof_accum"), CTL(opt_prof_accum)} 298a4bd5210SJason Evans }; 299a4bd5210SJason Evans 300d0e79aa3SJason Evans static const ctl_named_node_t tcache_node[] = { 301d0e79aa3SJason Evans {NAME("create"), CTL(tcache_create)}, 302d0e79aa3SJason Evans {NAME("flush"), CTL(tcache_flush)}, 303d0e79aa3SJason Evans {NAME("destroy"), CTL(tcache_destroy)} 304d0e79aa3SJason Evans }; 305d0e79aa3SJason Evans 30682872ac0SJason Evans static const ctl_named_node_t arena_i_node[] = { 30782872ac0SJason Evans {NAME("purge"), CTL(arena_i_purge)}, 308df0d881dSJason Evans {NAME("decay"), CTL(arena_i_decay)}, 3091f0a49e8SJason Evans {NAME("reset"), CTL(arena_i_reset)}, 310d0e79aa3SJason Evans {NAME("dss"), CTL(arena_i_dss)}, 311d0e79aa3SJason Evans {NAME("lg_dirty_mult"), CTL(arena_i_lg_dirty_mult)}, 312df0d881dSJason Evans {NAME("decay_time"), CTL(arena_i_decay_time)}, 313d0e79aa3SJason Evans {NAME("chunk_hooks"), CTL(arena_i_chunk_hooks)} 31482872ac0SJason Evans }; 31582872ac0SJason Evans static const ctl_named_node_t super_arena_i_node[] = { 31682872ac0SJason Evans {NAME(""), CHILD(named, arena_i)} 31782872ac0SJason Evans }; 31882872ac0SJason Evans 31982872ac0SJason Evans static const ctl_indexed_node_t arena_node[] = { 32082872ac0SJason Evans {INDEX(arena_i)} 32182872ac0SJason Evans }; 32282872ac0SJason Evans 323e722f8f8SJason Evans static const ctl_named_node_t arenas_bin_i_node[] = { 324a4bd5210SJason Evans {NAME("size"), CTL(arenas_bin_i_size)}, 325a4bd5210SJason Evans {NAME("nregs"), CTL(arenas_bin_i_nregs)}, 326a4bd5210SJason Evans {NAME("run_size"), CTL(arenas_bin_i_run_size)} 327a4bd5210SJason Evans }; 328e722f8f8SJason Evans static const ctl_named_node_t super_arenas_bin_i_node[] = { 329e722f8f8SJason Evans {NAME(""), CHILD(named, arenas_bin_i)} 330a4bd5210SJason Evans }; 331a4bd5210SJason Evans 332e722f8f8SJason Evans static const ctl_indexed_node_t arenas_bin_node[] = { 333a4bd5210SJason Evans {INDEX(arenas_bin_i)} 334a4bd5210SJason Evans }; 335a4bd5210SJason Evans 336e722f8f8SJason Evans static const ctl_named_node_t arenas_lrun_i_node[] = { 337a4bd5210SJason Evans {NAME("size"), CTL(arenas_lrun_i_size)} 338a4bd5210SJason Evans }; 339e722f8f8SJason Evans static const ctl_named_node_t super_arenas_lrun_i_node[] = { 340e722f8f8SJason Evans {NAME(""), CHILD(named, arenas_lrun_i)} 341a4bd5210SJason Evans }; 342a4bd5210SJason Evans 343e722f8f8SJason Evans static const ctl_indexed_node_t arenas_lrun_node[] = { 344a4bd5210SJason Evans {INDEX(arenas_lrun_i)} 345a4bd5210SJason Evans }; 346a4bd5210SJason Evans 347d0e79aa3SJason Evans static const ctl_named_node_t arenas_hchunk_i_node[] = { 348d0e79aa3SJason Evans {NAME("size"), CTL(arenas_hchunk_i_size)} 349d0e79aa3SJason Evans }; 350d0e79aa3SJason Evans static const ctl_named_node_t super_arenas_hchunk_i_node[] = { 351d0e79aa3SJason Evans {NAME(""), CHILD(named, arenas_hchunk_i)} 352d0e79aa3SJason Evans }; 353d0e79aa3SJason Evans 354d0e79aa3SJason Evans static const ctl_indexed_node_t arenas_hchunk_node[] = { 355d0e79aa3SJason Evans {INDEX(arenas_hchunk_i)} 356d0e79aa3SJason Evans }; 357d0e79aa3SJason Evans 358e722f8f8SJason Evans static const ctl_named_node_t arenas_node[] = { 359a4bd5210SJason Evans {NAME("narenas"), CTL(arenas_narenas)}, 360a4bd5210SJason Evans {NAME("initialized"), CTL(arenas_initialized)}, 361d0e79aa3SJason Evans {NAME("lg_dirty_mult"), CTL(arenas_lg_dirty_mult)}, 362df0d881dSJason Evans {NAME("decay_time"), CTL(arenas_decay_time)}, 363a4bd5210SJason Evans {NAME("quantum"), CTL(arenas_quantum)}, 364a4bd5210SJason Evans {NAME("page"), CTL(arenas_page)}, 365a4bd5210SJason Evans {NAME("tcache_max"), CTL(arenas_tcache_max)}, 366a4bd5210SJason Evans {NAME("nbins"), CTL(arenas_nbins)}, 367a4bd5210SJason Evans {NAME("nhbins"), CTL(arenas_nhbins)}, 368e722f8f8SJason Evans {NAME("bin"), CHILD(indexed, arenas_bin)}, 369a4bd5210SJason Evans {NAME("nlruns"), CTL(arenas_nlruns)}, 370e722f8f8SJason Evans {NAME("lrun"), CHILD(indexed, arenas_lrun)}, 371d0e79aa3SJason Evans {NAME("nhchunks"), CTL(arenas_nhchunks)}, 372d0e79aa3SJason Evans {NAME("hchunk"), CHILD(indexed, arenas_hchunk)}, 37382872ac0SJason Evans {NAME("extend"), CTL(arenas_extend)} 374a4bd5210SJason Evans }; 375a4bd5210SJason Evans 376e722f8f8SJason Evans static const ctl_named_node_t prof_node[] = { 377d0e79aa3SJason Evans {NAME("thread_active_init"), CTL(prof_thread_active_init)}, 378a4bd5210SJason Evans {NAME("active"), CTL(prof_active)}, 379a4bd5210SJason Evans {NAME("dump"), CTL(prof_dump)}, 380d0e79aa3SJason Evans {NAME("gdump"), CTL(prof_gdump)}, 381d0e79aa3SJason Evans {NAME("reset"), CTL(prof_reset)}, 382d0e79aa3SJason Evans {NAME("interval"), CTL(prof_interval)}, 383d0e79aa3SJason Evans {NAME("lg_sample"), CTL(lg_prof_sample)} 384a4bd5210SJason Evans }; 385a4bd5210SJason Evans 386d0e79aa3SJason Evans static const ctl_named_node_t stats_arenas_i_metadata_node[] = { 387d0e79aa3SJason Evans {NAME("mapped"), CTL(stats_arenas_i_metadata_mapped)}, 388d0e79aa3SJason Evans {NAME("allocated"), CTL(stats_arenas_i_metadata_allocated)} 389a4bd5210SJason Evans }; 390a4bd5210SJason Evans 391e722f8f8SJason Evans static const ctl_named_node_t stats_arenas_i_small_node[] = { 392a4bd5210SJason Evans {NAME("allocated"), CTL(stats_arenas_i_small_allocated)}, 393a4bd5210SJason Evans {NAME("nmalloc"), CTL(stats_arenas_i_small_nmalloc)}, 394a4bd5210SJason Evans {NAME("ndalloc"), CTL(stats_arenas_i_small_ndalloc)}, 395a4bd5210SJason Evans {NAME("nrequests"), CTL(stats_arenas_i_small_nrequests)} 396a4bd5210SJason Evans }; 397a4bd5210SJason Evans 398e722f8f8SJason Evans static const ctl_named_node_t stats_arenas_i_large_node[] = { 399a4bd5210SJason Evans {NAME("allocated"), CTL(stats_arenas_i_large_allocated)}, 400a4bd5210SJason Evans {NAME("nmalloc"), CTL(stats_arenas_i_large_nmalloc)}, 401a4bd5210SJason Evans {NAME("ndalloc"), CTL(stats_arenas_i_large_ndalloc)}, 402a4bd5210SJason Evans {NAME("nrequests"), CTL(stats_arenas_i_large_nrequests)} 403a4bd5210SJason Evans }; 404a4bd5210SJason Evans 405d0e79aa3SJason Evans static const ctl_named_node_t stats_arenas_i_huge_node[] = { 406d0e79aa3SJason Evans {NAME("allocated"), CTL(stats_arenas_i_huge_allocated)}, 407d0e79aa3SJason Evans {NAME("nmalloc"), CTL(stats_arenas_i_huge_nmalloc)}, 408d0e79aa3SJason Evans {NAME("ndalloc"), CTL(stats_arenas_i_huge_ndalloc)}, 409d0e79aa3SJason Evans {NAME("nrequests"), CTL(stats_arenas_i_huge_nrequests)} 410d0e79aa3SJason Evans }; 411d0e79aa3SJason Evans 412e722f8f8SJason Evans static const ctl_named_node_t stats_arenas_i_bins_j_node[] = { 413a4bd5210SJason Evans {NAME("nmalloc"), CTL(stats_arenas_i_bins_j_nmalloc)}, 414a4bd5210SJason Evans {NAME("ndalloc"), CTL(stats_arenas_i_bins_j_ndalloc)}, 415a4bd5210SJason Evans {NAME("nrequests"), CTL(stats_arenas_i_bins_j_nrequests)}, 416d0e79aa3SJason Evans {NAME("curregs"), CTL(stats_arenas_i_bins_j_curregs)}, 417a4bd5210SJason Evans {NAME("nfills"), CTL(stats_arenas_i_bins_j_nfills)}, 418a4bd5210SJason Evans {NAME("nflushes"), CTL(stats_arenas_i_bins_j_nflushes)}, 419a4bd5210SJason Evans {NAME("nruns"), CTL(stats_arenas_i_bins_j_nruns)}, 420a4bd5210SJason Evans {NAME("nreruns"), CTL(stats_arenas_i_bins_j_nreruns)}, 421a4bd5210SJason Evans {NAME("curruns"), CTL(stats_arenas_i_bins_j_curruns)} 422a4bd5210SJason Evans }; 423e722f8f8SJason Evans static const ctl_named_node_t super_stats_arenas_i_bins_j_node[] = { 424e722f8f8SJason Evans {NAME(""), CHILD(named, stats_arenas_i_bins_j)} 425a4bd5210SJason Evans }; 426a4bd5210SJason Evans 427e722f8f8SJason Evans static const ctl_indexed_node_t stats_arenas_i_bins_node[] = { 428a4bd5210SJason Evans {INDEX(stats_arenas_i_bins_j)} 429a4bd5210SJason Evans }; 430a4bd5210SJason Evans 431e722f8f8SJason Evans static const ctl_named_node_t stats_arenas_i_lruns_j_node[] = { 432a4bd5210SJason Evans {NAME("nmalloc"), CTL(stats_arenas_i_lruns_j_nmalloc)}, 433a4bd5210SJason Evans {NAME("ndalloc"), CTL(stats_arenas_i_lruns_j_ndalloc)}, 434a4bd5210SJason Evans {NAME("nrequests"), CTL(stats_arenas_i_lruns_j_nrequests)}, 435a4bd5210SJason Evans {NAME("curruns"), CTL(stats_arenas_i_lruns_j_curruns)} 436a4bd5210SJason Evans }; 437e722f8f8SJason Evans static const ctl_named_node_t super_stats_arenas_i_lruns_j_node[] = { 438e722f8f8SJason Evans {NAME(""), CHILD(named, stats_arenas_i_lruns_j)} 439a4bd5210SJason Evans }; 440a4bd5210SJason Evans 441e722f8f8SJason Evans static const ctl_indexed_node_t stats_arenas_i_lruns_node[] = { 442a4bd5210SJason Evans {INDEX(stats_arenas_i_lruns_j)} 443a4bd5210SJason Evans }; 444a4bd5210SJason Evans 445d0e79aa3SJason Evans static const ctl_named_node_t stats_arenas_i_hchunks_j_node[] = { 446d0e79aa3SJason Evans {NAME("nmalloc"), CTL(stats_arenas_i_hchunks_j_nmalloc)}, 447d0e79aa3SJason Evans {NAME("ndalloc"), CTL(stats_arenas_i_hchunks_j_ndalloc)}, 448d0e79aa3SJason Evans {NAME("nrequests"), CTL(stats_arenas_i_hchunks_j_nrequests)}, 449d0e79aa3SJason Evans {NAME("curhchunks"), CTL(stats_arenas_i_hchunks_j_curhchunks)} 450d0e79aa3SJason Evans }; 451d0e79aa3SJason Evans static const ctl_named_node_t super_stats_arenas_i_hchunks_j_node[] = { 452d0e79aa3SJason Evans {NAME(""), CHILD(named, stats_arenas_i_hchunks_j)} 453d0e79aa3SJason Evans }; 454d0e79aa3SJason Evans 455d0e79aa3SJason Evans static const ctl_indexed_node_t stats_arenas_i_hchunks_node[] = { 456d0e79aa3SJason Evans {INDEX(stats_arenas_i_hchunks_j)} 457d0e79aa3SJason Evans }; 458d0e79aa3SJason Evans 459e722f8f8SJason Evans static const ctl_named_node_t stats_arenas_i_node[] = { 460a4bd5210SJason Evans {NAME("nthreads"), CTL(stats_arenas_i_nthreads)}, 46182872ac0SJason Evans {NAME("dss"), CTL(stats_arenas_i_dss)}, 462d0e79aa3SJason Evans {NAME("lg_dirty_mult"), CTL(stats_arenas_i_lg_dirty_mult)}, 463df0d881dSJason Evans {NAME("decay_time"), CTL(stats_arenas_i_decay_time)}, 464a4bd5210SJason Evans {NAME("pactive"), CTL(stats_arenas_i_pactive)}, 465a4bd5210SJason Evans {NAME("pdirty"), CTL(stats_arenas_i_pdirty)}, 466a4bd5210SJason Evans {NAME("mapped"), CTL(stats_arenas_i_mapped)}, 4671f0a49e8SJason Evans {NAME("retained"), CTL(stats_arenas_i_retained)}, 468a4bd5210SJason Evans {NAME("npurge"), CTL(stats_arenas_i_npurge)}, 469a4bd5210SJason Evans {NAME("nmadvise"), CTL(stats_arenas_i_nmadvise)}, 470a4bd5210SJason Evans {NAME("purged"), CTL(stats_arenas_i_purged)}, 471d0e79aa3SJason Evans {NAME("metadata"), CHILD(named, stats_arenas_i_metadata)}, 472e722f8f8SJason Evans {NAME("small"), CHILD(named, stats_arenas_i_small)}, 473e722f8f8SJason Evans {NAME("large"), CHILD(named, stats_arenas_i_large)}, 474d0e79aa3SJason Evans {NAME("huge"), CHILD(named, stats_arenas_i_huge)}, 475e722f8f8SJason Evans {NAME("bins"), CHILD(indexed, stats_arenas_i_bins)}, 476d0e79aa3SJason Evans {NAME("lruns"), CHILD(indexed, stats_arenas_i_lruns)}, 477d0e79aa3SJason Evans {NAME("hchunks"), CHILD(indexed, stats_arenas_i_hchunks)} 478a4bd5210SJason Evans }; 479e722f8f8SJason Evans static const ctl_named_node_t super_stats_arenas_i_node[] = { 480e722f8f8SJason Evans {NAME(""), CHILD(named, stats_arenas_i)} 481a4bd5210SJason Evans }; 482a4bd5210SJason Evans 483e722f8f8SJason Evans static const ctl_indexed_node_t stats_arenas_node[] = { 484a4bd5210SJason Evans {INDEX(stats_arenas_i)} 485a4bd5210SJason Evans }; 486a4bd5210SJason Evans 487e722f8f8SJason Evans static const ctl_named_node_t stats_node[] = { 488a4bd5210SJason Evans {NAME("cactive"), CTL(stats_cactive)}, 489a4bd5210SJason Evans {NAME("allocated"), CTL(stats_allocated)}, 490a4bd5210SJason Evans {NAME("active"), CTL(stats_active)}, 491d0e79aa3SJason Evans {NAME("metadata"), CTL(stats_metadata)}, 492d0e79aa3SJason Evans {NAME("resident"), CTL(stats_resident)}, 493a4bd5210SJason Evans {NAME("mapped"), CTL(stats_mapped)}, 4941f0a49e8SJason Evans {NAME("retained"), CTL(stats_retained)}, 495e722f8f8SJason Evans {NAME("arenas"), CHILD(indexed, stats_arenas)} 496a4bd5210SJason Evans }; 497a4bd5210SJason Evans 498e722f8f8SJason Evans static const ctl_named_node_t root_node[] = { 499a4bd5210SJason Evans {NAME("version"), CTL(version)}, 500a4bd5210SJason Evans {NAME("epoch"), CTL(epoch)}, 501e722f8f8SJason Evans {NAME("thread"), CHILD(named, thread)}, 502e722f8f8SJason Evans {NAME("config"), CHILD(named, config)}, 503e722f8f8SJason Evans {NAME("opt"), CHILD(named, opt)}, 504d0e79aa3SJason Evans {NAME("tcache"), CHILD(named, tcache)}, 50582872ac0SJason Evans {NAME("arena"), CHILD(indexed, arena)}, 506e722f8f8SJason Evans {NAME("arenas"), CHILD(named, arenas)}, 507e722f8f8SJason Evans {NAME("prof"), CHILD(named, prof)}, 508e722f8f8SJason Evans {NAME("stats"), CHILD(named, stats)} 509a4bd5210SJason Evans }; 510e722f8f8SJason Evans static const ctl_named_node_t super_root_node[] = { 511e722f8f8SJason Evans {NAME(""), CHILD(named, root)} 512a4bd5210SJason Evans }; 513a4bd5210SJason Evans 514a4bd5210SJason Evans #undef NAME 515a4bd5210SJason Evans #undef CHILD 516a4bd5210SJason Evans #undef CTL 517a4bd5210SJason Evans #undef INDEX 518a4bd5210SJason Evans 519a4bd5210SJason Evans /******************************************************************************/ 520a4bd5210SJason Evans 521a4bd5210SJason Evans static bool 522a4bd5210SJason Evans ctl_arena_init(ctl_arena_stats_t *astats) 523a4bd5210SJason Evans { 524a4bd5210SJason Evans 525a4bd5210SJason Evans if (astats->lstats == NULL) { 526d0e79aa3SJason Evans astats->lstats = (malloc_large_stats_t *)a0malloc(nlclasses * 527a4bd5210SJason Evans sizeof(malloc_large_stats_t)); 528a4bd5210SJason Evans if (astats->lstats == NULL) 529a4bd5210SJason Evans return (true); 530a4bd5210SJason Evans } 531a4bd5210SJason Evans 532d0e79aa3SJason Evans if (astats->hstats == NULL) { 533d0e79aa3SJason Evans astats->hstats = (malloc_huge_stats_t *)a0malloc(nhclasses * 534d0e79aa3SJason Evans sizeof(malloc_huge_stats_t)); 535d0e79aa3SJason Evans if (astats->hstats == NULL) 536d0e79aa3SJason Evans return (true); 537d0e79aa3SJason Evans } 538d0e79aa3SJason Evans 539a4bd5210SJason Evans return (false); 540a4bd5210SJason Evans } 541a4bd5210SJason Evans 542a4bd5210SJason Evans static void 543a4bd5210SJason Evans ctl_arena_clear(ctl_arena_stats_t *astats) 544a4bd5210SJason Evans { 545a4bd5210SJason Evans 546df0d881dSJason Evans astats->nthreads = 0; 54782872ac0SJason Evans astats->dss = dss_prec_names[dss_prec_limit]; 548d0e79aa3SJason Evans astats->lg_dirty_mult = -1; 549df0d881dSJason Evans astats->decay_time = -1; 550a4bd5210SJason Evans astats->pactive = 0; 551a4bd5210SJason Evans astats->pdirty = 0; 552a4bd5210SJason Evans if (config_stats) { 553a4bd5210SJason Evans memset(&astats->astats, 0, sizeof(arena_stats_t)); 554a4bd5210SJason Evans astats->allocated_small = 0; 555a4bd5210SJason Evans astats->nmalloc_small = 0; 556a4bd5210SJason Evans astats->ndalloc_small = 0; 557a4bd5210SJason Evans astats->nrequests_small = 0; 558a4bd5210SJason Evans memset(astats->bstats, 0, NBINS * sizeof(malloc_bin_stats_t)); 559a4bd5210SJason Evans memset(astats->lstats, 0, nlclasses * 560a4bd5210SJason Evans sizeof(malloc_large_stats_t)); 561d0e79aa3SJason Evans memset(astats->hstats, 0, nhclasses * 562d0e79aa3SJason Evans sizeof(malloc_huge_stats_t)); 563a4bd5210SJason Evans } 564a4bd5210SJason Evans } 565a4bd5210SJason Evans 566a4bd5210SJason Evans static void 5671f0a49e8SJason Evans ctl_arena_stats_amerge(tsdn_t *tsdn, ctl_arena_stats_t *cstats, arena_t *arena) 568a4bd5210SJason Evans { 569a4bd5210SJason Evans unsigned i; 570a4bd5210SJason Evans 571df0d881dSJason Evans if (config_stats) { 5721f0a49e8SJason Evans arena_stats_merge(tsdn, arena, &cstats->nthreads, &cstats->dss, 573df0d881dSJason Evans &cstats->lg_dirty_mult, &cstats->decay_time, 574df0d881dSJason Evans &cstats->pactive, &cstats->pdirty, &cstats->astats, 575df0d881dSJason Evans cstats->bstats, cstats->lstats, cstats->hstats); 576a4bd5210SJason Evans 577a4bd5210SJason Evans for (i = 0; i < NBINS; i++) { 578d0e79aa3SJason Evans cstats->allocated_small += cstats->bstats[i].curregs * 579d0e79aa3SJason Evans index2size(i); 580a4bd5210SJason Evans cstats->nmalloc_small += cstats->bstats[i].nmalloc; 581a4bd5210SJason Evans cstats->ndalloc_small += cstats->bstats[i].ndalloc; 582a4bd5210SJason Evans cstats->nrequests_small += cstats->bstats[i].nrequests; 583a4bd5210SJason Evans } 584df0d881dSJason Evans } else { 5851f0a49e8SJason Evans arena_basic_stats_merge(tsdn, arena, &cstats->nthreads, 5861f0a49e8SJason Evans &cstats->dss, &cstats->lg_dirty_mult, &cstats->decay_time, 587df0d881dSJason Evans &cstats->pactive, &cstats->pdirty); 588df0d881dSJason Evans } 589a4bd5210SJason Evans } 590a4bd5210SJason Evans 591a4bd5210SJason Evans static void 592a4bd5210SJason Evans ctl_arena_stats_smerge(ctl_arena_stats_t *sstats, ctl_arena_stats_t *astats) 593a4bd5210SJason Evans { 594a4bd5210SJason Evans unsigned i; 595a4bd5210SJason Evans 596df0d881dSJason Evans sstats->nthreads += astats->nthreads; 597a4bd5210SJason Evans sstats->pactive += astats->pactive; 598a4bd5210SJason Evans sstats->pdirty += astats->pdirty; 599a4bd5210SJason Evans 600df0d881dSJason Evans if (config_stats) { 601a4bd5210SJason Evans sstats->astats.mapped += astats->astats.mapped; 6021f0a49e8SJason Evans sstats->astats.retained += astats->astats.retained; 603a4bd5210SJason Evans sstats->astats.npurge += astats->astats.npurge; 604a4bd5210SJason Evans sstats->astats.nmadvise += astats->astats.nmadvise; 605a4bd5210SJason Evans sstats->astats.purged += astats->astats.purged; 606a4bd5210SJason Evans 607df0d881dSJason Evans sstats->astats.metadata_mapped += 608df0d881dSJason Evans astats->astats.metadata_mapped; 609df0d881dSJason Evans sstats->astats.metadata_allocated += 610df0d881dSJason Evans astats->astats.metadata_allocated; 611d0e79aa3SJason Evans 612a4bd5210SJason Evans sstats->allocated_small += astats->allocated_small; 613a4bd5210SJason Evans sstats->nmalloc_small += astats->nmalloc_small; 614a4bd5210SJason Evans sstats->ndalloc_small += astats->ndalloc_small; 615a4bd5210SJason Evans sstats->nrequests_small += astats->nrequests_small; 616a4bd5210SJason Evans 617df0d881dSJason Evans sstats->astats.allocated_large += 618df0d881dSJason Evans astats->astats.allocated_large; 619a4bd5210SJason Evans sstats->astats.nmalloc_large += astats->astats.nmalloc_large; 620a4bd5210SJason Evans sstats->astats.ndalloc_large += astats->astats.ndalloc_large; 621df0d881dSJason Evans sstats->astats.nrequests_large += 622df0d881dSJason Evans astats->astats.nrequests_large; 623a4bd5210SJason Evans 624d0e79aa3SJason Evans sstats->astats.allocated_huge += astats->astats.allocated_huge; 625d0e79aa3SJason Evans sstats->astats.nmalloc_huge += astats->astats.nmalloc_huge; 626d0e79aa3SJason Evans sstats->astats.ndalloc_huge += astats->astats.ndalloc_huge; 627a4bd5210SJason Evans 628a4bd5210SJason Evans for (i = 0; i < NBINS; i++) { 629a4bd5210SJason Evans sstats->bstats[i].nmalloc += astats->bstats[i].nmalloc; 630a4bd5210SJason Evans sstats->bstats[i].ndalloc += astats->bstats[i].ndalloc; 631df0d881dSJason Evans sstats->bstats[i].nrequests += 632df0d881dSJason Evans astats->bstats[i].nrequests; 633d0e79aa3SJason Evans sstats->bstats[i].curregs += astats->bstats[i].curregs; 634a4bd5210SJason Evans if (config_tcache) { 635df0d881dSJason Evans sstats->bstats[i].nfills += 636df0d881dSJason Evans astats->bstats[i].nfills; 637a4bd5210SJason Evans sstats->bstats[i].nflushes += 638a4bd5210SJason Evans astats->bstats[i].nflushes; 639a4bd5210SJason Evans } 640a4bd5210SJason Evans sstats->bstats[i].nruns += astats->bstats[i].nruns; 641a4bd5210SJason Evans sstats->bstats[i].reruns += astats->bstats[i].reruns; 642a4bd5210SJason Evans sstats->bstats[i].curruns += astats->bstats[i].curruns; 643a4bd5210SJason Evans } 644d0e79aa3SJason Evans 645d0e79aa3SJason Evans for (i = 0; i < nlclasses; i++) { 646d0e79aa3SJason Evans sstats->lstats[i].nmalloc += astats->lstats[i].nmalloc; 647d0e79aa3SJason Evans sstats->lstats[i].ndalloc += astats->lstats[i].ndalloc; 648df0d881dSJason Evans sstats->lstats[i].nrequests += 649df0d881dSJason Evans astats->lstats[i].nrequests; 650d0e79aa3SJason Evans sstats->lstats[i].curruns += astats->lstats[i].curruns; 651d0e79aa3SJason Evans } 652d0e79aa3SJason Evans 653d0e79aa3SJason Evans for (i = 0; i < nhclasses; i++) { 654d0e79aa3SJason Evans sstats->hstats[i].nmalloc += astats->hstats[i].nmalloc; 655d0e79aa3SJason Evans sstats->hstats[i].ndalloc += astats->hstats[i].ndalloc; 656df0d881dSJason Evans sstats->hstats[i].curhchunks += 657df0d881dSJason Evans astats->hstats[i].curhchunks; 658df0d881dSJason Evans } 659d0e79aa3SJason Evans } 660a4bd5210SJason Evans } 661a4bd5210SJason Evans 662a4bd5210SJason Evans static void 6631f0a49e8SJason Evans ctl_arena_refresh(tsdn_t *tsdn, arena_t *arena, unsigned i) 664a4bd5210SJason Evans { 665a4bd5210SJason Evans ctl_arena_stats_t *astats = &ctl_stats.arenas[i]; 66682872ac0SJason Evans ctl_arena_stats_t *sstats = &ctl_stats.arenas[ctl_stats.narenas]; 667a4bd5210SJason Evans 668a4bd5210SJason Evans ctl_arena_clear(astats); 6691f0a49e8SJason Evans ctl_arena_stats_amerge(tsdn, astats, arena); 670a4bd5210SJason Evans /* Merge into sum stats as well. */ 671a4bd5210SJason Evans ctl_arena_stats_smerge(sstats, astats); 672a4bd5210SJason Evans } 673a4bd5210SJason Evans 67482872ac0SJason Evans static bool 6751f0a49e8SJason Evans ctl_grow(tsdn_t *tsdn) 67682872ac0SJason Evans { 67782872ac0SJason Evans ctl_arena_stats_t *astats; 67882872ac0SJason Evans 679d0e79aa3SJason Evans /* Initialize new arena. */ 6801f0a49e8SJason Evans if (arena_init(tsdn, ctl_stats.narenas) == NULL) 681d0e79aa3SJason Evans return (true); 682d0e79aa3SJason Evans 683d0e79aa3SJason Evans /* Allocate extended arena stats. */ 684d0e79aa3SJason Evans astats = (ctl_arena_stats_t *)a0malloc((ctl_stats.narenas + 2) * 6852b06b201SJason Evans sizeof(ctl_arena_stats_t)); 68682872ac0SJason Evans if (astats == NULL) 68782872ac0SJason Evans return (true); 68882872ac0SJason Evans 6892b06b201SJason Evans /* Initialize the new astats element. */ 6902b06b201SJason Evans memcpy(astats, ctl_stats.arenas, (ctl_stats.narenas + 1) * 6912b06b201SJason Evans sizeof(ctl_arena_stats_t)); 6922b06b201SJason Evans memset(&astats[ctl_stats.narenas + 1], 0, sizeof(ctl_arena_stats_t)); 6932b06b201SJason Evans if (ctl_arena_init(&astats[ctl_stats.narenas + 1])) { 694d0e79aa3SJason Evans a0dalloc(astats); 69582872ac0SJason Evans return (true); 69682872ac0SJason Evans } 69782872ac0SJason Evans /* Swap merged stats to their new location. */ 69882872ac0SJason Evans { 69982872ac0SJason Evans ctl_arena_stats_t tstats; 70082872ac0SJason Evans memcpy(&tstats, &astats[ctl_stats.narenas], 70182872ac0SJason Evans sizeof(ctl_arena_stats_t)); 70282872ac0SJason Evans memcpy(&astats[ctl_stats.narenas], 70382872ac0SJason Evans &astats[ctl_stats.narenas + 1], sizeof(ctl_arena_stats_t)); 70482872ac0SJason Evans memcpy(&astats[ctl_stats.narenas + 1], &tstats, 70582872ac0SJason Evans sizeof(ctl_arena_stats_t)); 70682872ac0SJason Evans } 707d0e79aa3SJason Evans a0dalloc(ctl_stats.arenas); 7082b06b201SJason Evans ctl_stats.arenas = astats; 7092b06b201SJason Evans ctl_stats.narenas++; 71082872ac0SJason Evans 71182872ac0SJason Evans return (false); 71282872ac0SJason Evans } 71382872ac0SJason Evans 714a4bd5210SJason Evans static void 7151f0a49e8SJason Evans ctl_refresh(tsdn_t *tsdn) 716a4bd5210SJason Evans { 717a4bd5210SJason Evans unsigned i; 71882872ac0SJason Evans VARIABLE_ARRAY(arena_t *, tarenas, ctl_stats.narenas); 719a4bd5210SJason Evans 720a4bd5210SJason Evans /* 721a4bd5210SJason Evans * Clear sum stats, since they will be merged into by 722a4bd5210SJason Evans * ctl_arena_refresh(). 723a4bd5210SJason Evans */ 72482872ac0SJason Evans ctl_arena_clear(&ctl_stats.arenas[ctl_stats.narenas]); 725a4bd5210SJason Evans 726df0d881dSJason Evans for (i = 0; i < ctl_stats.narenas; i++) 7271f0a49e8SJason Evans tarenas[i] = arena_get(tsdn, i, false); 728d0e79aa3SJason Evans 72982872ac0SJason Evans for (i = 0; i < ctl_stats.narenas; i++) { 730a4bd5210SJason Evans bool initialized = (tarenas[i] != NULL); 731a4bd5210SJason Evans 732a4bd5210SJason Evans ctl_stats.arenas[i].initialized = initialized; 733a4bd5210SJason Evans if (initialized) 7341f0a49e8SJason Evans ctl_arena_refresh(tsdn, tarenas[i], i); 735a4bd5210SJason Evans } 736a4bd5210SJason Evans 737a4bd5210SJason Evans if (config_stats) { 738d0e79aa3SJason Evans size_t base_allocated, base_resident, base_mapped; 7391f0a49e8SJason Evans base_stats_get(tsdn, &base_allocated, &base_resident, 7401f0a49e8SJason Evans &base_mapped); 74182872ac0SJason Evans ctl_stats.allocated = 742d0e79aa3SJason Evans ctl_stats.arenas[ctl_stats.narenas].allocated_small + 743d0e79aa3SJason Evans ctl_stats.arenas[ctl_stats.narenas].astats.allocated_large + 744d0e79aa3SJason Evans ctl_stats.arenas[ctl_stats.narenas].astats.allocated_huge; 74582872ac0SJason Evans ctl_stats.active = 746d0e79aa3SJason Evans (ctl_stats.arenas[ctl_stats.narenas].pactive << LG_PAGE); 747d0e79aa3SJason Evans ctl_stats.metadata = base_allocated + 748d0e79aa3SJason Evans ctl_stats.arenas[ctl_stats.narenas].astats.metadata_mapped + 749d0e79aa3SJason Evans ctl_stats.arenas[ctl_stats.narenas].astats 750d0e79aa3SJason Evans .metadata_allocated; 751d0e79aa3SJason Evans ctl_stats.resident = base_resident + 752d0e79aa3SJason Evans ctl_stats.arenas[ctl_stats.narenas].astats.metadata_mapped + 753d0e79aa3SJason Evans ((ctl_stats.arenas[ctl_stats.narenas].pactive + 754d0e79aa3SJason Evans ctl_stats.arenas[ctl_stats.narenas].pdirty) << LG_PAGE); 755d0e79aa3SJason Evans ctl_stats.mapped = base_mapped + 756d0e79aa3SJason Evans ctl_stats.arenas[ctl_stats.narenas].astats.mapped; 7571f0a49e8SJason Evans ctl_stats.retained = 7581f0a49e8SJason Evans ctl_stats.arenas[ctl_stats.narenas].astats.retained; 759a4bd5210SJason Evans } 760a4bd5210SJason Evans 761a4bd5210SJason Evans ctl_epoch++; 762a4bd5210SJason Evans } 763a4bd5210SJason Evans 764a4bd5210SJason Evans static bool 7651f0a49e8SJason Evans ctl_init(tsdn_t *tsdn) 766a4bd5210SJason Evans { 767a4bd5210SJason Evans bool ret; 768a4bd5210SJason Evans 7691f0a49e8SJason Evans malloc_mutex_lock(tsdn, &ctl_mtx); 770d0e79aa3SJason Evans if (!ctl_initialized) { 771a4bd5210SJason Evans /* 772a4bd5210SJason Evans * Allocate space for one extra arena stats element, which 773a4bd5210SJason Evans * contains summed stats across all arenas. 774a4bd5210SJason Evans */ 775d0e79aa3SJason Evans ctl_stats.narenas = narenas_total_get(); 776d0e79aa3SJason Evans ctl_stats.arenas = (ctl_arena_stats_t *)a0malloc( 77782872ac0SJason Evans (ctl_stats.narenas + 1) * sizeof(ctl_arena_stats_t)); 778a4bd5210SJason Evans if (ctl_stats.arenas == NULL) { 779a4bd5210SJason Evans ret = true; 780a4bd5210SJason Evans goto label_return; 781a4bd5210SJason Evans } 78282872ac0SJason Evans memset(ctl_stats.arenas, 0, (ctl_stats.narenas + 1) * 783a4bd5210SJason Evans sizeof(ctl_arena_stats_t)); 784a4bd5210SJason Evans 785a4bd5210SJason Evans /* 786a4bd5210SJason Evans * Initialize all stats structures, regardless of whether they 787a4bd5210SJason Evans * ever get used. Lazy initialization would allow errors to 788a4bd5210SJason Evans * cause inconsistent state to be viewable by the application. 789a4bd5210SJason Evans */ 790a4bd5210SJason Evans if (config_stats) { 791a4bd5210SJason Evans unsigned i; 79282872ac0SJason Evans for (i = 0; i <= ctl_stats.narenas; i++) { 793a4bd5210SJason Evans if (ctl_arena_init(&ctl_stats.arenas[i])) { 794d0e79aa3SJason Evans unsigned j; 795d0e79aa3SJason Evans for (j = 0; j < i; j++) { 796d0e79aa3SJason Evans a0dalloc( 797d0e79aa3SJason Evans ctl_stats.arenas[j].lstats); 798d0e79aa3SJason Evans a0dalloc( 799d0e79aa3SJason Evans ctl_stats.arenas[j].hstats); 800d0e79aa3SJason Evans } 801d0e79aa3SJason Evans a0dalloc(ctl_stats.arenas); 802d0e79aa3SJason Evans ctl_stats.arenas = NULL; 803a4bd5210SJason Evans ret = true; 804a4bd5210SJason Evans goto label_return; 805a4bd5210SJason Evans } 806a4bd5210SJason Evans } 807a4bd5210SJason Evans } 80882872ac0SJason Evans ctl_stats.arenas[ctl_stats.narenas].initialized = true; 809a4bd5210SJason Evans 810a4bd5210SJason Evans ctl_epoch = 0; 8111f0a49e8SJason Evans ctl_refresh(tsdn); 812a4bd5210SJason Evans ctl_initialized = true; 813a4bd5210SJason Evans } 814a4bd5210SJason Evans 815a4bd5210SJason Evans ret = false; 816a4bd5210SJason Evans label_return: 8171f0a49e8SJason Evans malloc_mutex_unlock(tsdn, &ctl_mtx); 818a4bd5210SJason Evans return (ret); 819a4bd5210SJason Evans } 820a4bd5210SJason Evans 821a4bd5210SJason Evans static int 8221f0a49e8SJason Evans ctl_lookup(tsdn_t *tsdn, const char *name, ctl_node_t const **nodesp, 8231f0a49e8SJason Evans size_t *mibp, size_t *depthp) 824a4bd5210SJason Evans { 825a4bd5210SJason Evans int ret; 826a4bd5210SJason Evans const char *elm, *tdot, *dot; 827a4bd5210SJason Evans size_t elen, i, j; 828e722f8f8SJason Evans const ctl_named_node_t *node; 829a4bd5210SJason Evans 830a4bd5210SJason Evans elm = name; 831a4bd5210SJason Evans /* Equivalent to strchrnul(). */ 832a4bd5210SJason Evans dot = ((tdot = strchr(elm, '.')) != NULL) ? tdot : strchr(elm, '\0'); 833a4bd5210SJason Evans elen = (size_t)((uintptr_t)dot - (uintptr_t)elm); 834a4bd5210SJason Evans if (elen == 0) { 835a4bd5210SJason Evans ret = ENOENT; 836a4bd5210SJason Evans goto label_return; 837a4bd5210SJason Evans } 838a4bd5210SJason Evans node = super_root_node; 839a4bd5210SJason Evans for (i = 0; i < *depthp; i++) { 840e722f8f8SJason Evans assert(node); 841e722f8f8SJason Evans assert(node->nchildren > 0); 842e722f8f8SJason Evans if (ctl_named_node(node->children) != NULL) { 843e722f8f8SJason Evans const ctl_named_node_t *pnode = node; 844a4bd5210SJason Evans 845a4bd5210SJason Evans /* Children are named. */ 846e722f8f8SJason Evans for (j = 0; j < node->nchildren; j++) { 847e722f8f8SJason Evans const ctl_named_node_t *child = 848e722f8f8SJason Evans ctl_named_children(node, j); 849e722f8f8SJason Evans if (strlen(child->name) == elen && 850e722f8f8SJason Evans strncmp(elm, child->name, elen) == 0) { 851a4bd5210SJason Evans node = child; 852a4bd5210SJason Evans if (nodesp != NULL) 853e722f8f8SJason Evans nodesp[i] = 854e722f8f8SJason Evans (const ctl_node_t *)node; 855a4bd5210SJason Evans mibp[i] = j; 856a4bd5210SJason Evans break; 857a4bd5210SJason Evans } 858a4bd5210SJason Evans } 859a4bd5210SJason Evans if (node == pnode) { 860a4bd5210SJason Evans ret = ENOENT; 861a4bd5210SJason Evans goto label_return; 862a4bd5210SJason Evans } 863a4bd5210SJason Evans } else { 864a4bd5210SJason Evans uintmax_t index; 865e722f8f8SJason Evans const ctl_indexed_node_t *inode; 866a4bd5210SJason Evans 867a4bd5210SJason Evans /* Children are indexed. */ 868a4bd5210SJason Evans index = malloc_strtoumax(elm, NULL, 10); 869a4bd5210SJason Evans if (index == UINTMAX_MAX || index > SIZE_T_MAX) { 870a4bd5210SJason Evans ret = ENOENT; 871a4bd5210SJason Evans goto label_return; 872a4bd5210SJason Evans } 873a4bd5210SJason Evans 874e722f8f8SJason Evans inode = ctl_indexed_node(node->children); 8751f0a49e8SJason Evans node = inode->index(tsdn, mibp, *depthp, (size_t)index); 876a4bd5210SJason Evans if (node == NULL) { 877a4bd5210SJason Evans ret = ENOENT; 878a4bd5210SJason Evans goto label_return; 879a4bd5210SJason Evans } 880a4bd5210SJason Evans 881a4bd5210SJason Evans if (nodesp != NULL) 882e722f8f8SJason Evans nodesp[i] = (const ctl_node_t *)node; 883a4bd5210SJason Evans mibp[i] = (size_t)index; 884a4bd5210SJason Evans } 885a4bd5210SJason Evans 886a4bd5210SJason Evans if (node->ctl != NULL) { 887a4bd5210SJason Evans /* Terminal node. */ 888a4bd5210SJason Evans if (*dot != '\0') { 889a4bd5210SJason Evans /* 890a4bd5210SJason Evans * The name contains more elements than are 891a4bd5210SJason Evans * in this path through the tree. 892a4bd5210SJason Evans */ 893a4bd5210SJason Evans ret = ENOENT; 894a4bd5210SJason Evans goto label_return; 895a4bd5210SJason Evans } 896a4bd5210SJason Evans /* Complete lookup successful. */ 897a4bd5210SJason Evans *depthp = i + 1; 898a4bd5210SJason Evans break; 899a4bd5210SJason Evans } 900a4bd5210SJason Evans 901a4bd5210SJason Evans /* Update elm. */ 902a4bd5210SJason Evans if (*dot == '\0') { 903a4bd5210SJason Evans /* No more elements. */ 904a4bd5210SJason Evans ret = ENOENT; 905a4bd5210SJason Evans goto label_return; 906a4bd5210SJason Evans } 907a4bd5210SJason Evans elm = &dot[1]; 908a4bd5210SJason Evans dot = ((tdot = strchr(elm, '.')) != NULL) ? tdot : 909a4bd5210SJason Evans strchr(elm, '\0'); 910a4bd5210SJason Evans elen = (size_t)((uintptr_t)dot - (uintptr_t)elm); 911a4bd5210SJason Evans } 912a4bd5210SJason Evans 913a4bd5210SJason Evans ret = 0; 914a4bd5210SJason Evans label_return: 915a4bd5210SJason Evans return (ret); 916a4bd5210SJason Evans } 917a4bd5210SJason Evans 918a4bd5210SJason Evans int 9191f0a49e8SJason Evans ctl_byname(tsd_t *tsd, const char *name, void *oldp, size_t *oldlenp, 9201f0a49e8SJason Evans void *newp, size_t newlen) 921a4bd5210SJason Evans { 922a4bd5210SJason Evans int ret; 923a4bd5210SJason Evans size_t depth; 924a4bd5210SJason Evans ctl_node_t const *nodes[CTL_MAX_DEPTH]; 925a4bd5210SJason Evans size_t mib[CTL_MAX_DEPTH]; 926e722f8f8SJason Evans const ctl_named_node_t *node; 927a4bd5210SJason Evans 9281f0a49e8SJason Evans if (!ctl_initialized && ctl_init(tsd_tsdn(tsd))) { 929a4bd5210SJason Evans ret = EAGAIN; 930a4bd5210SJason Evans goto label_return; 931a4bd5210SJason Evans } 932a4bd5210SJason Evans 933a4bd5210SJason Evans depth = CTL_MAX_DEPTH; 9341f0a49e8SJason Evans ret = ctl_lookup(tsd_tsdn(tsd), name, nodes, mib, &depth); 935a4bd5210SJason Evans if (ret != 0) 936a4bd5210SJason Evans goto label_return; 937a4bd5210SJason Evans 938e722f8f8SJason Evans node = ctl_named_node(nodes[depth-1]); 939e722f8f8SJason Evans if (node != NULL && node->ctl) 9401f0a49e8SJason Evans ret = node->ctl(tsd, mib, depth, oldp, oldlenp, newp, newlen); 941e722f8f8SJason Evans else { 942a4bd5210SJason Evans /* The name refers to a partial path through the ctl tree. */ 943a4bd5210SJason Evans ret = ENOENT; 944a4bd5210SJason Evans } 945a4bd5210SJason Evans 946a4bd5210SJason Evans label_return: 947a4bd5210SJason Evans return(ret); 948a4bd5210SJason Evans } 949a4bd5210SJason Evans 950a4bd5210SJason Evans int 9511f0a49e8SJason Evans ctl_nametomib(tsdn_t *tsdn, const char *name, size_t *mibp, size_t *miblenp) 952a4bd5210SJason Evans { 953a4bd5210SJason Evans int ret; 954a4bd5210SJason Evans 9551f0a49e8SJason Evans if (!ctl_initialized && ctl_init(tsdn)) { 956a4bd5210SJason Evans ret = EAGAIN; 957a4bd5210SJason Evans goto label_return; 958a4bd5210SJason Evans } 959a4bd5210SJason Evans 9601f0a49e8SJason Evans ret = ctl_lookup(tsdn, name, NULL, mibp, miblenp); 961a4bd5210SJason Evans label_return: 962a4bd5210SJason Evans return(ret); 963a4bd5210SJason Evans } 964a4bd5210SJason Evans 965a4bd5210SJason Evans int 9661f0a49e8SJason Evans ctl_bymib(tsd_t *tsd, const size_t *mib, size_t miblen, void *oldp, 9671f0a49e8SJason Evans size_t *oldlenp, void *newp, size_t newlen) 968a4bd5210SJason Evans { 969a4bd5210SJason Evans int ret; 970e722f8f8SJason Evans const ctl_named_node_t *node; 971a4bd5210SJason Evans size_t i; 972a4bd5210SJason Evans 9731f0a49e8SJason Evans if (!ctl_initialized && ctl_init(tsd_tsdn(tsd))) { 974a4bd5210SJason Evans ret = EAGAIN; 975a4bd5210SJason Evans goto label_return; 976a4bd5210SJason Evans } 977a4bd5210SJason Evans 978a4bd5210SJason Evans /* Iterate down the tree. */ 979a4bd5210SJason Evans node = super_root_node; 980a4bd5210SJason Evans for (i = 0; i < miblen; i++) { 981e722f8f8SJason Evans assert(node); 982e722f8f8SJason Evans assert(node->nchildren > 0); 983e722f8f8SJason Evans if (ctl_named_node(node->children) != NULL) { 984a4bd5210SJason Evans /* Children are named. */ 985df0d881dSJason Evans if (node->nchildren <= (unsigned)mib[i]) { 986a4bd5210SJason Evans ret = ENOENT; 987a4bd5210SJason Evans goto label_return; 988a4bd5210SJason Evans } 989e722f8f8SJason Evans node = ctl_named_children(node, mib[i]); 990a4bd5210SJason Evans } else { 991e722f8f8SJason Evans const ctl_indexed_node_t *inode; 992a4bd5210SJason Evans 993a4bd5210SJason Evans /* Indexed element. */ 994e722f8f8SJason Evans inode = ctl_indexed_node(node->children); 9951f0a49e8SJason Evans node = inode->index(tsd_tsdn(tsd), mib, miblen, mib[i]); 996a4bd5210SJason Evans if (node == NULL) { 997a4bd5210SJason Evans ret = ENOENT; 998a4bd5210SJason Evans goto label_return; 999a4bd5210SJason Evans } 1000a4bd5210SJason Evans } 1001a4bd5210SJason Evans } 1002a4bd5210SJason Evans 1003a4bd5210SJason Evans /* Call the ctl function. */ 1004e722f8f8SJason Evans if (node && node->ctl) 10051f0a49e8SJason Evans ret = node->ctl(tsd, mib, miblen, oldp, oldlenp, newp, newlen); 1006e722f8f8SJason Evans else { 1007a4bd5210SJason Evans /* Partial MIB. */ 1008a4bd5210SJason Evans ret = ENOENT; 1009a4bd5210SJason Evans } 1010a4bd5210SJason Evans 1011a4bd5210SJason Evans label_return: 1012a4bd5210SJason Evans return(ret); 1013a4bd5210SJason Evans } 1014a4bd5210SJason Evans 1015a4bd5210SJason Evans bool 1016a4bd5210SJason Evans ctl_boot(void) 1017a4bd5210SJason Evans { 1018a4bd5210SJason Evans 10191f0a49e8SJason Evans if (malloc_mutex_init(&ctl_mtx, "ctl", WITNESS_RANK_CTL)) 1020a4bd5210SJason Evans return (true); 1021a4bd5210SJason Evans 1022a4bd5210SJason Evans ctl_initialized = false; 1023a4bd5210SJason Evans 1024a4bd5210SJason Evans return (false); 1025a4bd5210SJason Evans } 1026a4bd5210SJason Evans 102782872ac0SJason Evans void 10281f0a49e8SJason Evans ctl_prefork(tsdn_t *tsdn) 102982872ac0SJason Evans { 103082872ac0SJason Evans 10311f0a49e8SJason Evans malloc_mutex_prefork(tsdn, &ctl_mtx); 103282872ac0SJason Evans } 103382872ac0SJason Evans 103482872ac0SJason Evans void 10351f0a49e8SJason Evans ctl_postfork_parent(tsdn_t *tsdn) 103682872ac0SJason Evans { 103782872ac0SJason Evans 10381f0a49e8SJason Evans malloc_mutex_postfork_parent(tsdn, &ctl_mtx); 103982872ac0SJason Evans } 104082872ac0SJason Evans 104182872ac0SJason Evans void 10421f0a49e8SJason Evans ctl_postfork_child(tsdn_t *tsdn) 104382872ac0SJason Evans { 104482872ac0SJason Evans 10451f0a49e8SJason Evans malloc_mutex_postfork_child(tsdn, &ctl_mtx); 104682872ac0SJason Evans } 104782872ac0SJason Evans 1048a4bd5210SJason Evans /******************************************************************************/ 1049a4bd5210SJason Evans /* *_ctl() functions. */ 1050a4bd5210SJason Evans 1051a4bd5210SJason Evans #define READONLY() do { \ 1052a4bd5210SJason Evans if (newp != NULL || newlen != 0) { \ 1053a4bd5210SJason Evans ret = EPERM; \ 1054a4bd5210SJason Evans goto label_return; \ 1055a4bd5210SJason Evans } \ 1056a4bd5210SJason Evans } while (0) 1057a4bd5210SJason Evans 1058a4bd5210SJason Evans #define WRITEONLY() do { \ 1059a4bd5210SJason Evans if (oldp != NULL || oldlenp != NULL) { \ 1060a4bd5210SJason Evans ret = EPERM; \ 1061a4bd5210SJason Evans goto label_return; \ 1062a4bd5210SJason Evans } \ 1063a4bd5210SJason Evans } while (0) 1064a4bd5210SJason Evans 1065d0e79aa3SJason Evans #define READ_XOR_WRITE() do { \ 1066d0e79aa3SJason Evans if ((oldp != NULL && oldlenp != NULL) && (newp != NULL || \ 1067d0e79aa3SJason Evans newlen != 0)) { \ 1068d0e79aa3SJason Evans ret = EPERM; \ 1069d0e79aa3SJason Evans goto label_return; \ 1070d0e79aa3SJason Evans } \ 1071d0e79aa3SJason Evans } while (0) 1072d0e79aa3SJason Evans 1073a4bd5210SJason Evans #define READ(v, t) do { \ 1074a4bd5210SJason Evans if (oldp != NULL && oldlenp != NULL) { \ 1075a4bd5210SJason Evans if (*oldlenp != sizeof(t)) { \ 1076a4bd5210SJason Evans size_t copylen = (sizeof(t) <= *oldlenp) \ 1077a4bd5210SJason Evans ? sizeof(t) : *oldlenp; \ 107888ad2f8dSJason Evans memcpy(oldp, (void *)&(v), copylen); \ 1079a4bd5210SJason Evans ret = EINVAL; \ 1080a4bd5210SJason Evans goto label_return; \ 1081d0e79aa3SJason Evans } \ 108288ad2f8dSJason Evans *(t *)oldp = (v); \ 1083a4bd5210SJason Evans } \ 1084a4bd5210SJason Evans } while (0) 1085a4bd5210SJason Evans 1086a4bd5210SJason Evans #define WRITE(v, t) do { \ 1087a4bd5210SJason Evans if (newp != NULL) { \ 1088a4bd5210SJason Evans if (newlen != sizeof(t)) { \ 1089a4bd5210SJason Evans ret = EINVAL; \ 1090a4bd5210SJason Evans goto label_return; \ 1091a4bd5210SJason Evans } \ 109288ad2f8dSJason Evans (v) = *(t *)newp; \ 1093a4bd5210SJason Evans } \ 1094a4bd5210SJason Evans } while (0) 1095a4bd5210SJason Evans 1096a4bd5210SJason Evans /* 1097a4bd5210SJason Evans * There's a lot of code duplication in the following macros due to limitations 1098a4bd5210SJason Evans * in how nested cpp macros are expanded. 1099a4bd5210SJason Evans */ 1100a4bd5210SJason Evans #define CTL_RO_CLGEN(c, l, n, v, t) \ 1101a4bd5210SJason Evans static int \ 11021f0a49e8SJason Evans n##_ctl(tsd_t *tsd, const size_t *mib, size_t miblen, void *oldp, \ 11031f0a49e8SJason Evans size_t *oldlenp, void *newp, size_t newlen) \ 1104a4bd5210SJason Evans { \ 1105a4bd5210SJason Evans int ret; \ 1106a4bd5210SJason Evans t oldval; \ 1107a4bd5210SJason Evans \ 1108d0e79aa3SJason Evans if (!(c)) \ 1109a4bd5210SJason Evans return (ENOENT); \ 1110a4bd5210SJason Evans if (l) \ 11111f0a49e8SJason Evans malloc_mutex_lock(tsd_tsdn(tsd), &ctl_mtx); \ 1112a4bd5210SJason Evans READONLY(); \ 111388ad2f8dSJason Evans oldval = (v); \ 1114a4bd5210SJason Evans READ(oldval, t); \ 1115a4bd5210SJason Evans \ 1116a4bd5210SJason Evans ret = 0; \ 1117a4bd5210SJason Evans label_return: \ 1118a4bd5210SJason Evans if (l) \ 11191f0a49e8SJason Evans malloc_mutex_unlock(tsd_tsdn(tsd), &ctl_mtx); \ 1120a4bd5210SJason Evans return (ret); \ 1121a4bd5210SJason Evans } 1122a4bd5210SJason Evans 1123a4bd5210SJason Evans #define CTL_RO_CGEN(c, n, v, t) \ 1124a4bd5210SJason Evans static int \ 11251f0a49e8SJason Evans n##_ctl(tsd_t *tsd, const size_t *mib, size_t miblen, void *oldp, \ 11261f0a49e8SJason Evans size_t *oldlenp, void *newp, size_t newlen) \ 1127a4bd5210SJason Evans { \ 1128a4bd5210SJason Evans int ret; \ 1129a4bd5210SJason Evans t oldval; \ 1130a4bd5210SJason Evans \ 1131d0e79aa3SJason Evans if (!(c)) \ 1132a4bd5210SJason Evans return (ENOENT); \ 11331f0a49e8SJason Evans malloc_mutex_lock(tsd_tsdn(tsd), &ctl_mtx); \ 1134a4bd5210SJason Evans READONLY(); \ 113588ad2f8dSJason Evans oldval = (v); \ 1136a4bd5210SJason Evans READ(oldval, t); \ 1137a4bd5210SJason Evans \ 1138a4bd5210SJason Evans ret = 0; \ 1139a4bd5210SJason Evans label_return: \ 11401f0a49e8SJason Evans malloc_mutex_unlock(tsd_tsdn(tsd), &ctl_mtx); \ 1141a4bd5210SJason Evans return (ret); \ 1142a4bd5210SJason Evans } 1143a4bd5210SJason Evans 1144a4bd5210SJason Evans #define CTL_RO_GEN(n, v, t) \ 1145a4bd5210SJason Evans static int \ 11461f0a49e8SJason Evans n##_ctl(tsd_t *tsd, const size_t *mib, size_t miblen, void *oldp, \ 11471f0a49e8SJason Evans size_t *oldlenp, void *newp, size_t newlen) \ 1148a4bd5210SJason Evans { \ 1149a4bd5210SJason Evans int ret; \ 1150a4bd5210SJason Evans t oldval; \ 1151a4bd5210SJason Evans \ 11521f0a49e8SJason Evans malloc_mutex_lock(tsd_tsdn(tsd), &ctl_mtx); \ 1153a4bd5210SJason Evans READONLY(); \ 115488ad2f8dSJason Evans oldval = (v); \ 1155a4bd5210SJason Evans READ(oldval, t); \ 1156a4bd5210SJason Evans \ 1157a4bd5210SJason Evans ret = 0; \ 1158a4bd5210SJason Evans label_return: \ 11591f0a49e8SJason Evans malloc_mutex_unlock(tsd_tsdn(tsd), &ctl_mtx); \ 1160a4bd5210SJason Evans return (ret); \ 1161a4bd5210SJason Evans } 1162a4bd5210SJason Evans 1163a4bd5210SJason Evans /* 1164a4bd5210SJason Evans * ctl_mtx is not acquired, under the assumption that no pertinent data will 1165a4bd5210SJason Evans * mutate during the call. 1166a4bd5210SJason Evans */ 1167a4bd5210SJason Evans #define CTL_RO_NL_CGEN(c, n, v, t) \ 1168a4bd5210SJason Evans static int \ 11691f0a49e8SJason Evans n##_ctl(tsd_t *tsd, const size_t *mib, size_t miblen, void *oldp, \ 11701f0a49e8SJason Evans size_t *oldlenp, void *newp, size_t newlen) \ 1171a4bd5210SJason Evans { \ 1172a4bd5210SJason Evans int ret; \ 1173a4bd5210SJason Evans t oldval; \ 1174a4bd5210SJason Evans \ 1175d0e79aa3SJason Evans if (!(c)) \ 1176a4bd5210SJason Evans return (ENOENT); \ 1177a4bd5210SJason Evans READONLY(); \ 117888ad2f8dSJason Evans oldval = (v); \ 1179a4bd5210SJason Evans READ(oldval, t); \ 1180a4bd5210SJason Evans \ 1181a4bd5210SJason Evans ret = 0; \ 1182a4bd5210SJason Evans label_return: \ 1183a4bd5210SJason Evans return (ret); \ 1184a4bd5210SJason Evans } 1185a4bd5210SJason Evans 1186a4bd5210SJason Evans #define CTL_RO_NL_GEN(n, v, t) \ 1187a4bd5210SJason Evans static int \ 11881f0a49e8SJason Evans n##_ctl(tsd_t *tsd, const size_t *mib, size_t miblen, void *oldp, \ 11891f0a49e8SJason Evans size_t *oldlenp, void *newp, size_t newlen) \ 1190a4bd5210SJason Evans { \ 1191a4bd5210SJason Evans int ret; \ 1192a4bd5210SJason Evans t oldval; \ 1193a4bd5210SJason Evans \ 1194a4bd5210SJason Evans READONLY(); \ 119588ad2f8dSJason Evans oldval = (v); \ 1196a4bd5210SJason Evans READ(oldval, t); \ 1197a4bd5210SJason Evans \ 1198a4bd5210SJason Evans ret = 0; \ 1199a4bd5210SJason Evans label_return: \ 1200a4bd5210SJason Evans return (ret); \ 1201a4bd5210SJason Evans } 1202a4bd5210SJason Evans 1203d0e79aa3SJason Evans #define CTL_TSD_RO_NL_CGEN(c, n, m, t) \ 1204d0e79aa3SJason Evans static int \ 12051f0a49e8SJason Evans n##_ctl(tsd_t *tsd, const size_t *mib, size_t miblen, void *oldp, \ 12061f0a49e8SJason Evans size_t *oldlenp, void *newp, size_t newlen) \ 1207d0e79aa3SJason Evans { \ 1208d0e79aa3SJason Evans int ret; \ 1209d0e79aa3SJason Evans t oldval; \ 1210d0e79aa3SJason Evans \ 1211d0e79aa3SJason Evans if (!(c)) \ 1212d0e79aa3SJason Evans return (ENOENT); \ 1213d0e79aa3SJason Evans READONLY(); \ 1214d0e79aa3SJason Evans oldval = (m(tsd)); \ 1215d0e79aa3SJason Evans READ(oldval, t); \ 1216d0e79aa3SJason Evans \ 1217d0e79aa3SJason Evans ret = 0; \ 1218d0e79aa3SJason Evans label_return: \ 1219d0e79aa3SJason Evans return (ret); \ 1220d0e79aa3SJason Evans } 1221d0e79aa3SJason Evans 1222df0d881dSJason Evans #define CTL_RO_CONFIG_GEN(n, t) \ 1223a4bd5210SJason Evans static int \ 12241f0a49e8SJason Evans n##_ctl(tsd_t *tsd, const size_t *mib, size_t miblen, void *oldp, \ 12251f0a49e8SJason Evans size_t *oldlenp, void *newp, size_t newlen) \ 1226a4bd5210SJason Evans { \ 1227a4bd5210SJason Evans int ret; \ 1228df0d881dSJason Evans t oldval; \ 1229a4bd5210SJason Evans \ 1230a4bd5210SJason Evans READONLY(); \ 1231a4bd5210SJason Evans oldval = n; \ 1232df0d881dSJason Evans READ(oldval, t); \ 1233a4bd5210SJason Evans \ 1234a4bd5210SJason Evans ret = 0; \ 1235a4bd5210SJason Evans label_return: \ 1236a4bd5210SJason Evans return (ret); \ 1237a4bd5210SJason Evans } 1238a4bd5210SJason Evans 1239f921d10fSJason Evans /******************************************************************************/ 1240f921d10fSJason Evans 1241a4bd5210SJason Evans CTL_RO_NL_GEN(version, JEMALLOC_VERSION, const char *) 1242a4bd5210SJason Evans 1243a4bd5210SJason Evans static int 12441f0a49e8SJason Evans epoch_ctl(tsd_t *tsd, const size_t *mib, size_t miblen, void *oldp, 12451f0a49e8SJason Evans size_t *oldlenp, void *newp, size_t newlen) 1246a4bd5210SJason Evans { 1247a4bd5210SJason Evans int ret; 12482b06b201SJason Evans UNUSED uint64_t newval; 1249a4bd5210SJason Evans 12501f0a49e8SJason Evans malloc_mutex_lock(tsd_tsdn(tsd), &ctl_mtx); 1251a4bd5210SJason Evans WRITE(newval, uint64_t); 1252e722f8f8SJason Evans if (newp != NULL) 12531f0a49e8SJason Evans ctl_refresh(tsd_tsdn(tsd)); 1254a4bd5210SJason Evans READ(ctl_epoch, uint64_t); 1255a4bd5210SJason Evans 1256a4bd5210SJason Evans ret = 0; 1257a4bd5210SJason Evans label_return: 12581f0a49e8SJason Evans malloc_mutex_unlock(tsd_tsdn(tsd), &ctl_mtx); 1259a4bd5210SJason Evans return (ret); 1260a4bd5210SJason Evans } 1261a4bd5210SJason Evans 1262f921d10fSJason Evans /******************************************************************************/ 1263a4bd5210SJason Evans 1264df0d881dSJason Evans CTL_RO_CONFIG_GEN(config_cache_oblivious, bool) 1265df0d881dSJason Evans CTL_RO_CONFIG_GEN(config_debug, bool) 1266df0d881dSJason Evans CTL_RO_CONFIG_GEN(config_fill, bool) 1267df0d881dSJason Evans CTL_RO_CONFIG_GEN(config_lazy_lock, bool) 1268df0d881dSJason Evans CTL_RO_CONFIG_GEN(config_malloc_conf, const char *) 1269df0d881dSJason Evans CTL_RO_CONFIG_GEN(config_munmap, bool) 1270df0d881dSJason Evans CTL_RO_CONFIG_GEN(config_prof, bool) 1271df0d881dSJason Evans CTL_RO_CONFIG_GEN(config_prof_libgcc, bool) 1272df0d881dSJason Evans CTL_RO_CONFIG_GEN(config_prof_libunwind, bool) 1273df0d881dSJason Evans CTL_RO_CONFIG_GEN(config_stats, bool) 1274df0d881dSJason Evans CTL_RO_CONFIG_GEN(config_tcache, bool) 1275*8244f2aaSJason Evans CTL_RO_CONFIG_GEN(config_thp, bool) 1276df0d881dSJason Evans CTL_RO_CONFIG_GEN(config_tls, bool) 1277df0d881dSJason Evans CTL_RO_CONFIG_GEN(config_utrace, bool) 1278df0d881dSJason Evans CTL_RO_CONFIG_GEN(config_valgrind, bool) 1279df0d881dSJason Evans CTL_RO_CONFIG_GEN(config_xmalloc, bool) 1280a4bd5210SJason Evans 1281f921d10fSJason Evans /******************************************************************************/ 1282a4bd5210SJason Evans 1283f921d10fSJason Evans CTL_RO_NL_GEN(opt_abort, opt_abort, bool) 1284f921d10fSJason Evans CTL_RO_NL_GEN(opt_dss, opt_dss, const char *) 1285f921d10fSJason Evans CTL_RO_NL_GEN(opt_lg_chunk, opt_lg_chunk, size_t) 1286df0d881dSJason Evans CTL_RO_NL_GEN(opt_narenas, opt_narenas, unsigned) 1287df0d881dSJason Evans CTL_RO_NL_GEN(opt_purge, purge_mode_names[opt_purge], const char *) 1288f921d10fSJason Evans CTL_RO_NL_GEN(opt_lg_dirty_mult, opt_lg_dirty_mult, ssize_t) 1289df0d881dSJason Evans CTL_RO_NL_GEN(opt_decay_time, opt_decay_time, ssize_t) 1290f921d10fSJason Evans CTL_RO_NL_GEN(opt_stats_print, opt_stats_print, bool) 1291d0e79aa3SJason Evans CTL_RO_NL_CGEN(config_fill, opt_junk, opt_junk, const char *) 1292f921d10fSJason Evans CTL_RO_NL_CGEN(config_fill, opt_quarantine, opt_quarantine, size_t) 1293f921d10fSJason Evans CTL_RO_NL_CGEN(config_fill, opt_redzone, opt_redzone, bool) 1294f921d10fSJason Evans CTL_RO_NL_CGEN(config_fill, opt_zero, opt_zero, bool) 1295f921d10fSJason Evans CTL_RO_NL_CGEN(config_utrace, opt_utrace, opt_utrace, bool) 1296f921d10fSJason Evans CTL_RO_NL_CGEN(config_xmalloc, opt_xmalloc, opt_xmalloc, bool) 1297f921d10fSJason Evans CTL_RO_NL_CGEN(config_tcache, opt_tcache, opt_tcache, bool) 1298f921d10fSJason Evans CTL_RO_NL_CGEN(config_tcache, opt_lg_tcache_max, opt_lg_tcache_max, ssize_t) 1299*8244f2aaSJason Evans CTL_RO_NL_CGEN(config_thp, opt_thp, opt_thp, bool) 1300f921d10fSJason Evans CTL_RO_NL_CGEN(config_prof, opt_prof, opt_prof, bool) 1301f921d10fSJason Evans CTL_RO_NL_CGEN(config_prof, opt_prof_prefix, opt_prof_prefix, const char *) 1302d0e79aa3SJason Evans CTL_RO_NL_CGEN(config_prof, opt_prof_active, opt_prof_active, bool) 1303d0e79aa3SJason Evans CTL_RO_NL_CGEN(config_prof, opt_prof_thread_active_init, 1304d0e79aa3SJason Evans opt_prof_thread_active_init, bool) 1305f921d10fSJason Evans CTL_RO_NL_CGEN(config_prof, opt_lg_prof_sample, opt_lg_prof_sample, size_t) 1306f921d10fSJason Evans CTL_RO_NL_CGEN(config_prof, opt_prof_accum, opt_prof_accum, bool) 1307f921d10fSJason Evans CTL_RO_NL_CGEN(config_prof, opt_lg_prof_interval, opt_lg_prof_interval, ssize_t) 1308f921d10fSJason Evans CTL_RO_NL_CGEN(config_prof, opt_prof_gdump, opt_prof_gdump, bool) 1309f921d10fSJason Evans CTL_RO_NL_CGEN(config_prof, opt_prof_final, opt_prof_final, bool) 1310f921d10fSJason Evans CTL_RO_NL_CGEN(config_prof, opt_prof_leak, opt_prof_leak, bool) 1311a4bd5210SJason Evans 1312f921d10fSJason Evans /******************************************************************************/ 1313a4bd5210SJason Evans 1314a4bd5210SJason Evans static int 13151f0a49e8SJason Evans thread_arena_ctl(tsd_t *tsd, const size_t *mib, size_t miblen, void *oldp, 13161f0a49e8SJason Evans size_t *oldlenp, void *newp, size_t newlen) 1317a4bd5210SJason Evans { 1318a4bd5210SJason Evans int ret; 1319d0e79aa3SJason Evans arena_t *oldarena; 1320a4bd5210SJason Evans unsigned newind, oldind; 1321a4bd5210SJason Evans 1322d0e79aa3SJason Evans oldarena = arena_choose(tsd, NULL); 1323d0e79aa3SJason Evans if (oldarena == NULL) 1324d0e79aa3SJason Evans return (EAGAIN); 1325d0e79aa3SJason Evans 13261f0a49e8SJason Evans malloc_mutex_lock(tsd_tsdn(tsd), &ctl_mtx); 1327d0e79aa3SJason Evans newind = oldind = oldarena->ind; 1328a4bd5210SJason Evans WRITE(newind, unsigned); 1329a4bd5210SJason Evans READ(oldind, unsigned); 1330a4bd5210SJason Evans if (newind != oldind) { 1331d0e79aa3SJason Evans arena_t *newarena; 1332a4bd5210SJason Evans 133382872ac0SJason Evans if (newind >= ctl_stats.narenas) { 1334a4bd5210SJason Evans /* New arena index is out of range. */ 1335a4bd5210SJason Evans ret = EFAULT; 1336a4bd5210SJason Evans goto label_return; 1337a4bd5210SJason Evans } 1338a4bd5210SJason Evans 1339a4bd5210SJason Evans /* Initialize arena if necessary. */ 13401f0a49e8SJason Evans newarena = arena_get(tsd_tsdn(tsd), newind, true); 1341d0e79aa3SJason Evans if (newarena == NULL) { 1342a4bd5210SJason Evans ret = EAGAIN; 1343a4bd5210SJason Evans goto label_return; 1344a4bd5210SJason Evans } 1345d0e79aa3SJason Evans /* Set new arena/tcache associations. */ 1346d0e79aa3SJason Evans arena_migrate(tsd, oldind, newind); 1347a4bd5210SJason Evans if (config_tcache) { 1348d0e79aa3SJason Evans tcache_t *tcache = tsd_tcache_get(tsd); 1349d0e79aa3SJason Evans if (tcache != NULL) { 13501f0a49e8SJason Evans tcache_arena_reassociate(tsd_tsdn(tsd), tcache, 13511f0a49e8SJason Evans oldarena, newarena); 1352a4bd5210SJason Evans } 1353a4bd5210SJason Evans } 1354a4bd5210SJason Evans } 1355a4bd5210SJason Evans 1356a4bd5210SJason Evans ret = 0; 1357a4bd5210SJason Evans label_return: 13581f0a49e8SJason Evans malloc_mutex_unlock(tsd_tsdn(tsd), &ctl_mtx); 1359a4bd5210SJason Evans return (ret); 1360a4bd5210SJason Evans } 1361a4bd5210SJason Evans 1362d0e79aa3SJason Evans CTL_TSD_RO_NL_CGEN(config_stats, thread_allocated, tsd_thread_allocated_get, 1363d0e79aa3SJason Evans uint64_t) 1364d0e79aa3SJason Evans CTL_TSD_RO_NL_CGEN(config_stats, thread_allocatedp, tsd_thread_allocatedp_get, 1365d0e79aa3SJason Evans uint64_t *) 1366d0e79aa3SJason Evans CTL_TSD_RO_NL_CGEN(config_stats, thread_deallocated, tsd_thread_deallocated_get, 1367d0e79aa3SJason Evans uint64_t) 1368d0e79aa3SJason Evans CTL_TSD_RO_NL_CGEN(config_stats, thread_deallocatedp, 1369d0e79aa3SJason Evans tsd_thread_deallocatedp_get, uint64_t *) 1370a4bd5210SJason Evans 1371f921d10fSJason Evans static int 13721f0a49e8SJason Evans thread_tcache_enabled_ctl(tsd_t *tsd, const size_t *mib, size_t miblen, 13731f0a49e8SJason Evans void *oldp, size_t *oldlenp, void *newp, size_t newlen) 1374f921d10fSJason Evans { 1375f921d10fSJason Evans int ret; 1376f921d10fSJason Evans bool oldval; 1377a4bd5210SJason Evans 1378d0e79aa3SJason Evans if (!config_tcache) 1379f921d10fSJason Evans return (ENOENT); 1380a4bd5210SJason Evans 1381f921d10fSJason Evans oldval = tcache_enabled_get(); 1382f921d10fSJason Evans if (newp != NULL) { 1383f921d10fSJason Evans if (newlen != sizeof(bool)) { 1384f921d10fSJason Evans ret = EINVAL; 1385f921d10fSJason Evans goto label_return; 1386f921d10fSJason Evans } 1387f921d10fSJason Evans tcache_enabled_set(*(bool *)newp); 1388f921d10fSJason Evans } 1389f921d10fSJason Evans READ(oldval, bool); 1390a4bd5210SJason Evans 1391f921d10fSJason Evans ret = 0; 1392f921d10fSJason Evans label_return: 1393f921d10fSJason Evans return (ret); 1394f921d10fSJason Evans } 1395f921d10fSJason Evans 1396f921d10fSJason Evans static int 13971f0a49e8SJason Evans thread_tcache_flush_ctl(tsd_t *tsd, const size_t *mib, size_t miblen, 13981f0a49e8SJason Evans void *oldp, size_t *oldlenp, void *newp, size_t newlen) 1399f921d10fSJason Evans { 1400f921d10fSJason Evans int ret; 1401f921d10fSJason Evans 1402d0e79aa3SJason Evans if (!config_tcache) 1403f921d10fSJason Evans return (ENOENT); 1404f921d10fSJason Evans 1405f921d10fSJason Evans READONLY(); 1406f921d10fSJason Evans WRITEONLY(); 1407f921d10fSJason Evans 1408f921d10fSJason Evans tcache_flush(); 1409f921d10fSJason Evans 1410f921d10fSJason Evans ret = 0; 1411f921d10fSJason Evans label_return: 1412f921d10fSJason Evans return (ret); 1413f921d10fSJason Evans } 1414a4bd5210SJason Evans 1415d0e79aa3SJason Evans static int 14161f0a49e8SJason Evans thread_prof_name_ctl(tsd_t *tsd, const size_t *mib, size_t miblen, void *oldp, 1417d0e79aa3SJason Evans size_t *oldlenp, void *newp, size_t newlen) 1418d0e79aa3SJason Evans { 1419d0e79aa3SJason Evans int ret; 1420d0e79aa3SJason Evans 1421d0e79aa3SJason Evans if (!config_prof) 1422d0e79aa3SJason Evans return (ENOENT); 1423d0e79aa3SJason Evans 1424d0e79aa3SJason Evans READ_XOR_WRITE(); 1425d0e79aa3SJason Evans 1426d0e79aa3SJason Evans if (newp != NULL) { 1427d0e79aa3SJason Evans if (newlen != sizeof(const char *)) { 1428d0e79aa3SJason Evans ret = EINVAL; 1429d0e79aa3SJason Evans goto label_return; 1430d0e79aa3SJason Evans } 1431d0e79aa3SJason Evans 1432d0e79aa3SJason Evans if ((ret = prof_thread_name_set(tsd, *(const char **)newp)) != 1433d0e79aa3SJason Evans 0) 1434d0e79aa3SJason Evans goto label_return; 1435d0e79aa3SJason Evans } else { 14361f0a49e8SJason Evans const char *oldname = prof_thread_name_get(tsd); 1437d0e79aa3SJason Evans READ(oldname, const char *); 1438d0e79aa3SJason Evans } 1439d0e79aa3SJason Evans 1440d0e79aa3SJason Evans ret = 0; 1441d0e79aa3SJason Evans label_return: 1442d0e79aa3SJason Evans return (ret); 1443d0e79aa3SJason Evans } 1444d0e79aa3SJason Evans 1445d0e79aa3SJason Evans static int 14461f0a49e8SJason Evans thread_prof_active_ctl(tsd_t *tsd, const size_t *mib, size_t miblen, void *oldp, 1447d0e79aa3SJason Evans size_t *oldlenp, void *newp, size_t newlen) 1448d0e79aa3SJason Evans { 1449d0e79aa3SJason Evans int ret; 1450d0e79aa3SJason Evans bool oldval; 1451d0e79aa3SJason Evans 1452d0e79aa3SJason Evans if (!config_prof) 1453d0e79aa3SJason Evans return (ENOENT); 1454d0e79aa3SJason Evans 14551f0a49e8SJason Evans oldval = prof_thread_active_get(tsd); 1456d0e79aa3SJason Evans if (newp != NULL) { 1457d0e79aa3SJason Evans if (newlen != sizeof(bool)) { 1458d0e79aa3SJason Evans ret = EINVAL; 1459d0e79aa3SJason Evans goto label_return; 1460d0e79aa3SJason Evans } 14611f0a49e8SJason Evans if (prof_thread_active_set(tsd, *(bool *)newp)) { 1462d0e79aa3SJason Evans ret = EAGAIN; 1463d0e79aa3SJason Evans goto label_return; 1464d0e79aa3SJason Evans } 1465d0e79aa3SJason Evans } 1466d0e79aa3SJason Evans READ(oldval, bool); 1467d0e79aa3SJason Evans 1468d0e79aa3SJason Evans ret = 0; 1469d0e79aa3SJason Evans label_return: 1470d0e79aa3SJason Evans return (ret); 1471d0e79aa3SJason Evans } 1472d0e79aa3SJason Evans 1473d0e79aa3SJason Evans /******************************************************************************/ 1474d0e79aa3SJason Evans 1475d0e79aa3SJason Evans static int 14761f0a49e8SJason Evans tcache_create_ctl(tsd_t *tsd, const size_t *mib, size_t miblen, void *oldp, 14771f0a49e8SJason Evans size_t *oldlenp, void *newp, size_t newlen) 1478d0e79aa3SJason Evans { 1479d0e79aa3SJason Evans int ret; 1480d0e79aa3SJason Evans unsigned tcache_ind; 1481d0e79aa3SJason Evans 1482d0e79aa3SJason Evans if (!config_tcache) 1483d0e79aa3SJason Evans return (ENOENT); 1484d0e79aa3SJason Evans 1485d0e79aa3SJason Evans READONLY(); 1486bde95144SJason Evans if (tcaches_create(tsd, &tcache_ind)) { 1487d0e79aa3SJason Evans ret = EFAULT; 1488d0e79aa3SJason Evans goto label_return; 1489d0e79aa3SJason Evans } 1490d0e79aa3SJason Evans READ(tcache_ind, unsigned); 1491d0e79aa3SJason Evans 1492d0e79aa3SJason Evans ret = 0; 1493d0e79aa3SJason Evans label_return: 1494*8244f2aaSJason Evans return ret; 1495d0e79aa3SJason Evans } 1496d0e79aa3SJason Evans 1497d0e79aa3SJason Evans static int 14981f0a49e8SJason Evans tcache_flush_ctl(tsd_t *tsd, const size_t *mib, size_t miblen, void *oldp, 14991f0a49e8SJason Evans size_t *oldlenp, void *newp, size_t newlen) 1500d0e79aa3SJason Evans { 1501d0e79aa3SJason Evans int ret; 1502d0e79aa3SJason Evans unsigned tcache_ind; 1503d0e79aa3SJason Evans 1504d0e79aa3SJason Evans if (!config_tcache) 1505d0e79aa3SJason Evans return (ENOENT); 1506d0e79aa3SJason Evans 1507d0e79aa3SJason Evans WRITEONLY(); 1508d0e79aa3SJason Evans tcache_ind = UINT_MAX; 1509d0e79aa3SJason Evans WRITE(tcache_ind, unsigned); 1510d0e79aa3SJason Evans if (tcache_ind == UINT_MAX) { 1511d0e79aa3SJason Evans ret = EFAULT; 1512d0e79aa3SJason Evans goto label_return; 1513d0e79aa3SJason Evans } 1514d0e79aa3SJason Evans tcaches_flush(tsd, tcache_ind); 1515d0e79aa3SJason Evans 1516d0e79aa3SJason Evans ret = 0; 1517d0e79aa3SJason Evans label_return: 1518d0e79aa3SJason Evans return (ret); 1519d0e79aa3SJason Evans } 1520d0e79aa3SJason Evans 1521d0e79aa3SJason Evans static int 15221f0a49e8SJason Evans tcache_destroy_ctl(tsd_t *tsd, const size_t *mib, size_t miblen, void *oldp, 1523d0e79aa3SJason Evans size_t *oldlenp, void *newp, size_t newlen) 1524d0e79aa3SJason Evans { 1525d0e79aa3SJason Evans int ret; 1526d0e79aa3SJason Evans unsigned tcache_ind; 1527d0e79aa3SJason Evans 1528d0e79aa3SJason Evans if (!config_tcache) 1529d0e79aa3SJason Evans return (ENOENT); 1530d0e79aa3SJason Evans 1531d0e79aa3SJason Evans WRITEONLY(); 1532d0e79aa3SJason Evans tcache_ind = UINT_MAX; 1533d0e79aa3SJason Evans WRITE(tcache_ind, unsigned); 1534d0e79aa3SJason Evans if (tcache_ind == UINT_MAX) { 1535d0e79aa3SJason Evans ret = EFAULT; 1536d0e79aa3SJason Evans goto label_return; 1537d0e79aa3SJason Evans } 1538d0e79aa3SJason Evans tcaches_destroy(tsd, tcache_ind); 1539d0e79aa3SJason Evans 1540d0e79aa3SJason Evans ret = 0; 1541d0e79aa3SJason Evans label_return: 1542d0e79aa3SJason Evans return (ret); 1543d0e79aa3SJason Evans } 1544d0e79aa3SJason Evans 1545a4bd5210SJason Evans /******************************************************************************/ 1546a4bd5210SJason Evans 154782872ac0SJason Evans static void 15481f0a49e8SJason Evans arena_i_purge(tsdn_t *tsdn, unsigned arena_ind, bool all) 154982872ac0SJason Evans { 155082872ac0SJason Evans 15511f0a49e8SJason Evans malloc_mutex_lock(tsdn, &ctl_mtx); 1552df0d881dSJason Evans { 1553df0d881dSJason Evans unsigned narenas = ctl_stats.narenas; 155482872ac0SJason Evans 1555df0d881dSJason Evans if (arena_ind == narenas) { 155682872ac0SJason Evans unsigned i; 1557df0d881dSJason Evans VARIABLE_ARRAY(arena_t *, tarenas, narenas); 1558df0d881dSJason Evans 1559df0d881dSJason Evans for (i = 0; i < narenas; i++) 15601f0a49e8SJason Evans tarenas[i] = arena_get(tsdn, i, false); 1561df0d881dSJason Evans 1562df0d881dSJason Evans /* 1563df0d881dSJason Evans * No further need to hold ctl_mtx, since narenas and 1564df0d881dSJason Evans * tarenas contain everything needed below. 1565df0d881dSJason Evans */ 15661f0a49e8SJason Evans malloc_mutex_unlock(tsdn, &ctl_mtx); 1567df0d881dSJason Evans 1568df0d881dSJason Evans for (i = 0; i < narenas; i++) { 156982872ac0SJason Evans if (tarenas[i] != NULL) 15701f0a49e8SJason Evans arena_purge(tsdn, tarenas[i], all); 157182872ac0SJason Evans } 157282872ac0SJason Evans } else { 1573df0d881dSJason Evans arena_t *tarena; 1574df0d881dSJason Evans 1575df0d881dSJason Evans assert(arena_ind < narenas); 1576df0d881dSJason Evans 15771f0a49e8SJason Evans tarena = arena_get(tsdn, arena_ind, false); 1578df0d881dSJason Evans 1579df0d881dSJason Evans /* No further need to hold ctl_mtx. */ 15801f0a49e8SJason Evans malloc_mutex_unlock(tsdn, &ctl_mtx); 1581df0d881dSJason Evans 1582df0d881dSJason Evans if (tarena != NULL) 15831f0a49e8SJason Evans arena_purge(tsdn, tarena, all); 1584df0d881dSJason Evans } 158582872ac0SJason Evans } 158682872ac0SJason Evans } 158782872ac0SJason Evans 158882872ac0SJason Evans static int 15891f0a49e8SJason Evans arena_i_purge_ctl(tsd_t *tsd, const size_t *mib, size_t miblen, void *oldp, 15901f0a49e8SJason Evans size_t *oldlenp, void *newp, size_t newlen) 159182872ac0SJason Evans { 159282872ac0SJason Evans int ret; 159382872ac0SJason Evans 159482872ac0SJason Evans READONLY(); 159582872ac0SJason Evans WRITEONLY(); 15961f0a49e8SJason Evans arena_i_purge(tsd_tsdn(tsd), (unsigned)mib[1], true); 1597df0d881dSJason Evans 1598df0d881dSJason Evans ret = 0; 1599df0d881dSJason Evans label_return: 1600df0d881dSJason Evans return (ret); 1601df0d881dSJason Evans } 1602df0d881dSJason Evans 1603df0d881dSJason Evans static int 16041f0a49e8SJason Evans arena_i_decay_ctl(tsd_t *tsd, const size_t *mib, size_t miblen, void *oldp, 16051f0a49e8SJason Evans size_t *oldlenp, void *newp, size_t newlen) 1606df0d881dSJason Evans { 1607df0d881dSJason Evans int ret; 1608df0d881dSJason Evans 1609df0d881dSJason Evans READONLY(); 1610df0d881dSJason Evans WRITEONLY(); 16111f0a49e8SJason Evans arena_i_purge(tsd_tsdn(tsd), (unsigned)mib[1], false); 161282872ac0SJason Evans 161382872ac0SJason Evans ret = 0; 161482872ac0SJason Evans label_return: 161582872ac0SJason Evans return (ret); 161682872ac0SJason Evans } 161782872ac0SJason Evans 161882872ac0SJason Evans static int 16191f0a49e8SJason Evans arena_i_reset_ctl(tsd_t *tsd, const size_t *mib, size_t miblen, void *oldp, 16201f0a49e8SJason Evans size_t *oldlenp, void *newp, size_t newlen) 16211f0a49e8SJason Evans { 16221f0a49e8SJason Evans int ret; 16231f0a49e8SJason Evans unsigned arena_ind; 16241f0a49e8SJason Evans arena_t *arena; 16251f0a49e8SJason Evans 16261f0a49e8SJason Evans READONLY(); 16271f0a49e8SJason Evans WRITEONLY(); 16281f0a49e8SJason Evans 16291f0a49e8SJason Evans if ((config_valgrind && unlikely(in_valgrind)) || (config_fill && 16301f0a49e8SJason Evans unlikely(opt_quarantine))) { 16311f0a49e8SJason Evans ret = EFAULT; 16321f0a49e8SJason Evans goto label_return; 16331f0a49e8SJason Evans } 16341f0a49e8SJason Evans 16351f0a49e8SJason Evans arena_ind = (unsigned)mib[1]; 16361f0a49e8SJason Evans if (config_debug) { 16371f0a49e8SJason Evans malloc_mutex_lock(tsd_tsdn(tsd), &ctl_mtx); 16381f0a49e8SJason Evans assert(arena_ind < ctl_stats.narenas); 16391f0a49e8SJason Evans malloc_mutex_unlock(tsd_tsdn(tsd), &ctl_mtx); 16401f0a49e8SJason Evans } 16411f0a49e8SJason Evans assert(arena_ind >= opt_narenas); 16421f0a49e8SJason Evans 16431f0a49e8SJason Evans arena = arena_get(tsd_tsdn(tsd), arena_ind, false); 16441f0a49e8SJason Evans 16451f0a49e8SJason Evans arena_reset(tsd, arena); 16461f0a49e8SJason Evans 16471f0a49e8SJason Evans ret = 0; 16481f0a49e8SJason Evans label_return: 16491f0a49e8SJason Evans return (ret); 16501f0a49e8SJason Evans } 16511f0a49e8SJason Evans 16521f0a49e8SJason Evans static int 16531f0a49e8SJason Evans arena_i_dss_ctl(tsd_t *tsd, const size_t *mib, size_t miblen, void *oldp, 16541f0a49e8SJason Evans size_t *oldlenp, void *newp, size_t newlen) 165582872ac0SJason Evans { 1656d0e79aa3SJason Evans int ret; 1657d0e79aa3SJason Evans const char *dss = NULL; 1658df0d881dSJason Evans unsigned arena_ind = (unsigned)mib[1]; 165982872ac0SJason Evans dss_prec_t dss_prec_old = dss_prec_limit; 166082872ac0SJason Evans dss_prec_t dss_prec = dss_prec_limit; 166182872ac0SJason Evans 16621f0a49e8SJason Evans malloc_mutex_lock(tsd_tsdn(tsd), &ctl_mtx); 166382872ac0SJason Evans WRITE(dss, const char *); 1664d0e79aa3SJason Evans if (dss != NULL) { 1665d0e79aa3SJason Evans int i; 1666d0e79aa3SJason Evans bool match = false; 1667d0e79aa3SJason Evans 166882872ac0SJason Evans for (i = 0; i < dss_prec_limit; i++) { 166982872ac0SJason Evans if (strcmp(dss_prec_names[i], dss) == 0) { 167082872ac0SJason Evans dss_prec = i; 167182872ac0SJason Evans match = true; 167282872ac0SJason Evans break; 167382872ac0SJason Evans } 167482872ac0SJason Evans } 1675d0e79aa3SJason Evans 1676d0e79aa3SJason Evans if (!match) { 167782872ac0SJason Evans ret = EINVAL; 167882872ac0SJason Evans goto label_return; 167982872ac0SJason Evans } 1680d0e79aa3SJason Evans } 168182872ac0SJason Evans 168282872ac0SJason Evans if (arena_ind < ctl_stats.narenas) { 16831f0a49e8SJason Evans arena_t *arena = arena_get(tsd_tsdn(tsd), arena_ind, false); 1684d0e79aa3SJason Evans if (arena == NULL || (dss_prec != dss_prec_limit && 16851f0a49e8SJason Evans arena_dss_prec_set(tsd_tsdn(tsd), arena, dss_prec))) { 1686d0e79aa3SJason Evans ret = EFAULT; 1687d0e79aa3SJason Evans goto label_return; 168882872ac0SJason Evans } 16891f0a49e8SJason Evans dss_prec_old = arena_dss_prec_get(tsd_tsdn(tsd), arena); 1690d0e79aa3SJason Evans } else { 1691d0e79aa3SJason Evans if (dss_prec != dss_prec_limit && 1692bde95144SJason Evans chunk_dss_prec_set(dss_prec)) { 1693d0e79aa3SJason Evans ret = EFAULT; 1694d0e79aa3SJason Evans goto label_return; 1695d0e79aa3SJason Evans } 1696bde95144SJason Evans dss_prec_old = chunk_dss_prec_get(); 1697d0e79aa3SJason Evans } 1698d0e79aa3SJason Evans 169982872ac0SJason Evans dss = dss_prec_names[dss_prec_old]; 170082872ac0SJason Evans READ(dss, const char *); 1701d0e79aa3SJason Evans 1702d0e79aa3SJason Evans ret = 0; 1703d0e79aa3SJason Evans label_return: 17041f0a49e8SJason Evans malloc_mutex_unlock(tsd_tsdn(tsd), &ctl_mtx); 1705d0e79aa3SJason Evans return (ret); 1706d0e79aa3SJason Evans } 1707d0e79aa3SJason Evans 1708d0e79aa3SJason Evans static int 17091f0a49e8SJason Evans arena_i_lg_dirty_mult_ctl(tsd_t *tsd, const size_t *mib, size_t miblen, 17101f0a49e8SJason Evans void *oldp, size_t *oldlenp, void *newp, size_t newlen) 1711d0e79aa3SJason Evans { 1712d0e79aa3SJason Evans int ret; 1713df0d881dSJason Evans unsigned arena_ind = (unsigned)mib[1]; 1714d0e79aa3SJason Evans arena_t *arena; 1715d0e79aa3SJason Evans 17161f0a49e8SJason Evans arena = arena_get(tsd_tsdn(tsd), arena_ind, false); 1717d0e79aa3SJason Evans if (arena == NULL) { 171882872ac0SJason Evans ret = EFAULT; 171982872ac0SJason Evans goto label_return; 172082872ac0SJason Evans } 172182872ac0SJason Evans 1722d0e79aa3SJason Evans if (oldp != NULL && oldlenp != NULL) { 17231f0a49e8SJason Evans size_t oldval = arena_lg_dirty_mult_get(tsd_tsdn(tsd), arena); 1724d0e79aa3SJason Evans READ(oldval, ssize_t); 1725d0e79aa3SJason Evans } 1726d0e79aa3SJason Evans if (newp != NULL) { 1727d0e79aa3SJason Evans if (newlen != sizeof(ssize_t)) { 1728d0e79aa3SJason Evans ret = EINVAL; 1729d0e79aa3SJason Evans goto label_return; 1730d0e79aa3SJason Evans } 17311f0a49e8SJason Evans if (arena_lg_dirty_mult_set(tsd_tsdn(tsd), arena, 17321f0a49e8SJason Evans *(ssize_t *)newp)) { 1733d0e79aa3SJason Evans ret = EFAULT; 1734d0e79aa3SJason Evans goto label_return; 1735d0e79aa3SJason Evans } 1736d0e79aa3SJason Evans } 1737d0e79aa3SJason Evans 1738d0e79aa3SJason Evans ret = 0; 1739d0e79aa3SJason Evans label_return: 1740d0e79aa3SJason Evans return (ret); 1741d0e79aa3SJason Evans } 1742d0e79aa3SJason Evans 1743d0e79aa3SJason Evans static int 17441f0a49e8SJason Evans arena_i_decay_time_ctl(tsd_t *tsd, const size_t *mib, size_t miblen, void *oldp, 1745df0d881dSJason Evans size_t *oldlenp, void *newp, size_t newlen) 1746df0d881dSJason Evans { 1747df0d881dSJason Evans int ret; 1748df0d881dSJason Evans unsigned arena_ind = (unsigned)mib[1]; 1749df0d881dSJason Evans arena_t *arena; 1750df0d881dSJason Evans 17511f0a49e8SJason Evans arena = arena_get(tsd_tsdn(tsd), arena_ind, false); 1752df0d881dSJason Evans if (arena == NULL) { 1753df0d881dSJason Evans ret = EFAULT; 1754df0d881dSJason Evans goto label_return; 1755df0d881dSJason Evans } 1756df0d881dSJason Evans 1757df0d881dSJason Evans if (oldp != NULL && oldlenp != NULL) { 17581f0a49e8SJason Evans size_t oldval = arena_decay_time_get(tsd_tsdn(tsd), arena); 1759df0d881dSJason Evans READ(oldval, ssize_t); 1760df0d881dSJason Evans } 1761df0d881dSJason Evans if (newp != NULL) { 1762df0d881dSJason Evans if (newlen != sizeof(ssize_t)) { 1763df0d881dSJason Evans ret = EINVAL; 1764df0d881dSJason Evans goto label_return; 1765df0d881dSJason Evans } 17661f0a49e8SJason Evans if (arena_decay_time_set(tsd_tsdn(tsd), arena, 17671f0a49e8SJason Evans *(ssize_t *)newp)) { 1768df0d881dSJason Evans ret = EFAULT; 1769df0d881dSJason Evans goto label_return; 1770df0d881dSJason Evans } 1771df0d881dSJason Evans } 1772df0d881dSJason Evans 1773df0d881dSJason Evans ret = 0; 1774df0d881dSJason Evans label_return: 1775df0d881dSJason Evans return (ret); 1776df0d881dSJason Evans } 1777df0d881dSJason Evans 1778df0d881dSJason Evans static int 17791f0a49e8SJason Evans arena_i_chunk_hooks_ctl(tsd_t *tsd, const size_t *mib, size_t miblen, 17801f0a49e8SJason Evans void *oldp, size_t *oldlenp, void *newp, size_t newlen) 1781d0e79aa3SJason Evans { 1782d0e79aa3SJason Evans int ret; 1783df0d881dSJason Evans unsigned arena_ind = (unsigned)mib[1]; 1784d0e79aa3SJason Evans arena_t *arena; 1785d0e79aa3SJason Evans 17861f0a49e8SJason Evans malloc_mutex_lock(tsd_tsdn(tsd), &ctl_mtx); 1787d0e79aa3SJason Evans if (arena_ind < narenas_total_get() && (arena = 17881f0a49e8SJason Evans arena_get(tsd_tsdn(tsd), arena_ind, false)) != NULL) { 1789d0e79aa3SJason Evans if (newp != NULL) { 1790d0e79aa3SJason Evans chunk_hooks_t old_chunk_hooks, new_chunk_hooks; 1791d0e79aa3SJason Evans WRITE(new_chunk_hooks, chunk_hooks_t); 17921f0a49e8SJason Evans old_chunk_hooks = chunk_hooks_set(tsd_tsdn(tsd), arena, 1793d0e79aa3SJason Evans &new_chunk_hooks); 1794d0e79aa3SJason Evans READ(old_chunk_hooks, chunk_hooks_t); 1795d0e79aa3SJason Evans } else { 17961f0a49e8SJason Evans chunk_hooks_t old_chunk_hooks = 17971f0a49e8SJason Evans chunk_hooks_get(tsd_tsdn(tsd), arena); 1798d0e79aa3SJason Evans READ(old_chunk_hooks, chunk_hooks_t); 1799d0e79aa3SJason Evans } 1800d0e79aa3SJason Evans } else { 1801d0e79aa3SJason Evans ret = EFAULT; 1802d0e79aa3SJason Evans goto label_return; 1803d0e79aa3SJason Evans } 180482872ac0SJason Evans ret = 0; 180582872ac0SJason Evans label_return: 18061f0a49e8SJason Evans malloc_mutex_unlock(tsd_tsdn(tsd), &ctl_mtx); 180782872ac0SJason Evans return (ret); 180882872ac0SJason Evans } 180982872ac0SJason Evans 181082872ac0SJason Evans static const ctl_named_node_t * 18111f0a49e8SJason Evans arena_i_index(tsdn_t *tsdn, const size_t *mib, size_t miblen, size_t i) 181282872ac0SJason Evans { 181382872ac0SJason Evans const ctl_named_node_t *ret; 181482872ac0SJason Evans 18151f0a49e8SJason Evans malloc_mutex_lock(tsdn, &ctl_mtx); 181682872ac0SJason Evans if (i > ctl_stats.narenas) { 181782872ac0SJason Evans ret = NULL; 181882872ac0SJason Evans goto label_return; 181982872ac0SJason Evans } 182082872ac0SJason Evans 182182872ac0SJason Evans ret = super_arena_i_node; 182282872ac0SJason Evans label_return: 18231f0a49e8SJason Evans malloc_mutex_unlock(tsdn, &ctl_mtx); 182482872ac0SJason Evans return (ret); 182582872ac0SJason Evans } 182682872ac0SJason Evans 182782872ac0SJason Evans /******************************************************************************/ 182882872ac0SJason Evans 182982872ac0SJason Evans static int 18301f0a49e8SJason Evans arenas_narenas_ctl(tsd_t *tsd, const size_t *mib, size_t miblen, void *oldp, 183182872ac0SJason Evans size_t *oldlenp, void *newp, size_t newlen) 183282872ac0SJason Evans { 183382872ac0SJason Evans int ret; 183482872ac0SJason Evans unsigned narenas; 183582872ac0SJason Evans 18361f0a49e8SJason Evans malloc_mutex_lock(tsd_tsdn(tsd), &ctl_mtx); 183782872ac0SJason Evans READONLY(); 183882872ac0SJason Evans if (*oldlenp != sizeof(unsigned)) { 183982872ac0SJason Evans ret = EINVAL; 184082872ac0SJason Evans goto label_return; 184182872ac0SJason Evans } 184282872ac0SJason Evans narenas = ctl_stats.narenas; 184382872ac0SJason Evans READ(narenas, unsigned); 184482872ac0SJason Evans 184582872ac0SJason Evans ret = 0; 184682872ac0SJason Evans label_return: 18471f0a49e8SJason Evans malloc_mutex_unlock(tsd_tsdn(tsd), &ctl_mtx); 184882872ac0SJason Evans return (ret); 184982872ac0SJason Evans } 1850a4bd5210SJason Evans 1851a4bd5210SJason Evans static int 18521f0a49e8SJason Evans arenas_initialized_ctl(tsd_t *tsd, const size_t *mib, size_t miblen, void *oldp, 1853a4bd5210SJason Evans size_t *oldlenp, void *newp, size_t newlen) 1854a4bd5210SJason Evans { 1855a4bd5210SJason Evans int ret; 1856a4bd5210SJason Evans unsigned nread, i; 1857a4bd5210SJason Evans 18581f0a49e8SJason Evans malloc_mutex_lock(tsd_tsdn(tsd), &ctl_mtx); 1859a4bd5210SJason Evans READONLY(); 186082872ac0SJason Evans if (*oldlenp != ctl_stats.narenas * sizeof(bool)) { 1861a4bd5210SJason Evans ret = EINVAL; 186282872ac0SJason Evans nread = (*oldlenp < ctl_stats.narenas * sizeof(bool)) 1863df0d881dSJason Evans ? (unsigned)(*oldlenp / sizeof(bool)) : ctl_stats.narenas; 1864a4bd5210SJason Evans } else { 1865a4bd5210SJason Evans ret = 0; 186682872ac0SJason Evans nread = ctl_stats.narenas; 1867a4bd5210SJason Evans } 1868a4bd5210SJason Evans 1869a4bd5210SJason Evans for (i = 0; i < nread; i++) 1870a4bd5210SJason Evans ((bool *)oldp)[i] = ctl_stats.arenas[i].initialized; 1871a4bd5210SJason Evans 1872a4bd5210SJason Evans label_return: 18731f0a49e8SJason Evans malloc_mutex_unlock(tsd_tsdn(tsd), &ctl_mtx); 1874a4bd5210SJason Evans return (ret); 1875a4bd5210SJason Evans } 1876a4bd5210SJason Evans 1877d0e79aa3SJason Evans static int 18781f0a49e8SJason Evans arenas_lg_dirty_mult_ctl(tsd_t *tsd, const size_t *mib, size_t miblen, 18791f0a49e8SJason Evans void *oldp, size_t *oldlenp, void *newp, size_t newlen) 1880d0e79aa3SJason Evans { 1881d0e79aa3SJason Evans int ret; 1882d0e79aa3SJason Evans 1883d0e79aa3SJason Evans if (oldp != NULL && oldlenp != NULL) { 1884d0e79aa3SJason Evans size_t oldval = arena_lg_dirty_mult_default_get(); 1885d0e79aa3SJason Evans READ(oldval, ssize_t); 1886d0e79aa3SJason Evans } 1887d0e79aa3SJason Evans if (newp != NULL) { 1888d0e79aa3SJason Evans if (newlen != sizeof(ssize_t)) { 1889d0e79aa3SJason Evans ret = EINVAL; 1890d0e79aa3SJason Evans goto label_return; 1891d0e79aa3SJason Evans } 1892d0e79aa3SJason Evans if (arena_lg_dirty_mult_default_set(*(ssize_t *)newp)) { 1893d0e79aa3SJason Evans ret = EFAULT; 1894d0e79aa3SJason Evans goto label_return; 1895d0e79aa3SJason Evans } 1896d0e79aa3SJason Evans } 1897d0e79aa3SJason Evans 1898d0e79aa3SJason Evans ret = 0; 1899d0e79aa3SJason Evans label_return: 1900d0e79aa3SJason Evans return (ret); 1901d0e79aa3SJason Evans } 1902d0e79aa3SJason Evans 1903df0d881dSJason Evans static int 19041f0a49e8SJason Evans arenas_decay_time_ctl(tsd_t *tsd, const size_t *mib, size_t miblen, void *oldp, 1905df0d881dSJason Evans size_t *oldlenp, void *newp, size_t newlen) 1906df0d881dSJason Evans { 1907df0d881dSJason Evans int ret; 1908df0d881dSJason Evans 1909df0d881dSJason Evans if (oldp != NULL && oldlenp != NULL) { 1910df0d881dSJason Evans size_t oldval = arena_decay_time_default_get(); 1911df0d881dSJason Evans READ(oldval, ssize_t); 1912df0d881dSJason Evans } 1913df0d881dSJason Evans if (newp != NULL) { 1914df0d881dSJason Evans if (newlen != sizeof(ssize_t)) { 1915df0d881dSJason Evans ret = EINVAL; 1916df0d881dSJason Evans goto label_return; 1917df0d881dSJason Evans } 1918df0d881dSJason Evans if (arena_decay_time_default_set(*(ssize_t *)newp)) { 1919df0d881dSJason Evans ret = EFAULT; 1920df0d881dSJason Evans goto label_return; 1921df0d881dSJason Evans } 1922df0d881dSJason Evans } 1923df0d881dSJason Evans 1924df0d881dSJason Evans ret = 0; 1925df0d881dSJason Evans label_return: 1926df0d881dSJason Evans return (ret); 1927df0d881dSJason Evans } 1928df0d881dSJason Evans 1929a4bd5210SJason Evans CTL_RO_NL_GEN(arenas_quantum, QUANTUM, size_t) 1930a4bd5210SJason Evans CTL_RO_NL_GEN(arenas_page, PAGE, size_t) 1931a4bd5210SJason Evans CTL_RO_NL_CGEN(config_tcache, arenas_tcache_max, tcache_maxclass, size_t) 1932a4bd5210SJason Evans CTL_RO_NL_GEN(arenas_nbins, NBINS, unsigned) 1933a4bd5210SJason Evans CTL_RO_NL_CGEN(config_tcache, arenas_nhbins, nhbins, unsigned) 1934f921d10fSJason Evans CTL_RO_NL_GEN(arenas_bin_i_size, arena_bin_info[mib[2]].reg_size, size_t) 1935f921d10fSJason Evans CTL_RO_NL_GEN(arenas_bin_i_nregs, arena_bin_info[mib[2]].nregs, uint32_t) 1936f921d10fSJason Evans CTL_RO_NL_GEN(arenas_bin_i_run_size, arena_bin_info[mib[2]].run_size, size_t) 1937f921d10fSJason Evans static const ctl_named_node_t * 19381f0a49e8SJason Evans arenas_bin_i_index(tsdn_t *tsdn, const size_t *mib, size_t miblen, size_t i) 1939f921d10fSJason Evans { 1940f921d10fSJason Evans 1941f921d10fSJason Evans if (i > NBINS) 1942f921d10fSJason Evans return (NULL); 1943f921d10fSJason Evans return (super_arenas_bin_i_node); 1944f921d10fSJason Evans } 1945f921d10fSJason Evans 1946d0e79aa3SJason Evans CTL_RO_NL_GEN(arenas_nlruns, nlclasses, unsigned) 1947df0d881dSJason Evans CTL_RO_NL_GEN(arenas_lrun_i_size, index2size(NBINS+(szind_t)mib[2]), size_t) 1948f921d10fSJason Evans static const ctl_named_node_t * 19491f0a49e8SJason Evans arenas_lrun_i_index(tsdn_t *tsdn, const size_t *mib, size_t miblen, size_t i) 1950f921d10fSJason Evans { 1951f921d10fSJason Evans 1952f921d10fSJason Evans if (i > nlclasses) 1953f921d10fSJason Evans return (NULL); 1954f921d10fSJason Evans return (super_arenas_lrun_i_node); 1955f921d10fSJason Evans } 1956a4bd5210SJason Evans 1957d0e79aa3SJason Evans CTL_RO_NL_GEN(arenas_nhchunks, nhclasses, unsigned) 1958df0d881dSJason Evans CTL_RO_NL_GEN(arenas_hchunk_i_size, index2size(NBINS+nlclasses+(szind_t)mib[2]), 1959df0d881dSJason Evans size_t) 1960d0e79aa3SJason Evans static const ctl_named_node_t * 19611f0a49e8SJason Evans arenas_hchunk_i_index(tsdn_t *tsdn, const size_t *mib, size_t miblen, size_t i) 1962a4bd5210SJason Evans { 1963a4bd5210SJason Evans 1964d0e79aa3SJason Evans if (i > nhclasses) 1965d0e79aa3SJason Evans return (NULL); 1966d0e79aa3SJason Evans return (super_arenas_hchunk_i_node); 196782872ac0SJason Evans } 196882872ac0SJason Evans 196982872ac0SJason Evans static int 19701f0a49e8SJason Evans arenas_extend_ctl(tsd_t *tsd, const size_t *mib, size_t miblen, void *oldp, 19711f0a49e8SJason Evans size_t *oldlenp, void *newp, size_t newlen) 197282872ac0SJason Evans { 197382872ac0SJason Evans int ret; 197488ad2f8dSJason Evans unsigned narenas; 197582872ac0SJason Evans 19761f0a49e8SJason Evans malloc_mutex_lock(tsd_tsdn(tsd), &ctl_mtx); 197782872ac0SJason Evans READONLY(); 19781f0a49e8SJason Evans if (ctl_grow(tsd_tsdn(tsd))) { 197982872ac0SJason Evans ret = EAGAIN; 1980a4bd5210SJason Evans goto label_return; 1981a4bd5210SJason Evans } 198288ad2f8dSJason Evans narenas = ctl_stats.narenas - 1; 198388ad2f8dSJason Evans READ(narenas, unsigned); 1984a4bd5210SJason Evans 1985a4bd5210SJason Evans ret = 0; 1986a4bd5210SJason Evans label_return: 19871f0a49e8SJason Evans malloc_mutex_unlock(tsd_tsdn(tsd), &ctl_mtx); 1988a4bd5210SJason Evans return (ret); 1989a4bd5210SJason Evans } 1990a4bd5210SJason Evans 1991a4bd5210SJason Evans /******************************************************************************/ 1992a4bd5210SJason Evans 1993a4bd5210SJason Evans static int 19941f0a49e8SJason Evans prof_thread_active_init_ctl(tsd_t *tsd, const size_t *mib, size_t miblen, 19951f0a49e8SJason Evans void *oldp, size_t *oldlenp, void *newp, size_t newlen) 19961f0a49e8SJason Evans { 19971f0a49e8SJason Evans int ret; 19981f0a49e8SJason Evans bool oldval; 19991f0a49e8SJason Evans 20001f0a49e8SJason Evans if (!config_prof) 20011f0a49e8SJason Evans return (ENOENT); 20021f0a49e8SJason Evans 20031f0a49e8SJason Evans if (newp != NULL) { 20041f0a49e8SJason Evans if (newlen != sizeof(bool)) { 20051f0a49e8SJason Evans ret = EINVAL; 20061f0a49e8SJason Evans goto label_return; 20071f0a49e8SJason Evans } 20081f0a49e8SJason Evans oldval = prof_thread_active_init_set(tsd_tsdn(tsd), 20091f0a49e8SJason Evans *(bool *)newp); 20101f0a49e8SJason Evans } else 20111f0a49e8SJason Evans oldval = prof_thread_active_init_get(tsd_tsdn(tsd)); 20121f0a49e8SJason Evans READ(oldval, bool); 20131f0a49e8SJason Evans 20141f0a49e8SJason Evans ret = 0; 20151f0a49e8SJason Evans label_return: 20161f0a49e8SJason Evans return (ret); 20171f0a49e8SJason Evans } 20181f0a49e8SJason Evans 20191f0a49e8SJason Evans static int 20201f0a49e8SJason Evans prof_active_ctl(tsd_t *tsd, const size_t *mib, size_t miblen, void *oldp, 2021d0e79aa3SJason Evans size_t *oldlenp, void *newp, size_t newlen) 2022d0e79aa3SJason Evans { 2023d0e79aa3SJason Evans int ret; 2024d0e79aa3SJason Evans bool oldval; 2025d0e79aa3SJason Evans 2026d0e79aa3SJason Evans if (!config_prof) 2027d0e79aa3SJason Evans return (ENOENT); 2028d0e79aa3SJason Evans 2029d0e79aa3SJason Evans if (newp != NULL) { 2030d0e79aa3SJason Evans if (newlen != sizeof(bool)) { 2031d0e79aa3SJason Evans ret = EINVAL; 2032d0e79aa3SJason Evans goto label_return; 2033d0e79aa3SJason Evans } 20341f0a49e8SJason Evans oldval = prof_active_set(tsd_tsdn(tsd), *(bool *)newp); 2035d0e79aa3SJason Evans } else 20361f0a49e8SJason Evans oldval = prof_active_get(tsd_tsdn(tsd)); 2037d0e79aa3SJason Evans READ(oldval, bool); 2038d0e79aa3SJason Evans 2039d0e79aa3SJason Evans ret = 0; 2040d0e79aa3SJason Evans label_return: 2041d0e79aa3SJason Evans return (ret); 2042d0e79aa3SJason Evans } 2043d0e79aa3SJason Evans 2044d0e79aa3SJason Evans static int 20451f0a49e8SJason Evans prof_dump_ctl(tsd_t *tsd, const size_t *mib, size_t miblen, void *oldp, 20461f0a49e8SJason Evans size_t *oldlenp, void *newp, size_t newlen) 2047a4bd5210SJason Evans { 2048a4bd5210SJason Evans int ret; 2049a4bd5210SJason Evans const char *filename = NULL; 2050a4bd5210SJason Evans 2051d0e79aa3SJason Evans if (!config_prof) 2052a4bd5210SJason Evans return (ENOENT); 2053a4bd5210SJason Evans 2054a4bd5210SJason Evans WRITEONLY(); 2055a4bd5210SJason Evans WRITE(filename, const char *); 2056a4bd5210SJason Evans 20571f0a49e8SJason Evans if (prof_mdump(tsd, filename)) { 2058a4bd5210SJason Evans ret = EFAULT; 2059a4bd5210SJason Evans goto label_return; 2060a4bd5210SJason Evans } 2061a4bd5210SJason Evans 2062a4bd5210SJason Evans ret = 0; 2063a4bd5210SJason Evans label_return: 2064a4bd5210SJason Evans return (ret); 2065a4bd5210SJason Evans } 2066a4bd5210SJason Evans 2067d0e79aa3SJason Evans static int 20681f0a49e8SJason Evans prof_gdump_ctl(tsd_t *tsd, const size_t *mib, size_t miblen, void *oldp, 20691f0a49e8SJason Evans size_t *oldlenp, void *newp, size_t newlen) 2070d0e79aa3SJason Evans { 2071d0e79aa3SJason Evans int ret; 2072d0e79aa3SJason Evans bool oldval; 2073d0e79aa3SJason Evans 2074d0e79aa3SJason Evans if (!config_prof) 2075d0e79aa3SJason Evans return (ENOENT); 2076d0e79aa3SJason Evans 2077d0e79aa3SJason Evans if (newp != NULL) { 2078d0e79aa3SJason Evans if (newlen != sizeof(bool)) { 2079d0e79aa3SJason Evans ret = EINVAL; 2080d0e79aa3SJason Evans goto label_return; 2081d0e79aa3SJason Evans } 20821f0a49e8SJason Evans oldval = prof_gdump_set(tsd_tsdn(tsd), *(bool *)newp); 2083d0e79aa3SJason Evans } else 20841f0a49e8SJason Evans oldval = prof_gdump_get(tsd_tsdn(tsd)); 2085d0e79aa3SJason Evans READ(oldval, bool); 2086d0e79aa3SJason Evans 2087d0e79aa3SJason Evans ret = 0; 2088d0e79aa3SJason Evans label_return: 2089d0e79aa3SJason Evans return (ret); 2090d0e79aa3SJason Evans } 2091d0e79aa3SJason Evans 2092d0e79aa3SJason Evans static int 20931f0a49e8SJason Evans prof_reset_ctl(tsd_t *tsd, const size_t *mib, size_t miblen, void *oldp, 20941f0a49e8SJason Evans size_t *oldlenp, void *newp, size_t newlen) 2095d0e79aa3SJason Evans { 2096d0e79aa3SJason Evans int ret; 2097d0e79aa3SJason Evans size_t lg_sample = lg_prof_sample; 2098d0e79aa3SJason Evans 2099d0e79aa3SJason Evans if (!config_prof) 2100d0e79aa3SJason Evans return (ENOENT); 2101d0e79aa3SJason Evans 2102d0e79aa3SJason Evans WRITEONLY(); 2103d0e79aa3SJason Evans WRITE(lg_sample, size_t); 2104d0e79aa3SJason Evans if (lg_sample >= (sizeof(uint64_t) << 3)) 2105d0e79aa3SJason Evans lg_sample = (sizeof(uint64_t) << 3) - 1; 2106d0e79aa3SJason Evans 2107bde95144SJason Evans prof_reset(tsd, lg_sample); 2108d0e79aa3SJason Evans 2109d0e79aa3SJason Evans ret = 0; 2110d0e79aa3SJason Evans label_return: 2111d0e79aa3SJason Evans return (ret); 2112d0e79aa3SJason Evans } 2113d0e79aa3SJason Evans 2114a4bd5210SJason Evans CTL_RO_NL_CGEN(config_prof, prof_interval, prof_interval, uint64_t) 2115d0e79aa3SJason Evans CTL_RO_NL_CGEN(config_prof, lg_prof_sample, lg_prof_sample, size_t) 2116a4bd5210SJason Evans 2117a4bd5210SJason Evans /******************************************************************************/ 2118a4bd5210SJason Evans 2119f921d10fSJason Evans CTL_RO_CGEN(config_stats, stats_cactive, &stats_cactive, size_t *) 2120f921d10fSJason Evans CTL_RO_CGEN(config_stats, stats_allocated, ctl_stats.allocated, size_t) 2121f921d10fSJason Evans CTL_RO_CGEN(config_stats, stats_active, ctl_stats.active, size_t) 2122d0e79aa3SJason Evans CTL_RO_CGEN(config_stats, stats_metadata, ctl_stats.metadata, size_t) 2123d0e79aa3SJason Evans CTL_RO_CGEN(config_stats, stats_resident, ctl_stats.resident, size_t) 2124f921d10fSJason Evans CTL_RO_CGEN(config_stats, stats_mapped, ctl_stats.mapped, size_t) 21251f0a49e8SJason Evans CTL_RO_CGEN(config_stats, stats_retained, ctl_stats.retained, size_t) 2126f921d10fSJason Evans 2127f921d10fSJason Evans CTL_RO_GEN(stats_arenas_i_dss, ctl_stats.arenas[mib[2]].dss, const char *) 2128d0e79aa3SJason Evans CTL_RO_GEN(stats_arenas_i_lg_dirty_mult, ctl_stats.arenas[mib[2]].lg_dirty_mult, 2129d0e79aa3SJason Evans ssize_t) 2130df0d881dSJason Evans CTL_RO_GEN(stats_arenas_i_decay_time, ctl_stats.arenas[mib[2]].decay_time, 2131df0d881dSJason Evans ssize_t) 2132f921d10fSJason Evans CTL_RO_GEN(stats_arenas_i_nthreads, ctl_stats.arenas[mib[2]].nthreads, unsigned) 2133f921d10fSJason Evans CTL_RO_GEN(stats_arenas_i_pactive, ctl_stats.arenas[mib[2]].pactive, size_t) 2134f921d10fSJason Evans CTL_RO_GEN(stats_arenas_i_pdirty, ctl_stats.arenas[mib[2]].pdirty, size_t) 2135f921d10fSJason Evans CTL_RO_CGEN(config_stats, stats_arenas_i_mapped, 2136f921d10fSJason Evans ctl_stats.arenas[mib[2]].astats.mapped, size_t) 21371f0a49e8SJason Evans CTL_RO_CGEN(config_stats, stats_arenas_i_retained, 21381f0a49e8SJason Evans ctl_stats.arenas[mib[2]].astats.retained, size_t) 2139f921d10fSJason Evans CTL_RO_CGEN(config_stats, stats_arenas_i_npurge, 2140f921d10fSJason Evans ctl_stats.arenas[mib[2]].astats.npurge, uint64_t) 2141f921d10fSJason Evans CTL_RO_CGEN(config_stats, stats_arenas_i_nmadvise, 2142f921d10fSJason Evans ctl_stats.arenas[mib[2]].astats.nmadvise, uint64_t) 2143f921d10fSJason Evans CTL_RO_CGEN(config_stats, stats_arenas_i_purged, 2144f921d10fSJason Evans ctl_stats.arenas[mib[2]].astats.purged, uint64_t) 2145d0e79aa3SJason Evans CTL_RO_CGEN(config_stats, stats_arenas_i_metadata_mapped, 2146d0e79aa3SJason Evans ctl_stats.arenas[mib[2]].astats.metadata_mapped, size_t) 2147d0e79aa3SJason Evans CTL_RO_CGEN(config_stats, stats_arenas_i_metadata_allocated, 2148d0e79aa3SJason Evans ctl_stats.arenas[mib[2]].astats.metadata_allocated, size_t) 2149f921d10fSJason Evans 2150a4bd5210SJason Evans CTL_RO_CGEN(config_stats, stats_arenas_i_small_allocated, 2151a4bd5210SJason Evans ctl_stats.arenas[mib[2]].allocated_small, size_t) 2152a4bd5210SJason Evans CTL_RO_CGEN(config_stats, stats_arenas_i_small_nmalloc, 2153a4bd5210SJason Evans ctl_stats.arenas[mib[2]].nmalloc_small, uint64_t) 2154a4bd5210SJason Evans CTL_RO_CGEN(config_stats, stats_arenas_i_small_ndalloc, 2155a4bd5210SJason Evans ctl_stats.arenas[mib[2]].ndalloc_small, uint64_t) 2156a4bd5210SJason Evans CTL_RO_CGEN(config_stats, stats_arenas_i_small_nrequests, 2157a4bd5210SJason Evans ctl_stats.arenas[mib[2]].nrequests_small, uint64_t) 2158a4bd5210SJason Evans CTL_RO_CGEN(config_stats, stats_arenas_i_large_allocated, 2159a4bd5210SJason Evans ctl_stats.arenas[mib[2]].astats.allocated_large, size_t) 2160a4bd5210SJason Evans CTL_RO_CGEN(config_stats, stats_arenas_i_large_nmalloc, 2161a4bd5210SJason Evans ctl_stats.arenas[mib[2]].astats.nmalloc_large, uint64_t) 2162a4bd5210SJason Evans CTL_RO_CGEN(config_stats, stats_arenas_i_large_ndalloc, 2163a4bd5210SJason Evans ctl_stats.arenas[mib[2]].astats.ndalloc_large, uint64_t) 2164a4bd5210SJason Evans CTL_RO_CGEN(config_stats, stats_arenas_i_large_nrequests, 2165a4bd5210SJason Evans ctl_stats.arenas[mib[2]].astats.nrequests_large, uint64_t) 2166d0e79aa3SJason Evans CTL_RO_CGEN(config_stats, stats_arenas_i_huge_allocated, 2167d0e79aa3SJason Evans ctl_stats.arenas[mib[2]].astats.allocated_huge, size_t) 2168d0e79aa3SJason Evans CTL_RO_CGEN(config_stats, stats_arenas_i_huge_nmalloc, 2169d0e79aa3SJason Evans ctl_stats.arenas[mib[2]].astats.nmalloc_huge, uint64_t) 2170d0e79aa3SJason Evans CTL_RO_CGEN(config_stats, stats_arenas_i_huge_ndalloc, 2171d0e79aa3SJason Evans ctl_stats.arenas[mib[2]].astats.ndalloc_huge, uint64_t) 2172d0e79aa3SJason Evans CTL_RO_CGEN(config_stats, stats_arenas_i_huge_nrequests, 2173d0e79aa3SJason Evans ctl_stats.arenas[mib[2]].astats.nmalloc_huge, uint64_t) /* Intentional. */ 2174a4bd5210SJason Evans 2175a4bd5210SJason Evans CTL_RO_CGEN(config_stats, stats_arenas_i_bins_j_nmalloc, 2176a4bd5210SJason Evans ctl_stats.arenas[mib[2]].bstats[mib[4]].nmalloc, uint64_t) 2177a4bd5210SJason Evans CTL_RO_CGEN(config_stats, stats_arenas_i_bins_j_ndalloc, 2178a4bd5210SJason Evans ctl_stats.arenas[mib[2]].bstats[mib[4]].ndalloc, uint64_t) 2179a4bd5210SJason Evans CTL_RO_CGEN(config_stats, stats_arenas_i_bins_j_nrequests, 2180a4bd5210SJason Evans ctl_stats.arenas[mib[2]].bstats[mib[4]].nrequests, uint64_t) 2181d0e79aa3SJason Evans CTL_RO_CGEN(config_stats, stats_arenas_i_bins_j_curregs, 2182d0e79aa3SJason Evans ctl_stats.arenas[mib[2]].bstats[mib[4]].curregs, size_t) 2183a4bd5210SJason Evans CTL_RO_CGEN(config_stats && config_tcache, stats_arenas_i_bins_j_nfills, 2184a4bd5210SJason Evans ctl_stats.arenas[mib[2]].bstats[mib[4]].nfills, uint64_t) 2185a4bd5210SJason Evans CTL_RO_CGEN(config_stats && config_tcache, stats_arenas_i_bins_j_nflushes, 2186a4bd5210SJason Evans ctl_stats.arenas[mib[2]].bstats[mib[4]].nflushes, uint64_t) 2187a4bd5210SJason Evans CTL_RO_CGEN(config_stats, stats_arenas_i_bins_j_nruns, 2188a4bd5210SJason Evans ctl_stats.arenas[mib[2]].bstats[mib[4]].nruns, uint64_t) 2189a4bd5210SJason Evans CTL_RO_CGEN(config_stats, stats_arenas_i_bins_j_nreruns, 2190a4bd5210SJason Evans ctl_stats.arenas[mib[2]].bstats[mib[4]].reruns, uint64_t) 2191a4bd5210SJason Evans CTL_RO_CGEN(config_stats, stats_arenas_i_bins_j_curruns, 2192a4bd5210SJason Evans ctl_stats.arenas[mib[2]].bstats[mib[4]].curruns, size_t) 2193a4bd5210SJason Evans 219482872ac0SJason Evans static const ctl_named_node_t * 21951f0a49e8SJason Evans stats_arenas_i_bins_j_index(tsdn_t *tsdn, const size_t *mib, size_t miblen, 21961f0a49e8SJason Evans size_t j) 2197a4bd5210SJason Evans { 2198a4bd5210SJason Evans 2199a4bd5210SJason Evans if (j > NBINS) 2200a4bd5210SJason Evans return (NULL); 2201a4bd5210SJason Evans return (super_stats_arenas_i_bins_j_node); 2202a4bd5210SJason Evans } 2203a4bd5210SJason Evans 2204a4bd5210SJason Evans CTL_RO_CGEN(config_stats, stats_arenas_i_lruns_j_nmalloc, 2205a4bd5210SJason Evans ctl_stats.arenas[mib[2]].lstats[mib[4]].nmalloc, uint64_t) 2206a4bd5210SJason Evans CTL_RO_CGEN(config_stats, stats_arenas_i_lruns_j_ndalloc, 2207a4bd5210SJason Evans ctl_stats.arenas[mib[2]].lstats[mib[4]].ndalloc, uint64_t) 2208a4bd5210SJason Evans CTL_RO_CGEN(config_stats, stats_arenas_i_lruns_j_nrequests, 2209a4bd5210SJason Evans ctl_stats.arenas[mib[2]].lstats[mib[4]].nrequests, uint64_t) 2210a4bd5210SJason Evans CTL_RO_CGEN(config_stats, stats_arenas_i_lruns_j_curruns, 2211a4bd5210SJason Evans ctl_stats.arenas[mib[2]].lstats[mib[4]].curruns, size_t) 2212a4bd5210SJason Evans 221382872ac0SJason Evans static const ctl_named_node_t * 22141f0a49e8SJason Evans stats_arenas_i_lruns_j_index(tsdn_t *tsdn, const size_t *mib, size_t miblen, 22151f0a49e8SJason Evans size_t j) 2216a4bd5210SJason Evans { 2217a4bd5210SJason Evans 2218a4bd5210SJason Evans if (j > nlclasses) 2219a4bd5210SJason Evans return (NULL); 2220a4bd5210SJason Evans return (super_stats_arenas_i_lruns_j_node); 2221a4bd5210SJason Evans } 2222a4bd5210SJason Evans 2223d0e79aa3SJason Evans CTL_RO_CGEN(config_stats, stats_arenas_i_hchunks_j_nmalloc, 2224d0e79aa3SJason Evans ctl_stats.arenas[mib[2]].hstats[mib[4]].nmalloc, uint64_t) 2225d0e79aa3SJason Evans CTL_RO_CGEN(config_stats, stats_arenas_i_hchunks_j_ndalloc, 2226d0e79aa3SJason Evans ctl_stats.arenas[mib[2]].hstats[mib[4]].ndalloc, uint64_t) 2227d0e79aa3SJason Evans CTL_RO_CGEN(config_stats, stats_arenas_i_hchunks_j_nrequests, 2228d0e79aa3SJason Evans ctl_stats.arenas[mib[2]].hstats[mib[4]].nmalloc, /* Intentional. */ 2229d0e79aa3SJason Evans uint64_t) 2230d0e79aa3SJason Evans CTL_RO_CGEN(config_stats, stats_arenas_i_hchunks_j_curhchunks, 2231d0e79aa3SJason Evans ctl_stats.arenas[mib[2]].hstats[mib[4]].curhchunks, size_t) 2232d0e79aa3SJason Evans 2233d0e79aa3SJason Evans static const ctl_named_node_t * 22341f0a49e8SJason Evans stats_arenas_i_hchunks_j_index(tsdn_t *tsdn, const size_t *mib, size_t miblen, 22351f0a49e8SJason Evans size_t j) 2236d0e79aa3SJason Evans { 2237d0e79aa3SJason Evans 2238d0e79aa3SJason Evans if (j > nhclasses) 2239d0e79aa3SJason Evans return (NULL); 2240d0e79aa3SJason Evans return (super_stats_arenas_i_hchunks_j_node); 2241d0e79aa3SJason Evans } 2242d0e79aa3SJason Evans 224382872ac0SJason Evans static const ctl_named_node_t * 22441f0a49e8SJason Evans stats_arenas_i_index(tsdn_t *tsdn, const size_t *mib, size_t miblen, size_t i) 2245a4bd5210SJason Evans { 2246e722f8f8SJason Evans const ctl_named_node_t * ret; 2247a4bd5210SJason Evans 22481f0a49e8SJason Evans malloc_mutex_lock(tsdn, &ctl_mtx); 2249d0e79aa3SJason Evans if (i > ctl_stats.narenas || !ctl_stats.arenas[i].initialized) { 2250a4bd5210SJason Evans ret = NULL; 2251a4bd5210SJason Evans goto label_return; 2252a4bd5210SJason Evans } 2253a4bd5210SJason Evans 2254a4bd5210SJason Evans ret = super_stats_arenas_i_node; 2255a4bd5210SJason Evans label_return: 22561f0a49e8SJason Evans malloc_mutex_unlock(tsdn, &ctl_mtx); 2257a4bd5210SJason Evans return (ret); 2258a4bd5210SJason Evans } 2259