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) \ 45299587Sjasonestatic int n##_ctl(tsd_t *tsd, const size_t *mib, size_t miblen, \ 46299587Sjasone void *oldp, size_t *oldlenp, void *newp, size_t newlen); 47234370Sjasone 48234370Sjasone#define INDEX_PROTO(n) \ 49299587Sjasonestatic const ctl_named_node_t *n##_index(tsdn_t *tsdn, \ 50299587Sjasone const size_t *mib, 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); 54299587Sjasonestatic void ctl_arena_stats_amerge(tsdn_t *tsdn, 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); 58299587Sjasonestatic void ctl_arena_refresh(tsdn_t *tsdn, arena_t *arena, unsigned i); 59299587Sjasonestatic bool ctl_grow(tsdn_t *tsdn); 60299587Sjasonestatic void ctl_refresh(tsdn_t *tsdn); 61299587Sjasonestatic bool ctl_init(tsdn_t *tsdn); 62299587Sjasonestatic int ctl_lookup(tsdn_t *tsdn, const char *name, 63299587Sjasone ctl_node_t const **nodesp, 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) 120299587Sjasonestatic void arena_i_purge(tsdn_t *tsdn, unsigned arena_ind, bool all); 121242844SjasoneCTL_PROTO(arena_i_purge) 122296221SjasoneCTL_PROTO(arena_i_decay) 123299587SjasoneCTL_PROTO(arena_i_reset) 124242844SjasoneCTL_PROTO(arena_i_dss) 125286866SjasoneCTL_PROTO(arena_i_lg_dirty_mult) 126296221SjasoneCTL_PROTO(arena_i_decay_time) 127286866SjasoneCTL_PROTO(arena_i_chunk_hooks) 128242844SjasoneINDEX_PROTO(arena_i) 129234370SjasoneCTL_PROTO(arenas_bin_i_size) 130234370SjasoneCTL_PROTO(arenas_bin_i_nregs) 131234370SjasoneCTL_PROTO(arenas_bin_i_run_size) 132234370SjasoneINDEX_PROTO(arenas_bin_i) 133234370SjasoneCTL_PROTO(arenas_lrun_i_size) 134234370SjasoneINDEX_PROTO(arenas_lrun_i) 135286866SjasoneCTL_PROTO(arenas_hchunk_i_size) 136286866SjasoneINDEX_PROTO(arenas_hchunk_i) 137234370SjasoneCTL_PROTO(arenas_narenas) 138234370SjasoneCTL_PROTO(arenas_initialized) 139286866SjasoneCTL_PROTO(arenas_lg_dirty_mult) 140296221SjasoneCTL_PROTO(arenas_decay_time) 141234370SjasoneCTL_PROTO(arenas_quantum) 142234370SjasoneCTL_PROTO(arenas_page) 143234370SjasoneCTL_PROTO(arenas_tcache_max) 144234370SjasoneCTL_PROTO(arenas_nbins) 145234370SjasoneCTL_PROTO(arenas_nhbins) 146234370SjasoneCTL_PROTO(arenas_nlruns) 147286866SjasoneCTL_PROTO(arenas_nhchunks) 148242844SjasoneCTL_PROTO(arenas_extend) 149286866SjasoneCTL_PROTO(prof_thread_active_init) 150234370SjasoneCTL_PROTO(prof_active) 151234370SjasoneCTL_PROTO(prof_dump) 152286866SjasoneCTL_PROTO(prof_gdump) 153286866SjasoneCTL_PROTO(prof_reset) 154234370SjasoneCTL_PROTO(prof_interval) 155286866SjasoneCTL_PROTO(lg_prof_sample) 156234370SjasoneCTL_PROTO(stats_arenas_i_small_allocated) 157234370SjasoneCTL_PROTO(stats_arenas_i_small_nmalloc) 158234370SjasoneCTL_PROTO(stats_arenas_i_small_ndalloc) 159234370SjasoneCTL_PROTO(stats_arenas_i_small_nrequests) 160234370SjasoneCTL_PROTO(stats_arenas_i_large_allocated) 161234370SjasoneCTL_PROTO(stats_arenas_i_large_nmalloc) 162234370SjasoneCTL_PROTO(stats_arenas_i_large_ndalloc) 163234370SjasoneCTL_PROTO(stats_arenas_i_large_nrequests) 164286866SjasoneCTL_PROTO(stats_arenas_i_huge_allocated) 165286866SjasoneCTL_PROTO(stats_arenas_i_huge_nmalloc) 166286866SjasoneCTL_PROTO(stats_arenas_i_huge_ndalloc) 167286866SjasoneCTL_PROTO(stats_arenas_i_huge_nrequests) 168234370SjasoneCTL_PROTO(stats_arenas_i_bins_j_nmalloc) 169234370SjasoneCTL_PROTO(stats_arenas_i_bins_j_ndalloc) 170234370SjasoneCTL_PROTO(stats_arenas_i_bins_j_nrequests) 171286866SjasoneCTL_PROTO(stats_arenas_i_bins_j_curregs) 172234370SjasoneCTL_PROTO(stats_arenas_i_bins_j_nfills) 173234370SjasoneCTL_PROTO(stats_arenas_i_bins_j_nflushes) 174234370SjasoneCTL_PROTO(stats_arenas_i_bins_j_nruns) 175234370SjasoneCTL_PROTO(stats_arenas_i_bins_j_nreruns) 176234370SjasoneCTL_PROTO(stats_arenas_i_bins_j_curruns) 177234370SjasoneINDEX_PROTO(stats_arenas_i_bins_j) 178234370SjasoneCTL_PROTO(stats_arenas_i_lruns_j_nmalloc) 179234370SjasoneCTL_PROTO(stats_arenas_i_lruns_j_ndalloc) 180234370SjasoneCTL_PROTO(stats_arenas_i_lruns_j_nrequests) 181234370SjasoneCTL_PROTO(stats_arenas_i_lruns_j_curruns) 182234370SjasoneINDEX_PROTO(stats_arenas_i_lruns_j) 183286866SjasoneCTL_PROTO(stats_arenas_i_hchunks_j_nmalloc) 184286866SjasoneCTL_PROTO(stats_arenas_i_hchunks_j_ndalloc) 185286866SjasoneCTL_PROTO(stats_arenas_i_hchunks_j_nrequests) 186286866SjasoneCTL_PROTO(stats_arenas_i_hchunks_j_curhchunks) 187286866SjasoneINDEX_PROTO(stats_arenas_i_hchunks_j) 188234370SjasoneCTL_PROTO(stats_arenas_i_nthreads) 189242844SjasoneCTL_PROTO(stats_arenas_i_dss) 190286866SjasoneCTL_PROTO(stats_arenas_i_lg_dirty_mult) 191296221SjasoneCTL_PROTO(stats_arenas_i_decay_time) 192234370SjasoneCTL_PROTO(stats_arenas_i_pactive) 193234370SjasoneCTL_PROTO(stats_arenas_i_pdirty) 194234370SjasoneCTL_PROTO(stats_arenas_i_mapped) 195299587SjasoneCTL_PROTO(stats_arenas_i_retained) 196234370SjasoneCTL_PROTO(stats_arenas_i_npurge) 197234370SjasoneCTL_PROTO(stats_arenas_i_nmadvise) 198234370SjasoneCTL_PROTO(stats_arenas_i_purged) 199286866SjasoneCTL_PROTO(stats_arenas_i_metadata_mapped) 200286866SjasoneCTL_PROTO(stats_arenas_i_metadata_allocated) 201234370SjasoneINDEX_PROTO(stats_arenas_i) 202234370SjasoneCTL_PROTO(stats_cactive) 203234370SjasoneCTL_PROTO(stats_allocated) 204234370SjasoneCTL_PROTO(stats_active) 205286866SjasoneCTL_PROTO(stats_metadata) 206286866SjasoneCTL_PROTO(stats_resident) 207234370SjasoneCTL_PROTO(stats_mapped) 208299587SjasoneCTL_PROTO(stats_retained) 209234370Sjasone 210234370Sjasone/******************************************************************************/ 211234370Sjasone/* mallctl tree. */ 212234370Sjasone 213234370Sjasone/* Maximum tree depth. */ 214234370Sjasone#define CTL_MAX_DEPTH 6 215234370Sjasone 216235238Sjasone#define NAME(n) {true}, n 217235238Sjasone#define CHILD(t, c) \ 218235238Sjasone sizeof(c##_node) / sizeof(ctl_##t##_node_t), \ 219235238Sjasone (ctl_node_t *)c##_node, \ 220235238Sjasone NULL 221235238Sjasone#define CTL(c) 0, NULL, c##_ctl 222234370Sjasone 223234370Sjasone/* 224234370Sjasone * Only handles internal indexed nodes, since there are currently no external 225234370Sjasone * ones. 226234370Sjasone */ 227235238Sjasone#define INDEX(i) {false}, i##_index 228234370Sjasone 229286866Sjasonestatic const ctl_named_node_t thread_tcache_node[] = { 230234370Sjasone {NAME("enabled"), CTL(thread_tcache_enabled)}, 231234370Sjasone {NAME("flush"), CTL(thread_tcache_flush)} 232234370Sjasone}; 233234370Sjasone 234286866Sjasonestatic const ctl_named_node_t thread_prof_node[] = { 235286866Sjasone {NAME("name"), CTL(thread_prof_name)}, 236286866Sjasone {NAME("active"), CTL(thread_prof_active)} 237286866Sjasone}; 238286866Sjasone 239235238Sjasonestatic const ctl_named_node_t thread_node[] = { 240234370Sjasone {NAME("arena"), CTL(thread_arena)}, 241234370Sjasone {NAME("allocated"), CTL(thread_allocated)}, 242234370Sjasone {NAME("allocatedp"), CTL(thread_allocatedp)}, 243234370Sjasone {NAME("deallocated"), CTL(thread_deallocated)}, 244234370Sjasone {NAME("deallocatedp"), CTL(thread_deallocatedp)}, 245286866Sjasone {NAME("tcache"), CHILD(named, thread_tcache)}, 246286866Sjasone {NAME("prof"), CHILD(named, thread_prof)} 247234370Sjasone}; 248234370Sjasone 249235238Sjasonestatic const ctl_named_node_t config_node[] = { 250286866Sjasone {NAME("cache_oblivious"), CTL(config_cache_oblivious)}, 251286866Sjasone {NAME("debug"), CTL(config_debug)}, 252286866Sjasone {NAME("fill"), CTL(config_fill)}, 253286866Sjasone {NAME("lazy_lock"), CTL(config_lazy_lock)}, 254296221Sjasone {NAME("malloc_conf"), CTL(config_malloc_conf)}, 255286866Sjasone {NAME("munmap"), CTL(config_munmap)}, 256286866Sjasone {NAME("prof"), CTL(config_prof)}, 257286866Sjasone {NAME("prof_libgcc"), CTL(config_prof_libgcc)}, 258286866Sjasone {NAME("prof_libunwind"), CTL(config_prof_libunwind)}, 259286866Sjasone {NAME("stats"), CTL(config_stats)}, 260286866Sjasone {NAME("tcache"), CTL(config_tcache)}, 261286866Sjasone {NAME("tls"), CTL(config_tls)}, 262286866Sjasone {NAME("utrace"), CTL(config_utrace)}, 263286866Sjasone {NAME("valgrind"), CTL(config_valgrind)}, 264286866Sjasone {NAME("xmalloc"), CTL(config_xmalloc)} 265234370Sjasone}; 266234370Sjasone 267235238Sjasonestatic const ctl_named_node_t opt_node[] = { 268286866Sjasone {NAME("abort"), CTL(opt_abort)}, 269286866Sjasone {NAME("dss"), CTL(opt_dss)}, 270286866Sjasone {NAME("lg_chunk"), CTL(opt_lg_chunk)}, 271286866Sjasone {NAME("narenas"), CTL(opt_narenas)}, 272296221Sjasone {NAME("purge"), CTL(opt_purge)}, 273286866Sjasone {NAME("lg_dirty_mult"), CTL(opt_lg_dirty_mult)}, 274296221Sjasone {NAME("decay_time"), CTL(opt_decay_time)}, 275286866Sjasone {NAME("stats_print"), CTL(opt_stats_print)}, 276286866Sjasone {NAME("junk"), CTL(opt_junk)}, 277286866Sjasone {NAME("zero"), CTL(opt_zero)}, 278286866Sjasone {NAME("quarantine"), CTL(opt_quarantine)}, 279286866Sjasone {NAME("redzone"), CTL(opt_redzone)}, 280286866Sjasone {NAME("utrace"), CTL(opt_utrace)}, 281286866Sjasone {NAME("xmalloc"), CTL(opt_xmalloc)}, 282286866Sjasone {NAME("tcache"), CTL(opt_tcache)}, 283286866Sjasone {NAME("lg_tcache_max"), CTL(opt_lg_tcache_max)}, 284286866Sjasone {NAME("prof"), CTL(opt_prof)}, 285286866Sjasone {NAME("prof_prefix"), CTL(opt_prof_prefix)}, 286286866Sjasone {NAME("prof_active"), CTL(opt_prof_active)}, 287286866Sjasone {NAME("prof_thread_active_init"), CTL(opt_prof_thread_active_init)}, 288286866Sjasone {NAME("lg_prof_sample"), CTL(opt_lg_prof_sample)}, 289286866Sjasone {NAME("lg_prof_interval"), CTL(opt_lg_prof_interval)}, 290286866Sjasone {NAME("prof_gdump"), CTL(opt_prof_gdump)}, 291286866Sjasone {NAME("prof_final"), CTL(opt_prof_final)}, 292286866Sjasone {NAME("prof_leak"), CTL(opt_prof_leak)}, 293286866Sjasone {NAME("prof_accum"), CTL(opt_prof_accum)} 294234370Sjasone}; 295234370Sjasone 296286866Sjasonestatic const ctl_named_node_t tcache_node[] = { 297286866Sjasone {NAME("create"), CTL(tcache_create)}, 298286866Sjasone {NAME("flush"), CTL(tcache_flush)}, 299286866Sjasone {NAME("destroy"), CTL(tcache_destroy)} 300286866Sjasone}; 301286866Sjasone 302242844Sjasonestatic const ctl_named_node_t arena_i_node[] = { 303286866Sjasone {NAME("purge"), CTL(arena_i_purge)}, 304296221Sjasone {NAME("decay"), CTL(arena_i_decay)}, 305299587Sjasone {NAME("reset"), CTL(arena_i_reset)}, 306286866Sjasone {NAME("dss"), CTL(arena_i_dss)}, 307286866Sjasone {NAME("lg_dirty_mult"), CTL(arena_i_lg_dirty_mult)}, 308296221Sjasone {NAME("decay_time"), CTL(arena_i_decay_time)}, 309286866Sjasone {NAME("chunk_hooks"), CTL(arena_i_chunk_hooks)} 310242844Sjasone}; 311242844Sjasonestatic const ctl_named_node_t super_arena_i_node[] = { 312286866Sjasone {NAME(""), CHILD(named, arena_i)} 313242844Sjasone}; 314242844Sjasone 315242844Sjasonestatic const ctl_indexed_node_t arena_node[] = { 316242844Sjasone {INDEX(arena_i)} 317242844Sjasone}; 318242844Sjasone 319235238Sjasonestatic const ctl_named_node_t arenas_bin_i_node[] = { 320286866Sjasone {NAME("size"), CTL(arenas_bin_i_size)}, 321286866Sjasone {NAME("nregs"), CTL(arenas_bin_i_nregs)}, 322286866Sjasone {NAME("run_size"), CTL(arenas_bin_i_run_size)} 323234370Sjasone}; 324235238Sjasonestatic const ctl_named_node_t super_arenas_bin_i_node[] = { 325286866Sjasone {NAME(""), CHILD(named, arenas_bin_i)} 326234370Sjasone}; 327234370Sjasone 328235238Sjasonestatic const ctl_indexed_node_t arenas_bin_node[] = { 329234370Sjasone {INDEX(arenas_bin_i)} 330234370Sjasone}; 331234370Sjasone 332235238Sjasonestatic const ctl_named_node_t arenas_lrun_i_node[] = { 333286866Sjasone {NAME("size"), CTL(arenas_lrun_i_size)} 334234370Sjasone}; 335235238Sjasonestatic const ctl_named_node_t super_arenas_lrun_i_node[] = { 336286866Sjasone {NAME(""), CHILD(named, arenas_lrun_i)} 337234370Sjasone}; 338234370Sjasone 339235238Sjasonestatic const ctl_indexed_node_t arenas_lrun_node[] = { 340234370Sjasone {INDEX(arenas_lrun_i)} 341234370Sjasone}; 342234370Sjasone 343286866Sjasonestatic const ctl_named_node_t arenas_hchunk_i_node[] = { 344286866Sjasone {NAME("size"), CTL(arenas_hchunk_i_size)} 345286866Sjasone}; 346286866Sjasonestatic const ctl_named_node_t super_arenas_hchunk_i_node[] = { 347286866Sjasone {NAME(""), CHILD(named, arenas_hchunk_i)} 348286866Sjasone}; 349286866Sjasone 350286866Sjasonestatic const ctl_indexed_node_t arenas_hchunk_node[] = { 351286866Sjasone {INDEX(arenas_hchunk_i)} 352286866Sjasone}; 353286866Sjasone 354235238Sjasonestatic const ctl_named_node_t arenas_node[] = { 355286866Sjasone {NAME("narenas"), CTL(arenas_narenas)}, 356286866Sjasone {NAME("initialized"), CTL(arenas_initialized)}, 357286866Sjasone {NAME("lg_dirty_mult"), CTL(arenas_lg_dirty_mult)}, 358296221Sjasone {NAME("decay_time"), CTL(arenas_decay_time)}, 359286866Sjasone {NAME("quantum"), CTL(arenas_quantum)}, 360286866Sjasone {NAME("page"), CTL(arenas_page)}, 361286866Sjasone {NAME("tcache_max"), CTL(arenas_tcache_max)}, 362286866Sjasone {NAME("nbins"), CTL(arenas_nbins)}, 363286866Sjasone {NAME("nhbins"), CTL(arenas_nhbins)}, 364286866Sjasone {NAME("bin"), CHILD(indexed, arenas_bin)}, 365286866Sjasone {NAME("nlruns"), CTL(arenas_nlruns)}, 366286866Sjasone {NAME("lrun"), CHILD(indexed, arenas_lrun)}, 367286866Sjasone {NAME("nhchunks"), CTL(arenas_nhchunks)}, 368286866Sjasone {NAME("hchunk"), CHILD(indexed, arenas_hchunk)}, 369286866Sjasone {NAME("extend"), CTL(arenas_extend)} 370234370Sjasone}; 371234370Sjasone 372235238Sjasonestatic const ctl_named_node_t prof_node[] = { 373286866Sjasone {NAME("thread_active_init"), CTL(prof_thread_active_init)}, 374234370Sjasone {NAME("active"), CTL(prof_active)}, 375234370Sjasone {NAME("dump"), CTL(prof_dump)}, 376286866Sjasone {NAME("gdump"), CTL(prof_gdump)}, 377286866Sjasone {NAME("reset"), CTL(prof_reset)}, 378286866Sjasone {NAME("interval"), CTL(prof_interval)}, 379286866Sjasone {NAME("lg_sample"), CTL(lg_prof_sample)} 380234370Sjasone}; 381234370Sjasone 382286866Sjasonestatic const ctl_named_node_t stats_arenas_i_metadata_node[] = { 383286866Sjasone {NAME("mapped"), CTL(stats_arenas_i_metadata_mapped)}, 384286866Sjasone {NAME("allocated"), CTL(stats_arenas_i_metadata_allocated)} 385234370Sjasone}; 386234370Sjasone 387235238Sjasonestatic const ctl_named_node_t stats_arenas_i_small_node[] = { 388286866Sjasone {NAME("allocated"), CTL(stats_arenas_i_small_allocated)}, 389286866Sjasone {NAME("nmalloc"), CTL(stats_arenas_i_small_nmalloc)}, 390286866Sjasone {NAME("ndalloc"), CTL(stats_arenas_i_small_ndalloc)}, 391286866Sjasone {NAME("nrequests"), CTL(stats_arenas_i_small_nrequests)} 392234370Sjasone}; 393234370Sjasone 394235238Sjasonestatic const ctl_named_node_t stats_arenas_i_large_node[] = { 395286866Sjasone {NAME("allocated"), CTL(stats_arenas_i_large_allocated)}, 396286866Sjasone {NAME("nmalloc"), CTL(stats_arenas_i_large_nmalloc)}, 397286866Sjasone {NAME("ndalloc"), CTL(stats_arenas_i_large_ndalloc)}, 398286866Sjasone {NAME("nrequests"), CTL(stats_arenas_i_large_nrequests)} 399234370Sjasone}; 400234370Sjasone 401286866Sjasonestatic const ctl_named_node_t stats_arenas_i_huge_node[] = { 402286866Sjasone {NAME("allocated"), CTL(stats_arenas_i_huge_allocated)}, 403286866Sjasone {NAME("nmalloc"), CTL(stats_arenas_i_huge_nmalloc)}, 404286866Sjasone {NAME("ndalloc"), CTL(stats_arenas_i_huge_ndalloc)}, 405286866Sjasone {NAME("nrequests"), CTL(stats_arenas_i_huge_nrequests)} 406286866Sjasone}; 407286866Sjasone 408235238Sjasonestatic const ctl_named_node_t stats_arenas_i_bins_j_node[] = { 409286866Sjasone {NAME("nmalloc"), CTL(stats_arenas_i_bins_j_nmalloc)}, 410286866Sjasone {NAME("ndalloc"), CTL(stats_arenas_i_bins_j_ndalloc)}, 411286866Sjasone {NAME("nrequests"), CTL(stats_arenas_i_bins_j_nrequests)}, 412286866Sjasone {NAME("curregs"), CTL(stats_arenas_i_bins_j_curregs)}, 413286866Sjasone {NAME("nfills"), CTL(stats_arenas_i_bins_j_nfills)}, 414286866Sjasone {NAME("nflushes"), CTL(stats_arenas_i_bins_j_nflushes)}, 415286866Sjasone {NAME("nruns"), CTL(stats_arenas_i_bins_j_nruns)}, 416286866Sjasone {NAME("nreruns"), CTL(stats_arenas_i_bins_j_nreruns)}, 417286866Sjasone {NAME("curruns"), CTL(stats_arenas_i_bins_j_curruns)} 418234370Sjasone}; 419235238Sjasonestatic const ctl_named_node_t super_stats_arenas_i_bins_j_node[] = { 420286866Sjasone {NAME(""), CHILD(named, stats_arenas_i_bins_j)} 421234370Sjasone}; 422234370Sjasone 423235238Sjasonestatic const ctl_indexed_node_t stats_arenas_i_bins_node[] = { 424234370Sjasone {INDEX(stats_arenas_i_bins_j)} 425234370Sjasone}; 426234370Sjasone 427235238Sjasonestatic const ctl_named_node_t stats_arenas_i_lruns_j_node[] = { 428286866Sjasone {NAME("nmalloc"), CTL(stats_arenas_i_lruns_j_nmalloc)}, 429286866Sjasone {NAME("ndalloc"), CTL(stats_arenas_i_lruns_j_ndalloc)}, 430286866Sjasone {NAME("nrequests"), CTL(stats_arenas_i_lruns_j_nrequests)}, 431286866Sjasone {NAME("curruns"), CTL(stats_arenas_i_lruns_j_curruns)} 432234370Sjasone}; 433235238Sjasonestatic const ctl_named_node_t super_stats_arenas_i_lruns_j_node[] = { 434286866Sjasone {NAME(""), CHILD(named, stats_arenas_i_lruns_j)} 435234370Sjasone}; 436234370Sjasone 437235238Sjasonestatic const ctl_indexed_node_t stats_arenas_i_lruns_node[] = { 438234370Sjasone {INDEX(stats_arenas_i_lruns_j)} 439234370Sjasone}; 440234370Sjasone 441286866Sjasonestatic const ctl_named_node_t stats_arenas_i_hchunks_j_node[] = { 442286866Sjasone {NAME("nmalloc"), CTL(stats_arenas_i_hchunks_j_nmalloc)}, 443286866Sjasone {NAME("ndalloc"), CTL(stats_arenas_i_hchunks_j_ndalloc)}, 444286866Sjasone {NAME("nrequests"), CTL(stats_arenas_i_hchunks_j_nrequests)}, 445286866Sjasone {NAME("curhchunks"), CTL(stats_arenas_i_hchunks_j_curhchunks)} 446286866Sjasone}; 447286866Sjasonestatic const ctl_named_node_t super_stats_arenas_i_hchunks_j_node[] = { 448286866Sjasone {NAME(""), CHILD(named, stats_arenas_i_hchunks_j)} 449286866Sjasone}; 450286866Sjasone 451286866Sjasonestatic const ctl_indexed_node_t stats_arenas_i_hchunks_node[] = { 452286866Sjasone {INDEX(stats_arenas_i_hchunks_j)} 453286866Sjasone}; 454286866Sjasone 455235238Sjasonestatic const ctl_named_node_t stats_arenas_i_node[] = { 456286866Sjasone {NAME("nthreads"), CTL(stats_arenas_i_nthreads)}, 457286866Sjasone {NAME("dss"), CTL(stats_arenas_i_dss)}, 458286866Sjasone {NAME("lg_dirty_mult"), CTL(stats_arenas_i_lg_dirty_mult)}, 459296221Sjasone {NAME("decay_time"), CTL(stats_arenas_i_decay_time)}, 460286866Sjasone {NAME("pactive"), CTL(stats_arenas_i_pactive)}, 461286866Sjasone {NAME("pdirty"), CTL(stats_arenas_i_pdirty)}, 462286866Sjasone {NAME("mapped"), CTL(stats_arenas_i_mapped)}, 463299587Sjasone {NAME("retained"), CTL(stats_arenas_i_retained)}, 464286866Sjasone {NAME("npurge"), CTL(stats_arenas_i_npurge)}, 465286866Sjasone {NAME("nmadvise"), CTL(stats_arenas_i_nmadvise)}, 466286866Sjasone {NAME("purged"), CTL(stats_arenas_i_purged)}, 467286866Sjasone {NAME("metadata"), CHILD(named, stats_arenas_i_metadata)}, 468286866Sjasone {NAME("small"), CHILD(named, stats_arenas_i_small)}, 469286866Sjasone {NAME("large"), CHILD(named, stats_arenas_i_large)}, 470286866Sjasone {NAME("huge"), CHILD(named, stats_arenas_i_huge)}, 471286866Sjasone {NAME("bins"), CHILD(indexed, stats_arenas_i_bins)}, 472286866Sjasone {NAME("lruns"), CHILD(indexed, stats_arenas_i_lruns)}, 473286866Sjasone {NAME("hchunks"), CHILD(indexed, stats_arenas_i_hchunks)} 474234370Sjasone}; 475235238Sjasonestatic const ctl_named_node_t super_stats_arenas_i_node[] = { 476286866Sjasone {NAME(""), CHILD(named, stats_arenas_i)} 477234370Sjasone}; 478234370Sjasone 479235238Sjasonestatic const ctl_indexed_node_t stats_arenas_node[] = { 480234370Sjasone {INDEX(stats_arenas_i)} 481234370Sjasone}; 482234370Sjasone 483235238Sjasonestatic const ctl_named_node_t stats_node[] = { 484286866Sjasone {NAME("cactive"), CTL(stats_cactive)}, 485286866Sjasone {NAME("allocated"), CTL(stats_allocated)}, 486286866Sjasone {NAME("active"), CTL(stats_active)}, 487286866Sjasone {NAME("metadata"), CTL(stats_metadata)}, 488286866Sjasone {NAME("resident"), CTL(stats_resident)}, 489286866Sjasone {NAME("mapped"), CTL(stats_mapped)}, 490299587Sjasone {NAME("retained"), CTL(stats_retained)}, 491286866Sjasone {NAME("arenas"), CHILD(indexed, stats_arenas)} 492234370Sjasone}; 493234370Sjasone 494235238Sjasonestatic const ctl_named_node_t root_node[] = { 495234370Sjasone {NAME("version"), CTL(version)}, 496234370Sjasone {NAME("epoch"), CTL(epoch)}, 497235238Sjasone {NAME("thread"), CHILD(named, thread)}, 498235238Sjasone {NAME("config"), CHILD(named, config)}, 499235238Sjasone {NAME("opt"), CHILD(named, opt)}, 500286866Sjasone {NAME("tcache"), CHILD(named, tcache)}, 501242844Sjasone {NAME("arena"), CHILD(indexed, arena)}, 502235238Sjasone {NAME("arenas"), CHILD(named, arenas)}, 503235238Sjasone {NAME("prof"), CHILD(named, prof)}, 504235238Sjasone {NAME("stats"), CHILD(named, stats)} 505234370Sjasone}; 506235238Sjasonestatic const ctl_named_node_t super_root_node[] = { 507235238Sjasone {NAME(""), CHILD(named, root)} 508234370Sjasone}; 509234370Sjasone 510234370Sjasone#undef NAME 511234370Sjasone#undef CHILD 512234370Sjasone#undef CTL 513234370Sjasone#undef INDEX 514234370Sjasone 515234370Sjasone/******************************************************************************/ 516234370Sjasone 517234370Sjasonestatic bool 518234370Sjasonectl_arena_init(ctl_arena_stats_t *astats) 519234370Sjasone{ 520234370Sjasone 521234370Sjasone if (astats->lstats == NULL) { 522286866Sjasone astats->lstats = (malloc_large_stats_t *)a0malloc(nlclasses * 523234370Sjasone sizeof(malloc_large_stats_t)); 524234370Sjasone if (astats->lstats == NULL) 525234370Sjasone return (true); 526234370Sjasone } 527234370Sjasone 528286866Sjasone if (astats->hstats == NULL) { 529286866Sjasone astats->hstats = (malloc_huge_stats_t *)a0malloc(nhclasses * 530286866Sjasone sizeof(malloc_huge_stats_t)); 531286866Sjasone if (astats->hstats == NULL) 532286866Sjasone return (true); 533286866Sjasone } 534286866Sjasone 535234370Sjasone return (false); 536234370Sjasone} 537234370Sjasone 538234370Sjasonestatic void 539234370Sjasonectl_arena_clear(ctl_arena_stats_t *astats) 540234370Sjasone{ 541234370Sjasone 542296221Sjasone astats->nthreads = 0; 543242844Sjasone astats->dss = dss_prec_names[dss_prec_limit]; 544286866Sjasone astats->lg_dirty_mult = -1; 545296221Sjasone astats->decay_time = -1; 546234370Sjasone astats->pactive = 0; 547234370Sjasone astats->pdirty = 0; 548234370Sjasone if (config_stats) { 549234370Sjasone memset(&astats->astats, 0, sizeof(arena_stats_t)); 550234370Sjasone astats->allocated_small = 0; 551234370Sjasone astats->nmalloc_small = 0; 552234370Sjasone astats->ndalloc_small = 0; 553234370Sjasone astats->nrequests_small = 0; 554234370Sjasone memset(astats->bstats, 0, NBINS * sizeof(malloc_bin_stats_t)); 555234370Sjasone memset(astats->lstats, 0, nlclasses * 556234370Sjasone sizeof(malloc_large_stats_t)); 557286866Sjasone memset(astats->hstats, 0, nhclasses * 558286866Sjasone sizeof(malloc_huge_stats_t)); 559234370Sjasone } 560234370Sjasone} 561234370Sjasone 562234370Sjasonestatic void 563299587Sjasonectl_arena_stats_amerge(tsdn_t *tsdn, ctl_arena_stats_t *cstats, arena_t *arena) 564234370Sjasone{ 565234370Sjasone unsigned i; 566234370Sjasone 567296221Sjasone if (config_stats) { 568299587Sjasone arena_stats_merge(tsdn, arena, &cstats->nthreads, &cstats->dss, 569296221Sjasone &cstats->lg_dirty_mult, &cstats->decay_time, 570296221Sjasone &cstats->pactive, &cstats->pdirty, &cstats->astats, 571296221Sjasone cstats->bstats, cstats->lstats, cstats->hstats); 572234370Sjasone 573296221Sjasone for (i = 0; i < NBINS; i++) { 574296221Sjasone cstats->allocated_small += cstats->bstats[i].curregs * 575296221Sjasone index2size(i); 576296221Sjasone cstats->nmalloc_small += cstats->bstats[i].nmalloc; 577296221Sjasone cstats->ndalloc_small += cstats->bstats[i].ndalloc; 578296221Sjasone cstats->nrequests_small += cstats->bstats[i].nrequests; 579296221Sjasone } 580296221Sjasone } else { 581299587Sjasone arena_basic_stats_merge(tsdn, arena, &cstats->nthreads, 582299587Sjasone &cstats->dss, &cstats->lg_dirty_mult, &cstats->decay_time, 583296221Sjasone &cstats->pactive, &cstats->pdirty); 584234370Sjasone } 585234370Sjasone} 586234370Sjasone 587234370Sjasonestatic void 588234370Sjasonectl_arena_stats_smerge(ctl_arena_stats_t *sstats, ctl_arena_stats_t *astats) 589234370Sjasone{ 590234370Sjasone unsigned i; 591234370Sjasone 592296221Sjasone sstats->nthreads += astats->nthreads; 593234370Sjasone sstats->pactive += astats->pactive; 594234370Sjasone sstats->pdirty += astats->pdirty; 595234370Sjasone 596296221Sjasone if (config_stats) { 597296221Sjasone sstats->astats.mapped += astats->astats.mapped; 598299587Sjasone sstats->astats.retained += astats->astats.retained; 599296221Sjasone sstats->astats.npurge += astats->astats.npurge; 600296221Sjasone sstats->astats.nmadvise += astats->astats.nmadvise; 601296221Sjasone sstats->astats.purged += astats->astats.purged; 602234370Sjasone 603296221Sjasone sstats->astats.metadata_mapped += 604296221Sjasone astats->astats.metadata_mapped; 605296221Sjasone sstats->astats.metadata_allocated += 606296221Sjasone astats->astats.metadata_allocated; 607286866Sjasone 608296221Sjasone sstats->allocated_small += astats->allocated_small; 609296221Sjasone sstats->nmalloc_small += astats->nmalloc_small; 610296221Sjasone sstats->ndalloc_small += astats->ndalloc_small; 611296221Sjasone sstats->nrequests_small += astats->nrequests_small; 612234370Sjasone 613296221Sjasone sstats->astats.allocated_large += 614296221Sjasone astats->astats.allocated_large; 615296221Sjasone sstats->astats.nmalloc_large += astats->astats.nmalloc_large; 616296221Sjasone sstats->astats.ndalloc_large += astats->astats.ndalloc_large; 617296221Sjasone sstats->astats.nrequests_large += 618296221Sjasone astats->astats.nrequests_large; 619234370Sjasone 620296221Sjasone sstats->astats.allocated_huge += astats->astats.allocated_huge; 621296221Sjasone sstats->astats.nmalloc_huge += astats->astats.nmalloc_huge; 622296221Sjasone sstats->astats.ndalloc_huge += astats->astats.ndalloc_huge; 623234370Sjasone 624296221Sjasone for (i = 0; i < NBINS; i++) { 625296221Sjasone sstats->bstats[i].nmalloc += astats->bstats[i].nmalloc; 626296221Sjasone sstats->bstats[i].ndalloc += astats->bstats[i].ndalloc; 627296221Sjasone sstats->bstats[i].nrequests += 628296221Sjasone astats->bstats[i].nrequests; 629296221Sjasone sstats->bstats[i].curregs += astats->bstats[i].curregs; 630296221Sjasone if (config_tcache) { 631296221Sjasone sstats->bstats[i].nfills += 632296221Sjasone astats->bstats[i].nfills; 633296221Sjasone sstats->bstats[i].nflushes += 634296221Sjasone astats->bstats[i].nflushes; 635296221Sjasone } 636296221Sjasone sstats->bstats[i].nruns += astats->bstats[i].nruns; 637296221Sjasone sstats->bstats[i].reruns += astats->bstats[i].reruns; 638296221Sjasone sstats->bstats[i].curruns += astats->bstats[i].curruns; 639234370Sjasone } 640286866Sjasone 641296221Sjasone for (i = 0; i < nlclasses; i++) { 642296221Sjasone sstats->lstats[i].nmalloc += astats->lstats[i].nmalloc; 643296221Sjasone sstats->lstats[i].ndalloc += astats->lstats[i].ndalloc; 644296221Sjasone sstats->lstats[i].nrequests += 645296221Sjasone astats->lstats[i].nrequests; 646296221Sjasone sstats->lstats[i].curruns += astats->lstats[i].curruns; 647296221Sjasone } 648286866Sjasone 649296221Sjasone for (i = 0; i < nhclasses; i++) { 650296221Sjasone sstats->hstats[i].nmalloc += astats->hstats[i].nmalloc; 651296221Sjasone sstats->hstats[i].ndalloc += astats->hstats[i].ndalloc; 652296221Sjasone sstats->hstats[i].curhchunks += 653296221Sjasone astats->hstats[i].curhchunks; 654296221Sjasone } 655286866Sjasone } 656234370Sjasone} 657234370Sjasone 658234370Sjasonestatic void 659299587Sjasonectl_arena_refresh(tsdn_t *tsdn, arena_t *arena, unsigned i) 660234370Sjasone{ 661234370Sjasone ctl_arena_stats_t *astats = &ctl_stats.arenas[i]; 662242844Sjasone ctl_arena_stats_t *sstats = &ctl_stats.arenas[ctl_stats.narenas]; 663234370Sjasone 664234370Sjasone ctl_arena_clear(astats); 665299587Sjasone ctl_arena_stats_amerge(tsdn, astats, arena); 666296221Sjasone /* Merge into sum stats as well. */ 667296221Sjasone ctl_arena_stats_smerge(sstats, astats); 668234370Sjasone} 669234370Sjasone 670242844Sjasonestatic bool 671299587Sjasonectl_grow(tsdn_t *tsdn) 672242844Sjasone{ 673242844Sjasone ctl_arena_stats_t *astats; 674242844Sjasone 675286866Sjasone /* Initialize new arena. */ 676299587Sjasone if (arena_init(tsdn, ctl_stats.narenas) == NULL) 677286866Sjasone return (true); 678286866Sjasone 679286866Sjasone /* Allocate extended arena stats. */ 680286866Sjasone astats = (ctl_arena_stats_t *)a0malloc((ctl_stats.narenas + 2) * 681256823Sjasone sizeof(ctl_arena_stats_t)); 682256823Sjasone if (astats == NULL) 683256823Sjasone return (true); 684242844Sjasone 685256823Sjasone /* Initialize the new astats element. */ 686256823Sjasone memcpy(astats, ctl_stats.arenas, (ctl_stats.narenas + 1) * 687256823Sjasone sizeof(ctl_arena_stats_t)); 688242844Sjasone memset(&astats[ctl_stats.narenas + 1], 0, sizeof(ctl_arena_stats_t)); 689256823Sjasone if (ctl_arena_init(&astats[ctl_stats.narenas + 1])) { 690286866Sjasone a0dalloc(astats); 691242844Sjasone return (true); 692256823Sjasone } 693242844Sjasone /* Swap merged stats to their new location. */ 694242844Sjasone { 695242844Sjasone ctl_arena_stats_t tstats; 696242844Sjasone memcpy(&tstats, &astats[ctl_stats.narenas], 697242844Sjasone sizeof(ctl_arena_stats_t)); 698242844Sjasone memcpy(&astats[ctl_stats.narenas], 699242844Sjasone &astats[ctl_stats.narenas + 1], sizeof(ctl_arena_stats_t)); 700242844Sjasone memcpy(&astats[ctl_stats.narenas + 1], &tstats, 701242844Sjasone sizeof(ctl_arena_stats_t)); 702242844Sjasone } 703286866Sjasone a0dalloc(ctl_stats.arenas); 704242844Sjasone ctl_stats.arenas = astats; 705242844Sjasone ctl_stats.narenas++; 706242844Sjasone 707242844Sjasone return (false); 708242844Sjasone} 709242844Sjasone 710234370Sjasonestatic void 711299587Sjasonectl_refresh(tsdn_t *tsdn) 712234370Sjasone{ 713234370Sjasone unsigned i; 714242844Sjasone VARIABLE_ARRAY(arena_t *, tarenas, ctl_stats.narenas); 715234370Sjasone 716234370Sjasone /* 717234370Sjasone * Clear sum stats, since they will be merged into by 718234370Sjasone * ctl_arena_refresh(). 719234370Sjasone */ 720242844Sjasone ctl_arena_clear(&ctl_stats.arenas[ctl_stats.narenas]); 721234370Sjasone 722296221Sjasone for (i = 0; i < ctl_stats.narenas; i++) 723299587Sjasone tarenas[i] = arena_get(tsdn, i, false); 724286866Sjasone 725242844Sjasone for (i = 0; i < ctl_stats.narenas; i++) { 726234370Sjasone bool initialized = (tarenas[i] != NULL); 727234370Sjasone 728234370Sjasone ctl_stats.arenas[i].initialized = initialized; 729234370Sjasone if (initialized) 730299587Sjasone ctl_arena_refresh(tsdn, tarenas[i], i); 731234370Sjasone } 732234370Sjasone 733234370Sjasone if (config_stats) { 734286866Sjasone size_t base_allocated, base_resident, base_mapped; 735299587Sjasone base_stats_get(tsdn, &base_allocated, &base_resident, 736299587Sjasone &base_mapped); 737242844Sjasone ctl_stats.allocated = 738286866Sjasone ctl_stats.arenas[ctl_stats.narenas].allocated_small + 739286866Sjasone ctl_stats.arenas[ctl_stats.narenas].astats.allocated_large + 740286866Sjasone ctl_stats.arenas[ctl_stats.narenas].astats.allocated_huge; 741242844Sjasone ctl_stats.active = 742286866Sjasone (ctl_stats.arenas[ctl_stats.narenas].pactive << LG_PAGE); 743286866Sjasone ctl_stats.metadata = base_allocated + 744286866Sjasone ctl_stats.arenas[ctl_stats.narenas].astats.metadata_mapped + 745286866Sjasone ctl_stats.arenas[ctl_stats.narenas].astats 746286866Sjasone .metadata_allocated; 747286866Sjasone ctl_stats.resident = base_resident + 748286866Sjasone ctl_stats.arenas[ctl_stats.narenas].astats.metadata_mapped + 749286866Sjasone ((ctl_stats.arenas[ctl_stats.narenas].pactive + 750286866Sjasone ctl_stats.arenas[ctl_stats.narenas].pdirty) << LG_PAGE); 751286866Sjasone ctl_stats.mapped = base_mapped + 752286866Sjasone ctl_stats.arenas[ctl_stats.narenas].astats.mapped; 753299587Sjasone ctl_stats.retained = 754299587Sjasone ctl_stats.arenas[ctl_stats.narenas].astats.retained; 755234370Sjasone } 756234370Sjasone 757234370Sjasone ctl_epoch++; 758234370Sjasone} 759234370Sjasone 760234370Sjasonestatic bool 761299587Sjasonectl_init(tsdn_t *tsdn) 762234370Sjasone{ 763234370Sjasone bool ret; 764234370Sjasone 765299587Sjasone malloc_mutex_lock(tsdn, &ctl_mtx); 766286866Sjasone if (!ctl_initialized) { 767234370Sjasone /* 768234370Sjasone * Allocate space for one extra arena stats element, which 769234370Sjasone * contains summed stats across all arenas. 770234370Sjasone */ 771286866Sjasone ctl_stats.narenas = narenas_total_get(); 772286866Sjasone ctl_stats.arenas = (ctl_arena_stats_t *)a0malloc( 773242844Sjasone (ctl_stats.narenas + 1) * sizeof(ctl_arena_stats_t)); 774234370Sjasone if (ctl_stats.arenas == NULL) { 775234370Sjasone ret = true; 776234370Sjasone goto label_return; 777234370Sjasone } 778242844Sjasone memset(ctl_stats.arenas, 0, (ctl_stats.narenas + 1) * 779234370Sjasone sizeof(ctl_arena_stats_t)); 780234370Sjasone 781234370Sjasone /* 782234370Sjasone * Initialize all stats structures, regardless of whether they 783234370Sjasone * ever get used. Lazy initialization would allow errors to 784234370Sjasone * cause inconsistent state to be viewable by the application. 785234370Sjasone */ 786234370Sjasone if (config_stats) { 787234370Sjasone unsigned i; 788242844Sjasone for (i = 0; i <= ctl_stats.narenas; i++) { 789234370Sjasone if (ctl_arena_init(&ctl_stats.arenas[i])) { 790286866Sjasone unsigned j; 791286866Sjasone for (j = 0; j < i; j++) { 792286866Sjasone a0dalloc( 793286866Sjasone ctl_stats.arenas[j].lstats); 794286866Sjasone a0dalloc( 795286866Sjasone ctl_stats.arenas[j].hstats); 796286866Sjasone } 797286866Sjasone a0dalloc(ctl_stats.arenas); 798286866Sjasone ctl_stats.arenas = NULL; 799234370Sjasone ret = true; 800234370Sjasone goto label_return; 801234370Sjasone } 802234370Sjasone } 803234370Sjasone } 804242844Sjasone ctl_stats.arenas[ctl_stats.narenas].initialized = true; 805234370Sjasone 806234370Sjasone ctl_epoch = 0; 807299587Sjasone ctl_refresh(tsdn); 808234370Sjasone ctl_initialized = true; 809234370Sjasone } 810234370Sjasone 811234370Sjasone ret = false; 812234370Sjasonelabel_return: 813299587Sjasone malloc_mutex_unlock(tsdn, &ctl_mtx); 814234370Sjasone return (ret); 815234370Sjasone} 816234370Sjasone 817234370Sjasonestatic int 818299587Sjasonectl_lookup(tsdn_t *tsdn, const char *name, ctl_node_t const **nodesp, 819299587Sjasone size_t *mibp, size_t *depthp) 820234370Sjasone{ 821234370Sjasone int ret; 822234370Sjasone const char *elm, *tdot, *dot; 823234370Sjasone size_t elen, i, j; 824235238Sjasone const ctl_named_node_t *node; 825234370Sjasone 826234370Sjasone elm = name; 827234370Sjasone /* Equivalent to strchrnul(). */ 828234370Sjasone dot = ((tdot = strchr(elm, '.')) != NULL) ? tdot : strchr(elm, '\0'); 829234370Sjasone elen = (size_t)((uintptr_t)dot - (uintptr_t)elm); 830234370Sjasone if (elen == 0) { 831234370Sjasone ret = ENOENT; 832234370Sjasone goto label_return; 833234370Sjasone } 834234370Sjasone node = super_root_node; 835234370Sjasone for (i = 0; i < *depthp; i++) { 836235238Sjasone assert(node); 837235238Sjasone assert(node->nchildren > 0); 838235238Sjasone if (ctl_named_node(node->children) != NULL) { 839235238Sjasone const ctl_named_node_t *pnode = node; 840234370Sjasone 841234370Sjasone /* Children are named. */ 842235238Sjasone for (j = 0; j < node->nchildren; j++) { 843235238Sjasone const ctl_named_node_t *child = 844235238Sjasone ctl_named_children(node, j); 845235238Sjasone if (strlen(child->name) == elen && 846235238Sjasone strncmp(elm, child->name, elen) == 0) { 847234370Sjasone node = child; 848234370Sjasone if (nodesp != NULL) 849235238Sjasone nodesp[i] = 850235238Sjasone (const ctl_node_t *)node; 851234370Sjasone mibp[i] = j; 852234370Sjasone break; 853234370Sjasone } 854234370Sjasone } 855234370Sjasone if (node == pnode) { 856234370Sjasone ret = ENOENT; 857234370Sjasone goto label_return; 858234370Sjasone } 859234370Sjasone } else { 860234370Sjasone uintmax_t index; 861235238Sjasone const ctl_indexed_node_t *inode; 862234370Sjasone 863234370Sjasone /* Children are indexed. */ 864234370Sjasone index = malloc_strtoumax(elm, NULL, 10); 865234370Sjasone if (index == UINTMAX_MAX || index > SIZE_T_MAX) { 866234370Sjasone ret = ENOENT; 867234370Sjasone goto label_return; 868234370Sjasone } 869234370Sjasone 870235238Sjasone inode = ctl_indexed_node(node->children); 871299587Sjasone node = inode->index(tsdn, mibp, *depthp, (size_t)index); 872234370Sjasone if (node == NULL) { 873234370Sjasone ret = ENOENT; 874234370Sjasone goto label_return; 875234370Sjasone } 876234370Sjasone 877234370Sjasone if (nodesp != NULL) 878235238Sjasone nodesp[i] = (const ctl_node_t *)node; 879234370Sjasone mibp[i] = (size_t)index; 880234370Sjasone } 881234370Sjasone 882234370Sjasone if (node->ctl != NULL) { 883234370Sjasone /* Terminal node. */ 884234370Sjasone if (*dot != '\0') { 885234370Sjasone /* 886234370Sjasone * The name contains more elements than are 887234370Sjasone * in this path through the tree. 888234370Sjasone */ 889234370Sjasone ret = ENOENT; 890234370Sjasone goto label_return; 891234370Sjasone } 892234370Sjasone /* Complete lookup successful. */ 893234370Sjasone *depthp = i + 1; 894234370Sjasone break; 895234370Sjasone } 896234370Sjasone 897234370Sjasone /* Update elm. */ 898234370Sjasone if (*dot == '\0') { 899234370Sjasone /* No more elements. */ 900234370Sjasone ret = ENOENT; 901234370Sjasone goto label_return; 902234370Sjasone } 903234370Sjasone elm = &dot[1]; 904234370Sjasone dot = ((tdot = strchr(elm, '.')) != NULL) ? tdot : 905234370Sjasone strchr(elm, '\0'); 906234370Sjasone elen = (size_t)((uintptr_t)dot - (uintptr_t)elm); 907234370Sjasone } 908234370Sjasone 909234370Sjasone ret = 0; 910234370Sjasonelabel_return: 911234370Sjasone return (ret); 912234370Sjasone} 913234370Sjasone 914234370Sjasoneint 915299587Sjasonectl_byname(tsd_t *tsd, const char *name, void *oldp, size_t *oldlenp, 916299587Sjasone void *newp, size_t newlen) 917234370Sjasone{ 918234370Sjasone int ret; 919234370Sjasone size_t depth; 920234370Sjasone ctl_node_t const *nodes[CTL_MAX_DEPTH]; 921234370Sjasone size_t mib[CTL_MAX_DEPTH]; 922235238Sjasone const ctl_named_node_t *node; 923234370Sjasone 924299587Sjasone if (!ctl_initialized && ctl_init(tsd_tsdn(tsd))) { 925234370Sjasone ret = EAGAIN; 926234370Sjasone goto label_return; 927234370Sjasone } 928234370Sjasone 929234370Sjasone depth = CTL_MAX_DEPTH; 930299587Sjasone ret = ctl_lookup(tsd_tsdn(tsd), name, nodes, mib, &depth); 931234370Sjasone if (ret != 0) 932234370Sjasone goto label_return; 933234370Sjasone 934235238Sjasone node = ctl_named_node(nodes[depth-1]); 935235238Sjasone if (node != NULL && node->ctl) 936299587Sjasone ret = node->ctl(tsd, mib, depth, oldp, oldlenp, newp, newlen); 937235238Sjasone else { 938234370Sjasone /* The name refers to a partial path through the ctl tree. */ 939234370Sjasone ret = ENOENT; 940234370Sjasone } 941234370Sjasone 942234370Sjasonelabel_return: 943234370Sjasone return(ret); 944234370Sjasone} 945234370Sjasone 946234370Sjasoneint 947299587Sjasonectl_nametomib(tsdn_t *tsdn, const char *name, size_t *mibp, size_t *miblenp) 948234370Sjasone{ 949234370Sjasone int ret; 950234370Sjasone 951299587Sjasone if (!ctl_initialized && ctl_init(tsdn)) { 952234370Sjasone ret = EAGAIN; 953234370Sjasone goto label_return; 954234370Sjasone } 955234370Sjasone 956299587Sjasone ret = ctl_lookup(tsdn, name, NULL, mibp, miblenp); 957234370Sjasonelabel_return: 958234370Sjasone return(ret); 959234370Sjasone} 960234370Sjasone 961234370Sjasoneint 962299587Sjasonectl_bymib(tsd_t *tsd, const size_t *mib, size_t miblen, void *oldp, 963299587Sjasone size_t *oldlenp, void *newp, size_t newlen) 964234370Sjasone{ 965234370Sjasone int ret; 966235238Sjasone const ctl_named_node_t *node; 967234370Sjasone size_t i; 968234370Sjasone 969299587Sjasone if (!ctl_initialized && ctl_init(tsd_tsdn(tsd))) { 970234370Sjasone ret = EAGAIN; 971234370Sjasone goto label_return; 972234370Sjasone } 973234370Sjasone 974234370Sjasone /* Iterate down the tree. */ 975234370Sjasone node = super_root_node; 976234370Sjasone for (i = 0; i < miblen; i++) { 977235238Sjasone assert(node); 978235238Sjasone assert(node->nchildren > 0); 979235238Sjasone if (ctl_named_node(node->children) != NULL) { 980234370Sjasone /* Children are named. */ 981296221Sjasone if (node->nchildren <= (unsigned)mib[i]) { 982234370Sjasone ret = ENOENT; 983234370Sjasone goto label_return; 984234370Sjasone } 985235238Sjasone node = ctl_named_children(node, mib[i]); 986234370Sjasone } else { 987235238Sjasone const ctl_indexed_node_t *inode; 988234370Sjasone 989234370Sjasone /* Indexed element. */ 990235238Sjasone inode = ctl_indexed_node(node->children); 991299587Sjasone node = inode->index(tsd_tsdn(tsd), mib, miblen, mib[i]); 992234370Sjasone if (node == NULL) { 993234370Sjasone ret = ENOENT; 994234370Sjasone goto label_return; 995234370Sjasone } 996234370Sjasone } 997234370Sjasone } 998234370Sjasone 999234370Sjasone /* Call the ctl function. */ 1000235238Sjasone if (node && node->ctl) 1001299587Sjasone ret = node->ctl(tsd, mib, miblen, oldp, oldlenp, newp, newlen); 1002235238Sjasone else { 1003234370Sjasone /* Partial MIB. */ 1004234370Sjasone ret = ENOENT; 1005234370Sjasone } 1006234370Sjasone 1007234370Sjasonelabel_return: 1008234370Sjasone return(ret); 1009234370Sjasone} 1010234370Sjasone 1011234370Sjasonebool 1012234370Sjasonectl_boot(void) 1013234370Sjasone{ 1014234370Sjasone 1015299587Sjasone if (malloc_mutex_init(&ctl_mtx, "ctl", WITNESS_RANK_CTL)) 1016234370Sjasone return (true); 1017234370Sjasone 1018234370Sjasone ctl_initialized = false; 1019234370Sjasone 1020234370Sjasone return (false); 1021234370Sjasone} 1022234370Sjasone 1023242844Sjasonevoid 1024299587Sjasonectl_prefork(tsdn_t *tsdn) 1025242844Sjasone{ 1026242844Sjasone 1027299587Sjasone malloc_mutex_prefork(tsdn, &ctl_mtx); 1028242844Sjasone} 1029242844Sjasone 1030242844Sjasonevoid 1031299587Sjasonectl_postfork_parent(tsdn_t *tsdn) 1032242844Sjasone{ 1033242844Sjasone 1034299587Sjasone malloc_mutex_postfork_parent(tsdn, &ctl_mtx); 1035242844Sjasone} 1036242844Sjasone 1037242844Sjasonevoid 1038299587Sjasonectl_postfork_child(tsdn_t *tsdn) 1039242844Sjasone{ 1040242844Sjasone 1041299587Sjasone malloc_mutex_postfork_child(tsdn, &ctl_mtx); 1042242844Sjasone} 1043242844Sjasone 1044234370Sjasone/******************************************************************************/ 1045234370Sjasone/* *_ctl() functions. */ 1046234370Sjasone 1047234370Sjasone#define READONLY() do { \ 1048234370Sjasone if (newp != NULL || newlen != 0) { \ 1049234370Sjasone ret = EPERM; \ 1050235238Sjasone goto label_return; \ 1051234370Sjasone } \ 1052234370Sjasone} while (0) 1053234370Sjasone 1054234370Sjasone#define WRITEONLY() do { \ 1055234370Sjasone if (oldp != NULL || oldlenp != NULL) { \ 1056234370Sjasone ret = EPERM; \ 1057235238Sjasone goto label_return; \ 1058234370Sjasone } \ 1059234370Sjasone} while (0) 1060234370Sjasone 1061286866Sjasone#define READ_XOR_WRITE() do { \ 1062286866Sjasone if ((oldp != NULL && oldlenp != NULL) && (newp != NULL || \ 1063286866Sjasone newlen != 0)) { \ 1064286866Sjasone ret = EPERM; \ 1065286866Sjasone goto label_return; \ 1066286866Sjasone } \ 1067286866Sjasone} while (0) 1068286866Sjasone 1069234370Sjasone#define READ(v, t) do { \ 1070234370Sjasone if (oldp != NULL && oldlenp != NULL) { \ 1071234370Sjasone if (*oldlenp != sizeof(t)) { \ 1072234370Sjasone size_t copylen = (sizeof(t) <= *oldlenp) \ 1073234370Sjasone ? sizeof(t) : *oldlenp; \ 1074245868Sjasone memcpy(oldp, (void *)&(v), copylen); \ 1075234370Sjasone ret = EINVAL; \ 1076235238Sjasone goto label_return; \ 1077286866Sjasone } \ 1078286866Sjasone *(t *)oldp = (v); \ 1079234370Sjasone } \ 1080234370Sjasone} while (0) 1081234370Sjasone 1082234370Sjasone#define WRITE(v, t) do { \ 1083234370Sjasone if (newp != NULL) { \ 1084234370Sjasone if (newlen != sizeof(t)) { \ 1085234370Sjasone ret = EINVAL; \ 1086235238Sjasone goto label_return; \ 1087234370Sjasone } \ 1088245868Sjasone (v) = *(t *)newp; \ 1089234370Sjasone } \ 1090234370Sjasone} while (0) 1091234370Sjasone 1092234370Sjasone/* 1093234370Sjasone * There's a lot of code duplication in the following macros due to limitations 1094234370Sjasone * in how nested cpp macros are expanded. 1095234370Sjasone */ 1096234370Sjasone#define CTL_RO_CLGEN(c, l, n, v, t) \ 1097234370Sjasonestatic int \ 1098299587Sjasonen##_ctl(tsd_t *tsd, const size_t *mib, size_t miblen, void *oldp, \ 1099299587Sjasone size_t *oldlenp, void *newp, size_t newlen) \ 1100234370Sjasone{ \ 1101234370Sjasone int ret; \ 1102234370Sjasone t oldval; \ 1103234370Sjasone \ 1104286866Sjasone if (!(c)) \ 1105234370Sjasone return (ENOENT); \ 1106234370Sjasone if (l) \ 1107299587Sjasone malloc_mutex_lock(tsd_tsdn(tsd), &ctl_mtx); \ 1108234370Sjasone READONLY(); \ 1109245868Sjasone oldval = (v); \ 1110234370Sjasone READ(oldval, t); \ 1111234370Sjasone \ 1112234370Sjasone ret = 0; \ 1113235238Sjasonelabel_return: \ 1114234370Sjasone if (l) \ 1115299587Sjasone malloc_mutex_unlock(tsd_tsdn(tsd), &ctl_mtx); \ 1116234370Sjasone return (ret); \ 1117234370Sjasone} 1118234370Sjasone 1119234370Sjasone#define CTL_RO_CGEN(c, n, v, t) \ 1120234370Sjasonestatic int \ 1121299587Sjasonen##_ctl(tsd_t *tsd, const size_t *mib, size_t miblen, void *oldp, \ 1122299587Sjasone size_t *oldlenp, void *newp, size_t newlen) \ 1123234370Sjasone{ \ 1124234370Sjasone int ret; \ 1125234370Sjasone t oldval; \ 1126234370Sjasone \ 1127286866Sjasone if (!(c)) \ 1128234370Sjasone return (ENOENT); \ 1129299587Sjasone malloc_mutex_lock(tsd_tsdn(tsd), &ctl_mtx); \ 1130234370Sjasone READONLY(); \ 1131245868Sjasone oldval = (v); \ 1132234370Sjasone READ(oldval, t); \ 1133234370Sjasone \ 1134234370Sjasone ret = 0; \ 1135235238Sjasonelabel_return: \ 1136299587Sjasone malloc_mutex_unlock(tsd_tsdn(tsd), &ctl_mtx); \ 1137234370Sjasone return (ret); \ 1138234370Sjasone} 1139234370Sjasone 1140234370Sjasone#define CTL_RO_GEN(n, v, t) \ 1141234370Sjasonestatic int \ 1142299587Sjasonen##_ctl(tsd_t *tsd, const size_t *mib, size_t miblen, void *oldp, \ 1143299587Sjasone size_t *oldlenp, void *newp, size_t newlen) \ 1144234370Sjasone{ \ 1145234370Sjasone int ret; \ 1146234370Sjasone t oldval; \ 1147234370Sjasone \ 1148299587Sjasone malloc_mutex_lock(tsd_tsdn(tsd), &ctl_mtx); \ 1149234370Sjasone READONLY(); \ 1150245868Sjasone oldval = (v); \ 1151234370Sjasone READ(oldval, t); \ 1152234370Sjasone \ 1153234370Sjasone ret = 0; \ 1154235238Sjasonelabel_return: \ 1155299587Sjasone malloc_mutex_unlock(tsd_tsdn(tsd), &ctl_mtx); \ 1156234370Sjasone return (ret); \ 1157234370Sjasone} 1158234370Sjasone 1159234370Sjasone/* 1160234370Sjasone * ctl_mtx is not acquired, under the assumption that no pertinent data will 1161234370Sjasone * mutate during the call. 1162234370Sjasone */ 1163234370Sjasone#define CTL_RO_NL_CGEN(c, n, v, t) \ 1164234370Sjasonestatic int \ 1165299587Sjasonen##_ctl(tsd_t *tsd, const size_t *mib, size_t miblen, void *oldp, \ 1166299587Sjasone size_t *oldlenp, void *newp, size_t newlen) \ 1167234370Sjasone{ \ 1168234370Sjasone int ret; \ 1169234370Sjasone t oldval; \ 1170234370Sjasone \ 1171286866Sjasone if (!(c)) \ 1172234370Sjasone return (ENOENT); \ 1173234370Sjasone READONLY(); \ 1174245868Sjasone oldval = (v); \ 1175234370Sjasone READ(oldval, t); \ 1176234370Sjasone \ 1177234370Sjasone ret = 0; \ 1178235238Sjasonelabel_return: \ 1179234370Sjasone return (ret); \ 1180234370Sjasone} 1181234370Sjasone 1182234370Sjasone#define CTL_RO_NL_GEN(n, v, t) \ 1183234370Sjasonestatic int \ 1184299587Sjasonen##_ctl(tsd_t *tsd, const size_t *mib, size_t miblen, void *oldp, \ 1185299587Sjasone size_t *oldlenp, void *newp, size_t newlen) \ 1186234370Sjasone{ \ 1187234370Sjasone int ret; \ 1188234370Sjasone t oldval; \ 1189234370Sjasone \ 1190234370Sjasone READONLY(); \ 1191245868Sjasone oldval = (v); \ 1192234370Sjasone READ(oldval, t); \ 1193234370Sjasone \ 1194234370Sjasone ret = 0; \ 1195235238Sjasonelabel_return: \ 1196234370Sjasone return (ret); \ 1197234370Sjasone} 1198234370Sjasone 1199286866Sjasone#define CTL_TSD_RO_NL_CGEN(c, n, m, t) \ 1200286866Sjasonestatic int \ 1201299587Sjasonen##_ctl(tsd_t *tsd, const size_t *mib, size_t miblen, void *oldp, \ 1202299587Sjasone size_t *oldlenp, void *newp, size_t newlen) \ 1203286866Sjasone{ \ 1204286866Sjasone int ret; \ 1205286866Sjasone t oldval; \ 1206286866Sjasone \ 1207286866Sjasone if (!(c)) \ 1208286866Sjasone return (ENOENT); \ 1209286866Sjasone READONLY(); \ 1210286866Sjasone oldval = (m(tsd)); \ 1211286866Sjasone READ(oldval, t); \ 1212286866Sjasone \ 1213286866Sjasone ret = 0; \ 1214286866Sjasonelabel_return: \ 1215286866Sjasone return (ret); \ 1216286866Sjasone} 1217286866Sjasone 1218296221Sjasone#define CTL_RO_CONFIG_GEN(n, t) \ 1219234370Sjasonestatic int \ 1220299587Sjasonen##_ctl(tsd_t *tsd, const size_t *mib, size_t miblen, void *oldp, \ 1221299587Sjasone size_t *oldlenp, void *newp, size_t newlen) \ 1222234370Sjasone{ \ 1223234370Sjasone int ret; \ 1224296221Sjasone t oldval; \ 1225234370Sjasone \ 1226234370Sjasone READONLY(); \ 1227234370Sjasone oldval = n; \ 1228296221Sjasone READ(oldval, t); \ 1229234370Sjasone \ 1230234370Sjasone ret = 0; \ 1231235238Sjasonelabel_return: \ 1232234370Sjasone return (ret); \ 1233234370Sjasone} 1234234370Sjasone 1235261071Sjasone/******************************************************************************/ 1236261071Sjasone 1237234370SjasoneCTL_RO_NL_GEN(version, JEMALLOC_VERSION, const char *) 1238234370Sjasone 1239234370Sjasonestatic int 1240299587Sjasoneepoch_ctl(tsd_t *tsd, const size_t *mib, size_t miblen, void *oldp, 1241299587Sjasone size_t *oldlenp, void *newp, size_t newlen) 1242234370Sjasone{ 1243234370Sjasone int ret; 1244256823Sjasone UNUSED uint64_t newval; 1245234370Sjasone 1246299587Sjasone malloc_mutex_lock(tsd_tsdn(tsd), &ctl_mtx); 1247234370Sjasone WRITE(newval, uint64_t); 1248235238Sjasone if (newp != NULL) 1249299587Sjasone ctl_refresh(tsd_tsdn(tsd)); 1250234370Sjasone READ(ctl_epoch, uint64_t); 1251234370Sjasone 1252234370Sjasone ret = 0; 1253234370Sjasonelabel_return: 1254299587Sjasone malloc_mutex_unlock(tsd_tsdn(tsd), &ctl_mtx); 1255234370Sjasone return (ret); 1256234370Sjasone} 1257234370Sjasone 1258261071Sjasone/******************************************************************************/ 1259234370Sjasone 1260296221SjasoneCTL_RO_CONFIG_GEN(config_cache_oblivious, bool) 1261296221SjasoneCTL_RO_CONFIG_GEN(config_debug, bool) 1262296221SjasoneCTL_RO_CONFIG_GEN(config_fill, bool) 1263296221SjasoneCTL_RO_CONFIG_GEN(config_lazy_lock, bool) 1264296221SjasoneCTL_RO_CONFIG_GEN(config_malloc_conf, const char *) 1265296221SjasoneCTL_RO_CONFIG_GEN(config_munmap, bool) 1266296221SjasoneCTL_RO_CONFIG_GEN(config_prof, bool) 1267296221SjasoneCTL_RO_CONFIG_GEN(config_prof_libgcc, bool) 1268296221SjasoneCTL_RO_CONFIG_GEN(config_prof_libunwind, bool) 1269296221SjasoneCTL_RO_CONFIG_GEN(config_stats, bool) 1270296221SjasoneCTL_RO_CONFIG_GEN(config_tcache, bool) 1271296221SjasoneCTL_RO_CONFIG_GEN(config_tls, bool) 1272296221SjasoneCTL_RO_CONFIG_GEN(config_utrace, bool) 1273296221SjasoneCTL_RO_CONFIG_GEN(config_valgrind, bool) 1274296221SjasoneCTL_RO_CONFIG_GEN(config_xmalloc, bool) 1275234370Sjasone 1276261071Sjasone/******************************************************************************/ 1277234370Sjasone 1278261071SjasoneCTL_RO_NL_GEN(opt_abort, opt_abort, bool) 1279261071SjasoneCTL_RO_NL_GEN(opt_dss, opt_dss, const char *) 1280261071SjasoneCTL_RO_NL_GEN(opt_lg_chunk, opt_lg_chunk, size_t) 1281296221SjasoneCTL_RO_NL_GEN(opt_narenas, opt_narenas, unsigned) 1282296221SjasoneCTL_RO_NL_GEN(opt_purge, purge_mode_names[opt_purge], const char *) 1283261071SjasoneCTL_RO_NL_GEN(opt_lg_dirty_mult, opt_lg_dirty_mult, ssize_t) 1284296221SjasoneCTL_RO_NL_GEN(opt_decay_time, opt_decay_time, ssize_t) 1285261071SjasoneCTL_RO_NL_GEN(opt_stats_print, opt_stats_print, bool) 1286286866SjasoneCTL_RO_NL_CGEN(config_fill, opt_junk, opt_junk, const char *) 1287261071SjasoneCTL_RO_NL_CGEN(config_fill, opt_quarantine, opt_quarantine, size_t) 1288261071SjasoneCTL_RO_NL_CGEN(config_fill, opt_redzone, opt_redzone, bool) 1289261071SjasoneCTL_RO_NL_CGEN(config_fill, opt_zero, opt_zero, bool) 1290261071SjasoneCTL_RO_NL_CGEN(config_utrace, opt_utrace, opt_utrace, bool) 1291261071SjasoneCTL_RO_NL_CGEN(config_xmalloc, opt_xmalloc, opt_xmalloc, bool) 1292261071SjasoneCTL_RO_NL_CGEN(config_tcache, opt_tcache, opt_tcache, bool) 1293261071SjasoneCTL_RO_NL_CGEN(config_tcache, opt_lg_tcache_max, opt_lg_tcache_max, ssize_t) 1294261071SjasoneCTL_RO_NL_CGEN(config_prof, opt_prof, opt_prof, bool) 1295261071SjasoneCTL_RO_NL_CGEN(config_prof, opt_prof_prefix, opt_prof_prefix, const char *) 1296286866SjasoneCTL_RO_NL_CGEN(config_prof, opt_prof_active, opt_prof_active, bool) 1297286866SjasoneCTL_RO_NL_CGEN(config_prof, opt_prof_thread_active_init, 1298286866Sjasone opt_prof_thread_active_init, bool) 1299261071SjasoneCTL_RO_NL_CGEN(config_prof, opt_lg_prof_sample, opt_lg_prof_sample, size_t) 1300261071SjasoneCTL_RO_NL_CGEN(config_prof, opt_prof_accum, opt_prof_accum, bool) 1301261071SjasoneCTL_RO_NL_CGEN(config_prof, opt_lg_prof_interval, opt_lg_prof_interval, ssize_t) 1302261071SjasoneCTL_RO_NL_CGEN(config_prof, opt_prof_gdump, opt_prof_gdump, bool) 1303261071SjasoneCTL_RO_NL_CGEN(config_prof, opt_prof_final, opt_prof_final, bool) 1304261071SjasoneCTL_RO_NL_CGEN(config_prof, opt_prof_leak, opt_prof_leak, bool) 1305234370Sjasone 1306261071Sjasone/******************************************************************************/ 1307234370Sjasone 1308234370Sjasonestatic int 1309299587Sjasonethread_arena_ctl(tsd_t *tsd, const size_t *mib, size_t miblen, void *oldp, 1310299587Sjasone size_t *oldlenp, void *newp, size_t newlen) 1311234370Sjasone{ 1312234370Sjasone int ret; 1313286866Sjasone arena_t *oldarena; 1314234370Sjasone unsigned newind, oldind; 1315234370Sjasone 1316286866Sjasone oldarena = arena_choose(tsd, NULL); 1317286866Sjasone if (oldarena == NULL) 1318286866Sjasone return (EAGAIN); 1319286866Sjasone 1320299587Sjasone malloc_mutex_lock(tsd_tsdn(tsd), &ctl_mtx); 1321286866Sjasone newind = oldind = oldarena->ind; 1322234370Sjasone WRITE(newind, unsigned); 1323234370Sjasone READ(oldind, unsigned); 1324234370Sjasone if (newind != oldind) { 1325286866Sjasone arena_t *newarena; 1326234370Sjasone 1327242844Sjasone if (newind >= ctl_stats.narenas) { 1328234370Sjasone /* New arena index is out of range. */ 1329234370Sjasone ret = EFAULT; 1330234370Sjasone goto label_return; 1331234370Sjasone } 1332234370Sjasone 1333234370Sjasone /* Initialize arena if necessary. */ 1334299587Sjasone newarena = arena_get(tsd_tsdn(tsd), newind, true); 1335286866Sjasone if (newarena == NULL) { 1336234370Sjasone ret = EAGAIN; 1337234370Sjasone goto label_return; 1338234370Sjasone } 1339286866Sjasone /* Set new arena/tcache associations. */ 1340286866Sjasone arena_migrate(tsd, oldind, newind); 1341234370Sjasone if (config_tcache) { 1342286866Sjasone tcache_t *tcache = tsd_tcache_get(tsd); 1343286866Sjasone if (tcache != NULL) { 1344299587Sjasone tcache_arena_reassociate(tsd_tsdn(tsd), tcache, 1345299587Sjasone oldarena, newarena); 1346234370Sjasone } 1347234370Sjasone } 1348234370Sjasone } 1349234370Sjasone 1350234370Sjasone ret = 0; 1351234370Sjasonelabel_return: 1352299587Sjasone malloc_mutex_unlock(tsd_tsdn(tsd), &ctl_mtx); 1353234370Sjasone return (ret); 1354234370Sjasone} 1355234370Sjasone 1356286866SjasoneCTL_TSD_RO_NL_CGEN(config_stats, thread_allocated, tsd_thread_allocated_get, 1357286866Sjasone uint64_t) 1358286866SjasoneCTL_TSD_RO_NL_CGEN(config_stats, thread_allocatedp, tsd_thread_allocatedp_get, 1359286866Sjasone uint64_t *) 1360286866SjasoneCTL_TSD_RO_NL_CGEN(config_stats, thread_deallocated, tsd_thread_deallocated_get, 1361286866Sjasone uint64_t) 1362286866SjasoneCTL_TSD_RO_NL_CGEN(config_stats, thread_deallocatedp, 1363286866Sjasone tsd_thread_deallocatedp_get, uint64_t *) 1364234370Sjasone 1365261071Sjasonestatic int 1366299587Sjasonethread_tcache_enabled_ctl(tsd_t *tsd, const size_t *mib, size_t miblen, 1367299587Sjasone void *oldp, size_t *oldlenp, void *newp, size_t newlen) 1368261071Sjasone{ 1369261071Sjasone int ret; 1370261071Sjasone bool oldval; 1371234370Sjasone 1372286866Sjasone if (!config_tcache) 1373261071Sjasone return (ENOENT); 1374234370Sjasone 1375261071Sjasone oldval = tcache_enabled_get(); 1376261071Sjasone if (newp != NULL) { 1377261071Sjasone if (newlen != sizeof(bool)) { 1378261071Sjasone ret = EINVAL; 1379261071Sjasone goto label_return; 1380261071Sjasone } 1381261071Sjasone tcache_enabled_set(*(bool *)newp); 1382261071Sjasone } 1383261071Sjasone READ(oldval, bool); 1384234370Sjasone 1385261071Sjasone ret = 0; 1386261071Sjasonelabel_return: 1387261071Sjasone return (ret); 1388261071Sjasone} 1389234370Sjasone 1390261071Sjasonestatic int 1391299587Sjasonethread_tcache_flush_ctl(tsd_t *tsd, const size_t *mib, size_t miblen, 1392299587Sjasone void *oldp, size_t *oldlenp, void *newp, size_t newlen) 1393261071Sjasone{ 1394261071Sjasone int ret; 1395261071Sjasone 1396286866Sjasone if (!config_tcache) 1397261071Sjasone return (ENOENT); 1398261071Sjasone 1399261071Sjasone READONLY(); 1400261071Sjasone WRITEONLY(); 1401261071Sjasone 1402261071Sjasone tcache_flush(); 1403261071Sjasone 1404261071Sjasone ret = 0; 1405261071Sjasonelabel_return: 1406261071Sjasone return (ret); 1407261071Sjasone} 1408261071Sjasone 1409286866Sjasonestatic int 1410299587Sjasonethread_prof_name_ctl(tsd_t *tsd, const size_t *mib, size_t miblen, void *oldp, 1411286866Sjasone size_t *oldlenp, void *newp, size_t newlen) 1412286866Sjasone{ 1413286866Sjasone int ret; 1414286866Sjasone 1415286866Sjasone if (!config_prof) 1416286866Sjasone return (ENOENT); 1417286866Sjasone 1418286866Sjasone READ_XOR_WRITE(); 1419286866Sjasone 1420286866Sjasone if (newp != NULL) { 1421286866Sjasone if (newlen != sizeof(const char *)) { 1422286866Sjasone ret = EINVAL; 1423286866Sjasone goto label_return; 1424286866Sjasone } 1425286866Sjasone 1426286866Sjasone if ((ret = prof_thread_name_set(tsd, *(const char **)newp)) != 1427286866Sjasone 0) 1428286866Sjasone goto label_return; 1429286866Sjasone } else { 1430299587Sjasone const char *oldname = prof_thread_name_get(tsd); 1431286866Sjasone READ(oldname, const char *); 1432286866Sjasone } 1433286866Sjasone 1434286866Sjasone ret = 0; 1435286866Sjasonelabel_return: 1436286866Sjasone return (ret); 1437286866Sjasone} 1438286866Sjasone 1439286866Sjasonestatic int 1440299587Sjasonethread_prof_active_ctl(tsd_t *tsd, const size_t *mib, size_t miblen, void *oldp, 1441286866Sjasone size_t *oldlenp, void *newp, size_t newlen) 1442286866Sjasone{ 1443286866Sjasone int ret; 1444286866Sjasone bool oldval; 1445286866Sjasone 1446286866Sjasone if (!config_prof) 1447286866Sjasone return (ENOENT); 1448286866Sjasone 1449299587Sjasone oldval = prof_thread_active_get(tsd); 1450286866Sjasone if (newp != NULL) { 1451286866Sjasone if (newlen != sizeof(bool)) { 1452286866Sjasone ret = EINVAL; 1453286866Sjasone goto label_return; 1454286866Sjasone } 1455299587Sjasone if (prof_thread_active_set(tsd, *(bool *)newp)) { 1456286866Sjasone ret = EAGAIN; 1457286866Sjasone goto label_return; 1458286866Sjasone } 1459286866Sjasone } 1460286866Sjasone READ(oldval, bool); 1461286866Sjasone 1462286866Sjasone ret = 0; 1463286866Sjasonelabel_return: 1464286866Sjasone return (ret); 1465286866Sjasone} 1466286866Sjasone 1467234370Sjasone/******************************************************************************/ 1468234370Sjasone 1469286866Sjasonestatic int 1470299587Sjasonetcache_create_ctl(tsd_t *tsd, const size_t *mib, size_t miblen, void *oldp, 1471299587Sjasone size_t *oldlenp, void *newp, size_t newlen) 1472286866Sjasone{ 1473286866Sjasone int ret; 1474286866Sjasone unsigned tcache_ind; 1475286866Sjasone 1476286866Sjasone if (!config_tcache) 1477286866Sjasone return (ENOENT); 1478286866Sjasone 1479299587Sjasone malloc_mutex_lock(tsd_tsdn(tsd), &ctl_mtx); 1480286866Sjasone READONLY(); 1481299587Sjasone if (tcaches_create(tsd_tsdn(tsd), &tcache_ind)) { 1482286866Sjasone ret = EFAULT; 1483286866Sjasone goto label_return; 1484286866Sjasone } 1485286866Sjasone READ(tcache_ind, unsigned); 1486286866Sjasone 1487286866Sjasone ret = 0; 1488286866Sjasonelabel_return: 1489299587Sjasone malloc_mutex_unlock(tsd_tsdn(tsd), &ctl_mtx); 1490286866Sjasone return (ret); 1491286866Sjasone} 1492286866Sjasone 1493286866Sjasonestatic int 1494299587Sjasonetcache_flush_ctl(tsd_t *tsd, const size_t *mib, size_t miblen, void *oldp, 1495299587Sjasone size_t *oldlenp, void *newp, size_t newlen) 1496286866Sjasone{ 1497286866Sjasone int ret; 1498286866Sjasone unsigned tcache_ind; 1499286866Sjasone 1500286866Sjasone if (!config_tcache) 1501286866Sjasone return (ENOENT); 1502286866Sjasone 1503286866Sjasone WRITEONLY(); 1504286866Sjasone tcache_ind = UINT_MAX; 1505286866Sjasone WRITE(tcache_ind, unsigned); 1506286866Sjasone if (tcache_ind == UINT_MAX) { 1507286866Sjasone ret = EFAULT; 1508286866Sjasone goto label_return; 1509286866Sjasone } 1510286866Sjasone tcaches_flush(tsd, tcache_ind); 1511286866Sjasone 1512286866Sjasone ret = 0; 1513286866Sjasonelabel_return: 1514286866Sjasone return (ret); 1515286866Sjasone} 1516286866Sjasone 1517286866Sjasonestatic int 1518299587Sjasonetcache_destroy_ctl(tsd_t *tsd, const size_t *mib, size_t miblen, void *oldp, 1519286866Sjasone size_t *oldlenp, void *newp, size_t newlen) 1520286866Sjasone{ 1521286866Sjasone int ret; 1522286866Sjasone unsigned tcache_ind; 1523286866Sjasone 1524286866Sjasone if (!config_tcache) 1525286866Sjasone return (ENOENT); 1526286866Sjasone 1527286866Sjasone WRITEONLY(); 1528286866Sjasone tcache_ind = UINT_MAX; 1529286866Sjasone WRITE(tcache_ind, unsigned); 1530286866Sjasone if (tcache_ind == UINT_MAX) { 1531286866Sjasone ret = EFAULT; 1532286866Sjasone goto label_return; 1533286866Sjasone } 1534286866Sjasone tcaches_destroy(tsd, tcache_ind); 1535286866Sjasone 1536286866Sjasone ret = 0; 1537286866Sjasonelabel_return: 1538286866Sjasone return (ret); 1539286866Sjasone} 1540286866Sjasone 1541286866Sjasone/******************************************************************************/ 1542286866Sjasone 1543242844Sjasonestatic void 1544299587Sjasonearena_i_purge(tsdn_t *tsdn, unsigned arena_ind, bool all) 1545242844Sjasone{ 1546242844Sjasone 1547299587Sjasone malloc_mutex_lock(tsdn, &ctl_mtx); 1548296221Sjasone { 1549296221Sjasone unsigned narenas = ctl_stats.narenas; 1550242844Sjasone 1551296221Sjasone if (arena_ind == narenas) { 1552296221Sjasone unsigned i; 1553296221Sjasone VARIABLE_ARRAY(arena_t *, tarenas, narenas); 1554296221Sjasone 1555296221Sjasone for (i = 0; i < narenas; i++) 1556299587Sjasone tarenas[i] = arena_get(tsdn, i, false); 1557296221Sjasone 1558296221Sjasone /* 1559296221Sjasone * No further need to hold ctl_mtx, since narenas and 1560296221Sjasone * tarenas contain everything needed below. 1561296221Sjasone */ 1562299587Sjasone malloc_mutex_unlock(tsdn, &ctl_mtx); 1563296221Sjasone 1564296221Sjasone for (i = 0; i < narenas; i++) { 1565296221Sjasone if (tarenas[i] != NULL) 1566299587Sjasone arena_purge(tsdn, tarenas[i], all); 1567296221Sjasone } 1568296221Sjasone } else { 1569296221Sjasone arena_t *tarena; 1570296221Sjasone 1571296221Sjasone assert(arena_ind < narenas); 1572296221Sjasone 1573299587Sjasone tarena = arena_get(tsdn, arena_ind, false); 1574296221Sjasone 1575296221Sjasone /* No further need to hold ctl_mtx. */ 1576299587Sjasone malloc_mutex_unlock(tsdn, &ctl_mtx); 1577296221Sjasone 1578296221Sjasone if (tarena != NULL) 1579299587Sjasone arena_purge(tsdn, tarena, all); 1580242844Sjasone } 1581242844Sjasone } 1582242844Sjasone} 1583242844Sjasone 1584242844Sjasonestatic int 1585299587Sjasonearena_i_purge_ctl(tsd_t *tsd, const size_t *mib, size_t miblen, void *oldp, 1586299587Sjasone size_t *oldlenp, void *newp, size_t newlen) 1587242844Sjasone{ 1588242844Sjasone int ret; 1589242844Sjasone 1590242844Sjasone READONLY(); 1591242844Sjasone WRITEONLY(); 1592299587Sjasone arena_i_purge(tsd_tsdn(tsd), (unsigned)mib[1], true); 1593242844Sjasone 1594242844Sjasone ret = 0; 1595242844Sjasonelabel_return: 1596242844Sjasone return (ret); 1597242844Sjasone} 1598242844Sjasone 1599242844Sjasonestatic int 1600299587Sjasonearena_i_decay_ctl(tsd_t *tsd, const size_t *mib, size_t miblen, void *oldp, 1601299587Sjasone size_t *oldlenp, void *newp, size_t newlen) 1602296221Sjasone{ 1603296221Sjasone int ret; 1604296221Sjasone 1605296221Sjasone READONLY(); 1606296221Sjasone WRITEONLY(); 1607299587Sjasone arena_i_purge(tsd_tsdn(tsd), (unsigned)mib[1], false); 1608296221Sjasone 1609296221Sjasone ret = 0; 1610296221Sjasonelabel_return: 1611296221Sjasone return (ret); 1612296221Sjasone} 1613296221Sjasone 1614296221Sjasonestatic int 1615299587Sjasonearena_i_reset_ctl(tsd_t *tsd, const size_t *mib, size_t miblen, void *oldp, 1616299587Sjasone size_t *oldlenp, void *newp, size_t newlen) 1617242844Sjasone{ 1618286866Sjasone int ret; 1619299587Sjasone unsigned arena_ind; 1620299587Sjasone arena_t *arena; 1621299587Sjasone 1622299587Sjasone READONLY(); 1623299587Sjasone WRITEONLY(); 1624299587Sjasone 1625299587Sjasone if ((config_valgrind && unlikely(in_valgrind)) || (config_fill && 1626299587Sjasone unlikely(opt_quarantine))) { 1627299587Sjasone ret = EFAULT; 1628299587Sjasone goto label_return; 1629299587Sjasone } 1630299587Sjasone 1631299587Sjasone arena_ind = (unsigned)mib[1]; 1632299587Sjasone if (config_debug) { 1633299587Sjasone malloc_mutex_lock(tsd_tsdn(tsd), &ctl_mtx); 1634299587Sjasone assert(arena_ind < ctl_stats.narenas); 1635299587Sjasone malloc_mutex_unlock(tsd_tsdn(tsd), &ctl_mtx); 1636299587Sjasone } 1637299587Sjasone assert(arena_ind >= opt_narenas); 1638299587Sjasone 1639299587Sjasone arena = arena_get(tsd_tsdn(tsd), arena_ind, false); 1640299587Sjasone 1641299587Sjasone arena_reset(tsd, arena); 1642299587Sjasone 1643299587Sjasone ret = 0; 1644299587Sjasonelabel_return: 1645299587Sjasone return (ret); 1646299587Sjasone} 1647299587Sjasone 1648299587Sjasonestatic int 1649299587Sjasonearena_i_dss_ctl(tsd_t *tsd, const size_t *mib, size_t miblen, void *oldp, 1650299587Sjasone size_t *oldlenp, void *newp, size_t newlen) 1651299587Sjasone{ 1652299587Sjasone int ret; 1653286866Sjasone const char *dss = NULL; 1654296221Sjasone unsigned arena_ind = (unsigned)mib[1]; 1655242844Sjasone dss_prec_t dss_prec_old = dss_prec_limit; 1656242844Sjasone dss_prec_t dss_prec = dss_prec_limit; 1657242844Sjasone 1658299587Sjasone malloc_mutex_lock(tsd_tsdn(tsd), &ctl_mtx); 1659242844Sjasone WRITE(dss, const char *); 1660286866Sjasone if (dss != NULL) { 1661286866Sjasone int i; 1662286866Sjasone bool match = false; 1663286866Sjasone 1664286866Sjasone for (i = 0; i < dss_prec_limit; i++) { 1665286866Sjasone if (strcmp(dss_prec_names[i], dss) == 0) { 1666286866Sjasone dss_prec = i; 1667286866Sjasone match = true; 1668286866Sjasone break; 1669286866Sjasone } 1670242844Sjasone } 1671286866Sjasone 1672286866Sjasone if (!match) { 1673286866Sjasone ret = EINVAL; 1674286866Sjasone goto label_return; 1675286866Sjasone } 1676242844Sjasone } 1677242844Sjasone 1678242844Sjasone if (arena_ind < ctl_stats.narenas) { 1679299587Sjasone arena_t *arena = arena_get(tsd_tsdn(tsd), arena_ind, false); 1680286866Sjasone if (arena == NULL || (dss_prec != dss_prec_limit && 1681299587Sjasone arena_dss_prec_set(tsd_tsdn(tsd), arena, dss_prec))) { 1682286866Sjasone ret = EFAULT; 1683286866Sjasone goto label_return; 1684286866Sjasone } 1685299587Sjasone dss_prec_old = arena_dss_prec_get(tsd_tsdn(tsd), arena); 1686242844Sjasone } else { 1687286866Sjasone if (dss_prec != dss_prec_limit && 1688299587Sjasone chunk_dss_prec_set(tsd_tsdn(tsd), dss_prec)) { 1689286866Sjasone ret = EFAULT; 1690286866Sjasone goto label_return; 1691286866Sjasone } 1692299587Sjasone dss_prec_old = chunk_dss_prec_get(tsd_tsdn(tsd)); 1693242844Sjasone } 1694286866Sjasone 1695242844Sjasone dss = dss_prec_names[dss_prec_old]; 1696242844Sjasone READ(dss, const char *); 1697286866Sjasone 1698286866Sjasone ret = 0; 1699286866Sjasonelabel_return: 1700299587Sjasone malloc_mutex_unlock(tsd_tsdn(tsd), &ctl_mtx); 1701286866Sjasone return (ret); 1702286866Sjasone} 1703286866Sjasone 1704286866Sjasonestatic int 1705299587Sjasonearena_i_lg_dirty_mult_ctl(tsd_t *tsd, const size_t *mib, size_t miblen, 1706299587Sjasone void *oldp, size_t *oldlenp, void *newp, size_t newlen) 1707286866Sjasone{ 1708286866Sjasone int ret; 1709296221Sjasone unsigned arena_ind = (unsigned)mib[1]; 1710286866Sjasone arena_t *arena; 1711286866Sjasone 1712299587Sjasone arena = arena_get(tsd_tsdn(tsd), arena_ind, false); 1713286866Sjasone if (arena == NULL) { 1714242844Sjasone ret = EFAULT; 1715242844Sjasone goto label_return; 1716242844Sjasone } 1717242844Sjasone 1718286866Sjasone if (oldp != NULL && oldlenp != NULL) { 1719299587Sjasone size_t oldval = arena_lg_dirty_mult_get(tsd_tsdn(tsd), arena); 1720286866Sjasone READ(oldval, ssize_t); 1721286866Sjasone } 1722286866Sjasone if (newp != NULL) { 1723286866Sjasone if (newlen != sizeof(ssize_t)) { 1724286866Sjasone ret = EINVAL; 1725286866Sjasone goto label_return; 1726286866Sjasone } 1727299587Sjasone if (arena_lg_dirty_mult_set(tsd_tsdn(tsd), arena, 1728299587Sjasone *(ssize_t *)newp)) { 1729286866Sjasone ret = EFAULT; 1730286866Sjasone goto label_return; 1731286866Sjasone } 1732286866Sjasone } 1733286866Sjasone 1734242844Sjasone ret = 0; 1735242844Sjasonelabel_return: 1736286866Sjasone return (ret); 1737286866Sjasone} 1738286866Sjasone 1739286866Sjasonestatic int 1740299587Sjasonearena_i_decay_time_ctl(tsd_t *tsd, const size_t *mib, size_t miblen, void *oldp, 1741296221Sjasone size_t *oldlenp, void *newp, size_t newlen) 1742296221Sjasone{ 1743296221Sjasone int ret; 1744296221Sjasone unsigned arena_ind = (unsigned)mib[1]; 1745296221Sjasone arena_t *arena; 1746296221Sjasone 1747299587Sjasone arena = arena_get(tsd_tsdn(tsd), arena_ind, false); 1748296221Sjasone if (arena == NULL) { 1749296221Sjasone ret = EFAULT; 1750296221Sjasone goto label_return; 1751296221Sjasone } 1752296221Sjasone 1753296221Sjasone if (oldp != NULL && oldlenp != NULL) { 1754299587Sjasone size_t oldval = arena_decay_time_get(tsd_tsdn(tsd), arena); 1755296221Sjasone READ(oldval, ssize_t); 1756296221Sjasone } 1757296221Sjasone if (newp != NULL) { 1758296221Sjasone if (newlen != sizeof(ssize_t)) { 1759296221Sjasone ret = EINVAL; 1760296221Sjasone goto label_return; 1761296221Sjasone } 1762299587Sjasone if (arena_decay_time_set(tsd_tsdn(tsd), arena, 1763299587Sjasone *(ssize_t *)newp)) { 1764296221Sjasone ret = EFAULT; 1765296221Sjasone goto label_return; 1766296221Sjasone } 1767296221Sjasone } 1768296221Sjasone 1769296221Sjasone ret = 0; 1770296221Sjasonelabel_return: 1771296221Sjasone return (ret); 1772296221Sjasone} 1773296221Sjasone 1774296221Sjasonestatic int 1775299587Sjasonearena_i_chunk_hooks_ctl(tsd_t *tsd, const size_t *mib, size_t miblen, 1776299587Sjasone void *oldp, size_t *oldlenp, void *newp, size_t newlen) 1777286866Sjasone{ 1778286866Sjasone int ret; 1779296221Sjasone unsigned arena_ind = (unsigned)mib[1]; 1780286866Sjasone arena_t *arena; 1781286866Sjasone 1782299587Sjasone malloc_mutex_lock(tsd_tsdn(tsd), &ctl_mtx); 1783286866Sjasone if (arena_ind < narenas_total_get() && (arena = 1784299587Sjasone arena_get(tsd_tsdn(tsd), arena_ind, false)) != NULL) { 1785286866Sjasone if (newp != NULL) { 1786286866Sjasone chunk_hooks_t old_chunk_hooks, new_chunk_hooks; 1787286866Sjasone WRITE(new_chunk_hooks, chunk_hooks_t); 1788299587Sjasone old_chunk_hooks = chunk_hooks_set(tsd_tsdn(tsd), arena, 1789286866Sjasone &new_chunk_hooks); 1790286866Sjasone READ(old_chunk_hooks, chunk_hooks_t); 1791286866Sjasone } else { 1792299587Sjasone chunk_hooks_t old_chunk_hooks = 1793299587Sjasone chunk_hooks_get(tsd_tsdn(tsd), arena); 1794286866Sjasone READ(old_chunk_hooks, chunk_hooks_t); 1795286866Sjasone } 1796286866Sjasone } else { 1797286866Sjasone ret = EFAULT; 1798286866Sjasone goto label_return; 1799286866Sjasone } 1800286866Sjasone ret = 0; 1801286866Sjasonelabel_return: 1802299587Sjasone malloc_mutex_unlock(tsd_tsdn(tsd), &ctl_mtx); 1803242844Sjasone return (ret); 1804242844Sjasone} 1805242844Sjasone 1806242844Sjasonestatic const ctl_named_node_t * 1807299587Sjasonearena_i_index(tsdn_t *tsdn, const size_t *mib, size_t miblen, size_t i) 1808242844Sjasone{ 1809299587Sjasone const ctl_named_node_t *ret; 1810242844Sjasone 1811299587Sjasone malloc_mutex_lock(tsdn, &ctl_mtx); 1812242844Sjasone if (i > ctl_stats.narenas) { 1813242844Sjasone ret = NULL; 1814242844Sjasone goto label_return; 1815242844Sjasone } 1816242844Sjasone 1817242844Sjasone ret = super_arena_i_node; 1818242844Sjasonelabel_return: 1819299587Sjasone malloc_mutex_unlock(tsdn, &ctl_mtx); 1820242844Sjasone return (ret); 1821242844Sjasone} 1822242844Sjasone 1823242844Sjasone/******************************************************************************/ 1824242844Sjasone 1825242844Sjasonestatic int 1826299587Sjasonearenas_narenas_ctl(tsd_t *tsd, const size_t *mib, size_t miblen, void *oldp, 1827242844Sjasone size_t *oldlenp, void *newp, size_t newlen) 1828242844Sjasone{ 1829242844Sjasone int ret; 1830242844Sjasone unsigned narenas; 1831234370Sjasone 1832299587Sjasone malloc_mutex_lock(tsd_tsdn(tsd), &ctl_mtx); 1833242844Sjasone READONLY(); 1834242844Sjasone if (*oldlenp != sizeof(unsigned)) { 1835242844Sjasone ret = EINVAL; 1836242844Sjasone goto label_return; 1837242844Sjasone } 1838242844Sjasone narenas = ctl_stats.narenas; 1839242844Sjasone READ(narenas, unsigned); 1840242844Sjasone 1841242844Sjasone ret = 0; 1842242844Sjasonelabel_return: 1843299587Sjasone malloc_mutex_unlock(tsd_tsdn(tsd), &ctl_mtx); 1844242844Sjasone return (ret); 1845242844Sjasone} 1846242844Sjasone 1847234370Sjasonestatic int 1848299587Sjasonearenas_initialized_ctl(tsd_t *tsd, const size_t *mib, size_t miblen, void *oldp, 1849234370Sjasone size_t *oldlenp, void *newp, size_t newlen) 1850234370Sjasone{ 1851234370Sjasone int ret; 1852234370Sjasone unsigned nread, i; 1853234370Sjasone 1854299587Sjasone malloc_mutex_lock(tsd_tsdn(tsd), &ctl_mtx); 1855234370Sjasone READONLY(); 1856242844Sjasone if (*oldlenp != ctl_stats.narenas * sizeof(bool)) { 1857234370Sjasone ret = EINVAL; 1858242844Sjasone nread = (*oldlenp < ctl_stats.narenas * sizeof(bool)) 1859296221Sjasone ? (unsigned)(*oldlenp / sizeof(bool)) : ctl_stats.narenas; 1860234370Sjasone } else { 1861234370Sjasone ret = 0; 1862242844Sjasone nread = ctl_stats.narenas; 1863234370Sjasone } 1864234370Sjasone 1865234370Sjasone for (i = 0; i < nread; i++) 1866234370Sjasone ((bool *)oldp)[i] = ctl_stats.arenas[i].initialized; 1867234370Sjasone 1868234370Sjasonelabel_return: 1869299587Sjasone malloc_mutex_unlock(tsd_tsdn(tsd), &ctl_mtx); 1870234370Sjasone return (ret); 1871234370Sjasone} 1872234370Sjasone 1873286866Sjasonestatic int 1874299587Sjasonearenas_lg_dirty_mult_ctl(tsd_t *tsd, const size_t *mib, size_t miblen, 1875299587Sjasone void *oldp, size_t *oldlenp, void *newp, size_t newlen) 1876286866Sjasone{ 1877286866Sjasone int ret; 1878286866Sjasone 1879286866Sjasone if (oldp != NULL && oldlenp != NULL) { 1880286866Sjasone size_t oldval = arena_lg_dirty_mult_default_get(); 1881286866Sjasone READ(oldval, ssize_t); 1882286866Sjasone } 1883286866Sjasone if (newp != NULL) { 1884286866Sjasone if (newlen != sizeof(ssize_t)) { 1885286866Sjasone ret = EINVAL; 1886286866Sjasone goto label_return; 1887286866Sjasone } 1888286866Sjasone if (arena_lg_dirty_mult_default_set(*(ssize_t *)newp)) { 1889286866Sjasone ret = EFAULT; 1890286866Sjasone goto label_return; 1891286866Sjasone } 1892286866Sjasone } 1893286866Sjasone 1894286866Sjasone ret = 0; 1895286866Sjasonelabel_return: 1896286866Sjasone return (ret); 1897286866Sjasone} 1898286866Sjasone 1899296221Sjasonestatic int 1900299587Sjasonearenas_decay_time_ctl(tsd_t *tsd, const size_t *mib, size_t miblen, void *oldp, 1901296221Sjasone size_t *oldlenp, void *newp, size_t newlen) 1902296221Sjasone{ 1903296221Sjasone int ret; 1904296221Sjasone 1905296221Sjasone if (oldp != NULL && oldlenp != NULL) { 1906296221Sjasone size_t oldval = arena_decay_time_default_get(); 1907296221Sjasone READ(oldval, ssize_t); 1908296221Sjasone } 1909296221Sjasone if (newp != NULL) { 1910296221Sjasone if (newlen != sizeof(ssize_t)) { 1911296221Sjasone ret = EINVAL; 1912296221Sjasone goto label_return; 1913296221Sjasone } 1914296221Sjasone if (arena_decay_time_default_set(*(ssize_t *)newp)) { 1915296221Sjasone ret = EFAULT; 1916296221Sjasone goto label_return; 1917296221Sjasone } 1918296221Sjasone } 1919296221Sjasone 1920296221Sjasone ret = 0; 1921296221Sjasonelabel_return: 1922296221Sjasone return (ret); 1923296221Sjasone} 1924296221Sjasone 1925234370SjasoneCTL_RO_NL_GEN(arenas_quantum, QUANTUM, size_t) 1926234370SjasoneCTL_RO_NL_GEN(arenas_page, PAGE, size_t) 1927234370SjasoneCTL_RO_NL_CGEN(config_tcache, arenas_tcache_max, tcache_maxclass, size_t) 1928234370SjasoneCTL_RO_NL_GEN(arenas_nbins, NBINS, unsigned) 1929234370SjasoneCTL_RO_NL_CGEN(config_tcache, arenas_nhbins, nhbins, unsigned) 1930261071SjasoneCTL_RO_NL_GEN(arenas_bin_i_size, arena_bin_info[mib[2]].reg_size, size_t) 1931261071SjasoneCTL_RO_NL_GEN(arenas_bin_i_nregs, arena_bin_info[mib[2]].nregs, uint32_t) 1932261071SjasoneCTL_RO_NL_GEN(arenas_bin_i_run_size, arena_bin_info[mib[2]].run_size, size_t) 1933261071Sjasonestatic const ctl_named_node_t * 1934299587Sjasonearenas_bin_i_index(tsdn_t *tsdn, const size_t *mib, size_t miblen, size_t i) 1935261071Sjasone{ 1936261071Sjasone 1937261071Sjasone if (i > NBINS) 1938261071Sjasone return (NULL); 1939261071Sjasone return (super_arenas_bin_i_node); 1940261071Sjasone} 1941261071Sjasone 1942286866SjasoneCTL_RO_NL_GEN(arenas_nlruns, nlclasses, unsigned) 1943296221SjasoneCTL_RO_NL_GEN(arenas_lrun_i_size, index2size(NBINS+(szind_t)mib[2]), size_t) 1944261071Sjasonestatic const ctl_named_node_t * 1945299587Sjasonearenas_lrun_i_index(tsdn_t *tsdn, const size_t *mib, size_t miblen, size_t i) 1946261071Sjasone{ 1947234370Sjasone 1948261071Sjasone if (i > nlclasses) 1949261071Sjasone return (NULL); 1950261071Sjasone return (super_arenas_lrun_i_node); 1951261071Sjasone} 1952261071Sjasone 1953286866SjasoneCTL_RO_NL_GEN(arenas_nhchunks, nhclasses, unsigned) 1954296221SjasoneCTL_RO_NL_GEN(arenas_hchunk_i_size, index2size(NBINS+nlclasses+(szind_t)mib[2]), 1955296221Sjasone size_t) 1956286866Sjasonestatic const ctl_named_node_t * 1957299587Sjasonearenas_hchunk_i_index(tsdn_t *tsdn, const size_t *mib, size_t miblen, size_t i) 1958234370Sjasone{ 1959234370Sjasone 1960286866Sjasone if (i > nhclasses) 1961286866Sjasone return (NULL); 1962286866Sjasone return (super_arenas_hchunk_i_node); 1963242844Sjasone} 1964234370Sjasone 1965242844Sjasonestatic int 1966299587Sjasonearenas_extend_ctl(tsd_t *tsd, const size_t *mib, size_t miblen, void *oldp, 1967299587Sjasone size_t *oldlenp, void *newp, size_t newlen) 1968242844Sjasone{ 1969242844Sjasone int ret; 1970245868Sjasone unsigned narenas; 1971242844Sjasone 1972299587Sjasone malloc_mutex_lock(tsd_tsdn(tsd), &ctl_mtx); 1973242844Sjasone READONLY(); 1974299587Sjasone if (ctl_grow(tsd_tsdn(tsd))) { 1975242844Sjasone ret = EAGAIN; 1976242844Sjasone goto label_return; 1977234370Sjasone } 1978245868Sjasone narenas = ctl_stats.narenas - 1; 1979245868Sjasone READ(narenas, unsigned); 1980234370Sjasone 1981234370Sjasone ret = 0; 1982234370Sjasonelabel_return: 1983299587Sjasone malloc_mutex_unlock(tsd_tsdn(tsd), &ctl_mtx); 1984234370Sjasone return (ret); 1985234370Sjasone} 1986234370Sjasone 1987234370Sjasone/******************************************************************************/ 1988234370Sjasone 1989234370Sjasonestatic int 1990299587Sjasoneprof_thread_active_init_ctl(tsd_t *tsd, const size_t *mib, size_t miblen, 1991299587Sjasone void *oldp, size_t *oldlenp, void *newp, size_t newlen) 1992286866Sjasone{ 1993286866Sjasone int ret; 1994286866Sjasone bool oldval; 1995286866Sjasone 1996286866Sjasone if (!config_prof) 1997286866Sjasone return (ENOENT); 1998286866Sjasone 1999286866Sjasone if (newp != NULL) { 2000286866Sjasone if (newlen != sizeof(bool)) { 2001286866Sjasone ret = EINVAL; 2002286866Sjasone goto label_return; 2003286866Sjasone } 2004299587Sjasone oldval = prof_thread_active_init_set(tsd_tsdn(tsd), 2005299587Sjasone *(bool *)newp); 2006286866Sjasone } else 2007299587Sjasone oldval = prof_thread_active_init_get(tsd_tsdn(tsd)); 2008286866Sjasone READ(oldval, bool); 2009286866Sjasone 2010286866Sjasone ret = 0; 2011286866Sjasonelabel_return: 2012286866Sjasone return (ret); 2013286866Sjasone} 2014286866Sjasone 2015286866Sjasonestatic int 2016299587Sjasoneprof_active_ctl(tsd_t *tsd, const size_t *mib, size_t miblen, void *oldp, 2017299587Sjasone size_t *oldlenp, void *newp, size_t newlen) 2018234370Sjasone{ 2019234370Sjasone int ret; 2020234370Sjasone bool oldval; 2021234370Sjasone 2022286866Sjasone if (!config_prof) 2023234370Sjasone return (ENOENT); 2024234370Sjasone 2025234370Sjasone if (newp != NULL) { 2026286866Sjasone if (newlen != sizeof(bool)) { 2027286866Sjasone ret = EINVAL; 2028286866Sjasone goto label_return; 2029286866Sjasone } 2030299587Sjasone oldval = prof_active_set(tsd_tsdn(tsd), *(bool *)newp); 2031286866Sjasone } else 2032299587Sjasone oldval = prof_active_get(tsd_tsdn(tsd)); 2033234370Sjasone READ(oldval, bool); 2034234370Sjasone 2035234370Sjasone ret = 0; 2036234370Sjasonelabel_return: 2037234370Sjasone return (ret); 2038234370Sjasone} 2039234370Sjasone 2040234370Sjasonestatic int 2041299587Sjasoneprof_dump_ctl(tsd_t *tsd, const size_t *mib, size_t miblen, void *oldp, 2042299587Sjasone size_t *oldlenp, void *newp, size_t newlen) 2043234370Sjasone{ 2044234370Sjasone int ret; 2045234370Sjasone const char *filename = NULL; 2046234370Sjasone 2047286866Sjasone if (!config_prof) 2048234370Sjasone return (ENOENT); 2049234370Sjasone 2050234370Sjasone WRITEONLY(); 2051234370Sjasone WRITE(filename, const char *); 2052234370Sjasone 2053299587Sjasone if (prof_mdump(tsd, filename)) { 2054234370Sjasone ret = EFAULT; 2055234370Sjasone goto label_return; 2056234370Sjasone } 2057234370Sjasone 2058234370Sjasone ret = 0; 2059234370Sjasonelabel_return: 2060234370Sjasone return (ret); 2061234370Sjasone} 2062234370Sjasone 2063286866Sjasonestatic int 2064299587Sjasoneprof_gdump_ctl(tsd_t *tsd, const size_t *mib, size_t miblen, void *oldp, 2065299587Sjasone size_t *oldlenp, void *newp, size_t newlen) 2066286866Sjasone{ 2067286866Sjasone int ret; 2068286866Sjasone bool oldval; 2069286866Sjasone 2070286866Sjasone if (!config_prof) 2071286866Sjasone return (ENOENT); 2072286866Sjasone 2073286866Sjasone if (newp != NULL) { 2074286866Sjasone if (newlen != sizeof(bool)) { 2075286866Sjasone ret = EINVAL; 2076286866Sjasone goto label_return; 2077286866Sjasone } 2078299587Sjasone oldval = prof_gdump_set(tsd_tsdn(tsd), *(bool *)newp); 2079286866Sjasone } else 2080299587Sjasone oldval = prof_gdump_get(tsd_tsdn(tsd)); 2081286866Sjasone READ(oldval, bool); 2082286866Sjasone 2083286866Sjasone ret = 0; 2084286866Sjasonelabel_return: 2085286866Sjasone return (ret); 2086286866Sjasone} 2087286866Sjasone 2088286866Sjasonestatic int 2089299587Sjasoneprof_reset_ctl(tsd_t *tsd, const size_t *mib, size_t miblen, void *oldp, 2090299587Sjasone size_t *oldlenp, void *newp, size_t newlen) 2091286866Sjasone{ 2092286866Sjasone int ret; 2093286866Sjasone size_t lg_sample = lg_prof_sample; 2094286866Sjasone 2095286866Sjasone if (!config_prof) 2096286866Sjasone return (ENOENT); 2097286866Sjasone 2098286866Sjasone WRITEONLY(); 2099286866Sjasone WRITE(lg_sample, size_t); 2100286866Sjasone if (lg_sample >= (sizeof(uint64_t) << 3)) 2101286866Sjasone lg_sample = (sizeof(uint64_t) << 3) - 1; 2102286866Sjasone 2103299587Sjasone prof_reset(tsd_tsdn(tsd), lg_sample); 2104286866Sjasone 2105286866Sjasone ret = 0; 2106286866Sjasonelabel_return: 2107286866Sjasone return (ret); 2108286866Sjasone} 2109286866Sjasone 2110234370SjasoneCTL_RO_NL_CGEN(config_prof, prof_interval, prof_interval, uint64_t) 2111286866SjasoneCTL_RO_NL_CGEN(config_prof, lg_prof_sample, lg_prof_sample, size_t) 2112234370Sjasone 2113234370Sjasone/******************************************************************************/ 2114234370Sjasone 2115261071SjasoneCTL_RO_CGEN(config_stats, stats_cactive, &stats_cactive, size_t *) 2116261071SjasoneCTL_RO_CGEN(config_stats, stats_allocated, ctl_stats.allocated, size_t) 2117261071SjasoneCTL_RO_CGEN(config_stats, stats_active, ctl_stats.active, size_t) 2118286866SjasoneCTL_RO_CGEN(config_stats, stats_metadata, ctl_stats.metadata, size_t) 2119286866SjasoneCTL_RO_CGEN(config_stats, stats_resident, ctl_stats.resident, size_t) 2120261071SjasoneCTL_RO_CGEN(config_stats, stats_mapped, ctl_stats.mapped, size_t) 2121299587SjasoneCTL_RO_CGEN(config_stats, stats_retained, ctl_stats.retained, size_t) 2122261071Sjasone 2123261071SjasoneCTL_RO_GEN(stats_arenas_i_dss, ctl_stats.arenas[mib[2]].dss, const char *) 2124286866SjasoneCTL_RO_GEN(stats_arenas_i_lg_dirty_mult, ctl_stats.arenas[mib[2]].lg_dirty_mult, 2125286866Sjasone ssize_t) 2126296221SjasoneCTL_RO_GEN(stats_arenas_i_decay_time, ctl_stats.arenas[mib[2]].decay_time, 2127296221Sjasone ssize_t) 2128261071SjasoneCTL_RO_GEN(stats_arenas_i_nthreads, ctl_stats.arenas[mib[2]].nthreads, unsigned) 2129261071SjasoneCTL_RO_GEN(stats_arenas_i_pactive, ctl_stats.arenas[mib[2]].pactive, size_t) 2130261071SjasoneCTL_RO_GEN(stats_arenas_i_pdirty, ctl_stats.arenas[mib[2]].pdirty, size_t) 2131261071SjasoneCTL_RO_CGEN(config_stats, stats_arenas_i_mapped, 2132261071Sjasone ctl_stats.arenas[mib[2]].astats.mapped, size_t) 2133299587SjasoneCTL_RO_CGEN(config_stats, stats_arenas_i_retained, 2134299587Sjasone ctl_stats.arenas[mib[2]].astats.retained, size_t) 2135261071SjasoneCTL_RO_CGEN(config_stats, stats_arenas_i_npurge, 2136261071Sjasone ctl_stats.arenas[mib[2]].astats.npurge, uint64_t) 2137261071SjasoneCTL_RO_CGEN(config_stats, stats_arenas_i_nmadvise, 2138261071Sjasone ctl_stats.arenas[mib[2]].astats.nmadvise, uint64_t) 2139261071SjasoneCTL_RO_CGEN(config_stats, stats_arenas_i_purged, 2140261071Sjasone ctl_stats.arenas[mib[2]].astats.purged, uint64_t) 2141286866SjasoneCTL_RO_CGEN(config_stats, stats_arenas_i_metadata_mapped, 2142286866Sjasone ctl_stats.arenas[mib[2]].astats.metadata_mapped, size_t) 2143286866SjasoneCTL_RO_CGEN(config_stats, stats_arenas_i_metadata_allocated, 2144286866Sjasone ctl_stats.arenas[mib[2]].astats.metadata_allocated, size_t) 2145261071Sjasone 2146234370SjasoneCTL_RO_CGEN(config_stats, stats_arenas_i_small_allocated, 2147234370Sjasone ctl_stats.arenas[mib[2]].allocated_small, size_t) 2148234370SjasoneCTL_RO_CGEN(config_stats, stats_arenas_i_small_nmalloc, 2149234370Sjasone ctl_stats.arenas[mib[2]].nmalloc_small, uint64_t) 2150234370SjasoneCTL_RO_CGEN(config_stats, stats_arenas_i_small_ndalloc, 2151234370Sjasone ctl_stats.arenas[mib[2]].ndalloc_small, uint64_t) 2152234370SjasoneCTL_RO_CGEN(config_stats, stats_arenas_i_small_nrequests, 2153234370Sjasone ctl_stats.arenas[mib[2]].nrequests_small, uint64_t) 2154234370SjasoneCTL_RO_CGEN(config_stats, stats_arenas_i_large_allocated, 2155234370Sjasone ctl_stats.arenas[mib[2]].astats.allocated_large, size_t) 2156234370SjasoneCTL_RO_CGEN(config_stats, stats_arenas_i_large_nmalloc, 2157234370Sjasone ctl_stats.arenas[mib[2]].astats.nmalloc_large, uint64_t) 2158234370SjasoneCTL_RO_CGEN(config_stats, stats_arenas_i_large_ndalloc, 2159234370Sjasone ctl_stats.arenas[mib[2]].astats.ndalloc_large, uint64_t) 2160234370SjasoneCTL_RO_CGEN(config_stats, stats_arenas_i_large_nrequests, 2161234370Sjasone ctl_stats.arenas[mib[2]].astats.nrequests_large, uint64_t) 2162286866SjasoneCTL_RO_CGEN(config_stats, stats_arenas_i_huge_allocated, 2163286866Sjasone ctl_stats.arenas[mib[2]].astats.allocated_huge, size_t) 2164286866SjasoneCTL_RO_CGEN(config_stats, stats_arenas_i_huge_nmalloc, 2165286866Sjasone ctl_stats.arenas[mib[2]].astats.nmalloc_huge, uint64_t) 2166286866SjasoneCTL_RO_CGEN(config_stats, stats_arenas_i_huge_ndalloc, 2167286866Sjasone ctl_stats.arenas[mib[2]].astats.ndalloc_huge, uint64_t) 2168286866SjasoneCTL_RO_CGEN(config_stats, stats_arenas_i_huge_nrequests, 2169286866Sjasone ctl_stats.arenas[mib[2]].astats.nmalloc_huge, uint64_t) /* Intentional. */ 2170234370Sjasone 2171234370SjasoneCTL_RO_CGEN(config_stats, stats_arenas_i_bins_j_nmalloc, 2172234370Sjasone ctl_stats.arenas[mib[2]].bstats[mib[4]].nmalloc, uint64_t) 2173234370SjasoneCTL_RO_CGEN(config_stats, stats_arenas_i_bins_j_ndalloc, 2174234370Sjasone ctl_stats.arenas[mib[2]].bstats[mib[4]].ndalloc, uint64_t) 2175234370SjasoneCTL_RO_CGEN(config_stats, stats_arenas_i_bins_j_nrequests, 2176234370Sjasone ctl_stats.arenas[mib[2]].bstats[mib[4]].nrequests, uint64_t) 2177286866SjasoneCTL_RO_CGEN(config_stats, stats_arenas_i_bins_j_curregs, 2178286866Sjasone ctl_stats.arenas[mib[2]].bstats[mib[4]].curregs, size_t) 2179234370SjasoneCTL_RO_CGEN(config_stats && config_tcache, stats_arenas_i_bins_j_nfills, 2180234370Sjasone ctl_stats.arenas[mib[2]].bstats[mib[4]].nfills, uint64_t) 2181234370SjasoneCTL_RO_CGEN(config_stats && config_tcache, stats_arenas_i_bins_j_nflushes, 2182234370Sjasone ctl_stats.arenas[mib[2]].bstats[mib[4]].nflushes, uint64_t) 2183234370SjasoneCTL_RO_CGEN(config_stats, stats_arenas_i_bins_j_nruns, 2184234370Sjasone ctl_stats.arenas[mib[2]].bstats[mib[4]].nruns, uint64_t) 2185234370SjasoneCTL_RO_CGEN(config_stats, stats_arenas_i_bins_j_nreruns, 2186234370Sjasone ctl_stats.arenas[mib[2]].bstats[mib[4]].reruns, uint64_t) 2187234370SjasoneCTL_RO_CGEN(config_stats, stats_arenas_i_bins_j_curruns, 2188234370Sjasone ctl_stats.arenas[mib[2]].bstats[mib[4]].curruns, size_t) 2189234370Sjasone 2190242844Sjasonestatic const ctl_named_node_t * 2191299587Sjasonestats_arenas_i_bins_j_index(tsdn_t *tsdn, const size_t *mib, size_t miblen, 2192299587Sjasone size_t j) 2193234370Sjasone{ 2194234370Sjasone 2195234370Sjasone if (j > NBINS) 2196234370Sjasone return (NULL); 2197234370Sjasone return (super_stats_arenas_i_bins_j_node); 2198234370Sjasone} 2199234370Sjasone 2200234370SjasoneCTL_RO_CGEN(config_stats, stats_arenas_i_lruns_j_nmalloc, 2201234370Sjasone ctl_stats.arenas[mib[2]].lstats[mib[4]].nmalloc, uint64_t) 2202234370SjasoneCTL_RO_CGEN(config_stats, stats_arenas_i_lruns_j_ndalloc, 2203234370Sjasone ctl_stats.arenas[mib[2]].lstats[mib[4]].ndalloc, uint64_t) 2204234370SjasoneCTL_RO_CGEN(config_stats, stats_arenas_i_lruns_j_nrequests, 2205234370Sjasone ctl_stats.arenas[mib[2]].lstats[mib[4]].nrequests, uint64_t) 2206234370SjasoneCTL_RO_CGEN(config_stats, stats_arenas_i_lruns_j_curruns, 2207234370Sjasone ctl_stats.arenas[mib[2]].lstats[mib[4]].curruns, size_t) 2208234370Sjasone 2209242844Sjasonestatic const ctl_named_node_t * 2210299587Sjasonestats_arenas_i_lruns_j_index(tsdn_t *tsdn, const size_t *mib, size_t miblen, 2211299587Sjasone size_t j) 2212234370Sjasone{ 2213234370Sjasone 2214234370Sjasone if (j > nlclasses) 2215234370Sjasone return (NULL); 2216234370Sjasone return (super_stats_arenas_i_lruns_j_node); 2217234370Sjasone} 2218234370Sjasone 2219286866SjasoneCTL_RO_CGEN(config_stats, stats_arenas_i_hchunks_j_nmalloc, 2220286866Sjasone ctl_stats.arenas[mib[2]].hstats[mib[4]].nmalloc, uint64_t) 2221286866SjasoneCTL_RO_CGEN(config_stats, stats_arenas_i_hchunks_j_ndalloc, 2222286866Sjasone ctl_stats.arenas[mib[2]].hstats[mib[4]].ndalloc, uint64_t) 2223286866SjasoneCTL_RO_CGEN(config_stats, stats_arenas_i_hchunks_j_nrequests, 2224286866Sjasone ctl_stats.arenas[mib[2]].hstats[mib[4]].nmalloc, /* Intentional. */ 2225286866Sjasone uint64_t) 2226286866SjasoneCTL_RO_CGEN(config_stats, stats_arenas_i_hchunks_j_curhchunks, 2227286866Sjasone ctl_stats.arenas[mib[2]].hstats[mib[4]].curhchunks, size_t) 2228286866Sjasone 2229242844Sjasonestatic const ctl_named_node_t * 2230299587Sjasonestats_arenas_i_hchunks_j_index(tsdn_t *tsdn, const size_t *mib, size_t miblen, 2231299587Sjasone size_t j) 2232286866Sjasone{ 2233286866Sjasone 2234286866Sjasone if (j > nhclasses) 2235286866Sjasone return (NULL); 2236286866Sjasone return (super_stats_arenas_i_hchunks_j_node); 2237286866Sjasone} 2238286866Sjasone 2239286866Sjasonestatic const ctl_named_node_t * 2240299587Sjasonestats_arenas_i_index(tsdn_t *tsdn, const size_t *mib, size_t miblen, size_t i) 2241234370Sjasone{ 2242235238Sjasone const ctl_named_node_t * ret; 2243234370Sjasone 2244299587Sjasone malloc_mutex_lock(tsdn, &ctl_mtx); 2245286866Sjasone if (i > ctl_stats.narenas || !ctl_stats.arenas[i].initialized) { 2246234370Sjasone ret = NULL; 2247234370Sjasone goto label_return; 2248234370Sjasone } 2249234370Sjasone 2250234370Sjasone ret = super_stats_arenas_i_node; 2251234370Sjasonelabel_return: 2252299587Sjasone malloc_mutex_unlock(tsdn, &ctl_mtx); 2253234370Sjasone return (ret); 2254234370Sjasone} 2255