ctl.c revision 235238
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 * - opt_prof_active 11234370Sjasone */ 12234370Sjasonestatic malloc_mutex_t ctl_mtx; 13234370Sjasonestatic bool ctl_initialized; 14234370Sjasonestatic uint64_t ctl_epoch; 15234370Sjasonestatic ctl_stats_t ctl_stats; 16234370Sjasone 17234370Sjasone/******************************************************************************/ 18235238Sjasone/* Helpers for named and indexed nodes. */ 19235238Sjasone 20235238Sjasonestatic inline const ctl_named_node_t * 21235238Sjasonectl_named_node(const ctl_node_t *node) 22235238Sjasone{ 23235238Sjasone 24235238Sjasone return ((node->named) ? (const ctl_named_node_t *)node : NULL); 25235238Sjasone} 26235238Sjasone 27235238Sjasonestatic inline const ctl_named_node_t * 28235238Sjasonectl_named_children(const ctl_named_node_t *node, int index) 29235238Sjasone{ 30235238Sjasone const ctl_named_node_t *children = ctl_named_node(node->children); 31235238Sjasone 32235238Sjasone return (children ? &children[index] : NULL); 33235238Sjasone} 34235238Sjasone 35235238Sjasonestatic inline const ctl_indexed_node_t * 36235238Sjasonectl_indexed_node(const ctl_node_t *node) 37235238Sjasone{ 38235238Sjasone 39235238Sjasone return ((node->named == false) ? (const ctl_indexed_node_t *)node : 40235238Sjasone NULL); 41235238Sjasone} 42235238Sjasone 43235238Sjasone/******************************************************************************/ 44234370Sjasone/* Function prototypes for non-inline static functions. */ 45234370Sjasone 46234370Sjasone#define CTL_PROTO(n) \ 47234370Sjasonestatic int n##_ctl(const size_t *mib, size_t miblen, void *oldp, \ 48234370Sjasone size_t *oldlenp, void *newp, size_t newlen); 49234370Sjasone 50234370Sjasone#define INDEX_PROTO(n) \ 51235238Sjasoneconst ctl_named_node_t *n##_index(const size_t *mib, size_t miblen, \ 52234370Sjasone size_t i); 53234370Sjasone 54234370Sjasonestatic bool ctl_arena_init(ctl_arena_stats_t *astats); 55234370Sjasonestatic void ctl_arena_clear(ctl_arena_stats_t *astats); 56234370Sjasonestatic void ctl_arena_stats_amerge(ctl_arena_stats_t *cstats, 57234370Sjasone arena_t *arena); 58234370Sjasonestatic void ctl_arena_stats_smerge(ctl_arena_stats_t *sstats, 59234370Sjasone ctl_arena_stats_t *astats); 60234370Sjasonestatic void ctl_arena_refresh(arena_t *arena, unsigned i); 61234370Sjasonestatic void ctl_refresh(void); 62234370Sjasonestatic bool ctl_init(void); 63234370Sjasonestatic int ctl_lookup(const char *name, ctl_node_t const **nodesp, 64234370Sjasone size_t *mibp, size_t *depthp); 65234370Sjasone 66234370SjasoneCTL_PROTO(version) 67234370SjasoneCTL_PROTO(epoch) 68234370SjasoneCTL_PROTO(thread_tcache_enabled) 69234370SjasoneCTL_PROTO(thread_tcache_flush) 70234370SjasoneCTL_PROTO(thread_arena) 71234370SjasoneCTL_PROTO(thread_allocated) 72234370SjasoneCTL_PROTO(thread_allocatedp) 73234370SjasoneCTL_PROTO(thread_deallocated) 74234370SjasoneCTL_PROTO(thread_deallocatedp) 75234370SjasoneCTL_PROTO(config_debug) 76234370SjasoneCTL_PROTO(config_dss) 77234370SjasoneCTL_PROTO(config_fill) 78234370SjasoneCTL_PROTO(config_lazy_lock) 79235238SjasoneCTL_PROTO(config_mremap) 80234370SjasoneCTL_PROTO(config_munmap) 81234370SjasoneCTL_PROTO(config_prof) 82234370SjasoneCTL_PROTO(config_prof_libgcc) 83234370SjasoneCTL_PROTO(config_prof_libunwind) 84234370SjasoneCTL_PROTO(config_stats) 85234370SjasoneCTL_PROTO(config_tcache) 86234370SjasoneCTL_PROTO(config_tls) 87234370SjasoneCTL_PROTO(config_utrace) 88234370SjasoneCTL_PROTO(config_valgrind) 89234370SjasoneCTL_PROTO(config_xmalloc) 90234370SjasoneCTL_PROTO(opt_abort) 91234370SjasoneCTL_PROTO(opt_lg_chunk) 92234370SjasoneCTL_PROTO(opt_narenas) 93234370SjasoneCTL_PROTO(opt_lg_dirty_mult) 94234370SjasoneCTL_PROTO(opt_stats_print) 95234370SjasoneCTL_PROTO(opt_junk) 96234370SjasoneCTL_PROTO(opt_zero) 97234370SjasoneCTL_PROTO(opt_quarantine) 98234370SjasoneCTL_PROTO(opt_redzone) 99234370SjasoneCTL_PROTO(opt_utrace) 100234370SjasoneCTL_PROTO(opt_valgrind) 101234370SjasoneCTL_PROTO(opt_xmalloc) 102234370SjasoneCTL_PROTO(opt_tcache) 103234370SjasoneCTL_PROTO(opt_lg_tcache_max) 104234370SjasoneCTL_PROTO(opt_prof) 105234370SjasoneCTL_PROTO(opt_prof_prefix) 106234370SjasoneCTL_PROTO(opt_prof_active) 107234370SjasoneCTL_PROTO(opt_lg_prof_sample) 108234370SjasoneCTL_PROTO(opt_lg_prof_interval) 109234370SjasoneCTL_PROTO(opt_prof_gdump) 110234543SjasoneCTL_PROTO(opt_prof_final) 111234370SjasoneCTL_PROTO(opt_prof_leak) 112234370SjasoneCTL_PROTO(opt_prof_accum) 113234370SjasoneCTL_PROTO(arenas_bin_i_size) 114234370SjasoneCTL_PROTO(arenas_bin_i_nregs) 115234370SjasoneCTL_PROTO(arenas_bin_i_run_size) 116234370SjasoneINDEX_PROTO(arenas_bin_i) 117234370SjasoneCTL_PROTO(arenas_lrun_i_size) 118234370SjasoneINDEX_PROTO(arenas_lrun_i) 119234370SjasoneCTL_PROTO(arenas_narenas) 120234370SjasoneCTL_PROTO(arenas_initialized) 121234370SjasoneCTL_PROTO(arenas_quantum) 122234370SjasoneCTL_PROTO(arenas_page) 123234370SjasoneCTL_PROTO(arenas_tcache_max) 124234370SjasoneCTL_PROTO(arenas_nbins) 125234370SjasoneCTL_PROTO(arenas_nhbins) 126234370SjasoneCTL_PROTO(arenas_nlruns) 127234370SjasoneCTL_PROTO(arenas_purge) 128234370SjasoneCTL_PROTO(prof_active) 129234370SjasoneCTL_PROTO(prof_dump) 130234370SjasoneCTL_PROTO(prof_interval) 131234370SjasoneCTL_PROTO(stats_chunks_current) 132234370SjasoneCTL_PROTO(stats_chunks_total) 133234370SjasoneCTL_PROTO(stats_chunks_high) 134234370SjasoneCTL_PROTO(stats_huge_allocated) 135234370SjasoneCTL_PROTO(stats_huge_nmalloc) 136234370SjasoneCTL_PROTO(stats_huge_ndalloc) 137234370SjasoneCTL_PROTO(stats_arenas_i_small_allocated) 138234370SjasoneCTL_PROTO(stats_arenas_i_small_nmalloc) 139234370SjasoneCTL_PROTO(stats_arenas_i_small_ndalloc) 140234370SjasoneCTL_PROTO(stats_arenas_i_small_nrequests) 141234370SjasoneCTL_PROTO(stats_arenas_i_large_allocated) 142234370SjasoneCTL_PROTO(stats_arenas_i_large_nmalloc) 143234370SjasoneCTL_PROTO(stats_arenas_i_large_ndalloc) 144234370SjasoneCTL_PROTO(stats_arenas_i_large_nrequests) 145234370SjasoneCTL_PROTO(stats_arenas_i_bins_j_allocated) 146234370SjasoneCTL_PROTO(stats_arenas_i_bins_j_nmalloc) 147234370SjasoneCTL_PROTO(stats_arenas_i_bins_j_ndalloc) 148234370SjasoneCTL_PROTO(stats_arenas_i_bins_j_nrequests) 149234370SjasoneCTL_PROTO(stats_arenas_i_bins_j_nfills) 150234370SjasoneCTL_PROTO(stats_arenas_i_bins_j_nflushes) 151234370SjasoneCTL_PROTO(stats_arenas_i_bins_j_nruns) 152234370SjasoneCTL_PROTO(stats_arenas_i_bins_j_nreruns) 153234370SjasoneCTL_PROTO(stats_arenas_i_bins_j_curruns) 154234370SjasoneINDEX_PROTO(stats_arenas_i_bins_j) 155234370SjasoneCTL_PROTO(stats_arenas_i_lruns_j_nmalloc) 156234370SjasoneCTL_PROTO(stats_arenas_i_lruns_j_ndalloc) 157234370SjasoneCTL_PROTO(stats_arenas_i_lruns_j_nrequests) 158234370SjasoneCTL_PROTO(stats_arenas_i_lruns_j_curruns) 159234370SjasoneINDEX_PROTO(stats_arenas_i_lruns_j) 160234370SjasoneCTL_PROTO(stats_arenas_i_nthreads) 161234370SjasoneCTL_PROTO(stats_arenas_i_pactive) 162234370SjasoneCTL_PROTO(stats_arenas_i_pdirty) 163234370SjasoneCTL_PROTO(stats_arenas_i_mapped) 164234370SjasoneCTL_PROTO(stats_arenas_i_npurge) 165234370SjasoneCTL_PROTO(stats_arenas_i_nmadvise) 166234370SjasoneCTL_PROTO(stats_arenas_i_purged) 167234370SjasoneINDEX_PROTO(stats_arenas_i) 168234370SjasoneCTL_PROTO(stats_cactive) 169234370SjasoneCTL_PROTO(stats_allocated) 170234370SjasoneCTL_PROTO(stats_active) 171234370SjasoneCTL_PROTO(stats_mapped) 172234370Sjasone 173234370Sjasone/******************************************************************************/ 174234370Sjasone/* mallctl tree. */ 175234370Sjasone 176234370Sjasone/* Maximum tree depth. */ 177234370Sjasone#define CTL_MAX_DEPTH 6 178234370Sjasone 179235238Sjasone#define NAME(n) {true}, n 180235238Sjasone#define CHILD(t, c) \ 181235238Sjasone sizeof(c##_node) / sizeof(ctl_##t##_node_t), \ 182235238Sjasone (ctl_node_t *)c##_node, \ 183235238Sjasone NULL 184235238Sjasone#define CTL(c) 0, NULL, c##_ctl 185234370Sjasone 186234370Sjasone/* 187234370Sjasone * Only handles internal indexed nodes, since there are currently no external 188234370Sjasone * ones. 189234370Sjasone */ 190235238Sjasone#define INDEX(i) {false}, i##_index 191234370Sjasone 192235238Sjasonestatic const ctl_named_node_t tcache_node[] = { 193234370Sjasone {NAME("enabled"), CTL(thread_tcache_enabled)}, 194234370Sjasone {NAME("flush"), CTL(thread_tcache_flush)} 195234370Sjasone}; 196234370Sjasone 197235238Sjasonestatic const ctl_named_node_t thread_node[] = { 198234370Sjasone {NAME("arena"), CTL(thread_arena)}, 199234370Sjasone {NAME("allocated"), CTL(thread_allocated)}, 200234370Sjasone {NAME("allocatedp"), CTL(thread_allocatedp)}, 201234370Sjasone {NAME("deallocated"), CTL(thread_deallocated)}, 202234370Sjasone {NAME("deallocatedp"), CTL(thread_deallocatedp)}, 203235238Sjasone {NAME("tcache"), CHILD(named, tcache)} 204234370Sjasone}; 205234370Sjasone 206235238Sjasonestatic const ctl_named_node_t config_node[] = { 207234370Sjasone {NAME("debug"), CTL(config_debug)}, 208234370Sjasone {NAME("dss"), CTL(config_dss)}, 209234370Sjasone {NAME("fill"), CTL(config_fill)}, 210234370Sjasone {NAME("lazy_lock"), CTL(config_lazy_lock)}, 211235238Sjasone {NAME("mremap"), CTL(config_mremap)}, 212234370Sjasone {NAME("munmap"), CTL(config_munmap)}, 213234370Sjasone {NAME("prof"), CTL(config_prof)}, 214234370Sjasone {NAME("prof_libgcc"), CTL(config_prof_libgcc)}, 215234370Sjasone {NAME("prof_libunwind"), CTL(config_prof_libunwind)}, 216234370Sjasone {NAME("stats"), CTL(config_stats)}, 217234370Sjasone {NAME("tcache"), CTL(config_tcache)}, 218234370Sjasone {NAME("tls"), CTL(config_tls)}, 219234370Sjasone {NAME("utrace"), CTL(config_utrace)}, 220234370Sjasone {NAME("valgrind"), CTL(config_valgrind)}, 221234370Sjasone {NAME("xmalloc"), CTL(config_xmalloc)} 222234370Sjasone}; 223234370Sjasone 224235238Sjasonestatic const ctl_named_node_t opt_node[] = { 225234370Sjasone {NAME("abort"), CTL(opt_abort)}, 226234370Sjasone {NAME("lg_chunk"), CTL(opt_lg_chunk)}, 227234370Sjasone {NAME("narenas"), CTL(opt_narenas)}, 228234370Sjasone {NAME("lg_dirty_mult"), CTL(opt_lg_dirty_mult)}, 229234370Sjasone {NAME("stats_print"), CTL(opt_stats_print)}, 230234370Sjasone {NAME("junk"), CTL(opt_junk)}, 231234370Sjasone {NAME("zero"), CTL(opt_zero)}, 232234370Sjasone {NAME("quarantine"), CTL(opt_quarantine)}, 233234370Sjasone {NAME("redzone"), CTL(opt_redzone)}, 234234370Sjasone {NAME("utrace"), CTL(opt_utrace)}, 235234370Sjasone {NAME("valgrind"), CTL(opt_valgrind)}, 236234370Sjasone {NAME("xmalloc"), CTL(opt_xmalloc)}, 237234370Sjasone {NAME("tcache"), CTL(opt_tcache)}, 238234370Sjasone {NAME("lg_tcache_max"), CTL(opt_lg_tcache_max)}, 239234370Sjasone {NAME("prof"), CTL(opt_prof)}, 240234370Sjasone {NAME("prof_prefix"), CTL(opt_prof_prefix)}, 241234370Sjasone {NAME("prof_active"), CTL(opt_prof_active)}, 242234370Sjasone {NAME("lg_prof_sample"), CTL(opt_lg_prof_sample)}, 243234370Sjasone {NAME("lg_prof_interval"), CTL(opt_lg_prof_interval)}, 244234370Sjasone {NAME("prof_gdump"), CTL(opt_prof_gdump)}, 245234543Sjasone {NAME("prof_final"), CTL(opt_prof_final)}, 246234370Sjasone {NAME("prof_leak"), CTL(opt_prof_leak)}, 247234370Sjasone {NAME("prof_accum"), CTL(opt_prof_accum)} 248234370Sjasone}; 249234370Sjasone 250235238Sjasonestatic const ctl_named_node_t arenas_bin_i_node[] = { 251234370Sjasone {NAME("size"), CTL(arenas_bin_i_size)}, 252234370Sjasone {NAME("nregs"), CTL(arenas_bin_i_nregs)}, 253234370Sjasone {NAME("run_size"), CTL(arenas_bin_i_run_size)} 254234370Sjasone}; 255235238Sjasonestatic const ctl_named_node_t super_arenas_bin_i_node[] = { 256235238Sjasone {NAME(""), CHILD(named, arenas_bin_i)} 257234370Sjasone}; 258234370Sjasone 259235238Sjasonestatic const ctl_indexed_node_t arenas_bin_node[] = { 260234370Sjasone {INDEX(arenas_bin_i)} 261234370Sjasone}; 262234370Sjasone 263235238Sjasonestatic const ctl_named_node_t arenas_lrun_i_node[] = { 264234370Sjasone {NAME("size"), CTL(arenas_lrun_i_size)} 265234370Sjasone}; 266235238Sjasonestatic const ctl_named_node_t super_arenas_lrun_i_node[] = { 267235238Sjasone {NAME(""), CHILD(named, arenas_lrun_i)} 268234370Sjasone}; 269234370Sjasone 270235238Sjasonestatic const ctl_indexed_node_t arenas_lrun_node[] = { 271234370Sjasone {INDEX(arenas_lrun_i)} 272234370Sjasone}; 273234370Sjasone 274235238Sjasonestatic const ctl_named_node_t arenas_node[] = { 275234370Sjasone {NAME("narenas"), CTL(arenas_narenas)}, 276234370Sjasone {NAME("initialized"), CTL(arenas_initialized)}, 277234370Sjasone {NAME("quantum"), CTL(arenas_quantum)}, 278234370Sjasone {NAME("page"), CTL(arenas_page)}, 279234370Sjasone {NAME("tcache_max"), CTL(arenas_tcache_max)}, 280234370Sjasone {NAME("nbins"), CTL(arenas_nbins)}, 281234370Sjasone {NAME("nhbins"), CTL(arenas_nhbins)}, 282235238Sjasone {NAME("bin"), CHILD(indexed, arenas_bin)}, 283234370Sjasone {NAME("nlruns"), CTL(arenas_nlruns)}, 284235238Sjasone {NAME("lrun"), CHILD(indexed, arenas_lrun)}, 285234370Sjasone {NAME("purge"), CTL(arenas_purge)} 286234370Sjasone}; 287234370Sjasone 288235238Sjasonestatic const ctl_named_node_t prof_node[] = { 289234370Sjasone {NAME("active"), CTL(prof_active)}, 290234370Sjasone {NAME("dump"), CTL(prof_dump)}, 291234370Sjasone {NAME("interval"), CTL(prof_interval)} 292234370Sjasone}; 293234370Sjasone 294235238Sjasonestatic const ctl_named_node_t stats_chunks_node[] = { 295234370Sjasone {NAME("current"), CTL(stats_chunks_current)}, 296234370Sjasone {NAME("total"), CTL(stats_chunks_total)}, 297234370Sjasone {NAME("high"), CTL(stats_chunks_high)} 298234370Sjasone}; 299234370Sjasone 300235238Sjasonestatic const ctl_named_node_t stats_huge_node[] = { 301234370Sjasone {NAME("allocated"), CTL(stats_huge_allocated)}, 302234370Sjasone {NAME("nmalloc"), CTL(stats_huge_nmalloc)}, 303234370Sjasone {NAME("ndalloc"), CTL(stats_huge_ndalloc)} 304234370Sjasone}; 305234370Sjasone 306235238Sjasonestatic const ctl_named_node_t stats_arenas_i_small_node[] = { 307234370Sjasone {NAME("allocated"), CTL(stats_arenas_i_small_allocated)}, 308234370Sjasone {NAME("nmalloc"), CTL(stats_arenas_i_small_nmalloc)}, 309234370Sjasone {NAME("ndalloc"), CTL(stats_arenas_i_small_ndalloc)}, 310234370Sjasone {NAME("nrequests"), CTL(stats_arenas_i_small_nrequests)} 311234370Sjasone}; 312234370Sjasone 313235238Sjasonestatic const ctl_named_node_t stats_arenas_i_large_node[] = { 314234370Sjasone {NAME("allocated"), CTL(stats_arenas_i_large_allocated)}, 315234370Sjasone {NAME("nmalloc"), CTL(stats_arenas_i_large_nmalloc)}, 316234370Sjasone {NAME("ndalloc"), CTL(stats_arenas_i_large_ndalloc)}, 317234370Sjasone {NAME("nrequests"), CTL(stats_arenas_i_large_nrequests)} 318234370Sjasone}; 319234370Sjasone 320235238Sjasonestatic const ctl_named_node_t stats_arenas_i_bins_j_node[] = { 321234370Sjasone {NAME("allocated"), CTL(stats_arenas_i_bins_j_allocated)}, 322234370Sjasone {NAME("nmalloc"), CTL(stats_arenas_i_bins_j_nmalloc)}, 323234370Sjasone {NAME("ndalloc"), CTL(stats_arenas_i_bins_j_ndalloc)}, 324234370Sjasone {NAME("nrequests"), CTL(stats_arenas_i_bins_j_nrequests)}, 325234370Sjasone {NAME("nfills"), CTL(stats_arenas_i_bins_j_nfills)}, 326234370Sjasone {NAME("nflushes"), CTL(stats_arenas_i_bins_j_nflushes)}, 327234370Sjasone {NAME("nruns"), CTL(stats_arenas_i_bins_j_nruns)}, 328234370Sjasone {NAME("nreruns"), CTL(stats_arenas_i_bins_j_nreruns)}, 329234370Sjasone {NAME("curruns"), CTL(stats_arenas_i_bins_j_curruns)} 330234370Sjasone}; 331235238Sjasonestatic const ctl_named_node_t super_stats_arenas_i_bins_j_node[] = { 332235238Sjasone {NAME(""), CHILD(named, stats_arenas_i_bins_j)} 333234370Sjasone}; 334234370Sjasone 335235238Sjasonestatic const ctl_indexed_node_t stats_arenas_i_bins_node[] = { 336234370Sjasone {INDEX(stats_arenas_i_bins_j)} 337234370Sjasone}; 338234370Sjasone 339235238Sjasonestatic const ctl_named_node_t stats_arenas_i_lruns_j_node[] = { 340234370Sjasone {NAME("nmalloc"), CTL(stats_arenas_i_lruns_j_nmalloc)}, 341234370Sjasone {NAME("ndalloc"), CTL(stats_arenas_i_lruns_j_ndalloc)}, 342234370Sjasone {NAME("nrequests"), CTL(stats_arenas_i_lruns_j_nrequests)}, 343234370Sjasone {NAME("curruns"), CTL(stats_arenas_i_lruns_j_curruns)} 344234370Sjasone}; 345235238Sjasonestatic const ctl_named_node_t super_stats_arenas_i_lruns_j_node[] = { 346235238Sjasone {NAME(""), CHILD(named, stats_arenas_i_lruns_j)} 347234370Sjasone}; 348234370Sjasone 349235238Sjasonestatic const ctl_indexed_node_t stats_arenas_i_lruns_node[] = { 350234370Sjasone {INDEX(stats_arenas_i_lruns_j)} 351234370Sjasone}; 352234370Sjasone 353235238Sjasonestatic const ctl_named_node_t stats_arenas_i_node[] = { 354234370Sjasone {NAME("nthreads"), CTL(stats_arenas_i_nthreads)}, 355234370Sjasone {NAME("pactive"), CTL(stats_arenas_i_pactive)}, 356234370Sjasone {NAME("pdirty"), CTL(stats_arenas_i_pdirty)}, 357234370Sjasone {NAME("mapped"), CTL(stats_arenas_i_mapped)}, 358234370Sjasone {NAME("npurge"), CTL(stats_arenas_i_npurge)}, 359234370Sjasone {NAME("nmadvise"), CTL(stats_arenas_i_nmadvise)}, 360234370Sjasone {NAME("purged"), CTL(stats_arenas_i_purged)}, 361235238Sjasone {NAME("small"), CHILD(named, stats_arenas_i_small)}, 362235238Sjasone {NAME("large"), CHILD(named, stats_arenas_i_large)}, 363235238Sjasone {NAME("bins"), CHILD(indexed, stats_arenas_i_bins)}, 364235238Sjasone {NAME("lruns"), CHILD(indexed, stats_arenas_i_lruns)} 365234370Sjasone}; 366235238Sjasonestatic const ctl_named_node_t super_stats_arenas_i_node[] = { 367235238Sjasone {NAME(""), CHILD(named, stats_arenas_i)} 368234370Sjasone}; 369234370Sjasone 370235238Sjasonestatic const ctl_indexed_node_t stats_arenas_node[] = { 371234370Sjasone {INDEX(stats_arenas_i)} 372234370Sjasone}; 373234370Sjasone 374235238Sjasonestatic const ctl_named_node_t stats_node[] = { 375234370Sjasone {NAME("cactive"), CTL(stats_cactive)}, 376234370Sjasone {NAME("allocated"), CTL(stats_allocated)}, 377234370Sjasone {NAME("active"), CTL(stats_active)}, 378234370Sjasone {NAME("mapped"), CTL(stats_mapped)}, 379235238Sjasone {NAME("chunks"), CHILD(named, stats_chunks)}, 380235238Sjasone {NAME("huge"), CHILD(named, stats_huge)}, 381235238Sjasone {NAME("arenas"), CHILD(indexed, stats_arenas)} 382234370Sjasone}; 383234370Sjasone 384235238Sjasonestatic const ctl_named_node_t root_node[] = { 385234370Sjasone {NAME("version"), CTL(version)}, 386234370Sjasone {NAME("epoch"), CTL(epoch)}, 387235238Sjasone {NAME("thread"), CHILD(named, thread)}, 388235238Sjasone {NAME("config"), CHILD(named, config)}, 389235238Sjasone {NAME("opt"), CHILD(named, opt)}, 390235238Sjasone {NAME("arenas"), CHILD(named, arenas)}, 391235238Sjasone {NAME("prof"), CHILD(named, prof)}, 392235238Sjasone {NAME("stats"), CHILD(named, stats)} 393234370Sjasone}; 394235238Sjasonestatic const ctl_named_node_t super_root_node[] = { 395235238Sjasone {NAME(""), CHILD(named, root)} 396234370Sjasone}; 397234370Sjasone 398234370Sjasone#undef NAME 399234370Sjasone#undef CHILD 400234370Sjasone#undef CTL 401234370Sjasone#undef INDEX 402234370Sjasone 403234370Sjasone/******************************************************************************/ 404234370Sjasone 405234370Sjasonestatic bool 406234370Sjasonectl_arena_init(ctl_arena_stats_t *astats) 407234370Sjasone{ 408234370Sjasone 409234370Sjasone if (astats->lstats == NULL) { 410234370Sjasone astats->lstats = (malloc_large_stats_t *)base_alloc(nlclasses * 411234370Sjasone sizeof(malloc_large_stats_t)); 412234370Sjasone if (astats->lstats == NULL) 413234370Sjasone return (true); 414234370Sjasone } 415234370Sjasone 416234370Sjasone return (false); 417234370Sjasone} 418234370Sjasone 419234370Sjasonestatic void 420234370Sjasonectl_arena_clear(ctl_arena_stats_t *astats) 421234370Sjasone{ 422234370Sjasone 423234370Sjasone astats->pactive = 0; 424234370Sjasone astats->pdirty = 0; 425234370Sjasone if (config_stats) { 426234370Sjasone memset(&astats->astats, 0, sizeof(arena_stats_t)); 427234370Sjasone astats->allocated_small = 0; 428234370Sjasone astats->nmalloc_small = 0; 429234370Sjasone astats->ndalloc_small = 0; 430234370Sjasone astats->nrequests_small = 0; 431234370Sjasone memset(astats->bstats, 0, NBINS * sizeof(malloc_bin_stats_t)); 432234370Sjasone memset(astats->lstats, 0, nlclasses * 433234370Sjasone sizeof(malloc_large_stats_t)); 434234370Sjasone } 435234370Sjasone} 436234370Sjasone 437234370Sjasonestatic void 438234370Sjasonectl_arena_stats_amerge(ctl_arena_stats_t *cstats, arena_t *arena) 439234370Sjasone{ 440234370Sjasone unsigned i; 441234370Sjasone 442234370Sjasone arena_stats_merge(arena, &cstats->pactive, &cstats->pdirty, 443234370Sjasone &cstats->astats, cstats->bstats, cstats->lstats); 444234370Sjasone 445234370Sjasone for (i = 0; i < NBINS; i++) { 446234370Sjasone cstats->allocated_small += cstats->bstats[i].allocated; 447234370Sjasone cstats->nmalloc_small += cstats->bstats[i].nmalloc; 448234370Sjasone cstats->ndalloc_small += cstats->bstats[i].ndalloc; 449234370Sjasone cstats->nrequests_small += cstats->bstats[i].nrequests; 450234370Sjasone } 451234370Sjasone} 452234370Sjasone 453234370Sjasonestatic void 454234370Sjasonectl_arena_stats_smerge(ctl_arena_stats_t *sstats, ctl_arena_stats_t *astats) 455234370Sjasone{ 456234370Sjasone unsigned i; 457234370Sjasone 458234370Sjasone sstats->pactive += astats->pactive; 459234370Sjasone sstats->pdirty += astats->pdirty; 460234370Sjasone 461234370Sjasone sstats->astats.mapped += astats->astats.mapped; 462234370Sjasone sstats->astats.npurge += astats->astats.npurge; 463234370Sjasone sstats->astats.nmadvise += astats->astats.nmadvise; 464234370Sjasone sstats->astats.purged += astats->astats.purged; 465234370Sjasone 466234370Sjasone sstats->allocated_small += astats->allocated_small; 467234370Sjasone sstats->nmalloc_small += astats->nmalloc_small; 468234370Sjasone sstats->ndalloc_small += astats->ndalloc_small; 469234370Sjasone sstats->nrequests_small += astats->nrequests_small; 470234370Sjasone 471234370Sjasone sstats->astats.allocated_large += astats->astats.allocated_large; 472234370Sjasone sstats->astats.nmalloc_large += astats->astats.nmalloc_large; 473234370Sjasone sstats->astats.ndalloc_large += astats->astats.ndalloc_large; 474234370Sjasone sstats->astats.nrequests_large += astats->astats.nrequests_large; 475234370Sjasone 476234370Sjasone for (i = 0; i < nlclasses; i++) { 477234370Sjasone sstats->lstats[i].nmalloc += astats->lstats[i].nmalloc; 478234370Sjasone sstats->lstats[i].ndalloc += astats->lstats[i].ndalloc; 479234370Sjasone sstats->lstats[i].nrequests += astats->lstats[i].nrequests; 480234370Sjasone sstats->lstats[i].curruns += astats->lstats[i].curruns; 481234370Sjasone } 482234370Sjasone 483234370Sjasone for (i = 0; i < NBINS; i++) { 484234370Sjasone sstats->bstats[i].allocated += astats->bstats[i].allocated; 485234370Sjasone sstats->bstats[i].nmalloc += astats->bstats[i].nmalloc; 486234370Sjasone sstats->bstats[i].ndalloc += astats->bstats[i].ndalloc; 487234370Sjasone sstats->bstats[i].nrequests += astats->bstats[i].nrequests; 488234370Sjasone if (config_tcache) { 489234370Sjasone sstats->bstats[i].nfills += astats->bstats[i].nfills; 490234370Sjasone sstats->bstats[i].nflushes += 491234370Sjasone astats->bstats[i].nflushes; 492234370Sjasone } 493234370Sjasone sstats->bstats[i].nruns += astats->bstats[i].nruns; 494234370Sjasone sstats->bstats[i].reruns += astats->bstats[i].reruns; 495234370Sjasone sstats->bstats[i].curruns += astats->bstats[i].curruns; 496234370Sjasone } 497234370Sjasone} 498234370Sjasone 499234370Sjasonestatic void 500234370Sjasonectl_arena_refresh(arena_t *arena, unsigned i) 501234370Sjasone{ 502234370Sjasone ctl_arena_stats_t *astats = &ctl_stats.arenas[i]; 503234370Sjasone ctl_arena_stats_t *sstats = &ctl_stats.arenas[narenas]; 504234370Sjasone 505234370Sjasone ctl_arena_clear(astats); 506234370Sjasone 507234370Sjasone sstats->nthreads += astats->nthreads; 508234370Sjasone if (config_stats) { 509234370Sjasone ctl_arena_stats_amerge(astats, arena); 510234370Sjasone /* Merge into sum stats as well. */ 511234370Sjasone ctl_arena_stats_smerge(sstats, astats); 512234370Sjasone } else { 513234370Sjasone astats->pactive += arena->nactive; 514234370Sjasone astats->pdirty += arena->ndirty; 515234370Sjasone /* Merge into sum stats as well. */ 516234370Sjasone sstats->pactive += arena->nactive; 517234370Sjasone sstats->pdirty += arena->ndirty; 518234370Sjasone } 519234370Sjasone} 520234370Sjasone 521234370Sjasonestatic void 522234370Sjasonectl_refresh(void) 523234370Sjasone{ 524234370Sjasone unsigned i; 525235238Sjasone VARIABLE_ARRAY(arena_t *, tarenas, narenas); 526234370Sjasone 527234370Sjasone if (config_stats) { 528234370Sjasone malloc_mutex_lock(&chunks_mtx); 529234370Sjasone ctl_stats.chunks.current = stats_chunks.curchunks; 530234370Sjasone ctl_stats.chunks.total = stats_chunks.nchunks; 531234370Sjasone ctl_stats.chunks.high = stats_chunks.highchunks; 532234370Sjasone malloc_mutex_unlock(&chunks_mtx); 533234370Sjasone 534234370Sjasone malloc_mutex_lock(&huge_mtx); 535234370Sjasone ctl_stats.huge.allocated = huge_allocated; 536234370Sjasone ctl_stats.huge.nmalloc = huge_nmalloc; 537234370Sjasone ctl_stats.huge.ndalloc = huge_ndalloc; 538234370Sjasone malloc_mutex_unlock(&huge_mtx); 539234370Sjasone } 540234370Sjasone 541234370Sjasone /* 542234370Sjasone * Clear sum stats, since they will be merged into by 543234370Sjasone * ctl_arena_refresh(). 544234370Sjasone */ 545234370Sjasone ctl_stats.arenas[narenas].nthreads = 0; 546234370Sjasone ctl_arena_clear(&ctl_stats.arenas[narenas]); 547234370Sjasone 548234370Sjasone malloc_mutex_lock(&arenas_lock); 549234370Sjasone memcpy(tarenas, arenas, sizeof(arena_t *) * narenas); 550234370Sjasone for (i = 0; i < narenas; i++) { 551234370Sjasone if (arenas[i] != NULL) 552234370Sjasone ctl_stats.arenas[i].nthreads = arenas[i]->nthreads; 553234370Sjasone else 554234370Sjasone ctl_stats.arenas[i].nthreads = 0; 555234370Sjasone } 556234370Sjasone malloc_mutex_unlock(&arenas_lock); 557234370Sjasone for (i = 0; i < narenas; i++) { 558234370Sjasone bool initialized = (tarenas[i] != NULL); 559234370Sjasone 560234370Sjasone ctl_stats.arenas[i].initialized = initialized; 561234370Sjasone if (initialized) 562234370Sjasone ctl_arena_refresh(tarenas[i], i); 563234370Sjasone } 564234370Sjasone 565234370Sjasone if (config_stats) { 566234370Sjasone ctl_stats.allocated = ctl_stats.arenas[narenas].allocated_small 567234370Sjasone + ctl_stats.arenas[narenas].astats.allocated_large 568234370Sjasone + ctl_stats.huge.allocated; 569234370Sjasone ctl_stats.active = (ctl_stats.arenas[narenas].pactive << 570234370Sjasone LG_PAGE) + ctl_stats.huge.allocated; 571234370Sjasone ctl_stats.mapped = (ctl_stats.chunks.current << opt_lg_chunk); 572234370Sjasone } 573234370Sjasone 574234370Sjasone ctl_epoch++; 575234370Sjasone} 576234370Sjasone 577234370Sjasonestatic bool 578234370Sjasonectl_init(void) 579234370Sjasone{ 580234370Sjasone bool ret; 581234370Sjasone 582234370Sjasone malloc_mutex_lock(&ctl_mtx); 583234370Sjasone if (ctl_initialized == false) { 584234370Sjasone /* 585234370Sjasone * Allocate space for one extra arena stats element, which 586234370Sjasone * contains summed stats across all arenas. 587234370Sjasone */ 588234370Sjasone ctl_stats.arenas = (ctl_arena_stats_t *)base_alloc( 589234370Sjasone (narenas + 1) * sizeof(ctl_arena_stats_t)); 590234370Sjasone if (ctl_stats.arenas == NULL) { 591234370Sjasone ret = true; 592234370Sjasone goto label_return; 593234370Sjasone } 594234370Sjasone memset(ctl_stats.arenas, 0, (narenas + 1) * 595234370Sjasone sizeof(ctl_arena_stats_t)); 596234370Sjasone 597234370Sjasone /* 598234370Sjasone * Initialize all stats structures, regardless of whether they 599234370Sjasone * ever get used. Lazy initialization would allow errors to 600234370Sjasone * cause inconsistent state to be viewable by the application. 601234370Sjasone */ 602234370Sjasone if (config_stats) { 603234370Sjasone unsigned i; 604234370Sjasone for (i = 0; i <= narenas; i++) { 605234370Sjasone if (ctl_arena_init(&ctl_stats.arenas[i])) { 606234370Sjasone ret = true; 607234370Sjasone goto label_return; 608234370Sjasone } 609234370Sjasone } 610234370Sjasone } 611234370Sjasone ctl_stats.arenas[narenas].initialized = true; 612234370Sjasone 613234370Sjasone ctl_epoch = 0; 614234370Sjasone ctl_refresh(); 615234370Sjasone ctl_initialized = true; 616234370Sjasone } 617234370Sjasone 618234370Sjasone ret = false; 619234370Sjasonelabel_return: 620234370Sjasone malloc_mutex_unlock(&ctl_mtx); 621234370Sjasone return (ret); 622234370Sjasone} 623234370Sjasone 624234370Sjasonestatic int 625234370Sjasonectl_lookup(const char *name, ctl_node_t const **nodesp, size_t *mibp, 626234370Sjasone size_t *depthp) 627234370Sjasone{ 628234370Sjasone int ret; 629234370Sjasone const char *elm, *tdot, *dot; 630234370Sjasone size_t elen, i, j; 631235238Sjasone const ctl_named_node_t *node; 632234370Sjasone 633234370Sjasone elm = name; 634234370Sjasone /* Equivalent to strchrnul(). */ 635234370Sjasone dot = ((tdot = strchr(elm, '.')) != NULL) ? tdot : strchr(elm, '\0'); 636234370Sjasone elen = (size_t)((uintptr_t)dot - (uintptr_t)elm); 637234370Sjasone if (elen == 0) { 638234370Sjasone ret = ENOENT; 639234370Sjasone goto label_return; 640234370Sjasone } 641234370Sjasone node = super_root_node; 642234370Sjasone for (i = 0; i < *depthp; i++) { 643235238Sjasone assert(node); 644235238Sjasone assert(node->nchildren > 0); 645235238Sjasone if (ctl_named_node(node->children) != NULL) { 646235238Sjasone const ctl_named_node_t *pnode = node; 647234370Sjasone 648234370Sjasone /* Children are named. */ 649235238Sjasone for (j = 0; j < node->nchildren; j++) { 650235238Sjasone const ctl_named_node_t *child = 651235238Sjasone ctl_named_children(node, j); 652235238Sjasone if (strlen(child->name) == elen && 653235238Sjasone strncmp(elm, child->name, elen) == 0) { 654234370Sjasone node = child; 655234370Sjasone if (nodesp != NULL) 656235238Sjasone nodesp[i] = 657235238Sjasone (const ctl_node_t *)node; 658234370Sjasone mibp[i] = j; 659234370Sjasone break; 660234370Sjasone } 661234370Sjasone } 662234370Sjasone if (node == pnode) { 663234370Sjasone ret = ENOENT; 664234370Sjasone goto label_return; 665234370Sjasone } 666234370Sjasone } else { 667234370Sjasone uintmax_t index; 668235238Sjasone const ctl_indexed_node_t *inode; 669234370Sjasone 670234370Sjasone /* Children are indexed. */ 671234370Sjasone index = malloc_strtoumax(elm, NULL, 10); 672234370Sjasone if (index == UINTMAX_MAX || index > SIZE_T_MAX) { 673234370Sjasone ret = ENOENT; 674234370Sjasone goto label_return; 675234370Sjasone } 676234370Sjasone 677235238Sjasone inode = ctl_indexed_node(node->children); 678235238Sjasone node = inode->index(mibp, *depthp, (size_t)index); 679234370Sjasone if (node == NULL) { 680234370Sjasone ret = ENOENT; 681234370Sjasone goto label_return; 682234370Sjasone } 683234370Sjasone 684234370Sjasone if (nodesp != NULL) 685235238Sjasone nodesp[i] = (const ctl_node_t *)node; 686234370Sjasone mibp[i] = (size_t)index; 687234370Sjasone } 688234370Sjasone 689234370Sjasone if (node->ctl != NULL) { 690234370Sjasone /* Terminal node. */ 691234370Sjasone if (*dot != '\0') { 692234370Sjasone /* 693234370Sjasone * The name contains more elements than are 694234370Sjasone * in this path through the tree. 695234370Sjasone */ 696234370Sjasone ret = ENOENT; 697234370Sjasone goto label_return; 698234370Sjasone } 699234370Sjasone /* Complete lookup successful. */ 700234370Sjasone *depthp = i + 1; 701234370Sjasone break; 702234370Sjasone } 703234370Sjasone 704234370Sjasone /* Update elm. */ 705234370Sjasone if (*dot == '\0') { 706234370Sjasone /* No more elements. */ 707234370Sjasone ret = ENOENT; 708234370Sjasone goto label_return; 709234370Sjasone } 710234370Sjasone elm = &dot[1]; 711234370Sjasone dot = ((tdot = strchr(elm, '.')) != NULL) ? tdot : 712234370Sjasone strchr(elm, '\0'); 713234370Sjasone elen = (size_t)((uintptr_t)dot - (uintptr_t)elm); 714234370Sjasone } 715234370Sjasone 716234370Sjasone ret = 0; 717234370Sjasonelabel_return: 718234370Sjasone return (ret); 719234370Sjasone} 720234370Sjasone 721234370Sjasoneint 722234370Sjasonectl_byname(const char *name, void *oldp, size_t *oldlenp, void *newp, 723234370Sjasone size_t newlen) 724234370Sjasone{ 725234370Sjasone int ret; 726234370Sjasone size_t depth; 727234370Sjasone ctl_node_t const *nodes[CTL_MAX_DEPTH]; 728234370Sjasone size_t mib[CTL_MAX_DEPTH]; 729235238Sjasone const ctl_named_node_t *node; 730234370Sjasone 731234370Sjasone if (ctl_initialized == false && ctl_init()) { 732234370Sjasone ret = EAGAIN; 733234370Sjasone goto label_return; 734234370Sjasone } 735234370Sjasone 736234370Sjasone depth = CTL_MAX_DEPTH; 737234370Sjasone ret = ctl_lookup(name, nodes, mib, &depth); 738234370Sjasone if (ret != 0) 739234370Sjasone goto label_return; 740234370Sjasone 741235238Sjasone node = ctl_named_node(nodes[depth-1]); 742235238Sjasone if (node != NULL && node->ctl) 743235238Sjasone ret = node->ctl(mib, depth, oldp, oldlenp, newp, newlen); 744235238Sjasone else { 745234370Sjasone /* The name refers to a partial path through the ctl tree. */ 746234370Sjasone ret = ENOENT; 747234370Sjasone } 748234370Sjasone 749234370Sjasonelabel_return: 750234370Sjasone return(ret); 751234370Sjasone} 752234370Sjasone 753234370Sjasoneint 754234370Sjasonectl_nametomib(const char *name, size_t *mibp, size_t *miblenp) 755234370Sjasone{ 756234370Sjasone int ret; 757234370Sjasone 758234370Sjasone if (ctl_initialized == false && ctl_init()) { 759234370Sjasone ret = EAGAIN; 760234370Sjasone goto label_return; 761234370Sjasone } 762234370Sjasone 763234370Sjasone ret = ctl_lookup(name, NULL, mibp, miblenp); 764234370Sjasonelabel_return: 765234370Sjasone return(ret); 766234370Sjasone} 767234370Sjasone 768234370Sjasoneint 769234370Sjasonectl_bymib(const size_t *mib, size_t miblen, void *oldp, size_t *oldlenp, 770234370Sjasone void *newp, size_t newlen) 771234370Sjasone{ 772234370Sjasone int ret; 773235238Sjasone const ctl_named_node_t *node; 774234370Sjasone size_t i; 775234370Sjasone 776234370Sjasone if (ctl_initialized == false && ctl_init()) { 777234370Sjasone ret = EAGAIN; 778234370Sjasone goto label_return; 779234370Sjasone } 780234370Sjasone 781234370Sjasone /* Iterate down the tree. */ 782234370Sjasone node = super_root_node; 783234370Sjasone for (i = 0; i < miblen; i++) { 784235238Sjasone assert(node); 785235238Sjasone assert(node->nchildren > 0); 786235238Sjasone if (ctl_named_node(node->children) != NULL) { 787234370Sjasone /* Children are named. */ 788235238Sjasone if (node->nchildren <= mib[i]) { 789234370Sjasone ret = ENOENT; 790234370Sjasone goto label_return; 791234370Sjasone } 792235238Sjasone node = ctl_named_children(node, mib[i]); 793234370Sjasone } else { 794235238Sjasone const ctl_indexed_node_t *inode; 795234370Sjasone 796234370Sjasone /* Indexed element. */ 797235238Sjasone inode = ctl_indexed_node(node->children); 798235238Sjasone node = inode->index(mib, miblen, mib[i]); 799234370Sjasone if (node == NULL) { 800234370Sjasone ret = ENOENT; 801234370Sjasone goto label_return; 802234370Sjasone } 803234370Sjasone } 804234370Sjasone } 805234370Sjasone 806234370Sjasone /* Call the ctl function. */ 807235238Sjasone if (node && node->ctl) 808235238Sjasone ret = node->ctl(mib, miblen, oldp, oldlenp, newp, newlen); 809235238Sjasone else { 810234370Sjasone /* Partial MIB. */ 811234370Sjasone ret = ENOENT; 812234370Sjasone } 813234370Sjasone 814234370Sjasonelabel_return: 815234370Sjasone return(ret); 816234370Sjasone} 817234370Sjasone 818234370Sjasonebool 819234370Sjasonectl_boot(void) 820234370Sjasone{ 821234370Sjasone 822234370Sjasone if (malloc_mutex_init(&ctl_mtx)) 823234370Sjasone return (true); 824234370Sjasone 825234370Sjasone ctl_initialized = false; 826234370Sjasone 827234370Sjasone return (false); 828234370Sjasone} 829234370Sjasone 830234370Sjasone/******************************************************************************/ 831234370Sjasone/* *_ctl() functions. */ 832234370Sjasone 833234370Sjasone#define READONLY() do { \ 834234370Sjasone if (newp != NULL || newlen != 0) { \ 835234370Sjasone ret = EPERM; \ 836235238Sjasone goto label_return; \ 837234370Sjasone } \ 838234370Sjasone} while (0) 839234370Sjasone 840234370Sjasone#define WRITEONLY() do { \ 841234370Sjasone if (oldp != NULL || oldlenp != NULL) { \ 842234370Sjasone ret = EPERM; \ 843235238Sjasone goto label_return; \ 844234370Sjasone } \ 845234370Sjasone} while (0) 846234370Sjasone 847234370Sjasone#define READ(v, t) do { \ 848234370Sjasone if (oldp != NULL && oldlenp != NULL) { \ 849234370Sjasone if (*oldlenp != sizeof(t)) { \ 850234370Sjasone size_t copylen = (sizeof(t) <= *oldlenp) \ 851234370Sjasone ? sizeof(t) : *oldlenp; \ 852234370Sjasone memcpy(oldp, (void *)&v, copylen); \ 853234370Sjasone ret = EINVAL; \ 854235238Sjasone goto label_return; \ 855234370Sjasone } else \ 856234370Sjasone *(t *)oldp = v; \ 857234370Sjasone } \ 858234370Sjasone} while (0) 859234370Sjasone 860234370Sjasone#define WRITE(v, t) do { \ 861234370Sjasone if (newp != NULL) { \ 862234370Sjasone if (newlen != sizeof(t)) { \ 863234370Sjasone ret = EINVAL; \ 864235238Sjasone goto label_return; \ 865234370Sjasone } \ 866234370Sjasone v = *(t *)newp; \ 867234370Sjasone } \ 868234370Sjasone} while (0) 869234370Sjasone 870234370Sjasone/* 871234370Sjasone * There's a lot of code duplication in the following macros due to limitations 872234370Sjasone * in how nested cpp macros are expanded. 873234370Sjasone */ 874234370Sjasone#define CTL_RO_CLGEN(c, l, n, v, t) \ 875234370Sjasonestatic int \ 876234370Sjasonen##_ctl(const size_t *mib, size_t miblen, void *oldp, size_t *oldlenp, \ 877234370Sjasone void *newp, size_t newlen) \ 878234370Sjasone{ \ 879234370Sjasone int ret; \ 880234370Sjasone t oldval; \ 881234370Sjasone \ 882234370Sjasone if ((c) == false) \ 883234370Sjasone return (ENOENT); \ 884234370Sjasone if (l) \ 885234370Sjasone malloc_mutex_lock(&ctl_mtx); \ 886234370Sjasone READONLY(); \ 887234370Sjasone oldval = v; \ 888234370Sjasone READ(oldval, t); \ 889234370Sjasone \ 890234370Sjasone ret = 0; \ 891235238Sjasonelabel_return: \ 892234370Sjasone if (l) \ 893234370Sjasone malloc_mutex_unlock(&ctl_mtx); \ 894234370Sjasone return (ret); \ 895234370Sjasone} 896234370Sjasone 897234370Sjasone#define CTL_RO_CGEN(c, n, v, t) \ 898234370Sjasonestatic int \ 899234370Sjasonen##_ctl(const size_t *mib, size_t miblen, void *oldp, size_t *oldlenp, \ 900234370Sjasone void *newp, size_t newlen) \ 901234370Sjasone{ \ 902234370Sjasone int ret; \ 903234370Sjasone t oldval; \ 904234370Sjasone \ 905234370Sjasone if ((c) == false) \ 906234370Sjasone return (ENOENT); \ 907234370Sjasone malloc_mutex_lock(&ctl_mtx); \ 908234370Sjasone READONLY(); \ 909234370Sjasone oldval = v; \ 910234370Sjasone READ(oldval, t); \ 911234370Sjasone \ 912234370Sjasone ret = 0; \ 913235238Sjasonelabel_return: \ 914234370Sjasone malloc_mutex_unlock(&ctl_mtx); \ 915234370Sjasone return (ret); \ 916234370Sjasone} 917234370Sjasone 918234370Sjasone#define CTL_RO_GEN(n, v, t) \ 919234370Sjasonestatic int \ 920234370Sjasonen##_ctl(const size_t *mib, size_t miblen, void *oldp, size_t *oldlenp, \ 921234370Sjasone void *newp, size_t newlen) \ 922234370Sjasone{ \ 923234370Sjasone int ret; \ 924234370Sjasone t oldval; \ 925234370Sjasone \ 926234370Sjasone malloc_mutex_lock(&ctl_mtx); \ 927234370Sjasone READONLY(); \ 928234370Sjasone oldval = v; \ 929234370Sjasone READ(oldval, t); \ 930234370Sjasone \ 931234370Sjasone ret = 0; \ 932235238Sjasonelabel_return: \ 933234370Sjasone malloc_mutex_unlock(&ctl_mtx); \ 934234370Sjasone return (ret); \ 935234370Sjasone} 936234370Sjasone 937234370Sjasone/* 938234370Sjasone * ctl_mtx is not acquired, under the assumption that no pertinent data will 939234370Sjasone * mutate during the call. 940234370Sjasone */ 941234370Sjasone#define CTL_RO_NL_CGEN(c, n, v, t) \ 942234370Sjasonestatic int \ 943234370Sjasonen##_ctl(const size_t *mib, size_t miblen, void *oldp, size_t *oldlenp, \ 944234370Sjasone void *newp, size_t newlen) \ 945234370Sjasone{ \ 946234370Sjasone int ret; \ 947234370Sjasone t oldval; \ 948234370Sjasone \ 949234370Sjasone if ((c) == false) \ 950234370Sjasone return (ENOENT); \ 951234370Sjasone READONLY(); \ 952234370Sjasone oldval = v; \ 953234370Sjasone READ(oldval, t); \ 954234370Sjasone \ 955234370Sjasone ret = 0; \ 956235238Sjasonelabel_return: \ 957234370Sjasone return (ret); \ 958234370Sjasone} 959234370Sjasone 960234370Sjasone#define CTL_RO_NL_GEN(n, v, t) \ 961234370Sjasonestatic int \ 962234370Sjasonen##_ctl(const size_t *mib, size_t miblen, void *oldp, size_t *oldlenp, \ 963234370Sjasone void *newp, size_t newlen) \ 964234370Sjasone{ \ 965234370Sjasone int ret; \ 966234370Sjasone t oldval; \ 967234370Sjasone \ 968234370Sjasone READONLY(); \ 969234370Sjasone oldval = v; \ 970234370Sjasone READ(oldval, t); \ 971234370Sjasone \ 972234370Sjasone ret = 0; \ 973235238Sjasonelabel_return: \ 974234370Sjasone return (ret); \ 975234370Sjasone} 976234370Sjasone 977234370Sjasone#define CTL_RO_BOOL_CONFIG_GEN(n) \ 978234370Sjasonestatic int \ 979234370Sjasonen##_ctl(const size_t *mib, size_t miblen, void *oldp, size_t *oldlenp, \ 980234370Sjasone void *newp, size_t newlen) \ 981234370Sjasone{ \ 982234370Sjasone int ret; \ 983234370Sjasone bool oldval; \ 984234370Sjasone \ 985234370Sjasone READONLY(); \ 986234370Sjasone oldval = n; \ 987234370Sjasone READ(oldval, bool); \ 988234370Sjasone \ 989234370Sjasone ret = 0; \ 990235238Sjasonelabel_return: \ 991234370Sjasone return (ret); \ 992234370Sjasone} 993234370Sjasone 994234370SjasoneCTL_RO_NL_GEN(version, JEMALLOC_VERSION, const char *) 995234370Sjasone 996234370Sjasonestatic int 997234370Sjasoneepoch_ctl(const size_t *mib, size_t miblen, void *oldp, size_t *oldlenp, 998234370Sjasone void *newp, size_t newlen) 999234370Sjasone{ 1000234370Sjasone int ret; 1001234370Sjasone uint64_t newval; 1002234370Sjasone 1003234370Sjasone malloc_mutex_lock(&ctl_mtx); 1004234370Sjasone WRITE(newval, uint64_t); 1005235238Sjasone if (newp != NULL) 1006234370Sjasone ctl_refresh(); 1007234370Sjasone READ(ctl_epoch, uint64_t); 1008234370Sjasone 1009234370Sjasone ret = 0; 1010234370Sjasonelabel_return: 1011234370Sjasone malloc_mutex_unlock(&ctl_mtx); 1012234370Sjasone return (ret); 1013234370Sjasone} 1014234370Sjasone 1015234370Sjasonestatic int 1016234370Sjasonethread_tcache_enabled_ctl(const size_t *mib, size_t miblen, void *oldp, 1017234370Sjasone size_t *oldlenp, void *newp, size_t newlen) 1018234370Sjasone{ 1019234370Sjasone int ret; 1020234370Sjasone bool oldval; 1021234370Sjasone 1022234370Sjasone if (config_tcache == false) 1023234370Sjasone return (ENOENT); 1024234370Sjasone 1025234370Sjasone oldval = tcache_enabled_get(); 1026234370Sjasone if (newp != NULL) { 1027234370Sjasone if (newlen != sizeof(bool)) { 1028234370Sjasone ret = EINVAL; 1029234370Sjasone goto label_return; 1030234370Sjasone } 1031234370Sjasone tcache_enabled_set(*(bool *)newp); 1032234370Sjasone } 1033234370Sjasone READ(oldval, bool); 1034234370Sjasone 1035234370Sjasonelabel_return: 1036234370Sjasone ret = 0; 1037234370Sjasone return (ret); 1038234370Sjasone} 1039234370Sjasone 1040234370Sjasonestatic int 1041234370Sjasonethread_tcache_flush_ctl(const size_t *mib, size_t miblen, void *oldp, 1042234370Sjasone size_t *oldlenp, void *newp, size_t newlen) 1043234370Sjasone{ 1044234370Sjasone int ret; 1045234370Sjasone 1046234370Sjasone if (config_tcache == false) 1047234370Sjasone return (ENOENT); 1048234370Sjasone 1049235238Sjasone READONLY(); 1050235238Sjasone WRITEONLY(); 1051234370Sjasone 1052234370Sjasone tcache_flush(); 1053234370Sjasone 1054234370Sjasone ret = 0; 1055234370Sjasonelabel_return: 1056234370Sjasone return (ret); 1057234370Sjasone} 1058234370Sjasone 1059234370Sjasonestatic int 1060234370Sjasonethread_arena_ctl(const size_t *mib, size_t miblen, void *oldp, size_t *oldlenp, 1061234370Sjasone void *newp, size_t newlen) 1062234370Sjasone{ 1063234370Sjasone int ret; 1064234370Sjasone unsigned newind, oldind; 1065234370Sjasone 1066234370Sjasone newind = oldind = choose_arena(NULL)->ind; 1067234370Sjasone WRITE(newind, unsigned); 1068234370Sjasone READ(oldind, unsigned); 1069234370Sjasone if (newind != oldind) { 1070234370Sjasone arena_t *arena; 1071234370Sjasone 1072234370Sjasone if (newind >= narenas) { 1073234370Sjasone /* New arena index is out of range. */ 1074234370Sjasone ret = EFAULT; 1075234370Sjasone goto label_return; 1076234370Sjasone } 1077234370Sjasone 1078234370Sjasone /* Initialize arena if necessary. */ 1079234370Sjasone malloc_mutex_lock(&arenas_lock); 1080234370Sjasone if ((arena = arenas[newind]) == NULL && (arena = 1081234370Sjasone arenas_extend(newind)) == NULL) { 1082234370Sjasone malloc_mutex_unlock(&arenas_lock); 1083234370Sjasone ret = EAGAIN; 1084234370Sjasone goto label_return; 1085234370Sjasone } 1086234370Sjasone assert(arena == arenas[newind]); 1087234370Sjasone arenas[oldind]->nthreads--; 1088234370Sjasone arenas[newind]->nthreads++; 1089234370Sjasone malloc_mutex_unlock(&arenas_lock); 1090234370Sjasone 1091234370Sjasone /* Set new arena association. */ 1092234370Sjasone if (config_tcache) { 1093234370Sjasone tcache_t *tcache; 1094234370Sjasone if ((uintptr_t)(tcache = *tcache_tsd_get()) > 1095234370Sjasone (uintptr_t)TCACHE_STATE_MAX) { 1096234370Sjasone tcache_arena_dissociate(tcache); 1097234370Sjasone tcache_arena_associate(tcache, arena); 1098234370Sjasone } 1099234370Sjasone } 1100234370Sjasone arenas_tsd_set(&arena); 1101234370Sjasone } 1102234370Sjasone 1103234370Sjasone ret = 0; 1104234370Sjasonelabel_return: 1105234370Sjasone return (ret); 1106234370Sjasone} 1107234370Sjasone 1108234370SjasoneCTL_RO_NL_CGEN(config_stats, thread_allocated, 1109234370Sjasone thread_allocated_tsd_get()->allocated, uint64_t) 1110234370SjasoneCTL_RO_NL_CGEN(config_stats, thread_allocatedp, 1111234370Sjasone &thread_allocated_tsd_get()->allocated, uint64_t *) 1112234370SjasoneCTL_RO_NL_CGEN(config_stats, thread_deallocated, 1113234370Sjasone thread_allocated_tsd_get()->deallocated, uint64_t) 1114234370SjasoneCTL_RO_NL_CGEN(config_stats, thread_deallocatedp, 1115234370Sjasone &thread_allocated_tsd_get()->deallocated, uint64_t *) 1116234370Sjasone 1117234370Sjasone/******************************************************************************/ 1118234370Sjasone 1119234370SjasoneCTL_RO_BOOL_CONFIG_GEN(config_debug) 1120234370SjasoneCTL_RO_BOOL_CONFIG_GEN(config_dss) 1121234370SjasoneCTL_RO_BOOL_CONFIG_GEN(config_fill) 1122234370SjasoneCTL_RO_BOOL_CONFIG_GEN(config_lazy_lock) 1123235238SjasoneCTL_RO_BOOL_CONFIG_GEN(config_mremap) 1124234370SjasoneCTL_RO_BOOL_CONFIG_GEN(config_munmap) 1125234370SjasoneCTL_RO_BOOL_CONFIG_GEN(config_prof) 1126234370SjasoneCTL_RO_BOOL_CONFIG_GEN(config_prof_libgcc) 1127234370SjasoneCTL_RO_BOOL_CONFIG_GEN(config_prof_libunwind) 1128234370SjasoneCTL_RO_BOOL_CONFIG_GEN(config_stats) 1129234370SjasoneCTL_RO_BOOL_CONFIG_GEN(config_tcache) 1130234370SjasoneCTL_RO_BOOL_CONFIG_GEN(config_tls) 1131234370SjasoneCTL_RO_BOOL_CONFIG_GEN(config_utrace) 1132234370SjasoneCTL_RO_BOOL_CONFIG_GEN(config_valgrind) 1133234370SjasoneCTL_RO_BOOL_CONFIG_GEN(config_xmalloc) 1134234370Sjasone 1135234370Sjasone/******************************************************************************/ 1136234370Sjasone 1137234370SjasoneCTL_RO_NL_GEN(opt_abort, opt_abort, bool) 1138234370SjasoneCTL_RO_NL_GEN(opt_lg_chunk, opt_lg_chunk, size_t) 1139234370SjasoneCTL_RO_NL_GEN(opt_narenas, opt_narenas, size_t) 1140234370SjasoneCTL_RO_NL_GEN(opt_lg_dirty_mult, opt_lg_dirty_mult, ssize_t) 1141234370SjasoneCTL_RO_NL_GEN(opt_stats_print, opt_stats_print, bool) 1142234370SjasoneCTL_RO_NL_CGEN(config_fill, opt_junk, opt_junk, bool) 1143234370SjasoneCTL_RO_NL_CGEN(config_fill, opt_zero, opt_zero, bool) 1144234370SjasoneCTL_RO_NL_CGEN(config_fill, opt_quarantine, opt_quarantine, size_t) 1145234370SjasoneCTL_RO_NL_CGEN(config_fill, opt_redzone, opt_redzone, bool) 1146234370SjasoneCTL_RO_NL_CGEN(config_utrace, opt_utrace, opt_utrace, bool) 1147234370SjasoneCTL_RO_NL_CGEN(config_valgrind, opt_valgrind, opt_valgrind, bool) 1148234370SjasoneCTL_RO_NL_CGEN(config_xmalloc, opt_xmalloc, opt_xmalloc, bool) 1149234370SjasoneCTL_RO_NL_CGEN(config_tcache, opt_tcache, opt_tcache, bool) 1150234370SjasoneCTL_RO_NL_CGEN(config_tcache, opt_lg_tcache_max, opt_lg_tcache_max, ssize_t) 1151234370SjasoneCTL_RO_NL_CGEN(config_prof, opt_prof, opt_prof, bool) 1152234370SjasoneCTL_RO_NL_CGEN(config_prof, opt_prof_prefix, opt_prof_prefix, const char *) 1153234370SjasoneCTL_RO_CGEN(config_prof, opt_prof_active, opt_prof_active, bool) /* Mutable. */ 1154234370SjasoneCTL_RO_NL_CGEN(config_prof, opt_lg_prof_sample, opt_lg_prof_sample, size_t) 1155234370SjasoneCTL_RO_NL_CGEN(config_prof, opt_lg_prof_interval, opt_lg_prof_interval, ssize_t) 1156234370SjasoneCTL_RO_NL_CGEN(config_prof, opt_prof_gdump, opt_prof_gdump, bool) 1157234543SjasoneCTL_RO_NL_CGEN(config_prof, opt_prof_final, opt_prof_final, bool) 1158234370SjasoneCTL_RO_NL_CGEN(config_prof, opt_prof_leak, opt_prof_leak, bool) 1159234370SjasoneCTL_RO_NL_CGEN(config_prof, opt_prof_accum, opt_prof_accum, bool) 1160234370Sjasone 1161234370Sjasone/******************************************************************************/ 1162234370Sjasone 1163234370SjasoneCTL_RO_NL_GEN(arenas_bin_i_size, arena_bin_info[mib[2]].reg_size, size_t) 1164234370SjasoneCTL_RO_NL_GEN(arenas_bin_i_nregs, arena_bin_info[mib[2]].nregs, uint32_t) 1165234370SjasoneCTL_RO_NL_GEN(arenas_bin_i_run_size, arena_bin_info[mib[2]].run_size, size_t) 1166235238Sjasoneconst ctl_named_node_t * 1167234370Sjasonearenas_bin_i_index(const size_t *mib, size_t miblen, size_t i) 1168234370Sjasone{ 1169234370Sjasone 1170234370Sjasone if (i > NBINS) 1171234370Sjasone return (NULL); 1172234370Sjasone return (super_arenas_bin_i_node); 1173234370Sjasone} 1174234370Sjasone 1175234370SjasoneCTL_RO_NL_GEN(arenas_lrun_i_size, ((mib[2]+1) << LG_PAGE), size_t) 1176235238Sjasoneconst ctl_named_node_t * 1177234370Sjasonearenas_lrun_i_index(const size_t *mib, size_t miblen, size_t i) 1178234370Sjasone{ 1179234370Sjasone 1180234370Sjasone if (i > nlclasses) 1181234370Sjasone return (NULL); 1182234370Sjasone return (super_arenas_lrun_i_node); 1183234370Sjasone} 1184234370Sjasone 1185234370SjasoneCTL_RO_NL_GEN(arenas_narenas, narenas, unsigned) 1186234370Sjasone 1187234370Sjasonestatic int 1188234370Sjasonearenas_initialized_ctl(const size_t *mib, size_t miblen, void *oldp, 1189234370Sjasone size_t *oldlenp, void *newp, size_t newlen) 1190234370Sjasone{ 1191234370Sjasone int ret; 1192234370Sjasone unsigned nread, i; 1193234370Sjasone 1194234370Sjasone malloc_mutex_lock(&ctl_mtx); 1195234370Sjasone READONLY(); 1196234370Sjasone if (*oldlenp != narenas * sizeof(bool)) { 1197234370Sjasone ret = EINVAL; 1198234370Sjasone nread = (*oldlenp < narenas * sizeof(bool)) 1199234370Sjasone ? (*oldlenp / sizeof(bool)) : narenas; 1200234370Sjasone } else { 1201234370Sjasone ret = 0; 1202234370Sjasone nread = narenas; 1203234370Sjasone } 1204234370Sjasone 1205234370Sjasone for (i = 0; i < nread; i++) 1206234370Sjasone ((bool *)oldp)[i] = ctl_stats.arenas[i].initialized; 1207234370Sjasone 1208234370Sjasonelabel_return: 1209234370Sjasone malloc_mutex_unlock(&ctl_mtx); 1210234370Sjasone return (ret); 1211234370Sjasone} 1212234370Sjasone 1213234370SjasoneCTL_RO_NL_GEN(arenas_quantum, QUANTUM, size_t) 1214234370SjasoneCTL_RO_NL_GEN(arenas_page, PAGE, size_t) 1215234370SjasoneCTL_RO_NL_CGEN(config_tcache, arenas_tcache_max, tcache_maxclass, size_t) 1216234370SjasoneCTL_RO_NL_GEN(arenas_nbins, NBINS, unsigned) 1217234370SjasoneCTL_RO_NL_CGEN(config_tcache, arenas_nhbins, nhbins, unsigned) 1218234370SjasoneCTL_RO_NL_GEN(arenas_nlruns, nlclasses, size_t) 1219234370Sjasone 1220234370Sjasonestatic int 1221234370Sjasonearenas_purge_ctl(const size_t *mib, size_t miblen, void *oldp, size_t *oldlenp, 1222234370Sjasone void *newp, size_t newlen) 1223234370Sjasone{ 1224234370Sjasone int ret; 1225234370Sjasone unsigned arena; 1226234370Sjasone 1227234370Sjasone WRITEONLY(); 1228234370Sjasone arena = UINT_MAX; 1229234370Sjasone WRITE(arena, unsigned); 1230234370Sjasone if (newp != NULL && arena >= narenas) { 1231234370Sjasone ret = EFAULT; 1232234370Sjasone goto label_return; 1233234370Sjasone } else { 1234235238Sjasone VARIABLE_ARRAY(arena_t *, tarenas, narenas); 1235234370Sjasone 1236234370Sjasone malloc_mutex_lock(&arenas_lock); 1237234370Sjasone memcpy(tarenas, arenas, sizeof(arena_t *) * narenas); 1238234370Sjasone malloc_mutex_unlock(&arenas_lock); 1239234370Sjasone 1240234370Sjasone if (arena == UINT_MAX) { 1241234370Sjasone unsigned i; 1242234370Sjasone for (i = 0; i < narenas; i++) { 1243234370Sjasone if (tarenas[i] != NULL) 1244234370Sjasone arena_purge_all(tarenas[i]); 1245234370Sjasone } 1246234370Sjasone } else { 1247234370Sjasone assert(arena < narenas); 1248234370Sjasone if (tarenas[arena] != NULL) 1249234370Sjasone arena_purge_all(tarenas[arena]); 1250234370Sjasone } 1251234370Sjasone } 1252234370Sjasone 1253234370Sjasone ret = 0; 1254234370Sjasonelabel_return: 1255234370Sjasone return (ret); 1256234370Sjasone} 1257234370Sjasone 1258234370Sjasone/******************************************************************************/ 1259234370Sjasone 1260234370Sjasonestatic int 1261234370Sjasoneprof_active_ctl(const size_t *mib, size_t miblen, void *oldp, size_t *oldlenp, 1262234370Sjasone void *newp, size_t newlen) 1263234370Sjasone{ 1264234370Sjasone int ret; 1265234370Sjasone bool oldval; 1266234370Sjasone 1267234370Sjasone if (config_prof == false) 1268234370Sjasone return (ENOENT); 1269234370Sjasone 1270234370Sjasone malloc_mutex_lock(&ctl_mtx); /* Protect opt_prof_active. */ 1271234370Sjasone oldval = opt_prof_active; 1272234370Sjasone if (newp != NULL) { 1273234370Sjasone /* 1274234370Sjasone * The memory barriers will tend to make opt_prof_active 1275234370Sjasone * propagate faster on systems with weak memory ordering. 1276234370Sjasone */ 1277234370Sjasone mb_write(); 1278234370Sjasone WRITE(opt_prof_active, bool); 1279234370Sjasone mb_write(); 1280234370Sjasone } 1281234370Sjasone READ(oldval, bool); 1282234370Sjasone 1283234370Sjasone ret = 0; 1284234370Sjasonelabel_return: 1285234370Sjasone malloc_mutex_unlock(&ctl_mtx); 1286234370Sjasone return (ret); 1287234370Sjasone} 1288234370Sjasone 1289234370Sjasonestatic int 1290234370Sjasoneprof_dump_ctl(const size_t *mib, size_t miblen, void *oldp, size_t *oldlenp, 1291234370Sjasone void *newp, size_t newlen) 1292234370Sjasone{ 1293234370Sjasone int ret; 1294234370Sjasone const char *filename = NULL; 1295234370Sjasone 1296234370Sjasone if (config_prof == false) 1297234370Sjasone return (ENOENT); 1298234370Sjasone 1299234370Sjasone WRITEONLY(); 1300234370Sjasone WRITE(filename, const char *); 1301234370Sjasone 1302234370Sjasone if (prof_mdump(filename)) { 1303234370Sjasone ret = EFAULT; 1304234370Sjasone goto label_return; 1305234370Sjasone } 1306234370Sjasone 1307234370Sjasone ret = 0; 1308234370Sjasonelabel_return: 1309234370Sjasone return (ret); 1310234370Sjasone} 1311234370Sjasone 1312234370SjasoneCTL_RO_NL_CGEN(config_prof, prof_interval, prof_interval, uint64_t) 1313234370Sjasone 1314234370Sjasone/******************************************************************************/ 1315234370Sjasone 1316234370SjasoneCTL_RO_CGEN(config_stats, stats_chunks_current, ctl_stats.chunks.current, 1317234370Sjasone size_t) 1318234370SjasoneCTL_RO_CGEN(config_stats, stats_chunks_total, ctl_stats.chunks.total, uint64_t) 1319234370SjasoneCTL_RO_CGEN(config_stats, stats_chunks_high, ctl_stats.chunks.high, size_t) 1320234370SjasoneCTL_RO_CGEN(config_stats, stats_huge_allocated, huge_allocated, size_t) 1321234370SjasoneCTL_RO_CGEN(config_stats, stats_huge_nmalloc, huge_nmalloc, uint64_t) 1322234370SjasoneCTL_RO_CGEN(config_stats, stats_huge_ndalloc, huge_ndalloc, uint64_t) 1323234370SjasoneCTL_RO_CGEN(config_stats, stats_arenas_i_small_allocated, 1324234370Sjasone ctl_stats.arenas[mib[2]].allocated_small, size_t) 1325234370SjasoneCTL_RO_CGEN(config_stats, stats_arenas_i_small_nmalloc, 1326234370Sjasone ctl_stats.arenas[mib[2]].nmalloc_small, uint64_t) 1327234370SjasoneCTL_RO_CGEN(config_stats, stats_arenas_i_small_ndalloc, 1328234370Sjasone ctl_stats.arenas[mib[2]].ndalloc_small, uint64_t) 1329234370SjasoneCTL_RO_CGEN(config_stats, stats_arenas_i_small_nrequests, 1330234370Sjasone ctl_stats.arenas[mib[2]].nrequests_small, uint64_t) 1331234370SjasoneCTL_RO_CGEN(config_stats, stats_arenas_i_large_allocated, 1332234370Sjasone ctl_stats.arenas[mib[2]].astats.allocated_large, size_t) 1333234370SjasoneCTL_RO_CGEN(config_stats, stats_arenas_i_large_nmalloc, 1334234370Sjasone ctl_stats.arenas[mib[2]].astats.nmalloc_large, uint64_t) 1335234370SjasoneCTL_RO_CGEN(config_stats, stats_arenas_i_large_ndalloc, 1336234370Sjasone ctl_stats.arenas[mib[2]].astats.ndalloc_large, uint64_t) 1337234370SjasoneCTL_RO_CGEN(config_stats, stats_arenas_i_large_nrequests, 1338234370Sjasone ctl_stats.arenas[mib[2]].astats.nrequests_large, uint64_t) 1339234370Sjasone 1340234370SjasoneCTL_RO_CGEN(config_stats, stats_arenas_i_bins_j_allocated, 1341234370Sjasone ctl_stats.arenas[mib[2]].bstats[mib[4]].allocated, size_t) 1342234370SjasoneCTL_RO_CGEN(config_stats, stats_arenas_i_bins_j_nmalloc, 1343234370Sjasone ctl_stats.arenas[mib[2]].bstats[mib[4]].nmalloc, uint64_t) 1344234370SjasoneCTL_RO_CGEN(config_stats, stats_arenas_i_bins_j_ndalloc, 1345234370Sjasone ctl_stats.arenas[mib[2]].bstats[mib[4]].ndalloc, uint64_t) 1346234370SjasoneCTL_RO_CGEN(config_stats, stats_arenas_i_bins_j_nrequests, 1347234370Sjasone ctl_stats.arenas[mib[2]].bstats[mib[4]].nrequests, uint64_t) 1348234370SjasoneCTL_RO_CGEN(config_stats && config_tcache, stats_arenas_i_bins_j_nfills, 1349234370Sjasone ctl_stats.arenas[mib[2]].bstats[mib[4]].nfills, uint64_t) 1350234370SjasoneCTL_RO_CGEN(config_stats && config_tcache, stats_arenas_i_bins_j_nflushes, 1351234370Sjasone ctl_stats.arenas[mib[2]].bstats[mib[4]].nflushes, uint64_t) 1352234370SjasoneCTL_RO_CGEN(config_stats, stats_arenas_i_bins_j_nruns, 1353234370Sjasone ctl_stats.arenas[mib[2]].bstats[mib[4]].nruns, uint64_t) 1354234370SjasoneCTL_RO_CGEN(config_stats, stats_arenas_i_bins_j_nreruns, 1355234370Sjasone ctl_stats.arenas[mib[2]].bstats[mib[4]].reruns, uint64_t) 1356234370SjasoneCTL_RO_CGEN(config_stats, stats_arenas_i_bins_j_curruns, 1357234370Sjasone ctl_stats.arenas[mib[2]].bstats[mib[4]].curruns, size_t) 1358234370Sjasone 1359235238Sjasoneconst ctl_named_node_t * 1360234370Sjasonestats_arenas_i_bins_j_index(const size_t *mib, size_t miblen, size_t j) 1361234370Sjasone{ 1362234370Sjasone 1363234370Sjasone if (j > NBINS) 1364234370Sjasone return (NULL); 1365234370Sjasone return (super_stats_arenas_i_bins_j_node); 1366234370Sjasone} 1367234370Sjasone 1368234370SjasoneCTL_RO_CGEN(config_stats, stats_arenas_i_lruns_j_nmalloc, 1369234370Sjasone ctl_stats.arenas[mib[2]].lstats[mib[4]].nmalloc, uint64_t) 1370234370SjasoneCTL_RO_CGEN(config_stats, stats_arenas_i_lruns_j_ndalloc, 1371234370Sjasone ctl_stats.arenas[mib[2]].lstats[mib[4]].ndalloc, uint64_t) 1372234370SjasoneCTL_RO_CGEN(config_stats, stats_arenas_i_lruns_j_nrequests, 1373234370Sjasone ctl_stats.arenas[mib[2]].lstats[mib[4]].nrequests, uint64_t) 1374234370SjasoneCTL_RO_CGEN(config_stats, stats_arenas_i_lruns_j_curruns, 1375234370Sjasone ctl_stats.arenas[mib[2]].lstats[mib[4]].curruns, size_t) 1376234370Sjasone 1377235238Sjasoneconst ctl_named_node_t * 1378234370Sjasonestats_arenas_i_lruns_j_index(const size_t *mib, size_t miblen, size_t j) 1379234370Sjasone{ 1380234370Sjasone 1381234370Sjasone if (j > nlclasses) 1382234370Sjasone return (NULL); 1383234370Sjasone return (super_stats_arenas_i_lruns_j_node); 1384234370Sjasone} 1385234370Sjasone 1386234370SjasoneCTL_RO_GEN(stats_arenas_i_nthreads, ctl_stats.arenas[mib[2]].nthreads, unsigned) 1387234370SjasoneCTL_RO_GEN(stats_arenas_i_pactive, ctl_stats.arenas[mib[2]].pactive, size_t) 1388234370SjasoneCTL_RO_GEN(stats_arenas_i_pdirty, ctl_stats.arenas[mib[2]].pdirty, size_t) 1389234370SjasoneCTL_RO_CGEN(config_stats, stats_arenas_i_mapped, 1390234370Sjasone ctl_stats.arenas[mib[2]].astats.mapped, size_t) 1391234370SjasoneCTL_RO_CGEN(config_stats, stats_arenas_i_npurge, 1392234370Sjasone ctl_stats.arenas[mib[2]].astats.npurge, uint64_t) 1393234370SjasoneCTL_RO_CGEN(config_stats, stats_arenas_i_nmadvise, 1394234370Sjasone ctl_stats.arenas[mib[2]].astats.nmadvise, uint64_t) 1395234370SjasoneCTL_RO_CGEN(config_stats, stats_arenas_i_purged, 1396234370Sjasone ctl_stats.arenas[mib[2]].astats.purged, uint64_t) 1397234370Sjasone 1398235238Sjasoneconst ctl_named_node_t * 1399234370Sjasonestats_arenas_i_index(const size_t *mib, size_t miblen, size_t i) 1400234370Sjasone{ 1401235238Sjasone const ctl_named_node_t * ret; 1402234370Sjasone 1403234370Sjasone malloc_mutex_lock(&ctl_mtx); 1404234370Sjasone if (ctl_stats.arenas[i].initialized == false) { 1405234370Sjasone ret = NULL; 1406234370Sjasone goto label_return; 1407234370Sjasone } 1408234370Sjasone 1409234370Sjasone ret = super_stats_arenas_i_node; 1410234370Sjasonelabel_return: 1411234370Sjasone malloc_mutex_unlock(&ctl_mtx); 1412234370Sjasone return (ret); 1413234370Sjasone} 1414234370Sjasone 1415234370SjasoneCTL_RO_CGEN(config_stats, stats_cactive, &stats_cactive, size_t *) 1416234370SjasoneCTL_RO_CGEN(config_stats, stats_allocated, ctl_stats.allocated, size_t) 1417234370SjasoneCTL_RO_CGEN(config_stats, stats_active, ctl_stats.active, size_t) 1418234370SjasoneCTL_RO_CGEN(config_stats, stats_mapped, ctl_stats.mapped, size_t) 1419