ctl.c revision 296221
1234370Sjasone#define JEMALLOC_CTL_C_ 2234370Sjasone#include "jemalloc/internal/jemalloc_internal.h" 3234370Sjasone 4234370Sjasone/******************************************************************************/ 5234370Sjasone/* Data. */ 6234370Sjasone 7234370Sjasone/* 8234370Sjasone * ctl_mtx protects the following: 9234370Sjasone * - ctl_stats.* 10234370Sjasone */ 11234370Sjasonestatic malloc_mutex_t ctl_mtx; 12234370Sjasonestatic bool ctl_initialized; 13234370Sjasonestatic uint64_t ctl_epoch; 14234370Sjasonestatic ctl_stats_t ctl_stats; 15234370Sjasone 16234370Sjasone/******************************************************************************/ 17235238Sjasone/* Helpers for named and indexed nodes. */ 18235238Sjasone 19286866SjasoneJEMALLOC_INLINE_C const ctl_named_node_t * 20235238Sjasonectl_named_node(const ctl_node_t *node) 21235238Sjasone{ 22235238Sjasone 23235238Sjasone return ((node->named) ? (const ctl_named_node_t *)node : NULL); 24235238Sjasone} 25235238Sjasone 26286866SjasoneJEMALLOC_INLINE_C const ctl_named_node_t * 27296221Sjasonectl_named_children(const ctl_named_node_t *node, size_t index) 28235238Sjasone{ 29235238Sjasone const ctl_named_node_t *children = ctl_named_node(node->children); 30235238Sjasone 31235238Sjasone return (children ? &children[index] : NULL); 32235238Sjasone} 33235238Sjasone 34286866SjasoneJEMALLOC_INLINE_C const ctl_indexed_node_t * 35235238Sjasonectl_indexed_node(const ctl_node_t *node) 36235238Sjasone{ 37235238Sjasone 38286866Sjasone return (!node->named ? (const ctl_indexed_node_t *)node : NULL); 39235238Sjasone} 40235238Sjasone 41235238Sjasone/******************************************************************************/ 42234370Sjasone/* Function prototypes for non-inline static functions. */ 43234370Sjasone 44234370Sjasone#define CTL_PROTO(n) \ 45234370Sjasonestatic int n##_ctl(const size_t *mib, size_t miblen, void *oldp, \ 46234370Sjasone size_t *oldlenp, void *newp, size_t newlen); 47234370Sjasone 48234370Sjasone#define INDEX_PROTO(n) \ 49242844Sjasonestatic const ctl_named_node_t *n##_index(const size_t *mib, \ 50242844Sjasone size_t miblen, size_t i); 51234370Sjasone 52234370Sjasonestatic bool ctl_arena_init(ctl_arena_stats_t *astats); 53234370Sjasonestatic void ctl_arena_clear(ctl_arena_stats_t *astats); 54234370Sjasonestatic void ctl_arena_stats_amerge(ctl_arena_stats_t *cstats, 55234370Sjasone arena_t *arena); 56234370Sjasonestatic void ctl_arena_stats_smerge(ctl_arena_stats_t *sstats, 57234370Sjasone ctl_arena_stats_t *astats); 58234370Sjasonestatic void ctl_arena_refresh(arena_t *arena, unsigned i); 59242844Sjasonestatic bool ctl_grow(void); 60234370Sjasonestatic void ctl_refresh(void); 61234370Sjasonestatic bool ctl_init(void); 62234370Sjasonestatic int ctl_lookup(const char *name, ctl_node_t const **nodesp, 63234370Sjasone size_t *mibp, size_t *depthp); 64234370Sjasone 65234370SjasoneCTL_PROTO(version) 66234370SjasoneCTL_PROTO(epoch) 67234370SjasoneCTL_PROTO(thread_tcache_enabled) 68234370SjasoneCTL_PROTO(thread_tcache_flush) 69286866SjasoneCTL_PROTO(thread_prof_name) 70286866SjasoneCTL_PROTO(thread_prof_active) 71234370SjasoneCTL_PROTO(thread_arena) 72234370SjasoneCTL_PROTO(thread_allocated) 73234370SjasoneCTL_PROTO(thread_allocatedp) 74234370SjasoneCTL_PROTO(thread_deallocated) 75234370SjasoneCTL_PROTO(thread_deallocatedp) 76286866SjasoneCTL_PROTO(config_cache_oblivious) 77234370SjasoneCTL_PROTO(config_debug) 78234370SjasoneCTL_PROTO(config_fill) 79234370SjasoneCTL_PROTO(config_lazy_lock) 80296221SjasoneCTL_PROTO(config_malloc_conf) 81234370SjasoneCTL_PROTO(config_munmap) 82234370SjasoneCTL_PROTO(config_prof) 83234370SjasoneCTL_PROTO(config_prof_libgcc) 84234370SjasoneCTL_PROTO(config_prof_libunwind) 85234370SjasoneCTL_PROTO(config_stats) 86234370SjasoneCTL_PROTO(config_tcache) 87234370SjasoneCTL_PROTO(config_tls) 88234370SjasoneCTL_PROTO(config_utrace) 89234370SjasoneCTL_PROTO(config_valgrind) 90234370SjasoneCTL_PROTO(config_xmalloc) 91234370SjasoneCTL_PROTO(opt_abort) 92242844SjasoneCTL_PROTO(opt_dss) 93234370SjasoneCTL_PROTO(opt_lg_chunk) 94234370SjasoneCTL_PROTO(opt_narenas) 95296221SjasoneCTL_PROTO(opt_purge) 96234370SjasoneCTL_PROTO(opt_lg_dirty_mult) 97296221SjasoneCTL_PROTO(opt_decay_time) 98234370SjasoneCTL_PROTO(opt_stats_print) 99234370SjasoneCTL_PROTO(opt_junk) 100234370SjasoneCTL_PROTO(opt_zero) 101234370SjasoneCTL_PROTO(opt_quarantine) 102234370SjasoneCTL_PROTO(opt_redzone) 103234370SjasoneCTL_PROTO(opt_utrace) 104234370SjasoneCTL_PROTO(opt_xmalloc) 105234370SjasoneCTL_PROTO(opt_tcache) 106234370SjasoneCTL_PROTO(opt_lg_tcache_max) 107234370SjasoneCTL_PROTO(opt_prof) 108234370SjasoneCTL_PROTO(opt_prof_prefix) 109234370SjasoneCTL_PROTO(opt_prof_active) 110286866SjasoneCTL_PROTO(opt_prof_thread_active_init) 111234370SjasoneCTL_PROTO(opt_lg_prof_sample) 112234370SjasoneCTL_PROTO(opt_lg_prof_interval) 113234370SjasoneCTL_PROTO(opt_prof_gdump) 114234543SjasoneCTL_PROTO(opt_prof_final) 115234370SjasoneCTL_PROTO(opt_prof_leak) 116234370SjasoneCTL_PROTO(opt_prof_accum) 117286866SjasoneCTL_PROTO(tcache_create) 118286866SjasoneCTL_PROTO(tcache_flush) 119286866SjasoneCTL_PROTO(tcache_destroy) 120296221Sjasonestatic void arena_i_purge(unsigned arena_ind, bool all); 121242844SjasoneCTL_PROTO(arena_i_purge) 122296221SjasoneCTL_PROTO(arena_i_decay) 123242844SjasoneCTL_PROTO(arena_i_dss) 124286866SjasoneCTL_PROTO(arena_i_lg_dirty_mult) 125296221SjasoneCTL_PROTO(arena_i_decay_time) 126286866SjasoneCTL_PROTO(arena_i_chunk_hooks) 127242844SjasoneINDEX_PROTO(arena_i) 128234370SjasoneCTL_PROTO(arenas_bin_i_size) 129234370SjasoneCTL_PROTO(arenas_bin_i_nregs) 130234370SjasoneCTL_PROTO(arenas_bin_i_run_size) 131234370SjasoneINDEX_PROTO(arenas_bin_i) 132234370SjasoneCTL_PROTO(arenas_lrun_i_size) 133234370SjasoneINDEX_PROTO(arenas_lrun_i) 134286866SjasoneCTL_PROTO(arenas_hchunk_i_size) 135286866SjasoneINDEX_PROTO(arenas_hchunk_i) 136234370SjasoneCTL_PROTO(arenas_narenas) 137234370SjasoneCTL_PROTO(arenas_initialized) 138286866SjasoneCTL_PROTO(arenas_lg_dirty_mult) 139296221SjasoneCTL_PROTO(arenas_decay_time) 140234370SjasoneCTL_PROTO(arenas_quantum) 141234370SjasoneCTL_PROTO(arenas_page) 142234370SjasoneCTL_PROTO(arenas_tcache_max) 143234370SjasoneCTL_PROTO(arenas_nbins) 144234370SjasoneCTL_PROTO(arenas_nhbins) 145234370SjasoneCTL_PROTO(arenas_nlruns) 146286866SjasoneCTL_PROTO(arenas_nhchunks) 147242844SjasoneCTL_PROTO(arenas_extend) 148286866SjasoneCTL_PROTO(prof_thread_active_init) 149234370SjasoneCTL_PROTO(prof_active) 150234370SjasoneCTL_PROTO(prof_dump) 151286866SjasoneCTL_PROTO(prof_gdump) 152286866SjasoneCTL_PROTO(prof_reset) 153234370SjasoneCTL_PROTO(prof_interval) 154286866SjasoneCTL_PROTO(lg_prof_sample) 155234370SjasoneCTL_PROTO(stats_arenas_i_small_allocated) 156234370SjasoneCTL_PROTO(stats_arenas_i_small_nmalloc) 157234370SjasoneCTL_PROTO(stats_arenas_i_small_ndalloc) 158234370SjasoneCTL_PROTO(stats_arenas_i_small_nrequests) 159234370SjasoneCTL_PROTO(stats_arenas_i_large_allocated) 160234370SjasoneCTL_PROTO(stats_arenas_i_large_nmalloc) 161234370SjasoneCTL_PROTO(stats_arenas_i_large_ndalloc) 162234370SjasoneCTL_PROTO(stats_arenas_i_large_nrequests) 163286866SjasoneCTL_PROTO(stats_arenas_i_huge_allocated) 164286866SjasoneCTL_PROTO(stats_arenas_i_huge_nmalloc) 165286866SjasoneCTL_PROTO(stats_arenas_i_huge_ndalloc) 166286866SjasoneCTL_PROTO(stats_arenas_i_huge_nrequests) 167234370SjasoneCTL_PROTO(stats_arenas_i_bins_j_nmalloc) 168234370SjasoneCTL_PROTO(stats_arenas_i_bins_j_ndalloc) 169234370SjasoneCTL_PROTO(stats_arenas_i_bins_j_nrequests) 170286866SjasoneCTL_PROTO(stats_arenas_i_bins_j_curregs) 171234370SjasoneCTL_PROTO(stats_arenas_i_bins_j_nfills) 172234370SjasoneCTL_PROTO(stats_arenas_i_bins_j_nflushes) 173234370SjasoneCTL_PROTO(stats_arenas_i_bins_j_nruns) 174234370SjasoneCTL_PROTO(stats_arenas_i_bins_j_nreruns) 175234370SjasoneCTL_PROTO(stats_arenas_i_bins_j_curruns) 176234370SjasoneINDEX_PROTO(stats_arenas_i_bins_j) 177234370SjasoneCTL_PROTO(stats_arenas_i_lruns_j_nmalloc) 178234370SjasoneCTL_PROTO(stats_arenas_i_lruns_j_ndalloc) 179234370SjasoneCTL_PROTO(stats_arenas_i_lruns_j_nrequests) 180234370SjasoneCTL_PROTO(stats_arenas_i_lruns_j_curruns) 181234370SjasoneINDEX_PROTO(stats_arenas_i_lruns_j) 182286866SjasoneCTL_PROTO(stats_arenas_i_hchunks_j_nmalloc) 183286866SjasoneCTL_PROTO(stats_arenas_i_hchunks_j_ndalloc) 184286866SjasoneCTL_PROTO(stats_arenas_i_hchunks_j_nrequests) 185286866SjasoneCTL_PROTO(stats_arenas_i_hchunks_j_curhchunks) 186286866SjasoneINDEX_PROTO(stats_arenas_i_hchunks_j) 187234370SjasoneCTL_PROTO(stats_arenas_i_nthreads) 188242844SjasoneCTL_PROTO(stats_arenas_i_dss) 189286866SjasoneCTL_PROTO(stats_arenas_i_lg_dirty_mult) 190296221SjasoneCTL_PROTO(stats_arenas_i_decay_time) 191234370SjasoneCTL_PROTO(stats_arenas_i_pactive) 192234370SjasoneCTL_PROTO(stats_arenas_i_pdirty) 193234370SjasoneCTL_PROTO(stats_arenas_i_mapped) 194234370SjasoneCTL_PROTO(stats_arenas_i_npurge) 195234370SjasoneCTL_PROTO(stats_arenas_i_nmadvise) 196234370SjasoneCTL_PROTO(stats_arenas_i_purged) 197286866SjasoneCTL_PROTO(stats_arenas_i_metadata_mapped) 198286866SjasoneCTL_PROTO(stats_arenas_i_metadata_allocated) 199234370SjasoneINDEX_PROTO(stats_arenas_i) 200234370SjasoneCTL_PROTO(stats_cactive) 201234370SjasoneCTL_PROTO(stats_allocated) 202234370SjasoneCTL_PROTO(stats_active) 203286866SjasoneCTL_PROTO(stats_metadata) 204286866SjasoneCTL_PROTO(stats_resident) 205234370SjasoneCTL_PROTO(stats_mapped) 206234370Sjasone 207234370Sjasone/******************************************************************************/ 208234370Sjasone/* mallctl tree. */ 209234370Sjasone 210234370Sjasone/* Maximum tree depth. */ 211234370Sjasone#define CTL_MAX_DEPTH 6 212234370Sjasone 213235238Sjasone#define NAME(n) {true}, n 214235238Sjasone#define CHILD(t, c) \ 215235238Sjasone sizeof(c##_node) / sizeof(ctl_##t##_node_t), \ 216235238Sjasone (ctl_node_t *)c##_node, \ 217235238Sjasone NULL 218235238Sjasone#define CTL(c) 0, NULL, c##_ctl 219234370Sjasone 220234370Sjasone/* 221234370Sjasone * Only handles internal indexed nodes, since there are currently no external 222234370Sjasone * ones. 223234370Sjasone */ 224235238Sjasone#define INDEX(i) {false}, i##_index 225234370Sjasone 226286866Sjasonestatic const ctl_named_node_t thread_tcache_node[] = { 227234370Sjasone {NAME("enabled"), CTL(thread_tcache_enabled)}, 228234370Sjasone {NAME("flush"), CTL(thread_tcache_flush)} 229234370Sjasone}; 230234370Sjasone 231286866Sjasonestatic const ctl_named_node_t thread_prof_node[] = { 232286866Sjasone {NAME("name"), CTL(thread_prof_name)}, 233286866Sjasone {NAME("active"), CTL(thread_prof_active)} 234286866Sjasone}; 235286866Sjasone 236235238Sjasonestatic const ctl_named_node_t thread_node[] = { 237234370Sjasone {NAME("arena"), CTL(thread_arena)}, 238234370Sjasone {NAME("allocated"), CTL(thread_allocated)}, 239234370Sjasone {NAME("allocatedp"), CTL(thread_allocatedp)}, 240234370Sjasone {NAME("deallocated"), CTL(thread_deallocated)}, 241234370Sjasone {NAME("deallocatedp"), CTL(thread_deallocatedp)}, 242286866Sjasone {NAME("tcache"), CHILD(named, thread_tcache)}, 243286866Sjasone {NAME("prof"), CHILD(named, thread_prof)} 244234370Sjasone}; 245234370Sjasone 246235238Sjasonestatic const ctl_named_node_t config_node[] = { 247286866Sjasone {NAME("cache_oblivious"), CTL(config_cache_oblivious)}, 248286866Sjasone {NAME("debug"), CTL(config_debug)}, 249286866Sjasone {NAME("fill"), CTL(config_fill)}, 250286866Sjasone {NAME("lazy_lock"), CTL(config_lazy_lock)}, 251296221Sjasone {NAME("malloc_conf"), CTL(config_malloc_conf)}, 252286866Sjasone {NAME("munmap"), CTL(config_munmap)}, 253286866Sjasone {NAME("prof"), CTL(config_prof)}, 254286866Sjasone {NAME("prof_libgcc"), CTL(config_prof_libgcc)}, 255286866Sjasone {NAME("prof_libunwind"), CTL(config_prof_libunwind)}, 256286866Sjasone {NAME("stats"), CTL(config_stats)}, 257286866Sjasone {NAME("tcache"), CTL(config_tcache)}, 258286866Sjasone {NAME("tls"), CTL(config_tls)}, 259286866Sjasone {NAME("utrace"), CTL(config_utrace)}, 260286866Sjasone {NAME("valgrind"), CTL(config_valgrind)}, 261286866Sjasone {NAME("xmalloc"), CTL(config_xmalloc)} 262234370Sjasone}; 263234370Sjasone 264235238Sjasonestatic const ctl_named_node_t opt_node[] = { 265286866Sjasone {NAME("abort"), CTL(opt_abort)}, 266286866Sjasone {NAME("dss"), CTL(opt_dss)}, 267286866Sjasone {NAME("lg_chunk"), CTL(opt_lg_chunk)}, 268286866Sjasone {NAME("narenas"), CTL(opt_narenas)}, 269296221Sjasone {NAME("purge"), CTL(opt_purge)}, 270286866Sjasone {NAME("lg_dirty_mult"), CTL(opt_lg_dirty_mult)}, 271296221Sjasone {NAME("decay_time"), CTL(opt_decay_time)}, 272286866Sjasone {NAME("stats_print"), CTL(opt_stats_print)}, 273286866Sjasone {NAME("junk"), CTL(opt_junk)}, 274286866Sjasone {NAME("zero"), CTL(opt_zero)}, 275286866Sjasone {NAME("quarantine"), CTL(opt_quarantine)}, 276286866Sjasone {NAME("redzone"), CTL(opt_redzone)}, 277286866Sjasone {NAME("utrace"), CTL(opt_utrace)}, 278286866Sjasone {NAME("xmalloc"), CTL(opt_xmalloc)}, 279286866Sjasone {NAME("tcache"), CTL(opt_tcache)}, 280286866Sjasone {NAME("lg_tcache_max"), CTL(opt_lg_tcache_max)}, 281286866Sjasone {NAME("prof"), CTL(opt_prof)}, 282286866Sjasone {NAME("prof_prefix"), CTL(opt_prof_prefix)}, 283286866Sjasone {NAME("prof_active"), CTL(opt_prof_active)}, 284286866Sjasone {NAME("prof_thread_active_init"), CTL(opt_prof_thread_active_init)}, 285286866Sjasone {NAME("lg_prof_sample"), CTL(opt_lg_prof_sample)}, 286286866Sjasone {NAME("lg_prof_interval"), CTL(opt_lg_prof_interval)}, 287286866Sjasone {NAME("prof_gdump"), CTL(opt_prof_gdump)}, 288286866Sjasone {NAME("prof_final"), CTL(opt_prof_final)}, 289286866Sjasone {NAME("prof_leak"), CTL(opt_prof_leak)}, 290286866Sjasone {NAME("prof_accum"), CTL(opt_prof_accum)} 291234370Sjasone}; 292234370Sjasone 293286866Sjasonestatic const ctl_named_node_t tcache_node[] = { 294286866Sjasone {NAME("create"), CTL(tcache_create)}, 295286866Sjasone {NAME("flush"), CTL(tcache_flush)}, 296286866Sjasone {NAME("destroy"), CTL(tcache_destroy)} 297286866Sjasone}; 298286866Sjasone 299242844Sjasonestatic const ctl_named_node_t arena_i_node[] = { 300286866Sjasone {NAME("purge"), CTL(arena_i_purge)}, 301296221Sjasone {NAME("decay"), CTL(arena_i_decay)}, 302286866Sjasone {NAME("dss"), CTL(arena_i_dss)}, 303286866Sjasone {NAME("lg_dirty_mult"), CTL(arena_i_lg_dirty_mult)}, 304296221Sjasone {NAME("decay_time"), CTL(arena_i_decay_time)}, 305286866Sjasone {NAME("chunk_hooks"), CTL(arena_i_chunk_hooks)} 306242844Sjasone}; 307242844Sjasonestatic const ctl_named_node_t super_arena_i_node[] = { 308286866Sjasone {NAME(""), CHILD(named, arena_i)} 309242844Sjasone}; 310242844Sjasone 311242844Sjasonestatic const ctl_indexed_node_t arena_node[] = { 312242844Sjasone {INDEX(arena_i)} 313242844Sjasone}; 314242844Sjasone 315235238Sjasonestatic const ctl_named_node_t arenas_bin_i_node[] = { 316286866Sjasone {NAME("size"), CTL(arenas_bin_i_size)}, 317286866Sjasone {NAME("nregs"), CTL(arenas_bin_i_nregs)}, 318286866Sjasone {NAME("run_size"), CTL(arenas_bin_i_run_size)} 319234370Sjasone}; 320235238Sjasonestatic const ctl_named_node_t super_arenas_bin_i_node[] = { 321286866Sjasone {NAME(""), CHILD(named, arenas_bin_i)} 322234370Sjasone}; 323234370Sjasone 324235238Sjasonestatic const ctl_indexed_node_t arenas_bin_node[] = { 325234370Sjasone {INDEX(arenas_bin_i)} 326234370Sjasone}; 327234370Sjasone 328235238Sjasonestatic const ctl_named_node_t arenas_lrun_i_node[] = { 329286866Sjasone {NAME("size"), CTL(arenas_lrun_i_size)} 330234370Sjasone}; 331235238Sjasonestatic const ctl_named_node_t super_arenas_lrun_i_node[] = { 332286866Sjasone {NAME(""), CHILD(named, arenas_lrun_i)} 333234370Sjasone}; 334234370Sjasone 335235238Sjasonestatic const ctl_indexed_node_t arenas_lrun_node[] = { 336234370Sjasone {INDEX(arenas_lrun_i)} 337234370Sjasone}; 338234370Sjasone 339286866Sjasonestatic const ctl_named_node_t arenas_hchunk_i_node[] = { 340286866Sjasone {NAME("size"), CTL(arenas_hchunk_i_size)} 341286866Sjasone}; 342286866Sjasonestatic const ctl_named_node_t super_arenas_hchunk_i_node[] = { 343286866Sjasone {NAME(""), CHILD(named, arenas_hchunk_i)} 344286866Sjasone}; 345286866Sjasone 346286866Sjasonestatic const ctl_indexed_node_t arenas_hchunk_node[] = { 347286866Sjasone {INDEX(arenas_hchunk_i)} 348286866Sjasone}; 349286866Sjasone 350235238Sjasonestatic const ctl_named_node_t arenas_node[] = { 351286866Sjasone {NAME("narenas"), CTL(arenas_narenas)}, 352286866Sjasone {NAME("initialized"), CTL(arenas_initialized)}, 353286866Sjasone {NAME("lg_dirty_mult"), CTL(arenas_lg_dirty_mult)}, 354296221Sjasone {NAME("decay_time"), CTL(arenas_decay_time)}, 355286866Sjasone {NAME("quantum"), CTL(arenas_quantum)}, 356286866Sjasone {NAME("page"), CTL(arenas_page)}, 357286866Sjasone {NAME("tcache_max"), CTL(arenas_tcache_max)}, 358286866Sjasone {NAME("nbins"), CTL(arenas_nbins)}, 359286866Sjasone {NAME("nhbins"), CTL(arenas_nhbins)}, 360286866Sjasone {NAME("bin"), CHILD(indexed, arenas_bin)}, 361286866Sjasone {NAME("nlruns"), CTL(arenas_nlruns)}, 362286866Sjasone {NAME("lrun"), CHILD(indexed, arenas_lrun)}, 363286866Sjasone {NAME("nhchunks"), CTL(arenas_nhchunks)}, 364286866Sjasone {NAME("hchunk"), CHILD(indexed, arenas_hchunk)}, 365286866Sjasone {NAME("extend"), CTL(arenas_extend)} 366234370Sjasone}; 367234370Sjasone 368235238Sjasonestatic const ctl_named_node_t prof_node[] = { 369286866Sjasone {NAME("thread_active_init"), CTL(prof_thread_active_init)}, 370234370Sjasone {NAME("active"), CTL(prof_active)}, 371234370Sjasone {NAME("dump"), CTL(prof_dump)}, 372286866Sjasone {NAME("gdump"), CTL(prof_gdump)}, 373286866Sjasone {NAME("reset"), CTL(prof_reset)}, 374286866Sjasone {NAME("interval"), CTL(prof_interval)}, 375286866Sjasone {NAME("lg_sample"), CTL(lg_prof_sample)} 376234370Sjasone}; 377234370Sjasone 378286866Sjasonestatic const ctl_named_node_t stats_arenas_i_metadata_node[] = { 379286866Sjasone {NAME("mapped"), CTL(stats_arenas_i_metadata_mapped)}, 380286866Sjasone {NAME("allocated"), CTL(stats_arenas_i_metadata_allocated)} 381234370Sjasone}; 382234370Sjasone 383235238Sjasonestatic const ctl_named_node_t stats_arenas_i_small_node[] = { 384286866Sjasone {NAME("allocated"), CTL(stats_arenas_i_small_allocated)}, 385286866Sjasone {NAME("nmalloc"), CTL(stats_arenas_i_small_nmalloc)}, 386286866Sjasone {NAME("ndalloc"), CTL(stats_arenas_i_small_ndalloc)}, 387286866Sjasone {NAME("nrequests"), CTL(stats_arenas_i_small_nrequests)} 388234370Sjasone}; 389234370Sjasone 390235238Sjasonestatic const ctl_named_node_t stats_arenas_i_large_node[] = { 391286866Sjasone {NAME("allocated"), CTL(stats_arenas_i_large_allocated)}, 392286866Sjasone {NAME("nmalloc"), CTL(stats_arenas_i_large_nmalloc)}, 393286866Sjasone {NAME("ndalloc"), CTL(stats_arenas_i_large_ndalloc)}, 394286866Sjasone {NAME("nrequests"), CTL(stats_arenas_i_large_nrequests)} 395234370Sjasone}; 396234370Sjasone 397286866Sjasonestatic const ctl_named_node_t stats_arenas_i_huge_node[] = { 398286866Sjasone {NAME("allocated"), CTL(stats_arenas_i_huge_allocated)}, 399286866Sjasone {NAME("nmalloc"), CTL(stats_arenas_i_huge_nmalloc)}, 400286866Sjasone {NAME("ndalloc"), CTL(stats_arenas_i_huge_ndalloc)}, 401286866Sjasone {NAME("nrequests"), CTL(stats_arenas_i_huge_nrequests)} 402286866Sjasone}; 403286866Sjasone 404235238Sjasonestatic const ctl_named_node_t stats_arenas_i_bins_j_node[] = { 405286866Sjasone {NAME("nmalloc"), CTL(stats_arenas_i_bins_j_nmalloc)}, 406286866Sjasone {NAME("ndalloc"), CTL(stats_arenas_i_bins_j_ndalloc)}, 407286866Sjasone {NAME("nrequests"), CTL(stats_arenas_i_bins_j_nrequests)}, 408286866Sjasone {NAME("curregs"), CTL(stats_arenas_i_bins_j_curregs)}, 409286866Sjasone {NAME("nfills"), CTL(stats_arenas_i_bins_j_nfills)}, 410286866Sjasone {NAME("nflushes"), CTL(stats_arenas_i_bins_j_nflushes)}, 411286866Sjasone {NAME("nruns"), CTL(stats_arenas_i_bins_j_nruns)}, 412286866Sjasone {NAME("nreruns"), CTL(stats_arenas_i_bins_j_nreruns)}, 413286866Sjasone {NAME("curruns"), CTL(stats_arenas_i_bins_j_curruns)} 414234370Sjasone}; 415235238Sjasonestatic const ctl_named_node_t super_stats_arenas_i_bins_j_node[] = { 416286866Sjasone {NAME(""), CHILD(named, stats_arenas_i_bins_j)} 417234370Sjasone}; 418234370Sjasone 419235238Sjasonestatic const ctl_indexed_node_t stats_arenas_i_bins_node[] = { 420234370Sjasone {INDEX(stats_arenas_i_bins_j)} 421234370Sjasone}; 422234370Sjasone 423235238Sjasonestatic const ctl_named_node_t stats_arenas_i_lruns_j_node[] = { 424286866Sjasone {NAME("nmalloc"), CTL(stats_arenas_i_lruns_j_nmalloc)}, 425286866Sjasone {NAME("ndalloc"), CTL(stats_arenas_i_lruns_j_ndalloc)}, 426286866Sjasone {NAME("nrequests"), CTL(stats_arenas_i_lruns_j_nrequests)}, 427286866Sjasone {NAME("curruns"), CTL(stats_arenas_i_lruns_j_curruns)} 428234370Sjasone}; 429235238Sjasonestatic const ctl_named_node_t super_stats_arenas_i_lruns_j_node[] = { 430286866Sjasone {NAME(""), CHILD(named, stats_arenas_i_lruns_j)} 431234370Sjasone}; 432234370Sjasone 433235238Sjasonestatic const ctl_indexed_node_t stats_arenas_i_lruns_node[] = { 434234370Sjasone {INDEX(stats_arenas_i_lruns_j)} 435234370Sjasone}; 436234370Sjasone 437286866Sjasonestatic const ctl_named_node_t stats_arenas_i_hchunks_j_node[] = { 438286866Sjasone {NAME("nmalloc"), CTL(stats_arenas_i_hchunks_j_nmalloc)}, 439286866Sjasone {NAME("ndalloc"), CTL(stats_arenas_i_hchunks_j_ndalloc)}, 440286866Sjasone {NAME("nrequests"), CTL(stats_arenas_i_hchunks_j_nrequests)}, 441286866Sjasone {NAME("curhchunks"), CTL(stats_arenas_i_hchunks_j_curhchunks)} 442286866Sjasone}; 443286866Sjasonestatic const ctl_named_node_t super_stats_arenas_i_hchunks_j_node[] = { 444286866Sjasone {NAME(""), CHILD(named, stats_arenas_i_hchunks_j)} 445286866Sjasone}; 446286866Sjasone 447286866Sjasonestatic const ctl_indexed_node_t stats_arenas_i_hchunks_node[] = { 448286866Sjasone {INDEX(stats_arenas_i_hchunks_j)} 449286866Sjasone}; 450286866Sjasone 451235238Sjasonestatic const ctl_named_node_t stats_arenas_i_node[] = { 452286866Sjasone {NAME("nthreads"), CTL(stats_arenas_i_nthreads)}, 453286866Sjasone {NAME("dss"), CTL(stats_arenas_i_dss)}, 454286866Sjasone {NAME("lg_dirty_mult"), CTL(stats_arenas_i_lg_dirty_mult)}, 455296221Sjasone {NAME("decay_time"), CTL(stats_arenas_i_decay_time)}, 456286866Sjasone {NAME("pactive"), CTL(stats_arenas_i_pactive)}, 457286866Sjasone {NAME("pdirty"), CTL(stats_arenas_i_pdirty)}, 458286866Sjasone {NAME("mapped"), CTL(stats_arenas_i_mapped)}, 459286866Sjasone {NAME("npurge"), CTL(stats_arenas_i_npurge)}, 460286866Sjasone {NAME("nmadvise"), CTL(stats_arenas_i_nmadvise)}, 461286866Sjasone {NAME("purged"), CTL(stats_arenas_i_purged)}, 462286866Sjasone {NAME("metadata"), CHILD(named, stats_arenas_i_metadata)}, 463286866Sjasone {NAME("small"), CHILD(named, stats_arenas_i_small)}, 464286866Sjasone {NAME("large"), CHILD(named, stats_arenas_i_large)}, 465286866Sjasone {NAME("huge"), CHILD(named, stats_arenas_i_huge)}, 466286866Sjasone {NAME("bins"), CHILD(indexed, stats_arenas_i_bins)}, 467286866Sjasone {NAME("lruns"), CHILD(indexed, stats_arenas_i_lruns)}, 468286866Sjasone {NAME("hchunks"), CHILD(indexed, stats_arenas_i_hchunks)} 469234370Sjasone}; 470235238Sjasonestatic const ctl_named_node_t super_stats_arenas_i_node[] = { 471286866Sjasone {NAME(""), CHILD(named, stats_arenas_i)} 472234370Sjasone}; 473234370Sjasone 474235238Sjasonestatic const ctl_indexed_node_t stats_arenas_node[] = { 475234370Sjasone {INDEX(stats_arenas_i)} 476234370Sjasone}; 477234370Sjasone 478235238Sjasonestatic const ctl_named_node_t stats_node[] = { 479286866Sjasone {NAME("cactive"), CTL(stats_cactive)}, 480286866Sjasone {NAME("allocated"), CTL(stats_allocated)}, 481286866Sjasone {NAME("active"), CTL(stats_active)}, 482286866Sjasone {NAME("metadata"), CTL(stats_metadata)}, 483286866Sjasone {NAME("resident"), CTL(stats_resident)}, 484286866Sjasone {NAME("mapped"), CTL(stats_mapped)}, 485286866Sjasone {NAME("arenas"), CHILD(indexed, stats_arenas)} 486234370Sjasone}; 487234370Sjasone 488235238Sjasonestatic const ctl_named_node_t root_node[] = { 489234370Sjasone {NAME("version"), CTL(version)}, 490234370Sjasone {NAME("epoch"), CTL(epoch)}, 491235238Sjasone {NAME("thread"), CHILD(named, thread)}, 492235238Sjasone {NAME("config"), CHILD(named, config)}, 493235238Sjasone {NAME("opt"), CHILD(named, opt)}, 494286866Sjasone {NAME("tcache"), CHILD(named, tcache)}, 495242844Sjasone {NAME("arena"), CHILD(indexed, arena)}, 496235238Sjasone {NAME("arenas"), CHILD(named, arenas)}, 497235238Sjasone {NAME("prof"), CHILD(named, prof)}, 498235238Sjasone {NAME("stats"), CHILD(named, stats)} 499234370Sjasone}; 500235238Sjasonestatic const ctl_named_node_t super_root_node[] = { 501235238Sjasone {NAME(""), CHILD(named, root)} 502234370Sjasone}; 503234370Sjasone 504234370Sjasone#undef NAME 505234370Sjasone#undef CHILD 506234370Sjasone#undef CTL 507234370Sjasone#undef INDEX 508234370Sjasone 509234370Sjasone/******************************************************************************/ 510234370Sjasone 511234370Sjasonestatic bool 512234370Sjasonectl_arena_init(ctl_arena_stats_t *astats) 513234370Sjasone{ 514234370Sjasone 515234370Sjasone if (astats->lstats == NULL) { 516286866Sjasone astats->lstats = (malloc_large_stats_t *)a0malloc(nlclasses * 517234370Sjasone sizeof(malloc_large_stats_t)); 518234370Sjasone if (astats->lstats == NULL) 519234370Sjasone return (true); 520234370Sjasone } 521234370Sjasone 522286866Sjasone if (astats->hstats == NULL) { 523286866Sjasone astats->hstats = (malloc_huge_stats_t *)a0malloc(nhclasses * 524286866Sjasone sizeof(malloc_huge_stats_t)); 525286866Sjasone if (astats->hstats == NULL) 526286866Sjasone return (true); 527286866Sjasone } 528286866Sjasone 529234370Sjasone return (false); 530234370Sjasone} 531234370Sjasone 532234370Sjasonestatic void 533234370Sjasonectl_arena_clear(ctl_arena_stats_t *astats) 534234370Sjasone{ 535234370Sjasone 536296221Sjasone astats->nthreads = 0; 537242844Sjasone astats->dss = dss_prec_names[dss_prec_limit]; 538286866Sjasone astats->lg_dirty_mult = -1; 539296221Sjasone astats->decay_time = -1; 540234370Sjasone astats->pactive = 0; 541234370Sjasone astats->pdirty = 0; 542234370Sjasone if (config_stats) { 543234370Sjasone memset(&astats->astats, 0, sizeof(arena_stats_t)); 544234370Sjasone astats->allocated_small = 0; 545234370Sjasone astats->nmalloc_small = 0; 546234370Sjasone astats->ndalloc_small = 0; 547234370Sjasone astats->nrequests_small = 0; 548234370Sjasone memset(astats->bstats, 0, NBINS * sizeof(malloc_bin_stats_t)); 549234370Sjasone memset(astats->lstats, 0, nlclasses * 550234370Sjasone sizeof(malloc_large_stats_t)); 551286866Sjasone memset(astats->hstats, 0, nhclasses * 552286866Sjasone sizeof(malloc_huge_stats_t)); 553234370Sjasone } 554234370Sjasone} 555234370Sjasone 556234370Sjasonestatic void 557234370Sjasonectl_arena_stats_amerge(ctl_arena_stats_t *cstats, arena_t *arena) 558234370Sjasone{ 559234370Sjasone unsigned i; 560234370Sjasone 561296221Sjasone if (config_stats) { 562296221Sjasone arena_stats_merge(arena, &cstats->nthreads, &cstats->dss, 563296221Sjasone &cstats->lg_dirty_mult, &cstats->decay_time, 564296221Sjasone &cstats->pactive, &cstats->pdirty, &cstats->astats, 565296221Sjasone cstats->bstats, cstats->lstats, cstats->hstats); 566234370Sjasone 567296221Sjasone for (i = 0; i < NBINS; i++) { 568296221Sjasone cstats->allocated_small += cstats->bstats[i].curregs * 569296221Sjasone index2size(i); 570296221Sjasone cstats->nmalloc_small += cstats->bstats[i].nmalloc; 571296221Sjasone cstats->ndalloc_small += cstats->bstats[i].ndalloc; 572296221Sjasone cstats->nrequests_small += cstats->bstats[i].nrequests; 573296221Sjasone } 574296221Sjasone } else { 575296221Sjasone arena_basic_stats_merge(arena, &cstats->nthreads, &cstats->dss, 576296221Sjasone &cstats->lg_dirty_mult, &cstats->decay_time, 577296221Sjasone &cstats->pactive, &cstats->pdirty); 578234370Sjasone } 579234370Sjasone} 580234370Sjasone 581234370Sjasonestatic void 582234370Sjasonectl_arena_stats_smerge(ctl_arena_stats_t *sstats, ctl_arena_stats_t *astats) 583234370Sjasone{ 584234370Sjasone unsigned i; 585234370Sjasone 586296221Sjasone sstats->nthreads += astats->nthreads; 587234370Sjasone sstats->pactive += astats->pactive; 588234370Sjasone sstats->pdirty += astats->pdirty; 589234370Sjasone 590296221Sjasone if (config_stats) { 591296221Sjasone sstats->astats.mapped += astats->astats.mapped; 592296221Sjasone sstats->astats.npurge += astats->astats.npurge; 593296221Sjasone sstats->astats.nmadvise += astats->astats.nmadvise; 594296221Sjasone sstats->astats.purged += astats->astats.purged; 595234370Sjasone 596296221Sjasone sstats->astats.metadata_mapped += 597296221Sjasone astats->astats.metadata_mapped; 598296221Sjasone sstats->astats.metadata_allocated += 599296221Sjasone astats->astats.metadata_allocated; 600286866Sjasone 601296221Sjasone sstats->allocated_small += astats->allocated_small; 602296221Sjasone sstats->nmalloc_small += astats->nmalloc_small; 603296221Sjasone sstats->ndalloc_small += astats->ndalloc_small; 604296221Sjasone sstats->nrequests_small += astats->nrequests_small; 605234370Sjasone 606296221Sjasone sstats->astats.allocated_large += 607296221Sjasone astats->astats.allocated_large; 608296221Sjasone sstats->astats.nmalloc_large += astats->astats.nmalloc_large; 609296221Sjasone sstats->astats.ndalloc_large += astats->astats.ndalloc_large; 610296221Sjasone sstats->astats.nrequests_large += 611296221Sjasone astats->astats.nrequests_large; 612234370Sjasone 613296221Sjasone sstats->astats.allocated_huge += astats->astats.allocated_huge; 614296221Sjasone sstats->astats.nmalloc_huge += astats->astats.nmalloc_huge; 615296221Sjasone sstats->astats.ndalloc_huge += astats->astats.ndalloc_huge; 616234370Sjasone 617296221Sjasone for (i = 0; i < NBINS; i++) { 618296221Sjasone sstats->bstats[i].nmalloc += astats->bstats[i].nmalloc; 619296221Sjasone sstats->bstats[i].ndalloc += astats->bstats[i].ndalloc; 620296221Sjasone sstats->bstats[i].nrequests += 621296221Sjasone astats->bstats[i].nrequests; 622296221Sjasone sstats->bstats[i].curregs += astats->bstats[i].curregs; 623296221Sjasone if (config_tcache) { 624296221Sjasone sstats->bstats[i].nfills += 625296221Sjasone astats->bstats[i].nfills; 626296221Sjasone sstats->bstats[i].nflushes += 627296221Sjasone astats->bstats[i].nflushes; 628296221Sjasone } 629296221Sjasone sstats->bstats[i].nruns += astats->bstats[i].nruns; 630296221Sjasone sstats->bstats[i].reruns += astats->bstats[i].reruns; 631296221Sjasone sstats->bstats[i].curruns += astats->bstats[i].curruns; 632234370Sjasone } 633286866Sjasone 634296221Sjasone for (i = 0; i < nlclasses; i++) { 635296221Sjasone sstats->lstats[i].nmalloc += astats->lstats[i].nmalloc; 636296221Sjasone sstats->lstats[i].ndalloc += astats->lstats[i].ndalloc; 637296221Sjasone sstats->lstats[i].nrequests += 638296221Sjasone astats->lstats[i].nrequests; 639296221Sjasone sstats->lstats[i].curruns += astats->lstats[i].curruns; 640296221Sjasone } 641286866Sjasone 642296221Sjasone for (i = 0; i < nhclasses; i++) { 643296221Sjasone sstats->hstats[i].nmalloc += astats->hstats[i].nmalloc; 644296221Sjasone sstats->hstats[i].ndalloc += astats->hstats[i].ndalloc; 645296221Sjasone sstats->hstats[i].curhchunks += 646296221Sjasone astats->hstats[i].curhchunks; 647296221Sjasone } 648286866Sjasone } 649234370Sjasone} 650234370Sjasone 651234370Sjasonestatic void 652234370Sjasonectl_arena_refresh(arena_t *arena, unsigned i) 653234370Sjasone{ 654234370Sjasone ctl_arena_stats_t *astats = &ctl_stats.arenas[i]; 655242844Sjasone ctl_arena_stats_t *sstats = &ctl_stats.arenas[ctl_stats.narenas]; 656234370Sjasone 657234370Sjasone ctl_arena_clear(astats); 658296221Sjasone ctl_arena_stats_amerge(astats, arena); 659296221Sjasone /* Merge into sum stats as well. */ 660296221Sjasone ctl_arena_stats_smerge(sstats, astats); 661234370Sjasone} 662234370Sjasone 663242844Sjasonestatic bool 664242844Sjasonectl_grow(void) 665242844Sjasone{ 666242844Sjasone ctl_arena_stats_t *astats; 667242844Sjasone 668286866Sjasone /* Initialize new arena. */ 669286866Sjasone if (arena_init(ctl_stats.narenas) == NULL) 670286866Sjasone return (true); 671286866Sjasone 672286866Sjasone /* Allocate extended arena stats. */ 673286866Sjasone astats = (ctl_arena_stats_t *)a0malloc((ctl_stats.narenas + 2) * 674256823Sjasone sizeof(ctl_arena_stats_t)); 675256823Sjasone if (astats == NULL) 676256823Sjasone return (true); 677242844Sjasone 678256823Sjasone /* Initialize the new astats element. */ 679256823Sjasone memcpy(astats, ctl_stats.arenas, (ctl_stats.narenas + 1) * 680256823Sjasone sizeof(ctl_arena_stats_t)); 681242844Sjasone memset(&astats[ctl_stats.narenas + 1], 0, sizeof(ctl_arena_stats_t)); 682256823Sjasone if (ctl_arena_init(&astats[ctl_stats.narenas + 1])) { 683286866Sjasone a0dalloc(astats); 684242844Sjasone return (true); 685256823Sjasone } 686242844Sjasone /* Swap merged stats to their new location. */ 687242844Sjasone { 688242844Sjasone ctl_arena_stats_t tstats; 689242844Sjasone memcpy(&tstats, &astats[ctl_stats.narenas], 690242844Sjasone sizeof(ctl_arena_stats_t)); 691242844Sjasone memcpy(&astats[ctl_stats.narenas], 692242844Sjasone &astats[ctl_stats.narenas + 1], sizeof(ctl_arena_stats_t)); 693242844Sjasone memcpy(&astats[ctl_stats.narenas + 1], &tstats, 694242844Sjasone sizeof(ctl_arena_stats_t)); 695242844Sjasone } 696286866Sjasone a0dalloc(ctl_stats.arenas); 697242844Sjasone ctl_stats.arenas = astats; 698242844Sjasone ctl_stats.narenas++; 699242844Sjasone 700242844Sjasone return (false); 701242844Sjasone} 702242844Sjasone 703234370Sjasonestatic void 704234370Sjasonectl_refresh(void) 705234370Sjasone{ 706234370Sjasone unsigned i; 707242844Sjasone VARIABLE_ARRAY(arena_t *, tarenas, ctl_stats.narenas); 708234370Sjasone 709234370Sjasone /* 710234370Sjasone * Clear sum stats, since they will be merged into by 711234370Sjasone * ctl_arena_refresh(). 712234370Sjasone */ 713242844Sjasone ctl_arena_clear(&ctl_stats.arenas[ctl_stats.narenas]); 714234370Sjasone 715296221Sjasone for (i = 0; i < ctl_stats.narenas; i++) 716296221Sjasone tarenas[i] = arena_get(i, false); 717286866Sjasone 718242844Sjasone for (i = 0; i < ctl_stats.narenas; i++) { 719234370Sjasone bool initialized = (tarenas[i] != NULL); 720234370Sjasone 721234370Sjasone ctl_stats.arenas[i].initialized = initialized; 722234370Sjasone if (initialized) 723234370Sjasone ctl_arena_refresh(tarenas[i], i); 724234370Sjasone } 725234370Sjasone 726234370Sjasone if (config_stats) { 727286866Sjasone size_t base_allocated, base_resident, base_mapped; 728286866Sjasone base_stats_get(&base_allocated, &base_resident, &base_mapped); 729242844Sjasone ctl_stats.allocated = 730286866Sjasone ctl_stats.arenas[ctl_stats.narenas].allocated_small + 731286866Sjasone ctl_stats.arenas[ctl_stats.narenas].astats.allocated_large + 732286866Sjasone ctl_stats.arenas[ctl_stats.narenas].astats.allocated_huge; 733242844Sjasone ctl_stats.active = 734286866Sjasone (ctl_stats.arenas[ctl_stats.narenas].pactive << LG_PAGE); 735286866Sjasone ctl_stats.metadata = base_allocated + 736286866Sjasone ctl_stats.arenas[ctl_stats.narenas].astats.metadata_mapped + 737286866Sjasone ctl_stats.arenas[ctl_stats.narenas].astats 738286866Sjasone .metadata_allocated; 739286866Sjasone ctl_stats.resident = base_resident + 740286866Sjasone ctl_stats.arenas[ctl_stats.narenas].astats.metadata_mapped + 741286866Sjasone ((ctl_stats.arenas[ctl_stats.narenas].pactive + 742286866Sjasone ctl_stats.arenas[ctl_stats.narenas].pdirty) << LG_PAGE); 743286866Sjasone ctl_stats.mapped = base_mapped + 744286866Sjasone ctl_stats.arenas[ctl_stats.narenas].astats.mapped; 745234370Sjasone } 746234370Sjasone 747234370Sjasone ctl_epoch++; 748234370Sjasone} 749234370Sjasone 750234370Sjasonestatic bool 751234370Sjasonectl_init(void) 752234370Sjasone{ 753234370Sjasone bool ret; 754234370Sjasone 755234370Sjasone malloc_mutex_lock(&ctl_mtx); 756286866Sjasone if (!ctl_initialized) { 757234370Sjasone /* 758234370Sjasone * Allocate space for one extra arena stats element, which 759234370Sjasone * contains summed stats across all arenas. 760234370Sjasone */ 761286866Sjasone ctl_stats.narenas = narenas_total_get(); 762286866Sjasone ctl_stats.arenas = (ctl_arena_stats_t *)a0malloc( 763242844Sjasone (ctl_stats.narenas + 1) * sizeof(ctl_arena_stats_t)); 764234370Sjasone if (ctl_stats.arenas == NULL) { 765234370Sjasone ret = true; 766234370Sjasone goto label_return; 767234370Sjasone } 768242844Sjasone memset(ctl_stats.arenas, 0, (ctl_stats.narenas + 1) * 769234370Sjasone sizeof(ctl_arena_stats_t)); 770234370Sjasone 771234370Sjasone /* 772234370Sjasone * Initialize all stats structures, regardless of whether they 773234370Sjasone * ever get used. Lazy initialization would allow errors to 774234370Sjasone * cause inconsistent state to be viewable by the application. 775234370Sjasone */ 776234370Sjasone if (config_stats) { 777234370Sjasone unsigned i; 778242844Sjasone for (i = 0; i <= ctl_stats.narenas; i++) { 779234370Sjasone if (ctl_arena_init(&ctl_stats.arenas[i])) { 780286866Sjasone unsigned j; 781286866Sjasone for (j = 0; j < i; j++) { 782286866Sjasone a0dalloc( 783286866Sjasone ctl_stats.arenas[j].lstats); 784286866Sjasone a0dalloc( 785286866Sjasone ctl_stats.arenas[j].hstats); 786286866Sjasone } 787286866Sjasone a0dalloc(ctl_stats.arenas); 788286866Sjasone ctl_stats.arenas = NULL; 789234370Sjasone ret = true; 790234370Sjasone goto label_return; 791234370Sjasone } 792234370Sjasone } 793234370Sjasone } 794242844Sjasone ctl_stats.arenas[ctl_stats.narenas].initialized = true; 795234370Sjasone 796234370Sjasone ctl_epoch = 0; 797234370Sjasone ctl_refresh(); 798234370Sjasone ctl_initialized = true; 799234370Sjasone } 800234370Sjasone 801234370Sjasone ret = false; 802234370Sjasonelabel_return: 803234370Sjasone malloc_mutex_unlock(&ctl_mtx); 804234370Sjasone return (ret); 805234370Sjasone} 806234370Sjasone 807234370Sjasonestatic int 808234370Sjasonectl_lookup(const char *name, ctl_node_t const **nodesp, size_t *mibp, 809234370Sjasone size_t *depthp) 810234370Sjasone{ 811234370Sjasone int ret; 812234370Sjasone const char *elm, *tdot, *dot; 813234370Sjasone size_t elen, i, j; 814235238Sjasone const ctl_named_node_t *node; 815234370Sjasone 816234370Sjasone elm = name; 817234370Sjasone /* Equivalent to strchrnul(). */ 818234370Sjasone dot = ((tdot = strchr(elm, '.')) != NULL) ? tdot : strchr(elm, '\0'); 819234370Sjasone elen = (size_t)((uintptr_t)dot - (uintptr_t)elm); 820234370Sjasone if (elen == 0) { 821234370Sjasone ret = ENOENT; 822234370Sjasone goto label_return; 823234370Sjasone } 824234370Sjasone node = super_root_node; 825234370Sjasone for (i = 0; i < *depthp; i++) { 826235238Sjasone assert(node); 827235238Sjasone assert(node->nchildren > 0); 828235238Sjasone if (ctl_named_node(node->children) != NULL) { 829235238Sjasone const ctl_named_node_t *pnode = node; 830234370Sjasone 831234370Sjasone /* Children are named. */ 832235238Sjasone for (j = 0; j < node->nchildren; j++) { 833235238Sjasone const ctl_named_node_t *child = 834235238Sjasone ctl_named_children(node, j); 835235238Sjasone if (strlen(child->name) == elen && 836235238Sjasone strncmp(elm, child->name, elen) == 0) { 837234370Sjasone node = child; 838234370Sjasone if (nodesp != NULL) 839235238Sjasone nodesp[i] = 840235238Sjasone (const ctl_node_t *)node; 841234370Sjasone mibp[i] = j; 842234370Sjasone break; 843234370Sjasone } 844234370Sjasone } 845234370Sjasone if (node == pnode) { 846234370Sjasone ret = ENOENT; 847234370Sjasone goto label_return; 848234370Sjasone } 849234370Sjasone } else { 850234370Sjasone uintmax_t index; 851235238Sjasone const ctl_indexed_node_t *inode; 852234370Sjasone 853234370Sjasone /* Children are indexed. */ 854234370Sjasone index = malloc_strtoumax(elm, NULL, 10); 855234370Sjasone if (index == UINTMAX_MAX || index > SIZE_T_MAX) { 856234370Sjasone ret = ENOENT; 857234370Sjasone goto label_return; 858234370Sjasone } 859234370Sjasone 860235238Sjasone inode = ctl_indexed_node(node->children); 861235238Sjasone node = inode->index(mibp, *depthp, (size_t)index); 862234370Sjasone if (node == NULL) { 863234370Sjasone ret = ENOENT; 864234370Sjasone goto label_return; 865234370Sjasone } 866234370Sjasone 867234370Sjasone if (nodesp != NULL) 868235238Sjasone nodesp[i] = (const ctl_node_t *)node; 869234370Sjasone mibp[i] = (size_t)index; 870234370Sjasone } 871234370Sjasone 872234370Sjasone if (node->ctl != NULL) { 873234370Sjasone /* Terminal node. */ 874234370Sjasone if (*dot != '\0') { 875234370Sjasone /* 876234370Sjasone * The name contains more elements than are 877234370Sjasone * in this path through the tree. 878234370Sjasone */ 879234370Sjasone ret = ENOENT; 880234370Sjasone goto label_return; 881234370Sjasone } 882234370Sjasone /* Complete lookup successful. */ 883234370Sjasone *depthp = i + 1; 884234370Sjasone break; 885234370Sjasone } 886234370Sjasone 887234370Sjasone /* Update elm. */ 888234370Sjasone if (*dot == '\0') { 889234370Sjasone /* No more elements. */ 890234370Sjasone ret = ENOENT; 891234370Sjasone goto label_return; 892234370Sjasone } 893234370Sjasone elm = &dot[1]; 894234370Sjasone dot = ((tdot = strchr(elm, '.')) != NULL) ? tdot : 895234370Sjasone strchr(elm, '\0'); 896234370Sjasone elen = (size_t)((uintptr_t)dot - (uintptr_t)elm); 897234370Sjasone } 898234370Sjasone 899234370Sjasone ret = 0; 900234370Sjasonelabel_return: 901234370Sjasone return (ret); 902234370Sjasone} 903234370Sjasone 904234370Sjasoneint 905234370Sjasonectl_byname(const char *name, void *oldp, size_t *oldlenp, void *newp, 906234370Sjasone size_t newlen) 907234370Sjasone{ 908234370Sjasone int ret; 909234370Sjasone size_t depth; 910234370Sjasone ctl_node_t const *nodes[CTL_MAX_DEPTH]; 911234370Sjasone size_t mib[CTL_MAX_DEPTH]; 912235238Sjasone const ctl_named_node_t *node; 913234370Sjasone 914286866Sjasone if (!ctl_initialized && ctl_init()) { 915234370Sjasone ret = EAGAIN; 916234370Sjasone goto label_return; 917234370Sjasone } 918234370Sjasone 919234370Sjasone depth = CTL_MAX_DEPTH; 920234370Sjasone ret = ctl_lookup(name, nodes, mib, &depth); 921234370Sjasone if (ret != 0) 922234370Sjasone goto label_return; 923234370Sjasone 924235238Sjasone node = ctl_named_node(nodes[depth-1]); 925235238Sjasone if (node != NULL && node->ctl) 926235238Sjasone ret = node->ctl(mib, depth, oldp, oldlenp, newp, newlen); 927235238Sjasone else { 928234370Sjasone /* The name refers to a partial path through the ctl tree. */ 929234370Sjasone ret = ENOENT; 930234370Sjasone } 931234370Sjasone 932234370Sjasonelabel_return: 933234370Sjasone return(ret); 934234370Sjasone} 935234370Sjasone 936234370Sjasoneint 937234370Sjasonectl_nametomib(const char *name, size_t *mibp, size_t *miblenp) 938234370Sjasone{ 939234370Sjasone int ret; 940234370Sjasone 941286866Sjasone if (!ctl_initialized && ctl_init()) { 942234370Sjasone ret = EAGAIN; 943234370Sjasone goto label_return; 944234370Sjasone } 945234370Sjasone 946234370Sjasone ret = ctl_lookup(name, NULL, mibp, miblenp); 947234370Sjasonelabel_return: 948234370Sjasone return(ret); 949234370Sjasone} 950234370Sjasone 951234370Sjasoneint 952234370Sjasonectl_bymib(const size_t *mib, size_t miblen, void *oldp, size_t *oldlenp, 953234370Sjasone void *newp, size_t newlen) 954234370Sjasone{ 955234370Sjasone int ret; 956235238Sjasone const ctl_named_node_t *node; 957234370Sjasone size_t i; 958234370Sjasone 959286866Sjasone if (!ctl_initialized && ctl_init()) { 960234370Sjasone ret = EAGAIN; 961234370Sjasone goto label_return; 962234370Sjasone } 963234370Sjasone 964234370Sjasone /* Iterate down the tree. */ 965234370Sjasone node = super_root_node; 966234370Sjasone for (i = 0; i < miblen; i++) { 967235238Sjasone assert(node); 968235238Sjasone assert(node->nchildren > 0); 969235238Sjasone if (ctl_named_node(node->children) != NULL) { 970234370Sjasone /* Children are named. */ 971296221Sjasone if (node->nchildren <= (unsigned)mib[i]) { 972234370Sjasone ret = ENOENT; 973234370Sjasone goto label_return; 974234370Sjasone } 975235238Sjasone node = ctl_named_children(node, mib[i]); 976234370Sjasone } else { 977235238Sjasone const ctl_indexed_node_t *inode; 978234370Sjasone 979234370Sjasone /* Indexed element. */ 980235238Sjasone inode = ctl_indexed_node(node->children); 981235238Sjasone node = inode->index(mib, miblen, mib[i]); 982234370Sjasone if (node == NULL) { 983234370Sjasone ret = ENOENT; 984234370Sjasone goto label_return; 985234370Sjasone } 986234370Sjasone } 987234370Sjasone } 988234370Sjasone 989234370Sjasone /* Call the ctl function. */ 990235238Sjasone if (node && node->ctl) 991235238Sjasone ret = node->ctl(mib, miblen, oldp, oldlenp, newp, newlen); 992235238Sjasone else { 993234370Sjasone /* Partial MIB. */ 994234370Sjasone ret = ENOENT; 995234370Sjasone } 996234370Sjasone 997234370Sjasonelabel_return: 998234370Sjasone return(ret); 999234370Sjasone} 1000234370Sjasone 1001234370Sjasonebool 1002234370Sjasonectl_boot(void) 1003234370Sjasone{ 1004234370Sjasone 1005234370Sjasone if (malloc_mutex_init(&ctl_mtx)) 1006234370Sjasone return (true); 1007234370Sjasone 1008234370Sjasone ctl_initialized = false; 1009234370Sjasone 1010234370Sjasone return (false); 1011234370Sjasone} 1012234370Sjasone 1013242844Sjasonevoid 1014242844Sjasonectl_prefork(void) 1015242844Sjasone{ 1016242844Sjasone 1017261071Sjasone malloc_mutex_prefork(&ctl_mtx); 1018242844Sjasone} 1019242844Sjasone 1020242844Sjasonevoid 1021242844Sjasonectl_postfork_parent(void) 1022242844Sjasone{ 1023242844Sjasone 1024242844Sjasone malloc_mutex_postfork_parent(&ctl_mtx); 1025242844Sjasone} 1026242844Sjasone 1027242844Sjasonevoid 1028242844Sjasonectl_postfork_child(void) 1029242844Sjasone{ 1030242844Sjasone 1031242844Sjasone malloc_mutex_postfork_child(&ctl_mtx); 1032242844Sjasone} 1033242844Sjasone 1034234370Sjasone/******************************************************************************/ 1035234370Sjasone/* *_ctl() functions. */ 1036234370Sjasone 1037234370Sjasone#define READONLY() do { \ 1038234370Sjasone if (newp != NULL || newlen != 0) { \ 1039234370Sjasone ret = EPERM; \ 1040235238Sjasone goto label_return; \ 1041234370Sjasone } \ 1042234370Sjasone} while (0) 1043234370Sjasone 1044234370Sjasone#define WRITEONLY() do { \ 1045234370Sjasone if (oldp != NULL || oldlenp != NULL) { \ 1046234370Sjasone ret = EPERM; \ 1047235238Sjasone goto label_return; \ 1048234370Sjasone } \ 1049234370Sjasone} while (0) 1050234370Sjasone 1051286866Sjasone#define READ_XOR_WRITE() do { \ 1052286866Sjasone if ((oldp != NULL && oldlenp != NULL) && (newp != NULL || \ 1053286866Sjasone newlen != 0)) { \ 1054286866Sjasone ret = EPERM; \ 1055286866Sjasone goto label_return; \ 1056286866Sjasone } \ 1057286866Sjasone} while (0) 1058286866Sjasone 1059234370Sjasone#define READ(v, t) do { \ 1060234370Sjasone if (oldp != NULL && oldlenp != NULL) { \ 1061234370Sjasone if (*oldlenp != sizeof(t)) { \ 1062234370Sjasone size_t copylen = (sizeof(t) <= *oldlenp) \ 1063234370Sjasone ? sizeof(t) : *oldlenp; \ 1064245868Sjasone memcpy(oldp, (void *)&(v), copylen); \ 1065234370Sjasone ret = EINVAL; \ 1066235238Sjasone goto label_return; \ 1067286866Sjasone } \ 1068286866Sjasone *(t *)oldp = (v); \ 1069234370Sjasone } \ 1070234370Sjasone} while (0) 1071234370Sjasone 1072234370Sjasone#define WRITE(v, t) do { \ 1073234370Sjasone if (newp != NULL) { \ 1074234370Sjasone if (newlen != sizeof(t)) { \ 1075234370Sjasone ret = EINVAL; \ 1076235238Sjasone goto label_return; \ 1077234370Sjasone } \ 1078245868Sjasone (v) = *(t *)newp; \ 1079234370Sjasone } \ 1080234370Sjasone} while (0) 1081234370Sjasone 1082234370Sjasone/* 1083234370Sjasone * There's a lot of code duplication in the following macros due to limitations 1084234370Sjasone * in how nested cpp macros are expanded. 1085234370Sjasone */ 1086234370Sjasone#define CTL_RO_CLGEN(c, l, n, v, t) \ 1087234370Sjasonestatic int \ 1088234370Sjasonen##_ctl(const size_t *mib, size_t miblen, void *oldp, size_t *oldlenp, \ 1089234370Sjasone void *newp, size_t newlen) \ 1090234370Sjasone{ \ 1091234370Sjasone int ret; \ 1092234370Sjasone t oldval; \ 1093234370Sjasone \ 1094286866Sjasone if (!(c)) \ 1095234370Sjasone return (ENOENT); \ 1096234370Sjasone if (l) \ 1097234370Sjasone malloc_mutex_lock(&ctl_mtx); \ 1098234370Sjasone READONLY(); \ 1099245868Sjasone oldval = (v); \ 1100234370Sjasone READ(oldval, t); \ 1101234370Sjasone \ 1102234370Sjasone ret = 0; \ 1103235238Sjasonelabel_return: \ 1104234370Sjasone if (l) \ 1105234370Sjasone malloc_mutex_unlock(&ctl_mtx); \ 1106234370Sjasone return (ret); \ 1107234370Sjasone} 1108234370Sjasone 1109234370Sjasone#define CTL_RO_CGEN(c, n, v, t) \ 1110234370Sjasonestatic int \ 1111234370Sjasonen##_ctl(const size_t *mib, size_t miblen, void *oldp, size_t *oldlenp, \ 1112234370Sjasone void *newp, size_t newlen) \ 1113234370Sjasone{ \ 1114234370Sjasone int ret; \ 1115234370Sjasone t oldval; \ 1116234370Sjasone \ 1117286866Sjasone if (!(c)) \ 1118234370Sjasone return (ENOENT); \ 1119234370Sjasone malloc_mutex_lock(&ctl_mtx); \ 1120234370Sjasone READONLY(); \ 1121245868Sjasone oldval = (v); \ 1122234370Sjasone READ(oldval, t); \ 1123234370Sjasone \ 1124234370Sjasone ret = 0; \ 1125235238Sjasonelabel_return: \ 1126234370Sjasone malloc_mutex_unlock(&ctl_mtx); \ 1127234370Sjasone return (ret); \ 1128234370Sjasone} 1129234370Sjasone 1130234370Sjasone#define CTL_RO_GEN(n, v, t) \ 1131234370Sjasonestatic int \ 1132234370Sjasonen##_ctl(const size_t *mib, size_t miblen, void *oldp, size_t *oldlenp, \ 1133234370Sjasone void *newp, size_t newlen) \ 1134234370Sjasone{ \ 1135234370Sjasone int ret; \ 1136234370Sjasone t oldval; \ 1137234370Sjasone \ 1138234370Sjasone malloc_mutex_lock(&ctl_mtx); \ 1139234370Sjasone READONLY(); \ 1140245868Sjasone oldval = (v); \ 1141234370Sjasone READ(oldval, t); \ 1142234370Sjasone \ 1143234370Sjasone ret = 0; \ 1144235238Sjasonelabel_return: \ 1145234370Sjasone malloc_mutex_unlock(&ctl_mtx); \ 1146234370Sjasone return (ret); \ 1147234370Sjasone} 1148234370Sjasone 1149234370Sjasone/* 1150234370Sjasone * ctl_mtx is not acquired, under the assumption that no pertinent data will 1151234370Sjasone * mutate during the call. 1152234370Sjasone */ 1153234370Sjasone#define CTL_RO_NL_CGEN(c, n, v, t) \ 1154234370Sjasonestatic int \ 1155234370Sjasonen##_ctl(const size_t *mib, size_t miblen, void *oldp, size_t *oldlenp, \ 1156234370Sjasone void *newp, size_t newlen) \ 1157234370Sjasone{ \ 1158234370Sjasone int ret; \ 1159234370Sjasone t oldval; \ 1160234370Sjasone \ 1161286866Sjasone if (!(c)) \ 1162234370Sjasone return (ENOENT); \ 1163234370Sjasone READONLY(); \ 1164245868Sjasone oldval = (v); \ 1165234370Sjasone READ(oldval, t); \ 1166234370Sjasone \ 1167234370Sjasone ret = 0; \ 1168235238Sjasonelabel_return: \ 1169234370Sjasone return (ret); \ 1170234370Sjasone} 1171234370Sjasone 1172234370Sjasone#define CTL_RO_NL_GEN(n, v, t) \ 1173234370Sjasonestatic int \ 1174234370Sjasonen##_ctl(const size_t *mib, size_t miblen, void *oldp, size_t *oldlenp, \ 1175234370Sjasone void *newp, size_t newlen) \ 1176234370Sjasone{ \ 1177234370Sjasone int ret; \ 1178234370Sjasone t oldval; \ 1179234370Sjasone \ 1180234370Sjasone READONLY(); \ 1181245868Sjasone oldval = (v); \ 1182234370Sjasone READ(oldval, t); \ 1183234370Sjasone \ 1184234370Sjasone ret = 0; \ 1185235238Sjasonelabel_return: \ 1186234370Sjasone return (ret); \ 1187234370Sjasone} 1188234370Sjasone 1189286866Sjasone#define CTL_TSD_RO_NL_CGEN(c, n, m, t) \ 1190286866Sjasonestatic int \ 1191286866Sjasonen##_ctl(const size_t *mib, size_t miblen, void *oldp, size_t *oldlenp, \ 1192286866Sjasone void *newp, size_t newlen) \ 1193286866Sjasone{ \ 1194286866Sjasone int ret; \ 1195286866Sjasone t oldval; \ 1196286866Sjasone tsd_t *tsd; \ 1197286866Sjasone \ 1198286866Sjasone if (!(c)) \ 1199286866Sjasone return (ENOENT); \ 1200286866Sjasone READONLY(); \ 1201286866Sjasone tsd = tsd_fetch(); \ 1202286866Sjasone oldval = (m(tsd)); \ 1203286866Sjasone READ(oldval, t); \ 1204286866Sjasone \ 1205286866Sjasone ret = 0; \ 1206286866Sjasonelabel_return: \ 1207286866Sjasone return (ret); \ 1208286866Sjasone} 1209286866Sjasone 1210296221Sjasone#define CTL_RO_CONFIG_GEN(n, t) \ 1211234370Sjasonestatic int \ 1212234370Sjasonen##_ctl(const size_t *mib, size_t miblen, void *oldp, size_t *oldlenp, \ 1213234370Sjasone void *newp, size_t newlen) \ 1214234370Sjasone{ \ 1215234370Sjasone int ret; \ 1216296221Sjasone t oldval; \ 1217234370Sjasone \ 1218234370Sjasone READONLY(); \ 1219234370Sjasone oldval = n; \ 1220296221Sjasone READ(oldval, t); \ 1221234370Sjasone \ 1222234370Sjasone ret = 0; \ 1223235238Sjasonelabel_return: \ 1224234370Sjasone return (ret); \ 1225234370Sjasone} 1226234370Sjasone 1227261071Sjasone/******************************************************************************/ 1228261071Sjasone 1229234370SjasoneCTL_RO_NL_GEN(version, JEMALLOC_VERSION, const char *) 1230234370Sjasone 1231234370Sjasonestatic int 1232234370Sjasoneepoch_ctl(const size_t *mib, size_t miblen, void *oldp, size_t *oldlenp, 1233234370Sjasone void *newp, size_t newlen) 1234234370Sjasone{ 1235234370Sjasone int ret; 1236256823Sjasone UNUSED uint64_t newval; 1237234370Sjasone 1238234370Sjasone malloc_mutex_lock(&ctl_mtx); 1239234370Sjasone WRITE(newval, uint64_t); 1240235238Sjasone if (newp != NULL) 1241234370Sjasone ctl_refresh(); 1242234370Sjasone READ(ctl_epoch, uint64_t); 1243234370Sjasone 1244234370Sjasone ret = 0; 1245234370Sjasonelabel_return: 1246234370Sjasone malloc_mutex_unlock(&ctl_mtx); 1247234370Sjasone return (ret); 1248234370Sjasone} 1249234370Sjasone 1250261071Sjasone/******************************************************************************/ 1251234370Sjasone 1252296221SjasoneCTL_RO_CONFIG_GEN(config_cache_oblivious, bool) 1253296221SjasoneCTL_RO_CONFIG_GEN(config_debug, bool) 1254296221SjasoneCTL_RO_CONFIG_GEN(config_fill, bool) 1255296221SjasoneCTL_RO_CONFIG_GEN(config_lazy_lock, bool) 1256296221SjasoneCTL_RO_CONFIG_GEN(config_malloc_conf, const char *) 1257296221SjasoneCTL_RO_CONFIG_GEN(config_munmap, bool) 1258296221SjasoneCTL_RO_CONFIG_GEN(config_prof, bool) 1259296221SjasoneCTL_RO_CONFIG_GEN(config_prof_libgcc, bool) 1260296221SjasoneCTL_RO_CONFIG_GEN(config_prof_libunwind, bool) 1261296221SjasoneCTL_RO_CONFIG_GEN(config_stats, bool) 1262296221SjasoneCTL_RO_CONFIG_GEN(config_tcache, bool) 1263296221SjasoneCTL_RO_CONFIG_GEN(config_tls, bool) 1264296221SjasoneCTL_RO_CONFIG_GEN(config_utrace, bool) 1265296221SjasoneCTL_RO_CONFIG_GEN(config_valgrind, bool) 1266296221SjasoneCTL_RO_CONFIG_GEN(config_xmalloc, bool) 1267234370Sjasone 1268261071Sjasone/******************************************************************************/ 1269234370Sjasone 1270261071SjasoneCTL_RO_NL_GEN(opt_abort, opt_abort, bool) 1271261071SjasoneCTL_RO_NL_GEN(opt_dss, opt_dss, const char *) 1272261071SjasoneCTL_RO_NL_GEN(opt_lg_chunk, opt_lg_chunk, size_t) 1273296221SjasoneCTL_RO_NL_GEN(opt_narenas, opt_narenas, unsigned) 1274296221SjasoneCTL_RO_NL_GEN(opt_purge, purge_mode_names[opt_purge], const char *) 1275261071SjasoneCTL_RO_NL_GEN(opt_lg_dirty_mult, opt_lg_dirty_mult, ssize_t) 1276296221SjasoneCTL_RO_NL_GEN(opt_decay_time, opt_decay_time, ssize_t) 1277261071SjasoneCTL_RO_NL_GEN(opt_stats_print, opt_stats_print, bool) 1278286866SjasoneCTL_RO_NL_CGEN(config_fill, opt_junk, opt_junk, const char *) 1279261071SjasoneCTL_RO_NL_CGEN(config_fill, opt_quarantine, opt_quarantine, size_t) 1280261071SjasoneCTL_RO_NL_CGEN(config_fill, opt_redzone, opt_redzone, bool) 1281261071SjasoneCTL_RO_NL_CGEN(config_fill, opt_zero, opt_zero, bool) 1282261071SjasoneCTL_RO_NL_CGEN(config_utrace, opt_utrace, opt_utrace, bool) 1283261071SjasoneCTL_RO_NL_CGEN(config_xmalloc, opt_xmalloc, opt_xmalloc, bool) 1284261071SjasoneCTL_RO_NL_CGEN(config_tcache, opt_tcache, opt_tcache, bool) 1285261071SjasoneCTL_RO_NL_CGEN(config_tcache, opt_lg_tcache_max, opt_lg_tcache_max, ssize_t) 1286261071SjasoneCTL_RO_NL_CGEN(config_prof, opt_prof, opt_prof, bool) 1287261071SjasoneCTL_RO_NL_CGEN(config_prof, opt_prof_prefix, opt_prof_prefix, const char *) 1288286866SjasoneCTL_RO_NL_CGEN(config_prof, opt_prof_active, opt_prof_active, bool) 1289286866SjasoneCTL_RO_NL_CGEN(config_prof, opt_prof_thread_active_init, 1290286866Sjasone opt_prof_thread_active_init, bool) 1291261071SjasoneCTL_RO_NL_CGEN(config_prof, opt_lg_prof_sample, opt_lg_prof_sample, size_t) 1292261071SjasoneCTL_RO_NL_CGEN(config_prof, opt_prof_accum, opt_prof_accum, bool) 1293261071SjasoneCTL_RO_NL_CGEN(config_prof, opt_lg_prof_interval, opt_lg_prof_interval, ssize_t) 1294261071SjasoneCTL_RO_NL_CGEN(config_prof, opt_prof_gdump, opt_prof_gdump, bool) 1295261071SjasoneCTL_RO_NL_CGEN(config_prof, opt_prof_final, opt_prof_final, bool) 1296261071SjasoneCTL_RO_NL_CGEN(config_prof, opt_prof_leak, opt_prof_leak, bool) 1297234370Sjasone 1298261071Sjasone/******************************************************************************/ 1299234370Sjasone 1300234370Sjasonestatic int 1301234370Sjasonethread_arena_ctl(const size_t *mib, size_t miblen, void *oldp, size_t *oldlenp, 1302234370Sjasone void *newp, size_t newlen) 1303234370Sjasone{ 1304234370Sjasone int ret; 1305286866Sjasone tsd_t *tsd; 1306286866Sjasone arena_t *oldarena; 1307234370Sjasone unsigned newind, oldind; 1308234370Sjasone 1309286866Sjasone tsd = tsd_fetch(); 1310286866Sjasone oldarena = arena_choose(tsd, NULL); 1311286866Sjasone if (oldarena == NULL) 1312286866Sjasone return (EAGAIN); 1313286866Sjasone 1314242844Sjasone malloc_mutex_lock(&ctl_mtx); 1315286866Sjasone newind = oldind = oldarena->ind; 1316234370Sjasone WRITE(newind, unsigned); 1317234370Sjasone READ(oldind, unsigned); 1318234370Sjasone if (newind != oldind) { 1319286866Sjasone arena_t *newarena; 1320234370Sjasone 1321242844Sjasone if (newind >= ctl_stats.narenas) { 1322234370Sjasone /* New arena index is out of range. */ 1323234370Sjasone ret = EFAULT; 1324234370Sjasone goto label_return; 1325234370Sjasone } 1326234370Sjasone 1327234370Sjasone /* Initialize arena if necessary. */ 1328296221Sjasone newarena = arena_get(newind, true); 1329286866Sjasone if (newarena == NULL) { 1330234370Sjasone ret = EAGAIN; 1331234370Sjasone goto label_return; 1332234370Sjasone } 1333286866Sjasone /* Set new arena/tcache associations. */ 1334286866Sjasone arena_migrate(tsd, oldind, newind); 1335234370Sjasone if (config_tcache) { 1336286866Sjasone tcache_t *tcache = tsd_tcache_get(tsd); 1337286866Sjasone if (tcache != NULL) { 1338286866Sjasone tcache_arena_reassociate(tcache, oldarena, 1339286866Sjasone newarena); 1340234370Sjasone } 1341234370Sjasone } 1342234370Sjasone } 1343234370Sjasone 1344234370Sjasone ret = 0; 1345234370Sjasonelabel_return: 1346242844Sjasone malloc_mutex_unlock(&ctl_mtx); 1347234370Sjasone return (ret); 1348234370Sjasone} 1349234370Sjasone 1350286866SjasoneCTL_TSD_RO_NL_CGEN(config_stats, thread_allocated, tsd_thread_allocated_get, 1351286866Sjasone uint64_t) 1352286866SjasoneCTL_TSD_RO_NL_CGEN(config_stats, thread_allocatedp, tsd_thread_allocatedp_get, 1353286866Sjasone uint64_t *) 1354286866SjasoneCTL_TSD_RO_NL_CGEN(config_stats, thread_deallocated, tsd_thread_deallocated_get, 1355286866Sjasone uint64_t) 1356286866SjasoneCTL_TSD_RO_NL_CGEN(config_stats, thread_deallocatedp, 1357286866Sjasone tsd_thread_deallocatedp_get, uint64_t *) 1358234370Sjasone 1359261071Sjasonestatic int 1360261071Sjasonethread_tcache_enabled_ctl(const size_t *mib, size_t miblen, void *oldp, 1361261071Sjasone size_t *oldlenp, void *newp, size_t newlen) 1362261071Sjasone{ 1363261071Sjasone int ret; 1364261071Sjasone bool oldval; 1365234370Sjasone 1366286866Sjasone if (!config_tcache) 1367261071Sjasone return (ENOENT); 1368234370Sjasone 1369261071Sjasone oldval = tcache_enabled_get(); 1370261071Sjasone if (newp != NULL) { 1371261071Sjasone if (newlen != sizeof(bool)) { 1372261071Sjasone ret = EINVAL; 1373261071Sjasone goto label_return; 1374261071Sjasone } 1375261071Sjasone tcache_enabled_set(*(bool *)newp); 1376261071Sjasone } 1377261071Sjasone READ(oldval, bool); 1378234370Sjasone 1379261071Sjasone ret = 0; 1380261071Sjasonelabel_return: 1381261071Sjasone return (ret); 1382261071Sjasone} 1383234370Sjasone 1384261071Sjasonestatic int 1385261071Sjasonethread_tcache_flush_ctl(const size_t *mib, size_t miblen, void *oldp, 1386261071Sjasone size_t *oldlenp, void *newp, size_t newlen) 1387261071Sjasone{ 1388261071Sjasone int ret; 1389261071Sjasone 1390286866Sjasone if (!config_tcache) 1391261071Sjasone return (ENOENT); 1392261071Sjasone 1393261071Sjasone READONLY(); 1394261071Sjasone WRITEONLY(); 1395261071Sjasone 1396261071Sjasone tcache_flush(); 1397261071Sjasone 1398261071Sjasone ret = 0; 1399261071Sjasonelabel_return: 1400261071Sjasone return (ret); 1401261071Sjasone} 1402261071Sjasone 1403286866Sjasonestatic int 1404286866Sjasonethread_prof_name_ctl(const size_t *mib, size_t miblen, void *oldp, 1405286866Sjasone size_t *oldlenp, void *newp, size_t newlen) 1406286866Sjasone{ 1407286866Sjasone int ret; 1408286866Sjasone 1409286866Sjasone if (!config_prof) 1410286866Sjasone return (ENOENT); 1411286866Sjasone 1412286866Sjasone READ_XOR_WRITE(); 1413286866Sjasone 1414286866Sjasone if (newp != NULL) { 1415286866Sjasone tsd_t *tsd; 1416286866Sjasone 1417286866Sjasone if (newlen != sizeof(const char *)) { 1418286866Sjasone ret = EINVAL; 1419286866Sjasone goto label_return; 1420286866Sjasone } 1421286866Sjasone 1422286866Sjasone tsd = tsd_fetch(); 1423286866Sjasone 1424286866Sjasone if ((ret = prof_thread_name_set(tsd, *(const char **)newp)) != 1425286866Sjasone 0) 1426286866Sjasone goto label_return; 1427286866Sjasone } else { 1428286866Sjasone const char *oldname = prof_thread_name_get(); 1429286866Sjasone READ(oldname, const char *); 1430286866Sjasone } 1431286866Sjasone 1432286866Sjasone ret = 0; 1433286866Sjasonelabel_return: 1434286866Sjasone return (ret); 1435286866Sjasone} 1436286866Sjasone 1437286866Sjasonestatic int 1438286866Sjasonethread_prof_active_ctl(const size_t *mib, size_t miblen, void *oldp, 1439286866Sjasone size_t *oldlenp, void *newp, size_t newlen) 1440286866Sjasone{ 1441286866Sjasone int ret; 1442286866Sjasone bool oldval; 1443286866Sjasone 1444286866Sjasone if (!config_prof) 1445286866Sjasone return (ENOENT); 1446286866Sjasone 1447286866Sjasone oldval = prof_thread_active_get(); 1448286866Sjasone if (newp != NULL) { 1449286866Sjasone if (newlen != sizeof(bool)) { 1450286866Sjasone ret = EINVAL; 1451286866Sjasone goto label_return; 1452286866Sjasone } 1453286866Sjasone if (prof_thread_active_set(*(bool *)newp)) { 1454286866Sjasone ret = EAGAIN; 1455286866Sjasone goto label_return; 1456286866Sjasone } 1457286866Sjasone } 1458286866Sjasone READ(oldval, bool); 1459286866Sjasone 1460286866Sjasone ret = 0; 1461286866Sjasonelabel_return: 1462286866Sjasone return (ret); 1463286866Sjasone} 1464286866Sjasone 1465234370Sjasone/******************************************************************************/ 1466234370Sjasone 1467286866Sjasonestatic int 1468286866Sjasonetcache_create_ctl(const size_t *mib, size_t miblen, void *oldp, size_t *oldlenp, 1469286866Sjasone void *newp, size_t newlen) 1470286866Sjasone{ 1471286866Sjasone int ret; 1472286866Sjasone tsd_t *tsd; 1473286866Sjasone unsigned tcache_ind; 1474286866Sjasone 1475286866Sjasone if (!config_tcache) 1476286866Sjasone return (ENOENT); 1477286866Sjasone 1478286866Sjasone tsd = tsd_fetch(); 1479286866Sjasone 1480286866Sjasone malloc_mutex_lock(&ctl_mtx); 1481286866Sjasone READONLY(); 1482286866Sjasone if (tcaches_create(tsd, &tcache_ind)) { 1483286866Sjasone ret = EFAULT; 1484286866Sjasone goto label_return; 1485286866Sjasone } 1486286866Sjasone READ(tcache_ind, unsigned); 1487286866Sjasone 1488286866Sjasone ret = 0; 1489286866Sjasonelabel_return: 1490286866Sjasone malloc_mutex_unlock(&ctl_mtx); 1491286866Sjasone return (ret); 1492286866Sjasone} 1493286866Sjasone 1494286866Sjasonestatic int 1495286866Sjasonetcache_flush_ctl(const size_t *mib, size_t miblen, void *oldp, size_t *oldlenp, 1496286866Sjasone void *newp, size_t newlen) 1497286866Sjasone{ 1498286866Sjasone int ret; 1499286866Sjasone tsd_t *tsd; 1500286866Sjasone unsigned tcache_ind; 1501286866Sjasone 1502286866Sjasone if (!config_tcache) 1503286866Sjasone return (ENOENT); 1504286866Sjasone 1505286866Sjasone tsd = tsd_fetch(); 1506286866Sjasone 1507286866Sjasone WRITEONLY(); 1508286866Sjasone tcache_ind = UINT_MAX; 1509286866Sjasone WRITE(tcache_ind, unsigned); 1510286866Sjasone if (tcache_ind == UINT_MAX) { 1511286866Sjasone ret = EFAULT; 1512286866Sjasone goto label_return; 1513286866Sjasone } 1514286866Sjasone tcaches_flush(tsd, tcache_ind); 1515286866Sjasone 1516286866Sjasone ret = 0; 1517286866Sjasonelabel_return: 1518286866Sjasone return (ret); 1519286866Sjasone} 1520286866Sjasone 1521286866Sjasonestatic int 1522286866Sjasonetcache_destroy_ctl(const size_t *mib, size_t miblen, void *oldp, 1523286866Sjasone size_t *oldlenp, void *newp, size_t newlen) 1524286866Sjasone{ 1525286866Sjasone int ret; 1526286866Sjasone tsd_t *tsd; 1527286866Sjasone unsigned tcache_ind; 1528286866Sjasone 1529286866Sjasone if (!config_tcache) 1530286866Sjasone return (ENOENT); 1531286866Sjasone 1532286866Sjasone tsd = tsd_fetch(); 1533286866Sjasone 1534286866Sjasone WRITEONLY(); 1535286866Sjasone tcache_ind = UINT_MAX; 1536286866Sjasone WRITE(tcache_ind, unsigned); 1537286866Sjasone if (tcache_ind == UINT_MAX) { 1538286866Sjasone ret = EFAULT; 1539286866Sjasone goto label_return; 1540286866Sjasone } 1541286866Sjasone tcaches_destroy(tsd, tcache_ind); 1542286866Sjasone 1543286866Sjasone ret = 0; 1544286866Sjasonelabel_return: 1545286866Sjasone return (ret); 1546286866Sjasone} 1547286866Sjasone 1548286866Sjasone/******************************************************************************/ 1549286866Sjasone 1550242844Sjasonestatic void 1551296221Sjasonearena_i_purge(unsigned arena_ind, bool all) 1552242844Sjasone{ 1553242844Sjasone 1554296221Sjasone malloc_mutex_lock(&ctl_mtx); 1555296221Sjasone { 1556296221Sjasone unsigned narenas = ctl_stats.narenas; 1557242844Sjasone 1558296221Sjasone if (arena_ind == narenas) { 1559296221Sjasone unsigned i; 1560296221Sjasone VARIABLE_ARRAY(arena_t *, tarenas, narenas); 1561296221Sjasone 1562296221Sjasone for (i = 0; i < narenas; i++) 1563296221Sjasone tarenas[i] = arena_get(i, false); 1564296221Sjasone 1565296221Sjasone /* 1566296221Sjasone * No further need to hold ctl_mtx, since narenas and 1567296221Sjasone * tarenas contain everything needed below. 1568296221Sjasone */ 1569296221Sjasone malloc_mutex_unlock(&ctl_mtx); 1570296221Sjasone 1571296221Sjasone for (i = 0; i < narenas; i++) { 1572296221Sjasone if (tarenas[i] != NULL) 1573296221Sjasone arena_purge(tarenas[i], all); 1574296221Sjasone } 1575296221Sjasone } else { 1576296221Sjasone arena_t *tarena; 1577296221Sjasone 1578296221Sjasone assert(arena_ind < narenas); 1579296221Sjasone 1580296221Sjasone tarena = arena_get(arena_ind, false); 1581296221Sjasone 1582296221Sjasone /* No further need to hold ctl_mtx. */ 1583296221Sjasone malloc_mutex_unlock(&ctl_mtx); 1584296221Sjasone 1585296221Sjasone if (tarena != NULL) 1586296221Sjasone arena_purge(tarena, all); 1587242844Sjasone } 1588242844Sjasone } 1589242844Sjasone} 1590242844Sjasone 1591242844Sjasonestatic int 1592242844Sjasonearena_i_purge_ctl(const size_t *mib, size_t miblen, void *oldp, size_t *oldlenp, 1593242844Sjasone void *newp, size_t newlen) 1594242844Sjasone{ 1595242844Sjasone int ret; 1596242844Sjasone 1597242844Sjasone READONLY(); 1598242844Sjasone WRITEONLY(); 1599296221Sjasone arena_i_purge((unsigned)mib[1], true); 1600242844Sjasone 1601242844Sjasone ret = 0; 1602242844Sjasonelabel_return: 1603242844Sjasone return (ret); 1604242844Sjasone} 1605242844Sjasone 1606242844Sjasonestatic int 1607296221Sjasonearena_i_decay_ctl(const size_t *mib, size_t miblen, void *oldp, size_t *oldlenp, 1608296221Sjasone void *newp, size_t newlen) 1609296221Sjasone{ 1610296221Sjasone int ret; 1611296221Sjasone 1612296221Sjasone READONLY(); 1613296221Sjasone WRITEONLY(); 1614296221Sjasone arena_i_purge((unsigned)mib[1], false); 1615296221Sjasone 1616296221Sjasone ret = 0; 1617296221Sjasonelabel_return: 1618296221Sjasone return (ret); 1619296221Sjasone} 1620296221Sjasone 1621296221Sjasonestatic int 1622242844Sjasonearena_i_dss_ctl(const size_t *mib, size_t miblen, void *oldp, size_t *oldlenp, 1623242844Sjasone void *newp, size_t newlen) 1624242844Sjasone{ 1625286866Sjasone int ret; 1626286866Sjasone const char *dss = NULL; 1627296221Sjasone unsigned arena_ind = (unsigned)mib[1]; 1628242844Sjasone dss_prec_t dss_prec_old = dss_prec_limit; 1629242844Sjasone dss_prec_t dss_prec = dss_prec_limit; 1630242844Sjasone 1631242844Sjasone malloc_mutex_lock(&ctl_mtx); 1632242844Sjasone WRITE(dss, const char *); 1633286866Sjasone if (dss != NULL) { 1634286866Sjasone int i; 1635286866Sjasone bool match = false; 1636286866Sjasone 1637286866Sjasone for (i = 0; i < dss_prec_limit; i++) { 1638286866Sjasone if (strcmp(dss_prec_names[i], dss) == 0) { 1639286866Sjasone dss_prec = i; 1640286866Sjasone match = true; 1641286866Sjasone break; 1642286866Sjasone } 1643242844Sjasone } 1644286866Sjasone 1645286866Sjasone if (!match) { 1646286866Sjasone ret = EINVAL; 1647286866Sjasone goto label_return; 1648286866Sjasone } 1649242844Sjasone } 1650242844Sjasone 1651242844Sjasone if (arena_ind < ctl_stats.narenas) { 1652296221Sjasone arena_t *arena = arena_get(arena_ind, false); 1653286866Sjasone if (arena == NULL || (dss_prec != dss_prec_limit && 1654286866Sjasone arena_dss_prec_set(arena, dss_prec))) { 1655286866Sjasone ret = EFAULT; 1656286866Sjasone goto label_return; 1657286866Sjasone } 1658286866Sjasone dss_prec_old = arena_dss_prec_get(arena); 1659242844Sjasone } else { 1660286866Sjasone if (dss_prec != dss_prec_limit && 1661286866Sjasone chunk_dss_prec_set(dss_prec)) { 1662286866Sjasone ret = EFAULT; 1663286866Sjasone goto label_return; 1664286866Sjasone } 1665242844Sjasone dss_prec_old = chunk_dss_prec_get(); 1666242844Sjasone } 1667286866Sjasone 1668242844Sjasone dss = dss_prec_names[dss_prec_old]; 1669242844Sjasone READ(dss, const char *); 1670286866Sjasone 1671286866Sjasone ret = 0; 1672286866Sjasonelabel_return: 1673286866Sjasone malloc_mutex_unlock(&ctl_mtx); 1674286866Sjasone return (ret); 1675286866Sjasone} 1676286866Sjasone 1677286866Sjasonestatic int 1678286866Sjasonearena_i_lg_dirty_mult_ctl(const size_t *mib, size_t miblen, void *oldp, 1679286866Sjasone size_t *oldlenp, void *newp, size_t newlen) 1680286866Sjasone{ 1681286866Sjasone int ret; 1682296221Sjasone unsigned arena_ind = (unsigned)mib[1]; 1683286866Sjasone arena_t *arena; 1684286866Sjasone 1685296221Sjasone arena = arena_get(arena_ind, false); 1686286866Sjasone if (arena == NULL) { 1687242844Sjasone ret = EFAULT; 1688242844Sjasone goto label_return; 1689242844Sjasone } 1690242844Sjasone 1691286866Sjasone if (oldp != NULL && oldlenp != NULL) { 1692286866Sjasone size_t oldval = arena_lg_dirty_mult_get(arena); 1693286866Sjasone READ(oldval, ssize_t); 1694286866Sjasone } 1695286866Sjasone if (newp != NULL) { 1696286866Sjasone if (newlen != sizeof(ssize_t)) { 1697286866Sjasone ret = EINVAL; 1698286866Sjasone goto label_return; 1699286866Sjasone } 1700286866Sjasone if (arena_lg_dirty_mult_set(arena, *(ssize_t *)newp)) { 1701286866Sjasone ret = EFAULT; 1702286866Sjasone goto label_return; 1703286866Sjasone } 1704286866Sjasone } 1705286866Sjasone 1706242844Sjasone ret = 0; 1707242844Sjasonelabel_return: 1708286866Sjasone return (ret); 1709286866Sjasone} 1710286866Sjasone 1711286866Sjasonestatic int 1712296221Sjasonearena_i_decay_time_ctl(const size_t *mib, size_t miblen, void *oldp, 1713296221Sjasone size_t *oldlenp, void *newp, size_t newlen) 1714296221Sjasone{ 1715296221Sjasone int ret; 1716296221Sjasone unsigned arena_ind = (unsigned)mib[1]; 1717296221Sjasone arena_t *arena; 1718296221Sjasone 1719296221Sjasone arena = arena_get(arena_ind, false); 1720296221Sjasone if (arena == NULL) { 1721296221Sjasone ret = EFAULT; 1722296221Sjasone goto label_return; 1723296221Sjasone } 1724296221Sjasone 1725296221Sjasone if (oldp != NULL && oldlenp != NULL) { 1726296221Sjasone size_t oldval = arena_decay_time_get(arena); 1727296221Sjasone READ(oldval, ssize_t); 1728296221Sjasone } 1729296221Sjasone if (newp != NULL) { 1730296221Sjasone if (newlen != sizeof(ssize_t)) { 1731296221Sjasone ret = EINVAL; 1732296221Sjasone goto label_return; 1733296221Sjasone } 1734296221Sjasone if (arena_decay_time_set(arena, *(ssize_t *)newp)) { 1735296221Sjasone ret = EFAULT; 1736296221Sjasone goto label_return; 1737296221Sjasone } 1738296221Sjasone } 1739296221Sjasone 1740296221Sjasone ret = 0; 1741296221Sjasonelabel_return: 1742296221Sjasone return (ret); 1743296221Sjasone} 1744296221Sjasone 1745296221Sjasonestatic int 1746286866Sjasonearena_i_chunk_hooks_ctl(const size_t *mib, size_t miblen, void *oldp, 1747286866Sjasone size_t *oldlenp, void *newp, size_t newlen) 1748286866Sjasone{ 1749286866Sjasone int ret; 1750296221Sjasone unsigned arena_ind = (unsigned)mib[1]; 1751286866Sjasone arena_t *arena; 1752286866Sjasone 1753286866Sjasone malloc_mutex_lock(&ctl_mtx); 1754286866Sjasone if (arena_ind < narenas_total_get() && (arena = 1755296221Sjasone arena_get(arena_ind, false)) != NULL) { 1756286866Sjasone if (newp != NULL) { 1757286866Sjasone chunk_hooks_t old_chunk_hooks, new_chunk_hooks; 1758286866Sjasone WRITE(new_chunk_hooks, chunk_hooks_t); 1759286866Sjasone old_chunk_hooks = chunk_hooks_set(arena, 1760286866Sjasone &new_chunk_hooks); 1761286866Sjasone READ(old_chunk_hooks, chunk_hooks_t); 1762286866Sjasone } else { 1763286866Sjasone chunk_hooks_t old_chunk_hooks = chunk_hooks_get(arena); 1764286866Sjasone READ(old_chunk_hooks, chunk_hooks_t); 1765286866Sjasone } 1766286866Sjasone } else { 1767286866Sjasone ret = EFAULT; 1768286866Sjasone goto label_return; 1769286866Sjasone } 1770286866Sjasone ret = 0; 1771286866Sjasonelabel_return: 1772242844Sjasone malloc_mutex_unlock(&ctl_mtx); 1773242844Sjasone return (ret); 1774242844Sjasone} 1775242844Sjasone 1776242844Sjasonestatic const ctl_named_node_t * 1777242844Sjasonearena_i_index(const size_t *mib, size_t miblen, size_t i) 1778242844Sjasone{ 1779242844Sjasone const ctl_named_node_t * ret; 1780242844Sjasone 1781242844Sjasone malloc_mutex_lock(&ctl_mtx); 1782242844Sjasone if (i > ctl_stats.narenas) { 1783242844Sjasone ret = NULL; 1784242844Sjasone goto label_return; 1785242844Sjasone } 1786242844Sjasone 1787242844Sjasone ret = super_arena_i_node; 1788242844Sjasonelabel_return: 1789242844Sjasone malloc_mutex_unlock(&ctl_mtx); 1790242844Sjasone return (ret); 1791242844Sjasone} 1792242844Sjasone 1793242844Sjasone/******************************************************************************/ 1794242844Sjasone 1795242844Sjasonestatic int 1796242844Sjasonearenas_narenas_ctl(const size_t *mib, size_t miblen, void *oldp, 1797242844Sjasone size_t *oldlenp, void *newp, size_t newlen) 1798242844Sjasone{ 1799242844Sjasone int ret; 1800242844Sjasone unsigned narenas; 1801234370Sjasone 1802242844Sjasone malloc_mutex_lock(&ctl_mtx); 1803242844Sjasone READONLY(); 1804242844Sjasone if (*oldlenp != sizeof(unsigned)) { 1805242844Sjasone ret = EINVAL; 1806242844Sjasone goto label_return; 1807242844Sjasone } 1808242844Sjasone narenas = ctl_stats.narenas; 1809242844Sjasone READ(narenas, unsigned); 1810242844Sjasone 1811242844Sjasone ret = 0; 1812242844Sjasonelabel_return: 1813242844Sjasone malloc_mutex_unlock(&ctl_mtx); 1814242844Sjasone return (ret); 1815242844Sjasone} 1816242844Sjasone 1817234370Sjasonestatic int 1818234370Sjasonearenas_initialized_ctl(const size_t *mib, size_t miblen, void *oldp, 1819234370Sjasone size_t *oldlenp, void *newp, size_t newlen) 1820234370Sjasone{ 1821234370Sjasone int ret; 1822234370Sjasone unsigned nread, i; 1823234370Sjasone 1824234370Sjasone malloc_mutex_lock(&ctl_mtx); 1825234370Sjasone READONLY(); 1826242844Sjasone if (*oldlenp != ctl_stats.narenas * sizeof(bool)) { 1827234370Sjasone ret = EINVAL; 1828242844Sjasone nread = (*oldlenp < ctl_stats.narenas * sizeof(bool)) 1829296221Sjasone ? (unsigned)(*oldlenp / sizeof(bool)) : ctl_stats.narenas; 1830234370Sjasone } else { 1831234370Sjasone ret = 0; 1832242844Sjasone nread = ctl_stats.narenas; 1833234370Sjasone } 1834234370Sjasone 1835234370Sjasone for (i = 0; i < nread; i++) 1836234370Sjasone ((bool *)oldp)[i] = ctl_stats.arenas[i].initialized; 1837234370Sjasone 1838234370Sjasonelabel_return: 1839234370Sjasone malloc_mutex_unlock(&ctl_mtx); 1840234370Sjasone return (ret); 1841234370Sjasone} 1842234370Sjasone 1843286866Sjasonestatic int 1844286866Sjasonearenas_lg_dirty_mult_ctl(const size_t *mib, size_t miblen, void *oldp, 1845286866Sjasone size_t *oldlenp, void *newp, size_t newlen) 1846286866Sjasone{ 1847286866Sjasone int ret; 1848286866Sjasone 1849286866Sjasone if (oldp != NULL && oldlenp != NULL) { 1850286866Sjasone size_t oldval = arena_lg_dirty_mult_default_get(); 1851286866Sjasone READ(oldval, ssize_t); 1852286866Sjasone } 1853286866Sjasone if (newp != NULL) { 1854286866Sjasone if (newlen != sizeof(ssize_t)) { 1855286866Sjasone ret = EINVAL; 1856286866Sjasone goto label_return; 1857286866Sjasone } 1858286866Sjasone if (arena_lg_dirty_mult_default_set(*(ssize_t *)newp)) { 1859286866Sjasone ret = EFAULT; 1860286866Sjasone goto label_return; 1861286866Sjasone } 1862286866Sjasone } 1863286866Sjasone 1864286866Sjasone ret = 0; 1865286866Sjasonelabel_return: 1866286866Sjasone return (ret); 1867286866Sjasone} 1868286866Sjasone 1869296221Sjasonestatic int 1870296221Sjasonearenas_decay_time_ctl(const size_t *mib, size_t miblen, void *oldp, 1871296221Sjasone size_t *oldlenp, void *newp, size_t newlen) 1872296221Sjasone{ 1873296221Sjasone int ret; 1874296221Sjasone 1875296221Sjasone if (oldp != NULL && oldlenp != NULL) { 1876296221Sjasone size_t oldval = arena_decay_time_default_get(); 1877296221Sjasone READ(oldval, ssize_t); 1878296221Sjasone } 1879296221Sjasone if (newp != NULL) { 1880296221Sjasone if (newlen != sizeof(ssize_t)) { 1881296221Sjasone ret = EINVAL; 1882296221Sjasone goto label_return; 1883296221Sjasone } 1884296221Sjasone if (arena_decay_time_default_set(*(ssize_t *)newp)) { 1885296221Sjasone ret = EFAULT; 1886296221Sjasone goto label_return; 1887296221Sjasone } 1888296221Sjasone } 1889296221Sjasone 1890296221Sjasone ret = 0; 1891296221Sjasonelabel_return: 1892296221Sjasone return (ret); 1893296221Sjasone} 1894296221Sjasone 1895234370SjasoneCTL_RO_NL_GEN(arenas_quantum, QUANTUM, size_t) 1896234370SjasoneCTL_RO_NL_GEN(arenas_page, PAGE, size_t) 1897234370SjasoneCTL_RO_NL_CGEN(config_tcache, arenas_tcache_max, tcache_maxclass, size_t) 1898234370SjasoneCTL_RO_NL_GEN(arenas_nbins, NBINS, unsigned) 1899234370SjasoneCTL_RO_NL_CGEN(config_tcache, arenas_nhbins, nhbins, unsigned) 1900261071SjasoneCTL_RO_NL_GEN(arenas_bin_i_size, arena_bin_info[mib[2]].reg_size, size_t) 1901261071SjasoneCTL_RO_NL_GEN(arenas_bin_i_nregs, arena_bin_info[mib[2]].nregs, uint32_t) 1902261071SjasoneCTL_RO_NL_GEN(arenas_bin_i_run_size, arena_bin_info[mib[2]].run_size, size_t) 1903261071Sjasonestatic const ctl_named_node_t * 1904261071Sjasonearenas_bin_i_index(const size_t *mib, size_t miblen, size_t i) 1905261071Sjasone{ 1906261071Sjasone 1907261071Sjasone if (i > NBINS) 1908261071Sjasone return (NULL); 1909261071Sjasone return (super_arenas_bin_i_node); 1910261071Sjasone} 1911261071Sjasone 1912286866SjasoneCTL_RO_NL_GEN(arenas_nlruns, nlclasses, unsigned) 1913296221SjasoneCTL_RO_NL_GEN(arenas_lrun_i_size, index2size(NBINS+(szind_t)mib[2]), size_t) 1914261071Sjasonestatic const ctl_named_node_t * 1915261071Sjasonearenas_lrun_i_index(const size_t *mib, size_t miblen, size_t i) 1916261071Sjasone{ 1917234370Sjasone 1918261071Sjasone if (i > nlclasses) 1919261071Sjasone return (NULL); 1920261071Sjasone return (super_arenas_lrun_i_node); 1921261071Sjasone} 1922261071Sjasone 1923286866SjasoneCTL_RO_NL_GEN(arenas_nhchunks, nhclasses, unsigned) 1924296221SjasoneCTL_RO_NL_GEN(arenas_hchunk_i_size, index2size(NBINS+nlclasses+(szind_t)mib[2]), 1925296221Sjasone size_t) 1926286866Sjasonestatic const ctl_named_node_t * 1927286866Sjasonearenas_hchunk_i_index(const size_t *mib, size_t miblen, size_t i) 1928234370Sjasone{ 1929234370Sjasone 1930286866Sjasone if (i > nhclasses) 1931286866Sjasone return (NULL); 1932286866Sjasone return (super_arenas_hchunk_i_node); 1933242844Sjasone} 1934234370Sjasone 1935242844Sjasonestatic int 1936242844Sjasonearenas_extend_ctl(const size_t *mib, size_t miblen, void *oldp, size_t *oldlenp, 1937242844Sjasone void *newp, size_t newlen) 1938242844Sjasone{ 1939242844Sjasone int ret; 1940245868Sjasone unsigned narenas; 1941242844Sjasone 1942242844Sjasone malloc_mutex_lock(&ctl_mtx); 1943242844Sjasone READONLY(); 1944242844Sjasone if (ctl_grow()) { 1945242844Sjasone ret = EAGAIN; 1946242844Sjasone goto label_return; 1947234370Sjasone } 1948245868Sjasone narenas = ctl_stats.narenas - 1; 1949245868Sjasone READ(narenas, unsigned); 1950234370Sjasone 1951234370Sjasone ret = 0; 1952234370Sjasonelabel_return: 1953242844Sjasone malloc_mutex_unlock(&ctl_mtx); 1954234370Sjasone return (ret); 1955234370Sjasone} 1956234370Sjasone 1957234370Sjasone/******************************************************************************/ 1958234370Sjasone 1959234370Sjasonestatic int 1960286866Sjasoneprof_thread_active_init_ctl(const size_t *mib, size_t miblen, void *oldp, 1961286866Sjasone size_t *oldlenp, void *newp, size_t newlen) 1962286866Sjasone{ 1963286866Sjasone int ret; 1964286866Sjasone bool oldval; 1965286866Sjasone 1966286866Sjasone if (!config_prof) 1967286866Sjasone return (ENOENT); 1968286866Sjasone 1969286866Sjasone if (newp != NULL) { 1970286866Sjasone if (newlen != sizeof(bool)) { 1971286866Sjasone ret = EINVAL; 1972286866Sjasone goto label_return; 1973286866Sjasone } 1974286866Sjasone oldval = prof_thread_active_init_set(*(bool *)newp); 1975286866Sjasone } else 1976286866Sjasone oldval = prof_thread_active_init_get(); 1977286866Sjasone READ(oldval, bool); 1978286866Sjasone 1979286866Sjasone ret = 0; 1980286866Sjasonelabel_return: 1981286866Sjasone return (ret); 1982286866Sjasone} 1983286866Sjasone 1984286866Sjasonestatic int 1985234370Sjasoneprof_active_ctl(const size_t *mib, size_t miblen, void *oldp, size_t *oldlenp, 1986234370Sjasone void *newp, size_t newlen) 1987234370Sjasone{ 1988234370Sjasone int ret; 1989234370Sjasone bool oldval; 1990234370Sjasone 1991286866Sjasone if (!config_prof) 1992234370Sjasone return (ENOENT); 1993234370Sjasone 1994234370Sjasone if (newp != NULL) { 1995286866Sjasone if (newlen != sizeof(bool)) { 1996286866Sjasone ret = EINVAL; 1997286866Sjasone goto label_return; 1998286866Sjasone } 1999286866Sjasone oldval = prof_active_set(*(bool *)newp); 2000286866Sjasone } else 2001286866Sjasone oldval = prof_active_get(); 2002234370Sjasone READ(oldval, bool); 2003234370Sjasone 2004234370Sjasone ret = 0; 2005234370Sjasonelabel_return: 2006234370Sjasone return (ret); 2007234370Sjasone} 2008234370Sjasone 2009234370Sjasonestatic int 2010234370Sjasoneprof_dump_ctl(const size_t *mib, size_t miblen, void *oldp, size_t *oldlenp, 2011234370Sjasone void *newp, size_t newlen) 2012234370Sjasone{ 2013234370Sjasone int ret; 2014234370Sjasone const char *filename = NULL; 2015234370Sjasone 2016286866Sjasone if (!config_prof) 2017234370Sjasone return (ENOENT); 2018234370Sjasone 2019234370Sjasone WRITEONLY(); 2020234370Sjasone WRITE(filename, const char *); 2021234370Sjasone 2022234370Sjasone if (prof_mdump(filename)) { 2023234370Sjasone ret = EFAULT; 2024234370Sjasone goto label_return; 2025234370Sjasone } 2026234370Sjasone 2027234370Sjasone ret = 0; 2028234370Sjasonelabel_return: 2029234370Sjasone return (ret); 2030234370Sjasone} 2031234370Sjasone 2032286866Sjasonestatic int 2033286866Sjasoneprof_gdump_ctl(const size_t *mib, size_t miblen, void *oldp, size_t *oldlenp, 2034286866Sjasone void *newp, size_t newlen) 2035286866Sjasone{ 2036286866Sjasone int ret; 2037286866Sjasone bool oldval; 2038286866Sjasone 2039286866Sjasone if (!config_prof) 2040286866Sjasone return (ENOENT); 2041286866Sjasone 2042286866Sjasone if (newp != NULL) { 2043286866Sjasone if (newlen != sizeof(bool)) { 2044286866Sjasone ret = EINVAL; 2045286866Sjasone goto label_return; 2046286866Sjasone } 2047286866Sjasone oldval = prof_gdump_set(*(bool *)newp); 2048286866Sjasone } else 2049286866Sjasone oldval = prof_gdump_get(); 2050286866Sjasone READ(oldval, bool); 2051286866Sjasone 2052286866Sjasone ret = 0; 2053286866Sjasonelabel_return: 2054286866Sjasone return (ret); 2055286866Sjasone} 2056286866Sjasone 2057286866Sjasonestatic int 2058286866Sjasoneprof_reset_ctl(const size_t *mib, size_t miblen, void *oldp, size_t *oldlenp, 2059286866Sjasone void *newp, size_t newlen) 2060286866Sjasone{ 2061286866Sjasone int ret; 2062286866Sjasone size_t lg_sample = lg_prof_sample; 2063286866Sjasone tsd_t *tsd; 2064286866Sjasone 2065286866Sjasone if (!config_prof) 2066286866Sjasone return (ENOENT); 2067286866Sjasone 2068286866Sjasone WRITEONLY(); 2069286866Sjasone WRITE(lg_sample, size_t); 2070286866Sjasone if (lg_sample >= (sizeof(uint64_t) << 3)) 2071286866Sjasone lg_sample = (sizeof(uint64_t) << 3) - 1; 2072286866Sjasone 2073286866Sjasone tsd = tsd_fetch(); 2074286866Sjasone 2075286866Sjasone prof_reset(tsd, lg_sample); 2076286866Sjasone 2077286866Sjasone ret = 0; 2078286866Sjasonelabel_return: 2079286866Sjasone return (ret); 2080286866Sjasone} 2081286866Sjasone 2082234370SjasoneCTL_RO_NL_CGEN(config_prof, prof_interval, prof_interval, uint64_t) 2083286866SjasoneCTL_RO_NL_CGEN(config_prof, lg_prof_sample, lg_prof_sample, size_t) 2084234370Sjasone 2085234370Sjasone/******************************************************************************/ 2086234370Sjasone 2087261071SjasoneCTL_RO_CGEN(config_stats, stats_cactive, &stats_cactive, size_t *) 2088261071SjasoneCTL_RO_CGEN(config_stats, stats_allocated, ctl_stats.allocated, size_t) 2089261071SjasoneCTL_RO_CGEN(config_stats, stats_active, ctl_stats.active, size_t) 2090286866SjasoneCTL_RO_CGEN(config_stats, stats_metadata, ctl_stats.metadata, size_t) 2091286866SjasoneCTL_RO_CGEN(config_stats, stats_resident, ctl_stats.resident, size_t) 2092261071SjasoneCTL_RO_CGEN(config_stats, stats_mapped, ctl_stats.mapped, size_t) 2093261071Sjasone 2094261071SjasoneCTL_RO_GEN(stats_arenas_i_dss, ctl_stats.arenas[mib[2]].dss, const char *) 2095286866SjasoneCTL_RO_GEN(stats_arenas_i_lg_dirty_mult, ctl_stats.arenas[mib[2]].lg_dirty_mult, 2096286866Sjasone ssize_t) 2097296221SjasoneCTL_RO_GEN(stats_arenas_i_decay_time, ctl_stats.arenas[mib[2]].decay_time, 2098296221Sjasone ssize_t) 2099261071SjasoneCTL_RO_GEN(stats_arenas_i_nthreads, ctl_stats.arenas[mib[2]].nthreads, unsigned) 2100261071SjasoneCTL_RO_GEN(stats_arenas_i_pactive, ctl_stats.arenas[mib[2]].pactive, size_t) 2101261071SjasoneCTL_RO_GEN(stats_arenas_i_pdirty, ctl_stats.arenas[mib[2]].pdirty, size_t) 2102261071SjasoneCTL_RO_CGEN(config_stats, stats_arenas_i_mapped, 2103261071Sjasone ctl_stats.arenas[mib[2]].astats.mapped, size_t) 2104261071SjasoneCTL_RO_CGEN(config_stats, stats_arenas_i_npurge, 2105261071Sjasone ctl_stats.arenas[mib[2]].astats.npurge, uint64_t) 2106261071SjasoneCTL_RO_CGEN(config_stats, stats_arenas_i_nmadvise, 2107261071Sjasone ctl_stats.arenas[mib[2]].astats.nmadvise, uint64_t) 2108261071SjasoneCTL_RO_CGEN(config_stats, stats_arenas_i_purged, 2109261071Sjasone ctl_stats.arenas[mib[2]].astats.purged, uint64_t) 2110286866SjasoneCTL_RO_CGEN(config_stats, stats_arenas_i_metadata_mapped, 2111286866Sjasone ctl_stats.arenas[mib[2]].astats.metadata_mapped, size_t) 2112286866SjasoneCTL_RO_CGEN(config_stats, stats_arenas_i_metadata_allocated, 2113286866Sjasone ctl_stats.arenas[mib[2]].astats.metadata_allocated, size_t) 2114261071Sjasone 2115234370SjasoneCTL_RO_CGEN(config_stats, stats_arenas_i_small_allocated, 2116234370Sjasone ctl_stats.arenas[mib[2]].allocated_small, size_t) 2117234370SjasoneCTL_RO_CGEN(config_stats, stats_arenas_i_small_nmalloc, 2118234370Sjasone ctl_stats.arenas[mib[2]].nmalloc_small, uint64_t) 2119234370SjasoneCTL_RO_CGEN(config_stats, stats_arenas_i_small_ndalloc, 2120234370Sjasone ctl_stats.arenas[mib[2]].ndalloc_small, uint64_t) 2121234370SjasoneCTL_RO_CGEN(config_stats, stats_arenas_i_small_nrequests, 2122234370Sjasone ctl_stats.arenas[mib[2]].nrequests_small, uint64_t) 2123234370SjasoneCTL_RO_CGEN(config_stats, stats_arenas_i_large_allocated, 2124234370Sjasone ctl_stats.arenas[mib[2]].astats.allocated_large, size_t) 2125234370SjasoneCTL_RO_CGEN(config_stats, stats_arenas_i_large_nmalloc, 2126234370Sjasone ctl_stats.arenas[mib[2]].astats.nmalloc_large, uint64_t) 2127234370SjasoneCTL_RO_CGEN(config_stats, stats_arenas_i_large_ndalloc, 2128234370Sjasone ctl_stats.arenas[mib[2]].astats.ndalloc_large, uint64_t) 2129234370SjasoneCTL_RO_CGEN(config_stats, stats_arenas_i_large_nrequests, 2130234370Sjasone ctl_stats.arenas[mib[2]].astats.nrequests_large, uint64_t) 2131286866SjasoneCTL_RO_CGEN(config_stats, stats_arenas_i_huge_allocated, 2132286866Sjasone ctl_stats.arenas[mib[2]].astats.allocated_huge, size_t) 2133286866SjasoneCTL_RO_CGEN(config_stats, stats_arenas_i_huge_nmalloc, 2134286866Sjasone ctl_stats.arenas[mib[2]].astats.nmalloc_huge, uint64_t) 2135286866SjasoneCTL_RO_CGEN(config_stats, stats_arenas_i_huge_ndalloc, 2136286866Sjasone ctl_stats.arenas[mib[2]].astats.ndalloc_huge, uint64_t) 2137286866SjasoneCTL_RO_CGEN(config_stats, stats_arenas_i_huge_nrequests, 2138286866Sjasone ctl_stats.arenas[mib[2]].astats.nmalloc_huge, uint64_t) /* Intentional. */ 2139234370Sjasone 2140234370SjasoneCTL_RO_CGEN(config_stats, stats_arenas_i_bins_j_nmalloc, 2141234370Sjasone ctl_stats.arenas[mib[2]].bstats[mib[4]].nmalloc, uint64_t) 2142234370SjasoneCTL_RO_CGEN(config_stats, stats_arenas_i_bins_j_ndalloc, 2143234370Sjasone ctl_stats.arenas[mib[2]].bstats[mib[4]].ndalloc, uint64_t) 2144234370SjasoneCTL_RO_CGEN(config_stats, stats_arenas_i_bins_j_nrequests, 2145234370Sjasone ctl_stats.arenas[mib[2]].bstats[mib[4]].nrequests, uint64_t) 2146286866SjasoneCTL_RO_CGEN(config_stats, stats_arenas_i_bins_j_curregs, 2147286866Sjasone ctl_stats.arenas[mib[2]].bstats[mib[4]].curregs, size_t) 2148234370SjasoneCTL_RO_CGEN(config_stats && config_tcache, stats_arenas_i_bins_j_nfills, 2149234370Sjasone ctl_stats.arenas[mib[2]].bstats[mib[4]].nfills, uint64_t) 2150234370SjasoneCTL_RO_CGEN(config_stats && config_tcache, stats_arenas_i_bins_j_nflushes, 2151234370Sjasone ctl_stats.arenas[mib[2]].bstats[mib[4]].nflushes, uint64_t) 2152234370SjasoneCTL_RO_CGEN(config_stats, stats_arenas_i_bins_j_nruns, 2153234370Sjasone ctl_stats.arenas[mib[2]].bstats[mib[4]].nruns, uint64_t) 2154234370SjasoneCTL_RO_CGEN(config_stats, stats_arenas_i_bins_j_nreruns, 2155234370Sjasone ctl_stats.arenas[mib[2]].bstats[mib[4]].reruns, uint64_t) 2156234370SjasoneCTL_RO_CGEN(config_stats, stats_arenas_i_bins_j_curruns, 2157234370Sjasone ctl_stats.arenas[mib[2]].bstats[mib[4]].curruns, size_t) 2158234370Sjasone 2159242844Sjasonestatic const ctl_named_node_t * 2160234370Sjasonestats_arenas_i_bins_j_index(const size_t *mib, size_t miblen, size_t j) 2161234370Sjasone{ 2162234370Sjasone 2163234370Sjasone if (j > NBINS) 2164234370Sjasone return (NULL); 2165234370Sjasone return (super_stats_arenas_i_bins_j_node); 2166234370Sjasone} 2167234370Sjasone 2168234370SjasoneCTL_RO_CGEN(config_stats, stats_arenas_i_lruns_j_nmalloc, 2169234370Sjasone ctl_stats.arenas[mib[2]].lstats[mib[4]].nmalloc, uint64_t) 2170234370SjasoneCTL_RO_CGEN(config_stats, stats_arenas_i_lruns_j_ndalloc, 2171234370Sjasone ctl_stats.arenas[mib[2]].lstats[mib[4]].ndalloc, uint64_t) 2172234370SjasoneCTL_RO_CGEN(config_stats, stats_arenas_i_lruns_j_nrequests, 2173234370Sjasone ctl_stats.arenas[mib[2]].lstats[mib[4]].nrequests, uint64_t) 2174234370SjasoneCTL_RO_CGEN(config_stats, stats_arenas_i_lruns_j_curruns, 2175234370Sjasone ctl_stats.arenas[mib[2]].lstats[mib[4]].curruns, size_t) 2176234370Sjasone 2177242844Sjasonestatic const ctl_named_node_t * 2178234370Sjasonestats_arenas_i_lruns_j_index(const size_t *mib, size_t miblen, size_t j) 2179234370Sjasone{ 2180234370Sjasone 2181234370Sjasone if (j > nlclasses) 2182234370Sjasone return (NULL); 2183234370Sjasone return (super_stats_arenas_i_lruns_j_node); 2184234370Sjasone} 2185234370Sjasone 2186286866SjasoneCTL_RO_CGEN(config_stats, stats_arenas_i_hchunks_j_nmalloc, 2187286866Sjasone ctl_stats.arenas[mib[2]].hstats[mib[4]].nmalloc, uint64_t) 2188286866SjasoneCTL_RO_CGEN(config_stats, stats_arenas_i_hchunks_j_ndalloc, 2189286866Sjasone ctl_stats.arenas[mib[2]].hstats[mib[4]].ndalloc, uint64_t) 2190286866SjasoneCTL_RO_CGEN(config_stats, stats_arenas_i_hchunks_j_nrequests, 2191286866Sjasone ctl_stats.arenas[mib[2]].hstats[mib[4]].nmalloc, /* Intentional. */ 2192286866Sjasone uint64_t) 2193286866SjasoneCTL_RO_CGEN(config_stats, stats_arenas_i_hchunks_j_curhchunks, 2194286866Sjasone ctl_stats.arenas[mib[2]].hstats[mib[4]].curhchunks, size_t) 2195286866Sjasone 2196242844Sjasonestatic const ctl_named_node_t * 2197286866Sjasonestats_arenas_i_hchunks_j_index(const size_t *mib, size_t miblen, size_t j) 2198286866Sjasone{ 2199286866Sjasone 2200286866Sjasone if (j > nhclasses) 2201286866Sjasone return (NULL); 2202286866Sjasone return (super_stats_arenas_i_hchunks_j_node); 2203286866Sjasone} 2204286866Sjasone 2205286866Sjasonestatic const ctl_named_node_t * 2206234370Sjasonestats_arenas_i_index(const size_t *mib, size_t miblen, size_t i) 2207234370Sjasone{ 2208235238Sjasone const ctl_named_node_t * ret; 2209234370Sjasone 2210234370Sjasone malloc_mutex_lock(&ctl_mtx); 2211286866Sjasone if (i > ctl_stats.narenas || !ctl_stats.arenas[i].initialized) { 2212234370Sjasone ret = NULL; 2213234370Sjasone goto label_return; 2214234370Sjasone } 2215234370Sjasone 2216234370Sjasone ret = super_stats_arenas_i_node; 2217234370Sjasonelabel_return: 2218234370Sjasone malloc_mutex_unlock(&ctl_mtx); 2219234370Sjasone return (ret); 2220234370Sjasone} 2221