mirror of
https://github.com/jemalloc/jemalloc.git
synced 2026-06-01 17:54:16 +03:00
Split ctl handlers by mallctl namespace
Move mallctl handler implementations out of src/ctl.c into namespace-oriented ctl_* modules, while keeping the mallctl tree and dispatch machinery centralized in ctl.c. Add shared ctl mallctl helper macros and thin ctl arena/stat interfaces needed by the split modules. Wire the new sources into Makefile.in and MSVC project files. Keep behavior unchanged; this is intended as a readability and navigation refactor.
This commit is contained in:
parent
2004cf039e
commit
ca77aca653
31 changed files with 4097 additions and 3760 deletions
|
|
@ -109,6 +109,15 @@ C_SRCS := $(srcroot)src/jemalloc.c \
|
|||
$(srcroot)src/ckh.c \
|
||||
$(srcroot)src/counter.c \
|
||||
$(srcroot)src/ctl.c \
|
||||
$(srcroot)src/ctl_arena.c \
|
||||
$(srcroot)src/ctl_background_thread.c \
|
||||
$(srcroot)src/ctl_config.c \
|
||||
$(srcroot)src/ctl_opt.c \
|
||||
$(srcroot)src/ctl_prof.c \
|
||||
$(srcroot)src/ctl_stats.c \
|
||||
$(srcroot)src/ctl_thread.c \
|
||||
$(srcroot)src/ctl_tcache.c \
|
||||
$(srcroot)src/ctl_utilization.c \
|
||||
$(srcroot)src/decay.c \
|
||||
$(srcroot)src/div.c \
|
||||
$(srcroot)src/ecache.c \
|
||||
|
|
|
|||
|
|
@ -115,7 +115,11 @@ bool ctl_boot(void);
|
|||
void ctl_prefork(tsdn_t *tsdn);
|
||||
void ctl_postfork_parent(tsdn_t *tsdn);
|
||||
void ctl_postfork_child(tsdn_t *tsdn);
|
||||
void ctl_mtx_lock(tsdn_t *tsdn);
|
||||
void ctl_mtx_unlock(tsdn_t *tsdn);
|
||||
void ctl_mtx_assert_held(tsdn_t *tsdn);
|
||||
void ctl_mtx_prof_read(tsdn_t *tsdn, mutex_prof_data_t *mutex_prof_data);
|
||||
void ctl_mtx_prof_data_reset(tsdn_t *tsdn);
|
||||
|
||||
#define xmallctl(name, oldp, oldlenp, newp, newlen) \
|
||||
do { \
|
||||
|
|
|
|||
54
include/jemalloc/internal/ctl_arena.h
Normal file
54
include/jemalloc/internal/ctl_arena.h
Normal file
|
|
@ -0,0 +1,54 @@
|
|||
#ifndef JEMALLOC_INTERNAL_CTL_ARENA_H
|
||||
#define JEMALLOC_INTERNAL_CTL_ARENA_H
|
||||
|
||||
#include "jemalloc/internal/ctl_mallctl.h"
|
||||
|
||||
#define CTL_ARENA_PROTO(n) \
|
||||
int n##_ctl(tsd_t *tsd, const size_t *mib, size_t miblen, \
|
||||
void *oldp, size_t *oldlenp, void *newp, size_t newlen);
|
||||
|
||||
CTL_ARENA_PROTO(arena_i_initialized)
|
||||
CTL_ARENA_PROTO(arena_i_decay)
|
||||
CTL_ARENA_PROTO(arena_i_purge)
|
||||
CTL_ARENA_PROTO(arena_i_reset)
|
||||
CTL_ARENA_PROTO(arena_i_destroy)
|
||||
CTL_ARENA_PROTO(arena_i_dss)
|
||||
CTL_ARENA_PROTO(arena_i_oversize_threshold)
|
||||
CTL_ARENA_PROTO(arena_i_dirty_decay_ms)
|
||||
CTL_ARENA_PROTO(arena_i_muzzy_decay_ms)
|
||||
CTL_ARENA_PROTO(arena_i_extent_hooks)
|
||||
CTL_ARENA_PROTO(arena_i_retain_grow_limit)
|
||||
CTL_ARENA_PROTO(arena_i_name)
|
||||
|
||||
CTL_ARENA_PROTO(arenas_narenas)
|
||||
CTL_ARENA_PROTO(arenas_dirty_decay_ms)
|
||||
CTL_ARENA_PROTO(arenas_muzzy_decay_ms)
|
||||
CTL_ARENA_PROTO(arenas_quantum)
|
||||
CTL_ARENA_PROTO(arenas_page)
|
||||
CTL_ARENA_PROTO(arenas_hugepage)
|
||||
CTL_ARENA_PROTO(arenas_tcache_max)
|
||||
CTL_ARENA_PROTO(arenas_nbins)
|
||||
CTL_ARENA_PROTO(arenas_nhbins)
|
||||
CTL_ARENA_PROTO(arenas_bin_i_size)
|
||||
CTL_ARENA_PROTO(arenas_bin_i_nregs)
|
||||
CTL_ARENA_PROTO(arenas_bin_i_slab_size)
|
||||
CTL_ARENA_PROTO(arenas_bin_i_nshards)
|
||||
CTL_ARENA_PROTO(arenas_nlextents)
|
||||
CTL_ARENA_PROTO(arenas_lextent_i_size)
|
||||
CTL_ARENA_PROTO(arenas_create)
|
||||
CTL_ARENA_PROTO(arenas_lookup)
|
||||
CTL_ARENA_PROTO(experimental_arenas_create_ext)
|
||||
|
||||
#undef CTL_ARENA_PROTO
|
||||
|
||||
bool ctl_arenas_init(tsd_t *tsd);
|
||||
ctl_arena_t *ctl_arenas_refresh(tsdn_t *tsdn);
|
||||
ctl_arena_t *ctl_arenas_i(size_t i);
|
||||
uint64_t ctl_arenas_epoch_get(void);
|
||||
void ctl_arenas_epoch_advance(void);
|
||||
bool ctl_arena_i_indexable(tsdn_t *tsdn, size_t i);
|
||||
bool ctl_arenas_i_verify(size_t i);
|
||||
int ctl_arena_create(tsd_t *tsd, void *oldp, size_t *oldlenp,
|
||||
const arena_config_t *config);
|
||||
|
||||
#endif /* JEMALLOC_INTERNAL_CTL_ARENA_H */
|
||||
11
include/jemalloc/internal/ctl_background_thread.h
Normal file
11
include/jemalloc/internal/ctl_background_thread.h
Normal file
|
|
@ -0,0 +1,11 @@
|
|||
#ifndef JEMALLOC_INTERNAL_CTL_BACKGROUND_THREAD_H
|
||||
#define JEMALLOC_INTERNAL_CTL_BACKGROUND_THREAD_H
|
||||
|
||||
#include "jemalloc/internal/ctl_mallctl.h"
|
||||
|
||||
int background_thread_ctl(tsd_t *tsd, const size_t *mib, size_t miblen,
|
||||
void *oldp, size_t *oldlenp, void *newp, size_t newlen);
|
||||
int max_background_threads_ctl(tsd_t *tsd, const size_t *mib, size_t miblen,
|
||||
void *oldp, size_t *oldlenp, void *newp, size_t newlen);
|
||||
|
||||
#endif /* JEMALLOC_INTERNAL_CTL_BACKGROUND_THREAD_H */
|
||||
33
include/jemalloc/internal/ctl_config.h
Normal file
33
include/jemalloc/internal/ctl_config.h
Normal file
|
|
@ -0,0 +1,33 @@
|
|||
#ifndef JEMALLOC_INTERNAL_CTL_CONFIG_H
|
||||
#define JEMALLOC_INTERNAL_CTL_CONFIG_H
|
||||
|
||||
#include "jemalloc/internal/ctl_mallctl.h"
|
||||
|
||||
int config_cache_oblivious_ctl(tsd_t *tsd, const size_t *mib, size_t miblen,
|
||||
void *oldp, size_t *oldlenp, void *newp, size_t newlen);
|
||||
int config_debug_ctl(tsd_t *tsd, const size_t *mib, size_t miblen, void *oldp,
|
||||
size_t *oldlenp, void *newp, size_t newlen);
|
||||
int config_fill_ctl(tsd_t *tsd, const size_t *mib, size_t miblen, void *oldp,
|
||||
size_t *oldlenp, void *newp, size_t newlen);
|
||||
int config_lazy_lock_ctl(tsd_t *tsd, const size_t *mib, size_t miblen,
|
||||
void *oldp, size_t *oldlenp, void *newp, size_t newlen);
|
||||
int config_malloc_conf_ctl(tsd_t *tsd, const size_t *mib, size_t miblen,
|
||||
void *oldp, size_t *oldlenp, void *newp, size_t newlen);
|
||||
int config_opt_safety_checks_ctl(tsd_t *tsd, const size_t *mib, size_t miblen,
|
||||
void *oldp, size_t *oldlenp, void *newp, size_t newlen);
|
||||
int config_prof_ctl(tsd_t *tsd, const size_t *mib, size_t miblen, void *oldp,
|
||||
size_t *oldlenp, void *newp, size_t newlen);
|
||||
int config_prof_libgcc_ctl(tsd_t *tsd, const size_t *mib, size_t miblen,
|
||||
void *oldp, size_t *oldlenp, void *newp, size_t newlen);
|
||||
int config_prof_libunwind_ctl(tsd_t *tsd, const size_t *mib, size_t miblen,
|
||||
void *oldp, size_t *oldlenp, void *newp, size_t newlen);
|
||||
int config_prof_frameptr_ctl(tsd_t *tsd, const size_t *mib, size_t miblen,
|
||||
void *oldp, size_t *oldlenp, void *newp, size_t newlen);
|
||||
int config_stats_ctl(tsd_t *tsd, const size_t *mib, size_t miblen, void *oldp,
|
||||
size_t *oldlenp, void *newp, size_t newlen);
|
||||
int config_utrace_ctl(tsd_t *tsd, const size_t *mib, size_t miblen, void *oldp,
|
||||
size_t *oldlenp, void *newp, size_t newlen);
|
||||
int config_xmalloc_ctl(tsd_t *tsd, const size_t *mib, size_t miblen, void *oldp,
|
||||
size_t *oldlenp, void *newp, size_t newlen);
|
||||
|
||||
#endif /* JEMALLOC_INTERNAL_CTL_CONFIG_H */
|
||||
170
include/jemalloc/internal/ctl_mallctl.h
Normal file
170
include/jemalloc/internal/ctl_mallctl.h
Normal file
|
|
@ -0,0 +1,170 @@
|
|||
#ifndef JEMALLOC_INTERNAL_CTL_MALLCTL_H
|
||||
#define JEMALLOC_INTERNAL_CTL_MALLCTL_H
|
||||
|
||||
#include "jemalloc/internal/ctl.h"
|
||||
|
||||
#define READONLY() \
|
||||
do { \
|
||||
if (newp != NULL || newlen != 0) { \
|
||||
ret = EPERM; \
|
||||
goto label_return; \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
#define WRITEONLY() \
|
||||
do { \
|
||||
if (oldp != NULL || oldlenp != NULL) { \
|
||||
ret = EPERM; \
|
||||
goto label_return; \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
/* Can read or write, but not both. */
|
||||
#define READ_XOR_WRITE() \
|
||||
do { \
|
||||
if ((oldp != NULL && oldlenp != NULL) \
|
||||
&& (newp != NULL || newlen != 0)) { \
|
||||
ret = EPERM; \
|
||||
goto label_return; \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
/* Can neither read nor write. */
|
||||
#define NEITHER_READ_NOR_WRITE() \
|
||||
do { \
|
||||
if (oldp != NULL || oldlenp != NULL || newp != NULL \
|
||||
|| newlen != 0) { \
|
||||
ret = EPERM; \
|
||||
goto label_return; \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
/* Verify that the space provided is enough. */
|
||||
#define VERIFY_READ(t) \
|
||||
do { \
|
||||
if (oldp == NULL || oldlenp == NULL \
|
||||
|| *oldlenp != sizeof(t)) { \
|
||||
if (oldlenp != NULL) { \
|
||||
*oldlenp = 0; \
|
||||
} \
|
||||
ret = EINVAL; \
|
||||
goto label_return; \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
#define READ(v, t) \
|
||||
do { \
|
||||
if (oldp != NULL && oldlenp != NULL) { \
|
||||
if (*oldlenp != sizeof(t)) { \
|
||||
size_t copylen = (sizeof(t) <= *oldlenp) \
|
||||
? sizeof(t) \
|
||||
: *oldlenp; \
|
||||
memcpy(oldp, (void *)&(v), copylen); \
|
||||
*oldlenp = copylen; \
|
||||
ret = EINVAL; \
|
||||
goto label_return; \
|
||||
} \
|
||||
*(t *)oldp = (v); \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
#define WRITE(v, t) \
|
||||
do { \
|
||||
if (newp != NULL) { \
|
||||
if (newlen != sizeof(t)) { \
|
||||
ret = EINVAL; \
|
||||
goto label_return; \
|
||||
} \
|
||||
(v) = *(t *)newp; \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
#define ASSURED_WRITE(v, t) \
|
||||
do { \
|
||||
if (newp == NULL || newlen != sizeof(t)) { \
|
||||
ret = EINVAL; \
|
||||
goto label_return; \
|
||||
} \
|
||||
(v) = *(t *)newp; \
|
||||
} while (0)
|
||||
|
||||
#define MIB_UNSIGNED(v, i) \
|
||||
do { \
|
||||
if (mib[i] > UINT_MAX) { \
|
||||
ret = EFAULT; \
|
||||
goto label_return; \
|
||||
} \
|
||||
v = (unsigned)mib[i]; \
|
||||
} while (0)
|
||||
|
||||
#define CTL_RO_NL_GEN_PUBLIC(n, v, t) \
|
||||
int n##_ctl(tsd_t *tsd, const size_t *mib, size_t miblen, \
|
||||
void *oldp, size_t *oldlenp, void *newp, size_t newlen) { \
|
||||
int ret; \
|
||||
t oldval; \
|
||||
\
|
||||
READONLY(); \
|
||||
oldval = (v); \
|
||||
READ(oldval, t); \
|
||||
\
|
||||
ret = 0; \
|
||||
label_return: \
|
||||
return ret; \
|
||||
}
|
||||
|
||||
#define CTL_RO_GEN_PUBLIC(n, v, t) \
|
||||
int n##_ctl(tsd_t *tsd, const size_t *mib, size_t miblen, \
|
||||
void *oldp, size_t *oldlenp, void *newp, size_t newlen) { \
|
||||
int ret; \
|
||||
t oldval; \
|
||||
\
|
||||
READONLY(); \
|
||||
ctl_mtx_lock(tsd_tsdn(tsd)); \
|
||||
oldval = (v); \
|
||||
READ(oldval, t); \
|
||||
\
|
||||
ret = 0; \
|
||||
label_return: \
|
||||
ctl_mtx_unlock(tsd_tsdn(tsd)); \
|
||||
return ret; \
|
||||
}
|
||||
|
||||
#define CTL_RO_NL_CGEN_PUBLIC(c, n, v, t) \
|
||||
int n##_ctl(tsd_t *tsd, const size_t *mib, size_t miblen, \
|
||||
void *oldp, size_t *oldlenp, void *newp, size_t newlen) { \
|
||||
int ret; \
|
||||
t oldval; \
|
||||
\
|
||||
if (!(c)) { \
|
||||
return ENOENT; \
|
||||
} \
|
||||
READONLY(); \
|
||||
oldval = (v); \
|
||||
READ(oldval, t); \
|
||||
\
|
||||
ret = 0; \
|
||||
label_return: \
|
||||
return ret; \
|
||||
}
|
||||
|
||||
#define CTL_RO_CGEN_PUBLIC(c, n, v, t) \
|
||||
int n##_ctl(tsd_t *tsd, const size_t *mib, size_t miblen, \
|
||||
void *oldp, size_t *oldlenp, void *newp, size_t newlen) { \
|
||||
int ret; \
|
||||
t oldval; \
|
||||
\
|
||||
if (!(c)) { \
|
||||
return ENOENT; \
|
||||
} \
|
||||
READONLY(); \
|
||||
ctl_mtx_lock(tsd_tsdn(tsd)); \
|
||||
oldval = (v); \
|
||||
READ(oldval, t); \
|
||||
\
|
||||
ret = 0; \
|
||||
label_return: \
|
||||
ctl_mtx_unlock(tsd_tsdn(tsd)); \
|
||||
return ret; \
|
||||
}
|
||||
|
||||
#endif /* JEMALLOC_INTERNAL_CTL_MALLCTL_H */
|
||||
93
include/jemalloc/internal/ctl_opt.h
Normal file
93
include/jemalloc/internal/ctl_opt.h
Normal file
|
|
@ -0,0 +1,93 @@
|
|||
#ifndef JEMALLOC_INTERNAL_CTL_OPT_H
|
||||
#define JEMALLOC_INTERNAL_CTL_OPT_H
|
||||
|
||||
#include "jemalloc/internal/ctl_mallctl.h"
|
||||
|
||||
#define CTL_OPT_PROTO(n) \
|
||||
int n##_ctl(tsd_t *tsd, const size_t *mib, size_t miblen, \
|
||||
void *oldp, size_t *oldlenp, void *newp, size_t newlen);
|
||||
|
||||
CTL_OPT_PROTO(opt_abort)
|
||||
CTL_OPT_PROTO(opt_abort_conf)
|
||||
CTL_OPT_PROTO(opt_cache_oblivious)
|
||||
CTL_OPT_PROTO(opt_debug_double_free_max_scan)
|
||||
CTL_OPT_PROTO(opt_trust_madvise)
|
||||
CTL_OPT_PROTO(opt_experimental_hpa_start_huge_if_thp_always)
|
||||
CTL_OPT_PROTO(opt_experimental_hpa_enforce_hugify)
|
||||
CTL_OPT_PROTO(opt_confirm_conf)
|
||||
CTL_OPT_PROTO(opt_hpa)
|
||||
CTL_OPT_PROTO(opt_hpa_slab_max_alloc)
|
||||
CTL_OPT_PROTO(opt_hpa_hugification_threshold)
|
||||
CTL_OPT_PROTO(opt_hpa_hugify_delay_ms)
|
||||
CTL_OPT_PROTO(opt_hpa_hugify_sync)
|
||||
CTL_OPT_PROTO(opt_hpa_min_purge_interval_ms)
|
||||
CTL_OPT_PROTO(opt_experimental_hpa_max_purge_nhp)
|
||||
CTL_OPT_PROTO(opt_hpa_purge_threshold)
|
||||
CTL_OPT_PROTO(opt_hpa_min_purge_delay_ms)
|
||||
CTL_OPT_PROTO(opt_hpa_hugify_style)
|
||||
CTL_OPT_PROTO(opt_hpa_dirty_mult)
|
||||
CTL_OPT_PROTO(opt_hpa_sec_nshards)
|
||||
CTL_OPT_PROTO(opt_hpa_sec_max_alloc)
|
||||
CTL_OPT_PROTO(opt_hpa_sec_max_bytes)
|
||||
CTL_OPT_PROTO(opt_huge_arena_pac_thp)
|
||||
CTL_OPT_PROTO(opt_metadata_thp)
|
||||
CTL_OPT_PROTO(opt_retain)
|
||||
CTL_OPT_PROTO(opt_dss)
|
||||
CTL_OPT_PROTO(opt_narenas)
|
||||
CTL_OPT_PROTO(opt_percpu_arena)
|
||||
CTL_OPT_PROTO(opt_oversize_threshold)
|
||||
CTL_OPT_PROTO(opt_background_thread)
|
||||
CTL_OPT_PROTO(opt_mutex_max_spin)
|
||||
CTL_OPT_PROTO(opt_max_background_threads)
|
||||
CTL_OPT_PROTO(opt_dirty_decay_ms)
|
||||
CTL_OPT_PROTO(opt_muzzy_decay_ms)
|
||||
CTL_OPT_PROTO(opt_stats_print)
|
||||
CTL_OPT_PROTO(opt_stats_print_opts)
|
||||
CTL_OPT_PROTO(opt_stats_interval)
|
||||
CTL_OPT_PROTO(opt_stats_interval_opts)
|
||||
CTL_OPT_PROTO(opt_junk)
|
||||
CTL_OPT_PROTO(opt_zero)
|
||||
CTL_OPT_PROTO(opt_utrace)
|
||||
CTL_OPT_PROTO(opt_xmalloc)
|
||||
CTL_OPT_PROTO(opt_experimental_infallible_new)
|
||||
CTL_OPT_PROTO(opt_experimental_tcache_gc)
|
||||
CTL_OPT_PROTO(opt_tcache)
|
||||
CTL_OPT_PROTO(opt_tcache_max)
|
||||
CTL_OPT_PROTO(opt_tcache_nslots_small_min)
|
||||
CTL_OPT_PROTO(opt_tcache_nslots_small_max)
|
||||
CTL_OPT_PROTO(opt_tcache_nslots_large)
|
||||
CTL_OPT_PROTO(opt_lg_tcache_nslots_mul)
|
||||
CTL_OPT_PROTO(opt_tcache_gc_incr_bytes)
|
||||
CTL_OPT_PROTO(opt_tcache_gc_delay_bytes)
|
||||
CTL_OPT_PROTO(opt_lg_tcache_flush_small_div)
|
||||
CTL_OPT_PROTO(opt_lg_tcache_flush_large_div)
|
||||
CTL_OPT_PROTO(opt_thp)
|
||||
CTL_OPT_PROTO(opt_lg_extent_max_active_fit)
|
||||
CTL_OPT_PROTO(opt_prof)
|
||||
CTL_OPT_PROTO(opt_prof_prefix)
|
||||
CTL_OPT_PROTO(opt_prof_active)
|
||||
CTL_OPT_PROTO(opt_prof_thread_active_init)
|
||||
CTL_OPT_PROTO(opt_prof_bt_max)
|
||||
CTL_OPT_PROTO(opt_lg_prof_sample)
|
||||
CTL_OPT_PROTO(opt_lg_prof_interval)
|
||||
CTL_OPT_PROTO(opt_prof_gdump)
|
||||
CTL_OPT_PROTO(opt_prof_final)
|
||||
CTL_OPT_PROTO(opt_prof_leak)
|
||||
CTL_OPT_PROTO(opt_prof_leak_error)
|
||||
CTL_OPT_PROTO(opt_prof_accum)
|
||||
CTL_OPT_PROTO(opt_prof_pid_namespace)
|
||||
CTL_OPT_PROTO(opt_prof_recent_alloc_max)
|
||||
CTL_OPT_PROTO(opt_prof_stats)
|
||||
CTL_OPT_PROTO(opt_prof_sys_thread_name)
|
||||
CTL_OPT_PROTO(opt_prof_time_res)
|
||||
CTL_OPT_PROTO(opt_lg_san_uaf_align)
|
||||
CTL_OPT_PROTO(opt_zero_realloc)
|
||||
CTL_OPT_PROTO(opt_disable_large_size_classes)
|
||||
CTL_OPT_PROTO(opt_process_madvise_max_batch)
|
||||
CTL_OPT_PROTO(opt_malloc_conf_symlink)
|
||||
CTL_OPT_PROTO(opt_malloc_conf_env_var)
|
||||
CTL_OPT_PROTO(opt_malloc_conf_global_var)
|
||||
|
||||
#undef CTL_OPT_PROTO
|
||||
|
||||
#endif /* JEMALLOC_INTERNAL_CTL_OPT_H */
|
||||
33
include/jemalloc/internal/ctl_prof.h
Normal file
33
include/jemalloc/internal/ctl_prof.h
Normal file
|
|
@ -0,0 +1,33 @@
|
|||
#ifndef JEMALLOC_INTERNAL_CTL_PROF_H
|
||||
#define JEMALLOC_INTERNAL_CTL_PROF_H
|
||||
|
||||
#include "jemalloc/internal/ctl_mallctl.h"
|
||||
|
||||
#define CTL_PROF_PROTO(n) \
|
||||
int n##_ctl(tsd_t *tsd, const size_t *mib, size_t miblen, \
|
||||
void *oldp, size_t *oldlenp, void *newp, size_t newlen);
|
||||
|
||||
CTL_PROF_PROTO(prof_thread_active_init)
|
||||
CTL_PROF_PROTO(prof_active)
|
||||
CTL_PROF_PROTO(prof_dump)
|
||||
CTL_PROF_PROTO(prof_gdump)
|
||||
CTL_PROF_PROTO(prof_prefix)
|
||||
CTL_PROF_PROTO(prof_reset)
|
||||
CTL_PROF_PROTO(prof_interval)
|
||||
CTL_PROF_PROTO(lg_prof_sample)
|
||||
CTL_PROF_PROTO(prof_log_start)
|
||||
CTL_PROF_PROTO(prof_log_stop)
|
||||
CTL_PROF_PROTO(prof_stats_bins_i_live)
|
||||
CTL_PROF_PROTO(prof_stats_bins_i_accum)
|
||||
CTL_PROF_PROTO(prof_stats_lextents_i_live)
|
||||
CTL_PROF_PROTO(prof_stats_lextents_i_accum)
|
||||
CTL_PROF_PROTO(experimental_hooks_prof_backtrace)
|
||||
CTL_PROF_PROTO(experimental_hooks_prof_dump)
|
||||
CTL_PROF_PROTO(experimental_hooks_prof_sample)
|
||||
CTL_PROF_PROTO(experimental_hooks_prof_sample_free)
|
||||
CTL_PROF_PROTO(experimental_prof_recent_alloc_max)
|
||||
CTL_PROF_PROTO(experimental_prof_recent_alloc_dump)
|
||||
|
||||
#undef CTL_PROF_PROTO
|
||||
|
||||
#endif /* JEMALLOC_INTERNAL_CTL_PROF_H */
|
||||
179
include/jemalloc/internal/ctl_stats.h
Normal file
179
include/jemalloc/internal/ctl_stats.h
Normal file
|
|
@ -0,0 +1,179 @@
|
|||
#ifndef JEMALLOC_INTERNAL_CTL_STATS_H
|
||||
#define JEMALLOC_INTERNAL_CTL_STATS_H
|
||||
|
||||
#include "jemalloc/internal/ctl_mallctl.h"
|
||||
|
||||
#define CTL_STATS_PROTO(n) \
|
||||
int n##_ctl(tsd_t *tsd, const size_t *mib, size_t miblen, \
|
||||
void *oldp, size_t *oldlenp, void *newp, size_t newlen);
|
||||
|
||||
CTL_STATS_PROTO(stats_arenas_i_small_allocated)
|
||||
CTL_STATS_PROTO(stats_arenas_i_small_nmalloc)
|
||||
CTL_STATS_PROTO(stats_arenas_i_small_ndalloc)
|
||||
CTL_STATS_PROTO(stats_arenas_i_small_nrequests)
|
||||
CTL_STATS_PROTO(stats_arenas_i_small_nfills)
|
||||
CTL_STATS_PROTO(stats_arenas_i_small_nflushes)
|
||||
CTL_STATS_PROTO(stats_arenas_i_large_allocated)
|
||||
CTL_STATS_PROTO(stats_arenas_i_large_nmalloc)
|
||||
CTL_STATS_PROTO(stats_arenas_i_large_ndalloc)
|
||||
CTL_STATS_PROTO(stats_arenas_i_large_nrequests)
|
||||
CTL_STATS_PROTO(stats_arenas_i_large_nfills)
|
||||
CTL_STATS_PROTO(stats_arenas_i_large_nflushes)
|
||||
CTL_STATS_PROTO(stats_arenas_i_bins_j_nmalloc)
|
||||
CTL_STATS_PROTO(stats_arenas_i_bins_j_ndalloc)
|
||||
CTL_STATS_PROTO(stats_arenas_i_bins_j_nrequests)
|
||||
CTL_STATS_PROTO(stats_arenas_i_bins_j_curregs)
|
||||
CTL_STATS_PROTO(stats_arenas_i_bins_j_nfills)
|
||||
CTL_STATS_PROTO(stats_arenas_i_bins_j_nflushes)
|
||||
CTL_STATS_PROTO(stats_arenas_i_bins_j_nslabs)
|
||||
CTL_STATS_PROTO(stats_arenas_i_bins_j_nreslabs)
|
||||
CTL_STATS_PROTO(stats_arenas_i_bins_j_curslabs)
|
||||
CTL_STATS_PROTO(stats_arenas_i_bins_j_nonfull_slabs)
|
||||
CTL_STATS_PROTO(stats_arenas_i_lextents_j_nmalloc)
|
||||
CTL_STATS_PROTO(stats_arenas_i_lextents_j_ndalloc)
|
||||
CTL_STATS_PROTO(stats_arenas_i_lextents_j_nrequests)
|
||||
CTL_STATS_PROTO(stats_arenas_i_lextents_j_curlextents)
|
||||
CTL_STATS_PROTO(stats_arenas_i_extents_j_ndirty)
|
||||
CTL_STATS_PROTO(stats_arenas_i_extents_j_nmuzzy)
|
||||
CTL_STATS_PROTO(stats_arenas_i_extents_j_nretained)
|
||||
CTL_STATS_PROTO(stats_arenas_i_extents_j_npinned)
|
||||
CTL_STATS_PROTO(stats_arenas_i_extents_j_dirty_bytes)
|
||||
CTL_STATS_PROTO(stats_arenas_i_extents_j_muzzy_bytes)
|
||||
CTL_STATS_PROTO(stats_arenas_i_extents_j_retained_bytes)
|
||||
CTL_STATS_PROTO(stats_arenas_i_extents_j_pinned_bytes)
|
||||
|
||||
/* Merged set of stats for HPA shard. */
|
||||
CTL_STATS_PROTO(stats_arenas_i_hpa_shard_npageslabs)
|
||||
CTL_STATS_PROTO(stats_arenas_i_hpa_shard_nactive)
|
||||
CTL_STATS_PROTO(stats_arenas_i_hpa_shard_ndirty)
|
||||
|
||||
CTL_STATS_PROTO(stats_arenas_i_hpa_shard_npurge_passes)
|
||||
CTL_STATS_PROTO(stats_arenas_i_hpa_shard_npurges)
|
||||
CTL_STATS_PROTO(stats_arenas_i_hpa_shard_nhugifies)
|
||||
CTL_STATS_PROTO(stats_arenas_i_hpa_shard_nhugify_failures)
|
||||
CTL_STATS_PROTO(stats_arenas_i_hpa_shard_ndehugifies)
|
||||
|
||||
/* Set of stats for non-hugified and hugified slabs. */
|
||||
CTL_STATS_PROTO(stats_arenas_i_hpa_shard_slabs_npageslabs_nonhuge)
|
||||
CTL_STATS_PROTO(stats_arenas_i_hpa_shard_slabs_npageslabs_huge)
|
||||
CTL_STATS_PROTO(stats_arenas_i_hpa_shard_slabs_nactive_nonhuge)
|
||||
CTL_STATS_PROTO(stats_arenas_i_hpa_shard_slabs_nactive_huge)
|
||||
CTL_STATS_PROTO(stats_arenas_i_hpa_shard_slabs_ndirty_nonhuge)
|
||||
CTL_STATS_PROTO(stats_arenas_i_hpa_shard_slabs_ndirty_huge)
|
||||
|
||||
/* A parallel set of stats for full slabs. */
|
||||
CTL_STATS_PROTO(stats_arenas_i_hpa_shard_full_slabs_npageslabs_nonhuge)
|
||||
CTL_STATS_PROTO(stats_arenas_i_hpa_shard_full_slabs_npageslabs_huge)
|
||||
CTL_STATS_PROTO(stats_arenas_i_hpa_shard_full_slabs_nactive_nonhuge)
|
||||
CTL_STATS_PROTO(stats_arenas_i_hpa_shard_full_slabs_nactive_huge)
|
||||
CTL_STATS_PROTO(stats_arenas_i_hpa_shard_full_slabs_ndirty_nonhuge)
|
||||
CTL_STATS_PROTO(stats_arenas_i_hpa_shard_full_slabs_ndirty_huge)
|
||||
|
||||
/* A parallel set for the empty slabs. */
|
||||
CTL_STATS_PROTO(stats_arenas_i_hpa_shard_empty_slabs_npageslabs_nonhuge)
|
||||
CTL_STATS_PROTO(stats_arenas_i_hpa_shard_empty_slabs_npageslabs_huge)
|
||||
CTL_STATS_PROTO(stats_arenas_i_hpa_shard_empty_slabs_nactive_nonhuge)
|
||||
CTL_STATS_PROTO(stats_arenas_i_hpa_shard_empty_slabs_nactive_huge)
|
||||
CTL_STATS_PROTO(stats_arenas_i_hpa_shard_empty_slabs_ndirty_nonhuge)
|
||||
CTL_STATS_PROTO(stats_arenas_i_hpa_shard_empty_slabs_ndirty_huge)
|
||||
|
||||
/*
|
||||
* And one for the slabs that are neither empty nor full, but indexed by how
|
||||
* full they are.
|
||||
*/
|
||||
CTL_STATS_PROTO(stats_arenas_i_hpa_shard_nonfull_slabs_j_npageslabs_nonhuge)
|
||||
CTL_STATS_PROTO(stats_arenas_i_hpa_shard_nonfull_slabs_j_npageslabs_huge)
|
||||
CTL_STATS_PROTO(stats_arenas_i_hpa_shard_nonfull_slabs_j_nactive_nonhuge)
|
||||
CTL_STATS_PROTO(stats_arenas_i_hpa_shard_nonfull_slabs_j_nactive_huge)
|
||||
CTL_STATS_PROTO(stats_arenas_i_hpa_shard_nonfull_slabs_j_ndirty_nonhuge)
|
||||
CTL_STATS_PROTO(stats_arenas_i_hpa_shard_nonfull_slabs_j_ndirty_huge)
|
||||
|
||||
CTL_STATS_PROTO(stats_arenas_i_hpa_shard_alloc_j_min_extents)
|
||||
CTL_STATS_PROTO(stats_arenas_i_hpa_shard_alloc_j_max_extents)
|
||||
CTL_STATS_PROTO(stats_arenas_i_hpa_shard_alloc_j_extents)
|
||||
CTL_STATS_PROTO(stats_arenas_i_hpa_shard_alloc_j_ps)
|
||||
CTL_STATS_PROTO(stats_arenas_i_hpa_shard_alloc_j_pages_per_ps)
|
||||
CTL_STATS_PROTO(stats_arenas_i_hpa_shard_alloc_j_extents_per_ps)
|
||||
CTL_STATS_PROTO(stats_arenas_i_hpa_shard_alloc_j_total_elapsed_ns_per_ps)
|
||||
|
||||
CTL_STATS_PROTO(stats_arenas_i_nthreads)
|
||||
CTL_STATS_PROTO(stats_arenas_i_uptime)
|
||||
CTL_STATS_PROTO(stats_arenas_i_dss)
|
||||
CTL_STATS_PROTO(stats_arenas_i_dirty_decay_ms)
|
||||
CTL_STATS_PROTO(stats_arenas_i_muzzy_decay_ms)
|
||||
CTL_STATS_PROTO(stats_arenas_i_pactive)
|
||||
CTL_STATS_PROTO(stats_arenas_i_pdirty)
|
||||
CTL_STATS_PROTO(stats_arenas_i_pmuzzy)
|
||||
CTL_STATS_PROTO(stats_arenas_i_mapped)
|
||||
CTL_STATS_PROTO(stats_arenas_i_retained)
|
||||
CTL_STATS_PROTO(stats_arenas_i_pinned)
|
||||
CTL_STATS_PROTO(stats_arenas_i_extent_avail)
|
||||
CTL_STATS_PROTO(stats_arenas_i_dirty_npurge)
|
||||
CTL_STATS_PROTO(stats_arenas_i_dirty_nmadvise)
|
||||
CTL_STATS_PROTO(stats_arenas_i_dirty_purged)
|
||||
CTL_STATS_PROTO(stats_arenas_i_muzzy_npurge)
|
||||
CTL_STATS_PROTO(stats_arenas_i_muzzy_nmadvise)
|
||||
CTL_STATS_PROTO(stats_arenas_i_muzzy_purged)
|
||||
CTL_STATS_PROTO(stats_arenas_i_base)
|
||||
CTL_STATS_PROTO(stats_arenas_i_internal)
|
||||
CTL_STATS_PROTO(stats_arenas_i_metadata_edata)
|
||||
CTL_STATS_PROTO(stats_arenas_i_metadata_rtree)
|
||||
CTL_STATS_PROTO(stats_arenas_i_metadata_thp)
|
||||
CTL_STATS_PROTO(stats_arenas_i_tcache_bytes)
|
||||
CTL_STATS_PROTO(stats_arenas_i_tcache_stashed_bytes)
|
||||
CTL_STATS_PROTO(stats_arenas_i_resident)
|
||||
CTL_STATS_PROTO(stats_arenas_i_abandoned_vm)
|
||||
CTL_STATS_PROTO(stats_arenas_i_hpa_sec_bytes)
|
||||
CTL_STATS_PROTO(stats_arenas_i_hpa_sec_hits)
|
||||
CTL_STATS_PROTO(stats_arenas_i_hpa_sec_misses)
|
||||
CTL_STATS_PROTO(stats_arenas_i_hpa_sec_dalloc_flush)
|
||||
CTL_STATS_PROTO(stats_arenas_i_hpa_sec_dalloc_noflush)
|
||||
CTL_STATS_PROTO(stats_arenas_i_hpa_sec_overfills)
|
||||
CTL_STATS_PROTO(stats_allocated)
|
||||
CTL_STATS_PROTO(stats_active)
|
||||
CTL_STATS_PROTO(stats_background_thread_num_threads)
|
||||
CTL_STATS_PROTO(stats_background_thread_num_runs)
|
||||
CTL_STATS_PROTO(stats_background_thread_run_interval)
|
||||
CTL_STATS_PROTO(stats_metadata)
|
||||
CTL_STATS_PROTO(stats_metadata_edata)
|
||||
CTL_STATS_PROTO(stats_metadata_rtree)
|
||||
CTL_STATS_PROTO(stats_metadata_thp)
|
||||
CTL_STATS_PROTO(stats_resident)
|
||||
CTL_STATS_PROTO(stats_mapped)
|
||||
CTL_STATS_PROTO(stats_retained)
|
||||
CTL_STATS_PROTO(stats_pinned)
|
||||
CTL_STATS_PROTO(stats_zero_reallocs)
|
||||
CTL_STATS_PROTO(approximate_stats_active)
|
||||
|
||||
#define MUTEX_STATS_CTL_PROTO_GEN(n) \
|
||||
CTL_STATS_PROTO(stats_##n##_num_ops) \
|
||||
CTL_STATS_PROTO(stats_##n##_num_wait) \
|
||||
CTL_STATS_PROTO(stats_##n##_num_spin_acq) \
|
||||
CTL_STATS_PROTO(stats_##n##_num_owner_switch) \
|
||||
CTL_STATS_PROTO(stats_##n##_total_wait_time) \
|
||||
CTL_STATS_PROTO(stats_##n##_max_wait_time) \
|
||||
CTL_STATS_PROTO(stats_##n##_max_num_thds)
|
||||
|
||||
/* Global mutexes. */
|
||||
#define OP(mtx) MUTEX_STATS_CTL_PROTO_GEN(mutexes_##mtx)
|
||||
MUTEX_PROF_GLOBAL_MUTEXES
|
||||
#undef OP
|
||||
|
||||
/* Per arena mutexes. */
|
||||
#define OP(mtx) MUTEX_STATS_CTL_PROTO_GEN(arenas_i_mutexes_##mtx)
|
||||
MUTEX_PROF_ARENA_MUTEXES
|
||||
#undef OP
|
||||
|
||||
/* Arena bin mutexes. */
|
||||
MUTEX_STATS_CTL_PROTO_GEN(arenas_i_bins_j_mutex)
|
||||
#undef MUTEX_STATS_CTL_PROTO_GEN
|
||||
|
||||
CTL_STATS_PROTO(stats_mutexes_reset)
|
||||
|
||||
|
||||
#undef CTL_STATS_PROTO
|
||||
|
||||
bool ctl_stats_init(tsdn_t *tsdn);
|
||||
void ctl_stats_refresh(tsdn_t *tsdn, ctl_arena_t *ctl_sarena);
|
||||
|
||||
#endif /* JEMALLOC_INTERNAL_CTL_STATS_H */
|
||||
13
include/jemalloc/internal/ctl_tcache.h
Normal file
13
include/jemalloc/internal/ctl_tcache.h
Normal file
|
|
@ -0,0 +1,13 @@
|
|||
#ifndef JEMALLOC_INTERNAL_CTL_TCACHE_H
|
||||
#define JEMALLOC_INTERNAL_CTL_TCACHE_H
|
||||
|
||||
#include "jemalloc/internal/ctl_mallctl.h"
|
||||
|
||||
int tcache_create_ctl(tsd_t *tsd, const size_t *mib, size_t miblen, void *oldp,
|
||||
size_t *oldlenp, void *newp, size_t newlen);
|
||||
int tcache_flush_ctl(tsd_t *tsd, const size_t *mib, size_t miblen, void *oldp,
|
||||
size_t *oldlenp, void *newp, size_t newlen);
|
||||
int tcache_destroy_ctl(tsd_t *tsd, const size_t *mib, size_t miblen, void *oldp,
|
||||
size_t *oldlenp, void *newp, size_t newlen);
|
||||
|
||||
#endif /* JEMALLOC_INTERNAL_CTL_TCACHE_H */
|
||||
39
include/jemalloc/internal/ctl_thread.h
Normal file
39
include/jemalloc/internal/ctl_thread.h
Normal file
|
|
@ -0,0 +1,39 @@
|
|||
#ifndef JEMALLOC_INTERNAL_CTL_THREAD_H
|
||||
#define JEMALLOC_INTERNAL_CTL_THREAD_H
|
||||
|
||||
#include "jemalloc/internal/ctl_mallctl.h"
|
||||
|
||||
int thread_tcache_enabled_ctl(tsd_t *tsd, const size_t *mib, size_t miblen,
|
||||
void *oldp, size_t *oldlenp, void *newp, size_t newlen);
|
||||
int thread_tcache_max_ctl(tsd_t *tsd, const size_t *mib, size_t miblen,
|
||||
void *oldp, size_t *oldlenp, void *newp, size_t newlen);
|
||||
int thread_tcache_flush_ctl(tsd_t *tsd, const size_t *mib, size_t miblen,
|
||||
void *oldp, size_t *oldlenp, void *newp, size_t newlen);
|
||||
int thread_tcache_ncached_max_write_ctl(tsd_t *tsd, const size_t *mib,
|
||||
size_t miblen, void *oldp, size_t *oldlenp, void *newp, size_t newlen);
|
||||
int thread_tcache_ncached_max_read_sizeclass_ctl(tsd_t *tsd, const size_t *mib,
|
||||
size_t miblen, void *oldp, size_t *oldlenp, void *newp, size_t newlen);
|
||||
int thread_peak_read_ctl(tsd_t *tsd, const size_t *mib, size_t miblen,
|
||||
void *oldp, size_t *oldlenp, void *newp, size_t newlen);
|
||||
int thread_peak_reset_ctl(tsd_t *tsd, const size_t *mib, size_t miblen,
|
||||
void *oldp, size_t *oldlenp, void *newp, size_t newlen);
|
||||
int thread_prof_name_ctl(tsd_t *tsd, const size_t *mib, size_t miblen,
|
||||
void *oldp, size_t *oldlenp, void *newp, size_t newlen);
|
||||
int thread_prof_active_ctl(tsd_t *tsd, const size_t *mib, size_t miblen,
|
||||
void *oldp, size_t *oldlenp, void *newp, size_t newlen);
|
||||
int thread_arena_ctl(tsd_t *tsd, const size_t *mib, size_t miblen, void *oldp,
|
||||
size_t *oldlenp, void *newp, size_t newlen);
|
||||
int thread_allocated_ctl(tsd_t *tsd, const size_t *mib, size_t miblen,
|
||||
void *oldp, size_t *oldlenp, void *newp, size_t newlen);
|
||||
int thread_allocatedp_ctl(tsd_t *tsd, const size_t *mib, size_t miblen,
|
||||
void *oldp, size_t *oldlenp, void *newp, size_t newlen);
|
||||
int thread_deallocated_ctl(tsd_t *tsd, const size_t *mib, size_t miblen,
|
||||
void *oldp, size_t *oldlenp, void *newp, size_t newlen);
|
||||
int thread_deallocatedp_ctl(tsd_t *tsd, const size_t *mib, size_t miblen,
|
||||
void *oldp, size_t *oldlenp, void *newp, size_t newlen);
|
||||
int thread_idle_ctl(tsd_t *tsd, const size_t *mib, size_t miblen, void *oldp,
|
||||
size_t *oldlenp, void *newp, size_t newlen);
|
||||
int experimental_hooks_thread_event_ctl(tsd_t *tsd, const size_t *mib,
|
||||
size_t miblen, void *oldp, size_t *oldlenp, void *newp, size_t newlen);
|
||||
|
||||
#endif /* JEMALLOC_INTERNAL_CTL_THREAD_H */
|
||||
9
include/jemalloc/internal/ctl_utilization.h
Normal file
9
include/jemalloc/internal/ctl_utilization.h
Normal file
|
|
@ -0,0 +1,9 @@
|
|||
#ifndef JEMALLOC_INTERNAL_CTL_UTILIZATION_H
|
||||
#define JEMALLOC_INTERNAL_CTL_UTILIZATION_H
|
||||
|
||||
#include "jemalloc/internal/ctl_mallctl.h"
|
||||
|
||||
int experimental_utilization_batch_query_ctl(tsd_t *tsd, const size_t *mib,
|
||||
size_t miblen, void *oldp, size_t *oldlenp, void *newp, size_t newlen);
|
||||
|
||||
#endif /* JEMALLOC_INTERNAL_CTL_UTILIZATION_H */
|
||||
|
|
@ -12,7 +12,7 @@
|
|||
|
||||
/*
|
||||
* The following struct is for experimental purposes. See
|
||||
* experimental_utilization_batch_query_ctl in src/ctl.c.
|
||||
* experimental_utilization_batch_query_ctl in src/ctl_utilization.c.
|
||||
*/
|
||||
typedef struct inspect_extent_util_stats_s inspect_extent_util_stats_t;
|
||||
struct inspect_extent_util_stats_s {
|
||||
|
|
|
|||
|
|
@ -48,6 +48,15 @@
|
|||
<ClCompile Include="..\..\..\..\src\conf.c" />
|
||||
<ClCompile Include="..\..\..\..\src\counter.c" />
|
||||
<ClCompile Include="..\..\..\..\src\ctl.c" />
|
||||
<ClCompile Include="..\..\..\..\src\ctl_arena.c" />
|
||||
<ClCompile Include="..\..\..\..\src\ctl_background_thread.c" />
|
||||
<ClCompile Include="..\..\..\..\src\ctl_config.c" />
|
||||
<ClCompile Include="..\..\..\..\src\ctl_opt.c" />
|
||||
<ClCompile Include="..\..\..\..\src\ctl_prof.c" />
|
||||
<ClCompile Include="..\..\..\..\src\ctl_stats.c" />
|
||||
<ClCompile Include="..\..\..\..\src\ctl_thread.c" />
|
||||
<ClCompile Include="..\..\..\..\src\ctl_tcache.c" />
|
||||
<ClCompile Include="..\..\..\..\src\ctl_utilization.c" />
|
||||
<ClCompile Include="..\..\..\..\src\decay.c" />
|
||||
<ClCompile Include="..\..\..\..\src\div.c" />
|
||||
<ClCompile Include="..\..\..\..\src\ecache.c" />
|
||||
|
|
|
|||
|
|
@ -40,6 +40,33 @@
|
|||
<ClCompile Include="..\..\..\..\src\ctl.c">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\..\..\src\ctl_arena.c">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\..\..\src\ctl_background_thread.c">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\..\..\src\ctl_config.c">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\..\..\src\ctl_opt.c">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\..\..\src\ctl_prof.c">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\..\..\src\ctl_stats.c">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\..\..\src\ctl_thread.c">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\..\..\src\ctl_tcache.c">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\..\..\src\ctl_utilization.c">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\..\..\src\decay.c">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
|
|
|
|||
|
|
@ -48,6 +48,15 @@
|
|||
<ClCompile Include="..\..\..\..\src\conf.c" />
|
||||
<ClCompile Include="..\..\..\..\src\counter.c" />
|
||||
<ClCompile Include="..\..\..\..\src\ctl.c" />
|
||||
<ClCompile Include="..\..\..\..\src\ctl_arena.c" />
|
||||
<ClCompile Include="..\..\..\..\src\ctl_background_thread.c" />
|
||||
<ClCompile Include="..\..\..\..\src\ctl_config.c" />
|
||||
<ClCompile Include="..\..\..\..\src\ctl_opt.c" />
|
||||
<ClCompile Include="..\..\..\..\src\ctl_prof.c" />
|
||||
<ClCompile Include="..\..\..\..\src\ctl_stats.c" />
|
||||
<ClCompile Include="..\..\..\..\src\ctl_thread.c" />
|
||||
<ClCompile Include="..\..\..\..\src\ctl_tcache.c" />
|
||||
<ClCompile Include="..\..\..\..\src\ctl_utilization.c" />
|
||||
<ClCompile Include="..\..\..\..\src\decay.c" />
|
||||
<ClCompile Include="..\..\..\..\src\div.c" />
|
||||
<ClCompile Include="..\..\..\..\src\ecache.c" />
|
||||
|
|
|
|||
|
|
@ -40,6 +40,33 @@
|
|||
<ClCompile Include="..\..\..\..\src\ctl.c">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\..\..\src\ctl_arena.c">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\..\..\src\ctl_background_thread.c">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\..\..\src\ctl_config.c">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\..\..\src\ctl_opt.c">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\..\..\src\ctl_prof.c">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\..\..\src\ctl_stats.c">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\..\..\src\ctl_thread.c">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\..\..\src\ctl_tcache.c">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\..\..\src\ctl_utilization.c">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\..\..\src\decay.c">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
|
|
|
|||
|
|
@ -48,6 +48,15 @@
|
|||
<ClCompile Include="..\..\..\..\src\conf.c" />
|
||||
<ClCompile Include="..\..\..\..\src\counter.c" />
|
||||
<ClCompile Include="..\..\..\..\src\ctl.c" />
|
||||
<ClCompile Include="..\..\..\..\src\ctl_arena.c" />
|
||||
<ClCompile Include="..\..\..\..\src\ctl_background_thread.c" />
|
||||
<ClCompile Include="..\..\..\..\src\ctl_config.c" />
|
||||
<ClCompile Include="..\..\..\..\src\ctl_opt.c" />
|
||||
<ClCompile Include="..\..\..\..\src\ctl_prof.c" />
|
||||
<ClCompile Include="..\..\..\..\src\ctl_stats.c" />
|
||||
<ClCompile Include="..\..\..\..\src\ctl_thread.c" />
|
||||
<ClCompile Include="..\..\..\..\src\ctl_tcache.c" />
|
||||
<ClCompile Include="..\..\..\..\src\ctl_utilization.c" />
|
||||
<ClCompile Include="..\..\..\..\src\decay.c" />
|
||||
<ClCompile Include="..\..\..\..\src\div.c" />
|
||||
<ClCompile Include="..\..\..\..\src\ecache.c" />
|
||||
|
|
|
|||
|
|
@ -40,6 +40,33 @@
|
|||
<ClCompile Include="..\..\..\..\src\ctl.c">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\..\..\src\ctl_arena.c">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\..\..\src\ctl_background_thread.c">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\..\..\src\ctl_config.c">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\..\..\src\ctl_opt.c">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\..\..\src\ctl_prof.c">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\..\..\src\ctl_stats.c">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\..\..\src\ctl_thread.c">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\..\..\src\ctl_tcache.c">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\..\..\src\ctl_utilization.c">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\..\..\src\decay.c">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
|
|
|
|||
|
|
@ -48,6 +48,15 @@
|
|||
<ClCompile Include="..\..\..\..\src\conf.c" />
|
||||
<ClCompile Include="..\..\..\..\src\counter.c" />
|
||||
<ClCompile Include="..\..\..\..\src\ctl.c" />
|
||||
<ClCompile Include="..\..\..\..\src\ctl_arena.c" />
|
||||
<ClCompile Include="..\..\..\..\src\ctl_background_thread.c" />
|
||||
<ClCompile Include="..\..\..\..\src\ctl_config.c" />
|
||||
<ClCompile Include="..\..\..\..\src\ctl_opt.c" />
|
||||
<ClCompile Include="..\..\..\..\src\ctl_prof.c" />
|
||||
<ClCompile Include="..\..\..\..\src\ctl_stats.c" />
|
||||
<ClCompile Include="..\..\..\..\src\ctl_thread.c" />
|
||||
<ClCompile Include="..\..\..\..\src\ctl_tcache.c" />
|
||||
<ClCompile Include="..\..\..\..\src\ctl_utilization.c" />
|
||||
<ClCompile Include="..\..\..\..\src\decay.c" />
|
||||
<ClCompile Include="..\..\..\..\src\div.c" />
|
||||
<ClCompile Include="..\..\..\..\src\ecache.c" />
|
||||
|
|
|
|||
|
|
@ -40,6 +40,33 @@
|
|||
<ClCompile Include="..\..\..\..\src\ctl.c">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\..\..\src\ctl_arena.c">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\..\..\src\ctl_background_thread.c">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\..\..\src\ctl_config.c">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\..\..\src\ctl_opt.c">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\..\..\src\ctl_prof.c">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\..\..\src\ctl_stats.c">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\..\..\src\ctl_thread.c">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\..\..\src\ctl_tcache.c">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\..\..\src\ctl_utilization.c">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\..\..\src\decay.c">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
|
|
|
|||
1143
src/ctl_arena.c
Normal file
1143
src/ctl_arena.c
Normal file
File diff suppressed because it is too large
Load diff
118
src/ctl_background_thread.c
Normal file
118
src/ctl_background_thread.c
Normal file
|
|
@ -0,0 +1,118 @@
|
|||
#include "jemalloc/internal/jemalloc_preamble.h"
|
||||
#include "jemalloc/internal/jemalloc_internal_includes.h"
|
||||
|
||||
#include "jemalloc/internal/background_thread_externs.h"
|
||||
#include "jemalloc/internal/background_thread_inlines.h"
|
||||
#include "jemalloc/internal/ctl_background_thread.h"
|
||||
|
||||
/******************************************************************************/
|
||||
/* background_thread mallctl handlers. */
|
||||
|
||||
int
|
||||
background_thread_ctl(tsd_t *tsd, const size_t *mib, size_t miblen, void *oldp,
|
||||
size_t *oldlenp, void *newp, size_t newlen) {
|
||||
int ret;
|
||||
bool oldval;
|
||||
|
||||
if (!have_background_thread) {
|
||||
return ENOENT;
|
||||
}
|
||||
background_thread_ctl_init(tsd_tsdn(tsd));
|
||||
|
||||
ctl_mtx_lock(tsd_tsdn(tsd));
|
||||
malloc_mutex_lock(tsd_tsdn(tsd), &background_thread_lock);
|
||||
if (newp == NULL) {
|
||||
oldval = background_thread_enabled();
|
||||
READ(oldval, bool);
|
||||
} else {
|
||||
if (newlen != sizeof(bool)) {
|
||||
ret = EINVAL;
|
||||
goto label_return;
|
||||
}
|
||||
oldval = background_thread_enabled();
|
||||
READ(oldval, bool);
|
||||
|
||||
bool newval = *(bool *)newp;
|
||||
if (newval == oldval) {
|
||||
ret = 0;
|
||||
goto label_return;
|
||||
}
|
||||
|
||||
background_thread_enabled_set(tsd_tsdn(tsd), newval);
|
||||
if (newval) {
|
||||
if (background_threads_enable(tsd)) {
|
||||
ret = EFAULT;
|
||||
goto label_return;
|
||||
}
|
||||
} else {
|
||||
if (background_threads_disable(tsd)) {
|
||||
ret = EFAULT;
|
||||
goto label_return;
|
||||
}
|
||||
}
|
||||
}
|
||||
ret = 0;
|
||||
label_return:
|
||||
malloc_mutex_unlock(tsd_tsdn(tsd), &background_thread_lock);
|
||||
ctl_mtx_unlock(tsd_tsdn(tsd));
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int
|
||||
max_background_threads_ctl(tsd_t *tsd, const size_t *mib, size_t miblen,
|
||||
void *oldp, size_t *oldlenp, void *newp, size_t newlen) {
|
||||
int ret;
|
||||
size_t oldval;
|
||||
|
||||
if (!have_background_thread) {
|
||||
return ENOENT;
|
||||
}
|
||||
background_thread_ctl_init(tsd_tsdn(tsd));
|
||||
|
||||
ctl_mtx_lock(tsd_tsdn(tsd));
|
||||
malloc_mutex_lock(tsd_tsdn(tsd), &background_thread_lock);
|
||||
if (newp == NULL) {
|
||||
oldval = max_background_threads;
|
||||
READ(oldval, size_t);
|
||||
} else {
|
||||
if (newlen != sizeof(size_t)) {
|
||||
ret = EINVAL;
|
||||
goto label_return;
|
||||
}
|
||||
oldval = max_background_threads;
|
||||
READ(oldval, size_t);
|
||||
|
||||
size_t newval = *(size_t *)newp;
|
||||
if (newval == oldval) {
|
||||
ret = 0;
|
||||
goto label_return;
|
||||
}
|
||||
if (newval > opt_max_background_threads || newval == 0) {
|
||||
ret = EINVAL;
|
||||
goto label_return;
|
||||
}
|
||||
|
||||
if (background_thread_enabled()) {
|
||||
background_thread_enabled_set(tsd_tsdn(tsd), false);
|
||||
if (background_threads_disable(tsd)) {
|
||||
ret = EFAULT;
|
||||
goto label_return;
|
||||
}
|
||||
max_background_threads = newval;
|
||||
background_thread_enabled_set(tsd_tsdn(tsd), true);
|
||||
if (background_threads_enable(tsd)) {
|
||||
ret = EFAULT;
|
||||
goto label_return;
|
||||
}
|
||||
} else {
|
||||
max_background_threads = newval;
|
||||
}
|
||||
}
|
||||
ret = 0;
|
||||
label_return:
|
||||
malloc_mutex_unlock(tsd_tsdn(tsd), &background_thread_lock);
|
||||
ctl_mtx_unlock(tsd_tsdn(tsd));
|
||||
|
||||
return ret;
|
||||
}
|
||||
38
src/ctl_config.c
Normal file
38
src/ctl_config.c
Normal file
|
|
@ -0,0 +1,38 @@
|
|||
#include "jemalloc/internal/jemalloc_preamble.h"
|
||||
#include "jemalloc/internal/jemalloc_internal_includes.h"
|
||||
|
||||
#include "jemalloc/internal/ctl_config.h"
|
||||
|
||||
/******************************************************************************/
|
||||
/* config.* mallctl handlers. */
|
||||
|
||||
#define CTL_RO_CONFIG_GEN(n, t) \
|
||||
int n##_ctl(tsd_t *tsd, const size_t *mib, size_t miblen, \
|
||||
void *oldp, size_t *oldlenp, void *newp, size_t newlen) { \
|
||||
int ret; \
|
||||
t oldval; \
|
||||
\
|
||||
READONLY(); \
|
||||
oldval = n; \
|
||||
READ(oldval, t); \
|
||||
\
|
||||
ret = 0; \
|
||||
label_return: \
|
||||
return ret; \
|
||||
}
|
||||
|
||||
CTL_RO_CONFIG_GEN(config_cache_oblivious, bool)
|
||||
CTL_RO_CONFIG_GEN(config_debug, bool)
|
||||
CTL_RO_CONFIG_GEN(config_fill, bool)
|
||||
CTL_RO_CONFIG_GEN(config_lazy_lock, bool)
|
||||
CTL_RO_CONFIG_GEN(config_malloc_conf, const char *)
|
||||
CTL_RO_CONFIG_GEN(config_opt_safety_checks, bool)
|
||||
CTL_RO_CONFIG_GEN(config_prof, bool)
|
||||
CTL_RO_CONFIG_GEN(config_prof_libgcc, bool)
|
||||
CTL_RO_CONFIG_GEN(config_prof_libunwind, bool)
|
||||
CTL_RO_CONFIG_GEN(config_prof_frameptr, bool)
|
||||
CTL_RO_CONFIG_GEN(config_stats, bool)
|
||||
CTL_RO_CONFIG_GEN(config_utrace, bool)
|
||||
CTL_RO_CONFIG_GEN(config_xmalloc, bool)
|
||||
|
||||
#undef CTL_RO_CONFIG_GEN
|
||||
138
src/ctl_opt.c
Normal file
138
src/ctl_opt.c
Normal file
|
|
@ -0,0 +1,138 @@
|
|||
#include "jemalloc/internal/jemalloc_preamble.h"
|
||||
#include "jemalloc/internal/jemalloc_internal_includes.h"
|
||||
|
||||
#include "jemalloc/internal/ctl_opt.h"
|
||||
|
||||
/******************************************************************************/
|
||||
/* opt.* mallctl handlers. */
|
||||
|
||||
CTL_RO_NL_GEN_PUBLIC(opt_abort, opt_abort, bool)
|
||||
CTL_RO_NL_GEN_PUBLIC(opt_abort_conf, opt_abort_conf, bool)
|
||||
CTL_RO_NL_GEN_PUBLIC(opt_cache_oblivious, opt_cache_oblivious, bool)
|
||||
CTL_RO_NL_GEN_PUBLIC(
|
||||
opt_debug_double_free_max_scan, opt_debug_double_free_max_scan, unsigned)
|
||||
CTL_RO_NL_GEN_PUBLIC(opt_trust_madvise, opt_trust_madvise, bool)
|
||||
CTL_RO_NL_GEN_PUBLIC(opt_experimental_hpa_start_huge_if_thp_always,
|
||||
opt_experimental_hpa_start_huge_if_thp_always, bool)
|
||||
CTL_RO_NL_GEN_PUBLIC(opt_experimental_hpa_enforce_hugify,
|
||||
opt_experimental_hpa_enforce_hugify, bool)
|
||||
CTL_RO_NL_GEN_PUBLIC(opt_confirm_conf, opt_confirm_conf, bool)
|
||||
|
||||
/* HPA options. */
|
||||
CTL_RO_NL_GEN_PUBLIC(opt_hpa, opt_hpa, bool)
|
||||
CTL_RO_NL_GEN_PUBLIC(
|
||||
opt_hpa_hugification_threshold, opt_hpa_opts.hugification_threshold, size_t)
|
||||
CTL_RO_NL_GEN_PUBLIC(
|
||||
opt_hpa_hugify_delay_ms, opt_hpa_opts.hugify_delay_ms, uint64_t)
|
||||
CTL_RO_NL_GEN_PUBLIC(opt_hpa_hugify_sync, opt_hpa_opts.hugify_sync, bool)
|
||||
CTL_RO_NL_GEN_PUBLIC(
|
||||
opt_hpa_min_purge_interval_ms, opt_hpa_opts.min_purge_interval_ms, uint64_t)
|
||||
CTL_RO_NL_GEN_PUBLIC(opt_experimental_hpa_max_purge_nhp,
|
||||
opt_hpa_opts.experimental_max_purge_nhp, ssize_t)
|
||||
CTL_RO_NL_GEN_PUBLIC(
|
||||
opt_hpa_purge_threshold, opt_hpa_opts.purge_threshold, size_t)
|
||||
CTL_RO_NL_GEN_PUBLIC(
|
||||
opt_hpa_min_purge_delay_ms, opt_hpa_opts.min_purge_delay_ms, uint64_t)
|
||||
CTL_RO_NL_GEN_PUBLIC(opt_hpa_hugify_style,
|
||||
hpa_hugify_style_names[opt_hpa_opts.hugify_style], const char *)
|
||||
/*
|
||||
* This will have to change before we publicly document this option; fxp_t and
|
||||
* its representation are internal implementation details.
|
||||
*/
|
||||
CTL_RO_NL_GEN_PUBLIC(opt_hpa_dirty_mult, opt_hpa_opts.dirty_mult, fxp_t)
|
||||
CTL_RO_NL_GEN_PUBLIC(
|
||||
opt_hpa_slab_max_alloc, opt_hpa_opts.slab_max_alloc, size_t)
|
||||
|
||||
/* HPA SEC options */
|
||||
CTL_RO_NL_GEN_PUBLIC(opt_hpa_sec_nshards, opt_hpa_sec_opts.nshards, size_t)
|
||||
CTL_RO_NL_GEN_PUBLIC(opt_hpa_sec_max_alloc, opt_hpa_sec_opts.max_alloc, size_t)
|
||||
CTL_RO_NL_GEN_PUBLIC(opt_hpa_sec_max_bytes, opt_hpa_sec_opts.max_bytes, size_t)
|
||||
CTL_RO_NL_GEN_PUBLIC(opt_huge_arena_pac_thp, opt_huge_arena_pac_thp, bool)
|
||||
CTL_RO_NL_GEN_PUBLIC(
|
||||
opt_metadata_thp, metadata_thp_mode_names[opt_metadata_thp], const char *)
|
||||
CTL_RO_NL_GEN_PUBLIC(opt_retain, opt_retain, bool)
|
||||
CTL_RO_NL_GEN_PUBLIC(opt_dss, opt_dss, const char *)
|
||||
CTL_RO_NL_GEN_PUBLIC(opt_narenas, opt_narenas, unsigned)
|
||||
CTL_RO_NL_GEN_PUBLIC(
|
||||
opt_percpu_arena, percpu_arena_mode_names[opt_percpu_arena], const char *)
|
||||
CTL_RO_NL_GEN_PUBLIC(opt_mutex_max_spin, opt_mutex_max_spin, int64_t)
|
||||
CTL_RO_NL_GEN_PUBLIC(opt_oversize_threshold, opt_oversize_threshold, size_t)
|
||||
CTL_RO_NL_GEN_PUBLIC(opt_background_thread, opt_background_thread, bool)
|
||||
CTL_RO_NL_GEN_PUBLIC(opt_max_background_threads, opt_max_background_threads,
|
||||
size_t)
|
||||
CTL_RO_NL_GEN_PUBLIC(opt_dirty_decay_ms, opt_dirty_decay_ms, ssize_t)
|
||||
CTL_RO_NL_GEN_PUBLIC(opt_muzzy_decay_ms, opt_muzzy_decay_ms, ssize_t)
|
||||
CTL_RO_NL_GEN_PUBLIC(opt_stats_print, opt_stats_print, bool)
|
||||
CTL_RO_NL_GEN_PUBLIC(opt_stats_print_opts, opt_stats_print_opts, const char *)
|
||||
CTL_RO_NL_GEN_PUBLIC(opt_stats_interval, opt_stats_interval, int64_t)
|
||||
CTL_RO_NL_GEN_PUBLIC(
|
||||
opt_stats_interval_opts, opt_stats_interval_opts, const char *)
|
||||
CTL_RO_NL_CGEN_PUBLIC(config_fill, opt_junk, opt_junk, const char *)
|
||||
CTL_RO_NL_CGEN_PUBLIC(config_fill, opt_zero, opt_zero, bool)
|
||||
CTL_RO_NL_CGEN_PUBLIC(config_utrace, opt_utrace, opt_utrace, bool)
|
||||
CTL_RO_NL_CGEN_PUBLIC(config_xmalloc, opt_xmalloc, opt_xmalloc, bool)
|
||||
CTL_RO_NL_CGEN_PUBLIC(config_enable_cxx, opt_experimental_infallible_new,
|
||||
opt_experimental_infallible_new, bool)
|
||||
CTL_RO_NL_GEN_PUBLIC(
|
||||
opt_experimental_tcache_gc, opt_experimental_tcache_gc, bool)
|
||||
CTL_RO_NL_GEN_PUBLIC(opt_tcache, opt_tcache, bool)
|
||||
CTL_RO_NL_GEN_PUBLIC(opt_tcache_max, opt_tcache_max, size_t)
|
||||
CTL_RO_NL_GEN_PUBLIC(
|
||||
opt_tcache_nslots_small_min, opt_tcache_nslots_small_min, unsigned)
|
||||
CTL_RO_NL_GEN_PUBLIC(
|
||||
opt_tcache_nslots_small_max, opt_tcache_nslots_small_max, unsigned)
|
||||
CTL_RO_NL_GEN_PUBLIC(opt_tcache_nslots_large, opt_tcache_nslots_large, unsigned)
|
||||
CTL_RO_NL_GEN_PUBLIC(
|
||||
opt_lg_tcache_nslots_mul, opt_lg_tcache_nslots_mul, ssize_t)
|
||||
CTL_RO_NL_GEN_PUBLIC(opt_tcache_gc_incr_bytes, opt_tcache_gc_incr_bytes, size_t)
|
||||
CTL_RO_NL_GEN_PUBLIC(opt_tcache_gc_delay_bytes, opt_tcache_gc_delay_bytes,
|
||||
size_t)
|
||||
CTL_RO_NL_GEN_PUBLIC(
|
||||
opt_lg_tcache_flush_small_div, opt_lg_tcache_flush_small_div, unsigned)
|
||||
CTL_RO_NL_GEN_PUBLIC(
|
||||
opt_lg_tcache_flush_large_div, opt_lg_tcache_flush_large_div, unsigned)
|
||||
CTL_RO_NL_GEN_PUBLIC(opt_thp, thp_mode_names[opt_thp], const char *)
|
||||
CTL_RO_NL_GEN_PUBLIC(
|
||||
opt_lg_extent_max_active_fit, opt_lg_extent_max_active_fit, size_t)
|
||||
CTL_RO_NL_GEN_PUBLIC(
|
||||
opt_process_madvise_max_batch, opt_process_madvise_max_batch, size_t)
|
||||
CTL_RO_NL_CGEN_PUBLIC(config_prof, opt_prof, opt_prof, bool)
|
||||
CTL_RO_NL_CGEN_PUBLIC(config_prof, opt_prof_prefix, opt_prof_prefix,
|
||||
const char *)
|
||||
CTL_RO_NL_CGEN_PUBLIC(config_prof, opt_prof_active, opt_prof_active, bool)
|
||||
CTL_RO_NL_CGEN_PUBLIC(
|
||||
config_prof, opt_prof_thread_active_init, opt_prof_thread_active_init, bool)
|
||||
CTL_RO_NL_CGEN_PUBLIC(config_prof, opt_prof_bt_max, opt_prof_bt_max, unsigned)
|
||||
CTL_RO_NL_CGEN_PUBLIC(
|
||||
config_prof, opt_lg_prof_sample, opt_lg_prof_sample, size_t)
|
||||
CTL_RO_NL_CGEN_PUBLIC(config_prof, opt_prof_accum, opt_prof_accum, bool)
|
||||
CTL_RO_NL_CGEN_PUBLIC(
|
||||
config_prof, opt_prof_pid_namespace, opt_prof_pid_namespace, bool)
|
||||
CTL_RO_NL_CGEN_PUBLIC(
|
||||
config_prof, opt_lg_prof_interval, opt_lg_prof_interval, ssize_t)
|
||||
CTL_RO_NL_CGEN_PUBLIC(config_prof, opt_prof_gdump, opt_prof_gdump, bool)
|
||||
CTL_RO_NL_CGEN_PUBLIC(config_prof, opt_prof_final, opt_prof_final, bool)
|
||||
CTL_RO_NL_CGEN_PUBLIC(config_prof, opt_prof_leak, opt_prof_leak, bool)
|
||||
CTL_RO_NL_CGEN_PUBLIC(
|
||||
config_prof, opt_prof_leak_error, opt_prof_leak_error, bool)
|
||||
CTL_RO_NL_CGEN_PUBLIC(
|
||||
config_prof, opt_prof_recent_alloc_max, opt_prof_recent_alloc_max, ssize_t)
|
||||
CTL_RO_NL_CGEN_PUBLIC(config_prof, opt_prof_stats, opt_prof_stats, bool)
|
||||
CTL_RO_NL_CGEN_PUBLIC(
|
||||
config_prof, opt_prof_sys_thread_name, opt_prof_sys_thread_name, bool)
|
||||
CTL_RO_NL_CGEN_PUBLIC(config_prof, opt_prof_time_res,
|
||||
prof_time_res_mode_names[opt_prof_time_res], const char *)
|
||||
CTL_RO_NL_CGEN_PUBLIC(
|
||||
config_uaf_detection, opt_lg_san_uaf_align, opt_lg_san_uaf_align, ssize_t)
|
||||
CTL_RO_NL_GEN_PUBLIC(opt_zero_realloc,
|
||||
zero_realloc_mode_names[opt_zero_realloc_action], const char *)
|
||||
CTL_RO_NL_GEN_PUBLIC(
|
||||
opt_disable_large_size_classes, opt_disable_large_size_classes, bool)
|
||||
|
||||
/* malloc_conf options */
|
||||
CTL_RO_NL_CGEN_PUBLIC(opt_malloc_conf_symlink, opt_malloc_conf_symlink,
|
||||
opt_malloc_conf_symlink, const char *)
|
||||
CTL_RO_NL_CGEN_PUBLIC(opt_malloc_conf_env_var, opt_malloc_conf_env_var,
|
||||
opt_malloc_conf_env_var, const char *)
|
||||
CTL_RO_NL_CGEN_PUBLIC(
|
||||
je_malloc_conf, opt_malloc_conf_global_var, je_malloc_conf, const char *)
|
||||
450
src/ctl_prof.c
Normal file
450
src/ctl_prof.c
Normal file
|
|
@ -0,0 +1,450 @@
|
|||
#include "jemalloc/internal/jemalloc_preamble.h"
|
||||
#include "jemalloc/internal/jemalloc_internal_includes.h"
|
||||
|
||||
#include "jemalloc/internal/ctl_prof.h"
|
||||
#include "jemalloc/internal/prof_data.h"
|
||||
#include "jemalloc/internal/prof_log.h"
|
||||
#include "jemalloc/internal/prof_recent.h"
|
||||
#include "jemalloc/internal/prof_stats.h"
|
||||
#include "jemalloc/internal/prof_sys.h"
|
||||
#include "jemalloc/internal/sc.h"
|
||||
|
||||
/******************************************************************************/
|
||||
/* prof.* mallctl handlers. */
|
||||
|
||||
int
|
||||
prof_thread_active_init_ctl(tsd_t *tsd, const size_t *mib, size_t miblen,
|
||||
void *oldp, size_t *oldlenp, void *newp, size_t newlen) {
|
||||
int ret;
|
||||
bool oldval;
|
||||
|
||||
if (!config_prof) {
|
||||
return ENOENT;
|
||||
}
|
||||
|
||||
if (newp != NULL) {
|
||||
if (!opt_prof) {
|
||||
ret = ENOENT;
|
||||
goto label_return;
|
||||
}
|
||||
if (newlen != sizeof(bool)) {
|
||||
ret = EINVAL;
|
||||
goto label_return;
|
||||
}
|
||||
oldval = prof_thread_active_init_set(
|
||||
tsd_tsdn(tsd), *(bool *)newp);
|
||||
} else {
|
||||
oldval = opt_prof ? prof_thread_active_init_get(tsd_tsdn(tsd))
|
||||
: false;
|
||||
}
|
||||
READ(oldval, bool);
|
||||
|
||||
ret = 0;
|
||||
label_return:
|
||||
return ret;
|
||||
}
|
||||
|
||||
int
|
||||
prof_active_ctl(tsd_t *tsd, const size_t *mib, size_t miblen, void *oldp,
|
||||
size_t *oldlenp, void *newp, size_t newlen) {
|
||||
int ret;
|
||||
bool oldval;
|
||||
|
||||
if (!config_prof) {
|
||||
ret = ENOENT;
|
||||
goto label_return;
|
||||
}
|
||||
|
||||
if (newp != NULL) {
|
||||
if (newlen != sizeof(bool)) {
|
||||
ret = EINVAL;
|
||||
goto label_return;
|
||||
}
|
||||
bool val = *(bool *)newp;
|
||||
if (!opt_prof) {
|
||||
if (val) {
|
||||
ret = ENOENT;
|
||||
goto label_return;
|
||||
} else {
|
||||
/* No change needed (already off). */
|
||||
oldval = false;
|
||||
}
|
||||
} else {
|
||||
oldval = prof_active_set(tsd_tsdn(tsd), val);
|
||||
}
|
||||
} else {
|
||||
oldval = opt_prof ? prof_active_get(tsd_tsdn(tsd)) : false;
|
||||
}
|
||||
READ(oldval, bool);
|
||||
|
||||
ret = 0;
|
||||
label_return:
|
||||
return ret;
|
||||
}
|
||||
|
||||
int
|
||||
prof_dump_ctl(tsd_t *tsd, const size_t *mib, size_t miblen, void *oldp,
|
||||
size_t *oldlenp, void *newp, size_t newlen) {
|
||||
int ret;
|
||||
const char *filename = NULL;
|
||||
|
||||
if (!config_prof || !opt_prof) {
|
||||
return ENOENT;
|
||||
}
|
||||
|
||||
WRITEONLY();
|
||||
WRITE(filename, const char *);
|
||||
|
||||
if (prof_mdump(tsd, filename)) {
|
||||
ret = EFAULT;
|
||||
goto label_return;
|
||||
}
|
||||
|
||||
ret = 0;
|
||||
label_return:
|
||||
return ret;
|
||||
}
|
||||
|
||||
int
|
||||
prof_gdump_ctl(tsd_t *tsd, const size_t *mib, size_t miblen, void *oldp,
|
||||
size_t *oldlenp, void *newp, size_t newlen) {
|
||||
int ret;
|
||||
bool oldval;
|
||||
|
||||
if (!config_prof) {
|
||||
return ENOENT;
|
||||
}
|
||||
|
||||
if (newp != NULL) {
|
||||
if (!opt_prof) {
|
||||
ret = ENOENT;
|
||||
goto label_return;
|
||||
}
|
||||
if (newlen != sizeof(bool)) {
|
||||
ret = EINVAL;
|
||||
goto label_return;
|
||||
}
|
||||
oldval = prof_gdump_set(tsd_tsdn(tsd), *(bool *)newp);
|
||||
} else {
|
||||
oldval = opt_prof ? prof_gdump_get(tsd_tsdn(tsd)) : false;
|
||||
}
|
||||
READ(oldval, bool);
|
||||
|
||||
ret = 0;
|
||||
label_return:
|
||||
return ret;
|
||||
}
|
||||
|
||||
int
|
||||
prof_prefix_ctl(tsd_t *tsd, const size_t *mib, size_t miblen, void *oldp,
|
||||
size_t *oldlenp, void *newp, size_t newlen) {
|
||||
int ret;
|
||||
const char *prefix = NULL;
|
||||
|
||||
if (!config_prof || !opt_prof) {
|
||||
return ENOENT;
|
||||
}
|
||||
|
||||
ctl_mtx_lock(tsd_tsdn(tsd));
|
||||
WRITEONLY();
|
||||
WRITE(prefix, const char *);
|
||||
|
||||
ret = prof_prefix_set(tsd_tsdn(tsd), prefix) ? EFAULT : 0;
|
||||
label_return:
|
||||
ctl_mtx_unlock(tsd_tsdn(tsd));
|
||||
return ret;
|
||||
}
|
||||
|
||||
int
|
||||
prof_reset_ctl(tsd_t *tsd, const size_t *mib, size_t miblen, void *oldp,
|
||||
size_t *oldlenp, void *newp, size_t newlen) {
|
||||
int ret;
|
||||
size_t lg_sample = lg_prof_sample;
|
||||
|
||||
if (!config_prof || !opt_prof) {
|
||||
return ENOENT;
|
||||
}
|
||||
|
||||
WRITEONLY();
|
||||
WRITE(lg_sample, size_t);
|
||||
if (lg_sample >= (sizeof(uint64_t) << 3)) {
|
||||
lg_sample = (sizeof(uint64_t) << 3) - 1;
|
||||
}
|
||||
|
||||
prof_reset(tsd, lg_sample);
|
||||
|
||||
ret = 0;
|
||||
label_return:
|
||||
return ret;
|
||||
}
|
||||
|
||||
CTL_RO_NL_CGEN_PUBLIC(config_prof, prof_interval, prof_interval, uint64_t)
|
||||
CTL_RO_NL_CGEN_PUBLIC(config_prof, lg_prof_sample, lg_prof_sample, size_t)
|
||||
|
||||
int
|
||||
prof_log_start_ctl(tsd_t *tsd, const size_t *mib, size_t miblen, void *oldp,
|
||||
size_t *oldlenp, void *newp, size_t newlen) {
|
||||
int ret;
|
||||
|
||||
const char *filename = NULL;
|
||||
|
||||
if (!config_prof || !opt_prof) {
|
||||
return ENOENT;
|
||||
}
|
||||
|
||||
WRITEONLY();
|
||||
WRITE(filename, const char *);
|
||||
|
||||
if (prof_log_start(tsd_tsdn(tsd), filename)) {
|
||||
ret = EFAULT;
|
||||
goto label_return;
|
||||
}
|
||||
|
||||
ret = 0;
|
||||
label_return:
|
||||
return ret;
|
||||
}
|
||||
|
||||
int
|
||||
prof_log_stop_ctl(tsd_t *tsd, const size_t *mib, size_t miblen, void *oldp,
|
||||
size_t *oldlenp, void *newp, size_t newlen) {
|
||||
if (!config_prof || !opt_prof) {
|
||||
return ENOENT;
|
||||
}
|
||||
|
||||
if (prof_log_stop(tsd_tsdn(tsd))) {
|
||||
return EFAULT;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
prof_stats_bins_i_live_ctl(tsd_t *tsd, const size_t *mib, size_t miblen,
|
||||
void *oldp, size_t *oldlenp, void *newp, size_t newlen) {
|
||||
int ret;
|
||||
unsigned binind;
|
||||
prof_stats_t stats;
|
||||
|
||||
if (!(config_prof && opt_prof && opt_prof_stats)) {
|
||||
ret = ENOENT;
|
||||
goto label_return;
|
||||
}
|
||||
|
||||
READONLY();
|
||||
MIB_UNSIGNED(binind, 3);
|
||||
if (binind >= SC_NBINS) {
|
||||
ret = EINVAL;
|
||||
goto label_return;
|
||||
}
|
||||
prof_stats_get_live(tsd, (szind_t)binind, &stats);
|
||||
READ(stats, prof_stats_t);
|
||||
|
||||
ret = 0;
|
||||
label_return:
|
||||
return ret;
|
||||
}
|
||||
|
||||
int
|
||||
prof_stats_bins_i_accum_ctl(tsd_t *tsd, const size_t *mib, size_t miblen,
|
||||
void *oldp, size_t *oldlenp, void *newp, size_t newlen) {
|
||||
int ret;
|
||||
unsigned binind;
|
||||
prof_stats_t stats;
|
||||
|
||||
if (!(config_prof && opt_prof && opt_prof_stats)) {
|
||||
ret = ENOENT;
|
||||
goto label_return;
|
||||
}
|
||||
|
||||
READONLY();
|
||||
MIB_UNSIGNED(binind, 3);
|
||||
if (binind >= SC_NBINS) {
|
||||
ret = EINVAL;
|
||||
goto label_return;
|
||||
}
|
||||
prof_stats_get_accum(tsd, (szind_t)binind, &stats);
|
||||
READ(stats, prof_stats_t);
|
||||
|
||||
ret = 0;
|
||||
label_return:
|
||||
return ret;
|
||||
}
|
||||
|
||||
int
|
||||
prof_stats_lextents_i_live_ctl(tsd_t *tsd, const size_t *mib, size_t miblen,
|
||||
void *oldp, size_t *oldlenp, void *newp, size_t newlen) {
|
||||
int ret;
|
||||
unsigned lextent_ind;
|
||||
prof_stats_t stats;
|
||||
|
||||
if (!(config_prof && opt_prof && opt_prof_stats)) {
|
||||
ret = ENOENT;
|
||||
goto label_return;
|
||||
}
|
||||
|
||||
READONLY();
|
||||
MIB_UNSIGNED(lextent_ind, 3);
|
||||
if (lextent_ind >= SC_NSIZES - SC_NBINS) {
|
||||
ret = EINVAL;
|
||||
goto label_return;
|
||||
}
|
||||
prof_stats_get_live(tsd, (szind_t)(lextent_ind + SC_NBINS), &stats);
|
||||
READ(stats, prof_stats_t);
|
||||
|
||||
ret = 0;
|
||||
label_return:
|
||||
return ret;
|
||||
}
|
||||
|
||||
int
|
||||
prof_stats_lextents_i_accum_ctl(tsd_t *tsd, const size_t *mib, size_t miblen,
|
||||
void *oldp, size_t *oldlenp, void *newp, size_t newlen) {
|
||||
int ret;
|
||||
unsigned lextent_ind;
|
||||
prof_stats_t stats;
|
||||
|
||||
if (!(config_prof && opt_prof && opt_prof_stats)) {
|
||||
ret = ENOENT;
|
||||
goto label_return;
|
||||
}
|
||||
|
||||
READONLY();
|
||||
MIB_UNSIGNED(lextent_ind, 3);
|
||||
if (lextent_ind >= SC_NSIZES - SC_NBINS) {
|
||||
ret = EINVAL;
|
||||
goto label_return;
|
||||
}
|
||||
prof_stats_get_accum(tsd, (szind_t)(lextent_ind + SC_NBINS), &stats);
|
||||
READ(stats, prof_stats_t);
|
||||
|
||||
ret = 0;
|
||||
label_return:
|
||||
return ret;
|
||||
}
|
||||
|
||||
/******************************************************************************/
|
||||
/* experimental.prof_recent.* and experimental.hooks.prof_* mallctl handlers. */
|
||||
|
||||
#define PROF_HOOK_CTL_BODY(hook_type, hook_get, hook_set, allow_null) \
|
||||
do { \
|
||||
int ret; \
|
||||
if (oldp == NULL && newp == NULL) { \
|
||||
ret = EINVAL; \
|
||||
goto label_return; \
|
||||
} \
|
||||
if (oldp != NULL) { \
|
||||
hook_type old_hook = hook_get(); \
|
||||
READ(old_hook, hook_type); \
|
||||
} \
|
||||
if (newp != NULL) { \
|
||||
if (!opt_prof) { \
|
||||
ret = ENOENT; \
|
||||
goto label_return; \
|
||||
} \
|
||||
hook_type new_hook JEMALLOC_CC_SILENCE_INIT(NULL); \
|
||||
WRITE(new_hook, hook_type); \
|
||||
if (!(allow_null) && new_hook == NULL) { \
|
||||
ret = EINVAL; \
|
||||
goto label_return; \
|
||||
} \
|
||||
hook_set(new_hook); \
|
||||
} \
|
||||
ret = 0; \
|
||||
label_return: \
|
||||
return ret; \
|
||||
} while (0)
|
||||
|
||||
int
|
||||
experimental_hooks_prof_backtrace_ctl(tsd_t *tsd, const size_t *mib,
|
||||
size_t miblen, void *oldp, size_t *oldlenp, void *newp, size_t newlen) {
|
||||
PROF_HOOK_CTL_BODY(prof_backtrace_hook_t, prof_backtrace_hook_get,
|
||||
prof_backtrace_hook_set, false);
|
||||
}
|
||||
|
||||
int
|
||||
experimental_hooks_prof_dump_ctl(tsd_t *tsd, const size_t *mib, size_t miblen,
|
||||
void *oldp, size_t *oldlenp, void *newp, size_t newlen) {
|
||||
PROF_HOOK_CTL_BODY(prof_dump_hook_t, prof_dump_hook_get,
|
||||
prof_dump_hook_set, true);
|
||||
}
|
||||
|
||||
int
|
||||
experimental_hooks_prof_sample_ctl(tsd_t *tsd, const size_t *mib, size_t miblen,
|
||||
void *oldp, size_t *oldlenp, void *newp, size_t newlen) {
|
||||
PROF_HOOK_CTL_BODY(prof_sample_hook_t, prof_sample_hook_get,
|
||||
prof_sample_hook_set, true);
|
||||
}
|
||||
|
||||
int
|
||||
experimental_hooks_prof_sample_free_ctl(tsd_t *tsd, const size_t *mib,
|
||||
size_t miblen, void *oldp, size_t *oldlenp, void *newp, size_t newlen) {
|
||||
PROF_HOOK_CTL_BODY(prof_sample_free_hook_t, prof_sample_free_hook_get,
|
||||
prof_sample_free_hook_set, true);
|
||||
}
|
||||
|
||||
#undef PROF_HOOK_CTL_BODY
|
||||
|
||||
int
|
||||
experimental_prof_recent_alloc_max_ctl(tsd_t *tsd, const size_t *mib,
|
||||
size_t miblen, void *oldp, size_t *oldlenp, void *newp, size_t newlen) {
|
||||
int ret;
|
||||
|
||||
if (!(config_prof && opt_prof)) {
|
||||
ret = ENOENT;
|
||||
goto label_return;
|
||||
}
|
||||
|
||||
ssize_t old_max;
|
||||
if (newp != NULL) {
|
||||
if (newlen != sizeof(ssize_t)) {
|
||||
ret = EINVAL;
|
||||
goto label_return;
|
||||
}
|
||||
ssize_t max = *(ssize_t *)newp;
|
||||
if (max < -1) {
|
||||
ret = EINVAL;
|
||||
goto label_return;
|
||||
}
|
||||
old_max = prof_recent_alloc_max_ctl_write(tsd, max);
|
||||
} else {
|
||||
old_max = prof_recent_alloc_max_ctl_read();
|
||||
}
|
||||
READ(old_max, ssize_t);
|
||||
|
||||
ret = 0;
|
||||
|
||||
label_return:
|
||||
return ret;
|
||||
}
|
||||
|
||||
typedef struct write_cb_packet_s write_cb_packet_t;
|
||||
struct write_cb_packet_s {
|
||||
write_cb_t *write_cb;
|
||||
void *cbopaque;
|
||||
};
|
||||
|
||||
int
|
||||
experimental_prof_recent_alloc_dump_ctl(tsd_t *tsd, const size_t *mib,
|
||||
size_t miblen, void *oldp, size_t *oldlenp, void *newp, size_t newlen) {
|
||||
int ret;
|
||||
|
||||
if (!(config_prof && opt_prof)) {
|
||||
ret = ENOENT;
|
||||
goto label_return;
|
||||
}
|
||||
|
||||
assert(sizeof(write_cb_packet_t) == sizeof(void *) * 2);
|
||||
|
||||
WRITEONLY();
|
||||
write_cb_packet_t write_cb_packet;
|
||||
ASSURED_WRITE(write_cb_packet, write_cb_packet_t);
|
||||
|
||||
prof_recent_alloc_dump(
|
||||
tsd, write_cb_packet.write_cb, write_cb_packet.cbopaque);
|
||||
|
||||
ret = 0;
|
||||
|
||||
label_return:
|
||||
return ret;
|
||||
}
|
||||
577
src/ctl_stats.c
Normal file
577
src/ctl_stats.c
Normal file
|
|
@ -0,0 +1,577 @@
|
|||
#include "jemalloc/internal/jemalloc_preamble.h"
|
||||
#include "jemalloc/internal/jemalloc_internal_includes.h"
|
||||
|
||||
#include "jemalloc/internal/assert.h"
|
||||
#include "jemalloc/internal/ctl_arena.h"
|
||||
#include "jemalloc/internal/ctl_mallctl.h"
|
||||
#include "jemalloc/internal/ctl_stats.h"
|
||||
#include "jemalloc/internal/mutex.h"
|
||||
#include "jemalloc/internal/nstime.h"
|
||||
#include "jemalloc/internal/prof_data.h"
|
||||
#include "jemalloc/internal/prof_recent.h"
|
||||
#include "jemalloc/internal/prof_stats.h"
|
||||
#include "jemalloc/internal/sc.h"
|
||||
|
||||
/******************************************************************************/
|
||||
/* stats.* ctl state. */
|
||||
|
||||
static ctl_stats_t *ctl_stats;
|
||||
|
||||
bool
|
||||
ctl_stats_init(tsdn_t *tsdn) {
|
||||
if (!config_stats || ctl_stats != NULL) {
|
||||
return false;
|
||||
}
|
||||
|
||||
ctl_stats = (ctl_stats_t *)base_alloc(
|
||||
tsdn, b0get(), sizeof(ctl_stats_t), QUANTUM);
|
||||
return ctl_stats == NULL;
|
||||
}
|
||||
|
||||
static void
|
||||
ctl_background_thread_stats_read(tsdn_t *tsdn) {
|
||||
background_thread_stats_t *stats = &ctl_stats->background_thread;
|
||||
if (!have_background_thread
|
||||
|| background_thread_stats_read(tsdn, stats)) {
|
||||
memset(stats, 0, sizeof(background_thread_stats_t));
|
||||
nstime_init_zero(&stats->run_interval);
|
||||
}
|
||||
malloc_mutex_prof_copy(
|
||||
&ctl_stats->mutex_prof_data[global_prof_mutex_max_per_bg_thd],
|
||||
&stats->max_counter_per_bg_thd);
|
||||
}
|
||||
|
||||
void
|
||||
ctl_stats_refresh(tsdn_t *tsdn, ctl_arena_t *ctl_sarena) {
|
||||
if (!config_stats) {
|
||||
return;
|
||||
}
|
||||
|
||||
ctl_stats->allocated = ctl_sarena->astats->allocated_small
|
||||
+ ctl_sarena->astats->astats.allocated_large;
|
||||
ctl_stats->active = (ctl_sarena->pactive << LG_PAGE);
|
||||
ctl_stats->metadata = ctl_sarena->astats->astats.base
|
||||
+ atomic_load_zu(
|
||||
&ctl_sarena->astats->astats.internal, ATOMIC_RELAXED);
|
||||
ctl_stats->metadata_edata = ctl_sarena->astats->astats.metadata_edata;
|
||||
ctl_stats->metadata_rtree = ctl_sarena->astats->astats.metadata_rtree;
|
||||
ctl_stats->resident = ctl_sarena->astats->astats.resident;
|
||||
ctl_stats->metadata_thp = ctl_sarena->astats->astats.metadata_thp;
|
||||
ctl_stats->mapped = ctl_sarena->astats->astats.mapped;
|
||||
ctl_stats->retained = ctl_sarena->astats->astats.pa_shard_stats
|
||||
.pac_stats.retained;
|
||||
ctl_stats->pinned = ctl_sarena->astats->astats.pa_shard_stats
|
||||
.pac_stats.pinned;
|
||||
|
||||
ctl_background_thread_stats_read(tsdn);
|
||||
|
||||
#define READ_GLOBAL_MUTEX_PROF_DATA(i, mtx) \
|
||||
malloc_mutex_lock(tsdn, &mtx); \
|
||||
malloc_mutex_prof_read(tsdn, &ctl_stats->mutex_prof_data[i], &mtx); \
|
||||
malloc_mutex_unlock(tsdn, &mtx);
|
||||
|
||||
if (config_prof && opt_prof) {
|
||||
READ_GLOBAL_MUTEX_PROF_DATA(
|
||||
global_prof_mutex_prof, bt2gctx_mtx);
|
||||
READ_GLOBAL_MUTEX_PROF_DATA(
|
||||
global_prof_mutex_prof_thds_data, tdatas_mtx);
|
||||
READ_GLOBAL_MUTEX_PROF_DATA(
|
||||
global_prof_mutex_prof_dump, prof_dump_mtx);
|
||||
READ_GLOBAL_MUTEX_PROF_DATA(
|
||||
global_prof_mutex_prof_recent_alloc,
|
||||
prof_recent_alloc_mtx);
|
||||
READ_GLOBAL_MUTEX_PROF_DATA(
|
||||
global_prof_mutex_prof_recent_dump,
|
||||
prof_recent_dump_mtx);
|
||||
READ_GLOBAL_MUTEX_PROF_DATA(
|
||||
global_prof_mutex_prof_stats, prof_stats_mtx);
|
||||
}
|
||||
if (have_background_thread) {
|
||||
READ_GLOBAL_MUTEX_PROF_DATA(
|
||||
global_prof_mutex_background_thread, background_thread_lock);
|
||||
} else {
|
||||
memset(&ctl_stats->mutex_prof_data
|
||||
[global_prof_mutex_background_thread],
|
||||
0, sizeof(mutex_prof_data_t));
|
||||
}
|
||||
ctl_mtx_prof_read(
|
||||
tsdn, &ctl_stats->mutex_prof_data[global_prof_mutex_ctl]);
|
||||
#undef READ_GLOBAL_MUTEX_PROF_DATA
|
||||
}
|
||||
|
||||
/******************************************************************************/
|
||||
/* stats.* mallctl handlers. */
|
||||
|
||||
CTL_RO_CGEN_PUBLIC(config_stats, stats_allocated, ctl_stats->allocated, size_t)
|
||||
CTL_RO_CGEN_PUBLIC(config_stats, stats_active, ctl_stats->active, size_t)
|
||||
CTL_RO_CGEN_PUBLIC(config_stats, stats_metadata, ctl_stats->metadata, size_t)
|
||||
CTL_RO_CGEN_PUBLIC(
|
||||
config_stats, stats_metadata_edata, ctl_stats->metadata_edata, size_t)
|
||||
CTL_RO_CGEN_PUBLIC(
|
||||
config_stats, stats_metadata_rtree, ctl_stats->metadata_rtree, size_t)
|
||||
CTL_RO_CGEN_PUBLIC(config_stats, stats_metadata_thp, ctl_stats->metadata_thp, size_t)
|
||||
CTL_RO_CGEN_PUBLIC(config_stats, stats_resident, ctl_stats->resident, size_t)
|
||||
CTL_RO_CGEN_PUBLIC(config_stats, stats_mapped, ctl_stats->mapped, size_t)
|
||||
CTL_RO_CGEN_PUBLIC(config_stats, stats_retained, ctl_stats->retained, size_t)
|
||||
CTL_RO_CGEN_PUBLIC(config_stats, stats_pinned, ctl_stats->pinned, size_t)
|
||||
|
||||
CTL_RO_CGEN_PUBLIC(config_stats, stats_background_thread_num_threads,
|
||||
ctl_stats->background_thread.num_threads, size_t)
|
||||
CTL_RO_CGEN_PUBLIC(config_stats, stats_background_thread_num_runs,
|
||||
ctl_stats->background_thread.num_runs, uint64_t)
|
||||
CTL_RO_CGEN_PUBLIC(config_stats, stats_background_thread_run_interval,
|
||||
nstime_ns(&ctl_stats->background_thread.run_interval), uint64_t)
|
||||
|
||||
CTL_RO_CGEN_PUBLIC(config_stats, stats_zero_reallocs,
|
||||
atomic_load_zu(&zero_realloc_count, ATOMIC_RELAXED), size_t)
|
||||
|
||||
/*
|
||||
* approximate_stats.active returns a result that is informative itself,
|
||||
* but the returned value SHOULD NOT be compared against other stats retrieved.
|
||||
* For instance, approximate_stats.active should not be compared against
|
||||
* any stats, e.g., stats.active or stats.resident, because there is no
|
||||
* guarantee in the comparison results. Results returned by stats.*, on the
|
||||
* other hand, provides such guarantees, i.e., stats.active <= stats.resident,
|
||||
* as long as epoch is called right before the queries.
|
||||
*/
|
||||
|
||||
int
|
||||
approximate_stats_active_ctl(tsd_t *tsd, const size_t *mib, size_t miblen,
|
||||
void *oldp, size_t *oldlenp, void *newp, size_t newlen) {
|
||||
int ret;
|
||||
size_t approximate_nactive = 0;
|
||||
size_t approximate_active_bytes = 0;
|
||||
|
||||
READONLY();
|
||||
|
||||
tsdn_t *tsdn = tsd_tsdn(tsd);
|
||||
unsigned n = narenas_total_get();
|
||||
|
||||
for (unsigned i = 0; i < n; i++) {
|
||||
arena_t *arena = arena_get(tsdn, i, false);
|
||||
if (!arena) {
|
||||
continue;
|
||||
}
|
||||
/* Accumulate nactive pages from each arena's pa_shard */
|
||||
approximate_nactive += pa_shard_nactive(&arena->pa_shard);
|
||||
}
|
||||
|
||||
approximate_active_bytes = approximate_nactive << LG_PAGE;
|
||||
READ(approximate_active_bytes, size_t);
|
||||
|
||||
ret = 0;
|
||||
label_return:
|
||||
return ret;
|
||||
}
|
||||
|
||||
CTL_RO_GEN_PUBLIC(stats_arenas_i_dss, ctl_arenas_i(mib[2])->dss, const char *)
|
||||
CTL_RO_GEN_PUBLIC(
|
||||
stats_arenas_i_dirty_decay_ms, ctl_arenas_i(mib[2])->dirty_decay_ms, ssize_t)
|
||||
CTL_RO_GEN_PUBLIC(
|
||||
stats_arenas_i_muzzy_decay_ms, ctl_arenas_i(mib[2])->muzzy_decay_ms, ssize_t)
|
||||
CTL_RO_GEN_PUBLIC(stats_arenas_i_nthreads, ctl_arenas_i(mib[2])->nthreads, unsigned)
|
||||
CTL_RO_GEN_PUBLIC(stats_arenas_i_uptime,
|
||||
nstime_ns(&ctl_arenas_i(mib[2])->astats->astats.uptime), uint64_t)
|
||||
CTL_RO_GEN_PUBLIC(stats_arenas_i_pactive, ctl_arenas_i(mib[2])->pactive, size_t)
|
||||
CTL_RO_GEN_PUBLIC(stats_arenas_i_pdirty, ctl_arenas_i(mib[2])->pdirty, size_t)
|
||||
CTL_RO_GEN_PUBLIC(stats_arenas_i_pmuzzy, ctl_arenas_i(mib[2])->pmuzzy, size_t)
|
||||
CTL_RO_CGEN_PUBLIC(config_stats, stats_arenas_i_mapped,
|
||||
ctl_arenas_i(mib[2])->astats->astats.mapped, size_t)
|
||||
CTL_RO_CGEN_PUBLIC(config_stats, stats_arenas_i_retained,
|
||||
ctl_arenas_i(mib[2])->astats->astats.pa_shard_stats.pac_stats.retained, size_t)
|
||||
CTL_RO_CGEN_PUBLIC(config_stats, stats_arenas_i_pinned,
|
||||
ctl_arenas_i(mib[2])->astats->astats.pa_shard_stats.pac_stats.pinned, size_t)
|
||||
CTL_RO_CGEN_PUBLIC(config_stats, stats_arenas_i_extent_avail,
|
||||
ctl_arenas_i(mib[2])->astats->astats.pa_shard_stats.edata_avail, size_t)
|
||||
|
||||
CTL_RO_CGEN_PUBLIC(config_stats, stats_arenas_i_dirty_npurge,
|
||||
locked_read_u64_unsynchronized(&ctl_arenas_i(mib[2])
|
||||
->astats->astats.pa_shard_stats.pac_stats.decay_dirty.npurge),
|
||||
uint64_t)
|
||||
CTL_RO_CGEN_PUBLIC(config_stats, stats_arenas_i_dirty_nmadvise,
|
||||
locked_read_u64_unsynchronized(&ctl_arenas_i(mib[2])
|
||||
->astats->astats.pa_shard_stats.pac_stats.decay_dirty.nmadvise),
|
||||
uint64_t)
|
||||
CTL_RO_CGEN_PUBLIC(config_stats, stats_arenas_i_dirty_purged,
|
||||
locked_read_u64_unsynchronized(&ctl_arenas_i(mib[2])
|
||||
->astats->astats.pa_shard_stats.pac_stats.decay_dirty.purged),
|
||||
uint64_t)
|
||||
|
||||
CTL_RO_CGEN_PUBLIC(config_stats, stats_arenas_i_muzzy_npurge,
|
||||
locked_read_u64_unsynchronized(&ctl_arenas_i(mib[2])
|
||||
->astats->astats.pa_shard_stats.pac_stats.decay_muzzy.npurge),
|
||||
uint64_t)
|
||||
CTL_RO_CGEN_PUBLIC(config_stats, stats_arenas_i_muzzy_nmadvise,
|
||||
locked_read_u64_unsynchronized(&ctl_arenas_i(mib[2])
|
||||
->astats->astats.pa_shard_stats.pac_stats.decay_muzzy.nmadvise),
|
||||
uint64_t)
|
||||
CTL_RO_CGEN_PUBLIC(config_stats, stats_arenas_i_muzzy_purged,
|
||||
locked_read_u64_unsynchronized(&ctl_arenas_i(mib[2])
|
||||
->astats->astats.pa_shard_stats.pac_stats.decay_muzzy.purged),
|
||||
uint64_t)
|
||||
|
||||
CTL_RO_CGEN_PUBLIC(config_stats, stats_arenas_i_base,
|
||||
ctl_arenas_i(mib[2])->astats->astats.base, size_t)
|
||||
CTL_RO_CGEN_PUBLIC(config_stats, stats_arenas_i_internal,
|
||||
atomic_load_zu(&ctl_arenas_i(mib[2])->astats->astats.internal, ATOMIC_RELAXED),
|
||||
size_t)
|
||||
CTL_RO_CGEN_PUBLIC(config_stats, stats_arenas_i_metadata_edata,
|
||||
ctl_arenas_i(mib[2])->astats->astats.metadata_edata, size_t)
|
||||
CTL_RO_CGEN_PUBLIC(config_stats, stats_arenas_i_metadata_rtree,
|
||||
ctl_arenas_i(mib[2])->astats->astats.metadata_rtree, size_t)
|
||||
CTL_RO_CGEN_PUBLIC(config_stats, stats_arenas_i_metadata_thp,
|
||||
ctl_arenas_i(mib[2])->astats->astats.metadata_thp, size_t)
|
||||
CTL_RO_CGEN_PUBLIC(config_stats, stats_arenas_i_tcache_bytes,
|
||||
ctl_arenas_i(mib[2])->astats->astats.tcache_bytes, size_t)
|
||||
CTL_RO_CGEN_PUBLIC(config_stats, stats_arenas_i_tcache_stashed_bytes,
|
||||
ctl_arenas_i(mib[2])->astats->astats.tcache_stashed_bytes, size_t)
|
||||
CTL_RO_CGEN_PUBLIC(config_stats, stats_arenas_i_resident,
|
||||
ctl_arenas_i(mib[2])->astats->astats.resident, size_t)
|
||||
CTL_RO_CGEN_PUBLIC(config_stats, stats_arenas_i_abandoned_vm,
|
||||
atomic_load_zu(
|
||||
&ctl_arenas_i(mib[2])->astats->astats.pa_shard_stats.pac_stats.abandoned_vm,
|
||||
ATOMIC_RELAXED),
|
||||
size_t)
|
||||
|
||||
CTL_RO_CGEN_PUBLIC(config_stats, stats_arenas_i_hpa_sec_bytes,
|
||||
ctl_arenas_i(mib[2])->astats->hpastats.secstats.bytes, size_t)
|
||||
CTL_RO_CGEN_PUBLIC(config_stats, stats_arenas_i_hpa_sec_hits,
|
||||
ctl_arenas_i(mib[2])->astats->hpastats.secstats.total.nhits, size_t)
|
||||
CTL_RO_CGEN_PUBLIC(config_stats, stats_arenas_i_hpa_sec_misses,
|
||||
ctl_arenas_i(mib[2])->astats->hpastats.secstats.total.nmisses, size_t)
|
||||
CTL_RO_CGEN_PUBLIC(config_stats, stats_arenas_i_hpa_sec_dalloc_flush,
|
||||
ctl_arenas_i(mib[2])->astats->hpastats.secstats.total.ndalloc_flush, size_t)
|
||||
CTL_RO_CGEN_PUBLIC(config_stats, stats_arenas_i_hpa_sec_dalloc_noflush,
|
||||
ctl_arenas_i(mib[2])->astats->hpastats.secstats.total.ndalloc_noflush, size_t)
|
||||
CTL_RO_CGEN_PUBLIC(config_stats, stats_arenas_i_hpa_sec_overfills,
|
||||
ctl_arenas_i(mib[2])->astats->hpastats.secstats.total.noverfills, size_t)
|
||||
|
||||
CTL_RO_CGEN_PUBLIC(config_stats, stats_arenas_i_small_allocated,
|
||||
ctl_arenas_i(mib[2])->astats->allocated_small, size_t)
|
||||
CTL_RO_CGEN_PUBLIC(config_stats, stats_arenas_i_small_nmalloc,
|
||||
ctl_arenas_i(mib[2])->astats->nmalloc_small, uint64_t)
|
||||
CTL_RO_CGEN_PUBLIC(config_stats, stats_arenas_i_small_ndalloc,
|
||||
ctl_arenas_i(mib[2])->astats->ndalloc_small, uint64_t)
|
||||
CTL_RO_CGEN_PUBLIC(config_stats, stats_arenas_i_small_nrequests,
|
||||
ctl_arenas_i(mib[2])->astats->nrequests_small, uint64_t)
|
||||
CTL_RO_CGEN_PUBLIC(config_stats, stats_arenas_i_small_nfills,
|
||||
ctl_arenas_i(mib[2])->astats->nfills_small, uint64_t)
|
||||
CTL_RO_CGEN_PUBLIC(config_stats, stats_arenas_i_small_nflushes,
|
||||
ctl_arenas_i(mib[2])->astats->nflushes_small, uint64_t)
|
||||
CTL_RO_CGEN_PUBLIC(config_stats, stats_arenas_i_large_allocated,
|
||||
ctl_arenas_i(mib[2])->astats->astats.allocated_large, size_t)
|
||||
CTL_RO_CGEN_PUBLIC(config_stats, stats_arenas_i_large_nmalloc,
|
||||
ctl_arenas_i(mib[2])->astats->astats.nmalloc_large, uint64_t)
|
||||
CTL_RO_CGEN_PUBLIC(config_stats, stats_arenas_i_large_ndalloc,
|
||||
ctl_arenas_i(mib[2])->astats->astats.ndalloc_large, uint64_t)
|
||||
CTL_RO_CGEN_PUBLIC(config_stats, stats_arenas_i_large_nrequests,
|
||||
ctl_arenas_i(mib[2])->astats->astats.nrequests_large, uint64_t)
|
||||
/*
|
||||
* Note: "nmalloc_large" here instead of "nfills" in the read. This is
|
||||
* intentional (large has no batch fill).
|
||||
*/
|
||||
CTL_RO_CGEN_PUBLIC(config_stats, stats_arenas_i_large_nfills,
|
||||
ctl_arenas_i(mib[2])->astats->astats.nmalloc_large, uint64_t)
|
||||
CTL_RO_CGEN_PUBLIC(config_stats, stats_arenas_i_large_nflushes,
|
||||
ctl_arenas_i(mib[2])->astats->astats.nflushes_large, uint64_t)
|
||||
|
||||
/* Lock profiling related APIs below. */
|
||||
#define RO_MUTEX_CTL_GEN(n, l) \
|
||||
CTL_RO_CGEN_PUBLIC(config_stats, stats_##n##_num_ops, l.n_lock_ops, uint64_t) \
|
||||
CTL_RO_CGEN_PUBLIC( \
|
||||
config_stats, stats_##n##_num_wait, l.n_wait_times, uint64_t) \
|
||||
CTL_RO_CGEN_PUBLIC(config_stats, stats_##n##_num_spin_acq, l.n_spin_acquired, \
|
||||
uint64_t) \
|
||||
CTL_RO_CGEN_PUBLIC(config_stats, stats_##n##_num_owner_switch, \
|
||||
l.n_owner_switches, uint64_t) \
|
||||
CTL_RO_CGEN_PUBLIC(config_stats, stats_##n##_total_wait_time, \
|
||||
nstime_ns(&l.tot_wait_time), uint64_t) \
|
||||
CTL_RO_CGEN_PUBLIC(config_stats, stats_##n##_max_wait_time, \
|
||||
nstime_ns(&l.max_wait_time), uint64_t) \
|
||||
CTL_RO_CGEN_PUBLIC( \
|
||||
config_stats, stats_##n##_max_num_thds, l.max_n_thds, uint32_t)
|
||||
|
||||
/* Global mutexes. */
|
||||
#define OP(mtx) \
|
||||
RO_MUTEX_CTL_GEN(mutexes_##mtx, \
|
||||
ctl_stats->mutex_prof_data[global_prof_mutex_##mtx])
|
||||
MUTEX_PROF_GLOBAL_MUTEXES
|
||||
#undef OP
|
||||
|
||||
/* Per arena mutexes */
|
||||
#define OP(mtx) \
|
||||
RO_MUTEX_CTL_GEN(arenas_i_mutexes_##mtx, \
|
||||
ctl_arenas_i(mib[2]) \
|
||||
->astats->astats.mutex_prof_data[arena_prof_mutex_##mtx])
|
||||
MUTEX_PROF_ARENA_MUTEXES
|
||||
#undef OP
|
||||
|
||||
/* tcache bin mutex */
|
||||
RO_MUTEX_CTL_GEN(
|
||||
arenas_i_bins_j_mutex, ctl_arenas_i(mib[2])->astats->bstats[mib[4]].mutex_data)
|
||||
#undef RO_MUTEX_CTL_GEN
|
||||
|
||||
/* Resets all mutex stats, including global, arena and bin mutexes. */
|
||||
int
|
||||
stats_mutexes_reset_ctl(tsd_t *tsd, const size_t *mib, size_t miblen,
|
||||
void *oldp, size_t *oldlenp, void *newp, size_t newlen) {
|
||||
if (!config_stats) {
|
||||
return ENOENT;
|
||||
}
|
||||
|
||||
tsdn_t *tsdn = tsd_tsdn(tsd);
|
||||
|
||||
#define MUTEX_PROF_RESET(mtx) \
|
||||
malloc_mutex_lock(tsdn, &mtx); \
|
||||
malloc_mutex_prof_data_reset(tsdn, &mtx); \
|
||||
malloc_mutex_unlock(tsdn, &mtx);
|
||||
|
||||
/* Global mutexes: ctl and prof. */
|
||||
ctl_mtx_prof_data_reset(tsdn);
|
||||
if (have_background_thread) {
|
||||
MUTEX_PROF_RESET(background_thread_lock);
|
||||
}
|
||||
if (config_prof && opt_prof) {
|
||||
MUTEX_PROF_RESET(bt2gctx_mtx);
|
||||
MUTEX_PROF_RESET(tdatas_mtx);
|
||||
MUTEX_PROF_RESET(prof_dump_mtx);
|
||||
MUTEX_PROF_RESET(prof_recent_alloc_mtx);
|
||||
MUTEX_PROF_RESET(prof_recent_dump_mtx);
|
||||
MUTEX_PROF_RESET(prof_stats_mtx);
|
||||
}
|
||||
|
||||
/* Per arena mutexes. */
|
||||
unsigned n = narenas_total_get();
|
||||
|
||||
for (unsigned i = 0; i < n; i++) {
|
||||
arena_t *arena = arena_get(tsdn, i, false);
|
||||
if (!arena) {
|
||||
continue;
|
||||
}
|
||||
MUTEX_PROF_RESET(arena->large_mtx);
|
||||
MUTEX_PROF_RESET(arena->pa_shard.edata_cache.mtx);
|
||||
MUTEX_PROF_RESET(arena->pa_shard.pac.ecache_dirty.mtx);
|
||||
MUTEX_PROF_RESET(arena->pa_shard.pac.ecache_muzzy.mtx);
|
||||
MUTEX_PROF_RESET(arena->pa_shard.pac.ecache_retained.mtx);
|
||||
MUTEX_PROF_RESET(arena->pa_shard.pac.ecache_pinned.mtx);
|
||||
MUTEX_PROF_RESET(arena->pa_shard.pac.decay_dirty.mtx);
|
||||
MUTEX_PROF_RESET(arena->pa_shard.pac.decay_muzzy.mtx);
|
||||
MUTEX_PROF_RESET(arena->cache_bin_array_descriptor_ql_mtx);
|
||||
MUTEX_PROF_RESET(arena->base->mtx);
|
||||
|
||||
for (szind_t j = 0; j < SC_NBINS; j++) {
|
||||
for (unsigned k = 0; k < bin_infos[j].n_shards; k++) {
|
||||
bin_t *bin = arena_get_bin(arena, j, k);
|
||||
MUTEX_PROF_RESET(bin->lock);
|
||||
}
|
||||
}
|
||||
}
|
||||
#undef MUTEX_PROF_RESET
|
||||
return 0;
|
||||
}
|
||||
|
||||
CTL_RO_CGEN_PUBLIC(config_stats, stats_arenas_i_bins_j_nmalloc,
|
||||
ctl_arenas_i(mib[2])->astats->bstats[mib[4]].stats_data.nmalloc, uint64_t)
|
||||
CTL_RO_CGEN_PUBLIC(config_stats, stats_arenas_i_bins_j_ndalloc,
|
||||
ctl_arenas_i(mib[2])->astats->bstats[mib[4]].stats_data.ndalloc, uint64_t)
|
||||
CTL_RO_CGEN_PUBLIC(config_stats, stats_arenas_i_bins_j_nrequests,
|
||||
ctl_arenas_i(mib[2])->astats->bstats[mib[4]].stats_data.nrequests, uint64_t)
|
||||
CTL_RO_CGEN_PUBLIC(config_stats, stats_arenas_i_bins_j_curregs,
|
||||
ctl_arenas_i(mib[2])->astats->bstats[mib[4]].stats_data.curregs, size_t)
|
||||
CTL_RO_CGEN_PUBLIC(config_stats, stats_arenas_i_bins_j_nfills,
|
||||
ctl_arenas_i(mib[2])->astats->bstats[mib[4]].stats_data.nfills, uint64_t)
|
||||
CTL_RO_CGEN_PUBLIC(config_stats, stats_arenas_i_bins_j_nflushes,
|
||||
ctl_arenas_i(mib[2])->astats->bstats[mib[4]].stats_data.nflushes, uint64_t)
|
||||
CTL_RO_CGEN_PUBLIC(config_stats, stats_arenas_i_bins_j_nslabs,
|
||||
ctl_arenas_i(mib[2])->astats->bstats[mib[4]].stats_data.nslabs, uint64_t)
|
||||
CTL_RO_CGEN_PUBLIC(config_stats, stats_arenas_i_bins_j_nreslabs,
|
||||
ctl_arenas_i(mib[2])->astats->bstats[mib[4]].stats_data.reslabs, uint64_t)
|
||||
CTL_RO_CGEN_PUBLIC(config_stats, stats_arenas_i_bins_j_curslabs,
|
||||
ctl_arenas_i(mib[2])->astats->bstats[mib[4]].stats_data.curslabs, size_t)
|
||||
CTL_RO_CGEN_PUBLIC(config_stats, stats_arenas_i_bins_j_nonfull_slabs,
|
||||
ctl_arenas_i(mib[2])->astats->bstats[mib[4]].stats_data.nonfull_slabs, size_t)
|
||||
|
||||
|
||||
CTL_RO_CGEN_PUBLIC(config_stats, stats_arenas_i_lextents_j_nmalloc,
|
||||
locked_read_u64_unsynchronized(
|
||||
&ctl_arenas_i(mib[2])->astats->lstats[mib[4]].nmalloc),
|
||||
uint64_t)
|
||||
CTL_RO_CGEN_PUBLIC(config_stats, stats_arenas_i_lextents_j_ndalloc,
|
||||
locked_read_u64_unsynchronized(
|
||||
&ctl_arenas_i(mib[2])->astats->lstats[mib[4]].ndalloc),
|
||||
uint64_t)
|
||||
CTL_RO_CGEN_PUBLIC(config_stats, stats_arenas_i_lextents_j_nrequests,
|
||||
locked_read_u64_unsynchronized(
|
||||
&ctl_arenas_i(mib[2])->astats->lstats[mib[4]].nrequests),
|
||||
uint64_t)
|
||||
CTL_RO_CGEN_PUBLIC(config_stats, stats_arenas_i_lextents_j_curlextents,
|
||||
ctl_arenas_i(mib[2])->astats->lstats[mib[4]].curlextents, size_t)
|
||||
|
||||
|
||||
CTL_RO_CGEN_PUBLIC(config_stats, stats_arenas_i_extents_j_ndirty,
|
||||
ctl_arenas_i(mib[2])->astats->estats[mib[4]].ndirty, size_t)
|
||||
CTL_RO_CGEN_PUBLIC(config_stats, stats_arenas_i_extents_j_nmuzzy,
|
||||
ctl_arenas_i(mib[2])->astats->estats[mib[4]].nmuzzy, size_t)
|
||||
CTL_RO_CGEN_PUBLIC(config_stats, stats_arenas_i_extents_j_nretained,
|
||||
ctl_arenas_i(mib[2])->astats->estats[mib[4]].nretained, size_t)
|
||||
CTL_RO_CGEN_PUBLIC(config_stats, stats_arenas_i_extents_j_npinned,
|
||||
ctl_arenas_i(mib[2])->astats->estats[mib[4]].npinned, size_t)
|
||||
CTL_RO_CGEN_PUBLIC(config_stats, stats_arenas_i_extents_j_dirty_bytes,
|
||||
ctl_arenas_i(mib[2])->astats->estats[mib[4]].dirty_bytes, size_t)
|
||||
CTL_RO_CGEN_PUBLIC(config_stats, stats_arenas_i_extents_j_muzzy_bytes,
|
||||
ctl_arenas_i(mib[2])->astats->estats[mib[4]].muzzy_bytes, size_t)
|
||||
CTL_RO_CGEN_PUBLIC(config_stats, stats_arenas_i_extents_j_retained_bytes,
|
||||
ctl_arenas_i(mib[2])->astats->estats[mib[4]].retained_bytes, size_t)
|
||||
CTL_RO_CGEN_PUBLIC(config_stats, stats_arenas_i_extents_j_pinned_bytes,
|
||||
ctl_arenas_i(mib[2])->astats->estats[mib[4]].pinned_bytes, size_t)
|
||||
|
||||
|
||||
CTL_RO_CGEN_PUBLIC(config_stats, stats_arenas_i_hpa_shard_npageslabs,
|
||||
ctl_arenas_i(mib[2])->astats->hpastats.psset_stats.merged.npageslabs, size_t)
|
||||
CTL_RO_CGEN_PUBLIC(config_stats, stats_arenas_i_hpa_shard_nactive,
|
||||
ctl_arenas_i(mib[2])->astats->hpastats.psset_stats.merged.nactive, size_t)
|
||||
CTL_RO_CGEN_PUBLIC(config_stats, stats_arenas_i_hpa_shard_ndirty,
|
||||
ctl_arenas_i(mib[2])->astats->hpastats.psset_stats.merged.ndirty, size_t)
|
||||
|
||||
/* Nonhuge slabs */
|
||||
CTL_RO_CGEN_PUBLIC(config_stats, stats_arenas_i_hpa_shard_slabs_npageslabs_nonhuge,
|
||||
ctl_arenas_i(mib[2])->astats->hpastats.psset_stats.slabs[0].npageslabs, size_t)
|
||||
CTL_RO_CGEN_PUBLIC(config_stats, stats_arenas_i_hpa_shard_slabs_nactive_nonhuge,
|
||||
ctl_arenas_i(mib[2])->astats->hpastats.psset_stats.slabs[0].nactive, size_t)
|
||||
CTL_RO_CGEN_PUBLIC(config_stats, stats_arenas_i_hpa_shard_slabs_ndirty_nonhuge,
|
||||
ctl_arenas_i(mib[2])->astats->hpastats.psset_stats.slabs[0].ndirty, size_t)
|
||||
|
||||
/* Huge slabs */
|
||||
CTL_RO_CGEN_PUBLIC(config_stats, stats_arenas_i_hpa_shard_slabs_npageslabs_huge,
|
||||
ctl_arenas_i(mib[2])->astats->hpastats.psset_stats.slabs[1].npageslabs, size_t)
|
||||
CTL_RO_CGEN_PUBLIC(config_stats, stats_arenas_i_hpa_shard_slabs_nactive_huge,
|
||||
ctl_arenas_i(mib[2])->astats->hpastats.psset_stats.slabs[1].nactive, size_t)
|
||||
CTL_RO_CGEN_PUBLIC(config_stats, stats_arenas_i_hpa_shard_slabs_ndirty_huge,
|
||||
ctl_arenas_i(mib[2])->astats->hpastats.psset_stats.slabs[1].ndirty, size_t)
|
||||
|
||||
CTL_RO_CGEN_PUBLIC(config_stats, stats_arenas_i_hpa_shard_npurge_passes,
|
||||
ctl_arenas_i(mib[2])->astats->hpastats.nonderived_stats.npurge_passes,
|
||||
uint64_t)
|
||||
CTL_RO_CGEN_PUBLIC(config_stats, stats_arenas_i_hpa_shard_npurges,
|
||||
ctl_arenas_i(mib[2])->astats->hpastats.nonderived_stats.npurges, uint64_t)
|
||||
CTL_RO_CGEN_PUBLIC(config_stats, stats_arenas_i_hpa_shard_nhugifies,
|
||||
ctl_arenas_i(mib[2])->astats->hpastats.nonderived_stats.nhugifies, uint64_t)
|
||||
CTL_RO_CGEN_PUBLIC(config_stats, stats_arenas_i_hpa_shard_nhugify_failures,
|
||||
ctl_arenas_i(mib[2])->astats->hpastats.nonderived_stats.nhugify_failures,
|
||||
uint64_t)
|
||||
CTL_RO_CGEN_PUBLIC(config_stats, stats_arenas_i_hpa_shard_ndehugifies,
|
||||
ctl_arenas_i(mib[2])->astats->hpastats.nonderived_stats.ndehugifies, uint64_t)
|
||||
|
||||
CTL_RO_CGEN_PUBLIC(config_stats, stats_arenas_i_hpa_shard_alloc_j_min_extents,
|
||||
ctl_arenas_i(mib[2])
|
||||
->astats->hpastats.nonderived_stats.hpa_alloc_min_extents[mib[5]],
|
||||
uint64_t);
|
||||
CTL_RO_CGEN_PUBLIC(config_stats, stats_arenas_i_hpa_shard_alloc_j_max_extents,
|
||||
ctl_arenas_i(mib[2])
|
||||
->astats->hpastats.nonderived_stats.hpa_alloc_max_extents[mib[5]],
|
||||
uint64_t);
|
||||
CTL_RO_CGEN_PUBLIC(config_stats, stats_arenas_i_hpa_shard_alloc_j_extents,
|
||||
ctl_arenas_i(mib[2])
|
||||
->astats->hpastats.nonderived_stats.hpa_alloc_extents[mib[5]],
|
||||
uint64_t);
|
||||
CTL_RO_CGEN_PUBLIC(config_stats, stats_arenas_i_hpa_shard_alloc_j_ps,
|
||||
ctl_arenas_i(mib[2])->astats->hpastats.nonderived_stats.hpa_alloc_ps[mib[5]],
|
||||
uint64_t);
|
||||
CTL_RO_CGEN_PUBLIC(config_stats, stats_arenas_i_hpa_shard_alloc_j_pages_per_ps,
|
||||
ctl_arenas_i(mib[2])
|
||||
->astats->hpastats.nonderived_stats.hpa_alloc_pages_per_ps[mib[5]],
|
||||
uint64_t);
|
||||
CTL_RO_CGEN_PUBLIC(config_stats, stats_arenas_i_hpa_shard_alloc_j_extents_per_ps,
|
||||
ctl_arenas_i(mib[2])
|
||||
->astats->hpastats.nonderived_stats.hpa_alloc_extents_per_ps[mib[5]],
|
||||
uint64_t);
|
||||
CTL_RO_CGEN_PUBLIC(config_stats,
|
||||
stats_arenas_i_hpa_shard_alloc_j_total_elapsed_ns_per_ps,
|
||||
ctl_arenas_i(mib[2])
|
||||
->astats->hpastats.nonderived_stats
|
||||
.hpa_alloc_total_elapsed_ns_per_ps[mib[5]],
|
||||
uint64_t);
|
||||
|
||||
/* Full, nonhuge */
|
||||
CTL_RO_CGEN_PUBLIC(config_stats,
|
||||
stats_arenas_i_hpa_shard_full_slabs_npageslabs_nonhuge,
|
||||
ctl_arenas_i(mib[2])->astats->hpastats.psset_stats.full_slabs[0].npageslabs,
|
||||
size_t)
|
||||
CTL_RO_CGEN_PUBLIC(config_stats, stats_arenas_i_hpa_shard_full_slabs_nactive_nonhuge,
|
||||
ctl_arenas_i(mib[2])->astats->hpastats.psset_stats.full_slabs[0].nactive,
|
||||
size_t)
|
||||
CTL_RO_CGEN_PUBLIC(config_stats, stats_arenas_i_hpa_shard_full_slabs_ndirty_nonhuge,
|
||||
ctl_arenas_i(mib[2])->astats->hpastats.psset_stats.full_slabs[0].ndirty,
|
||||
size_t)
|
||||
|
||||
/* Full, huge */
|
||||
CTL_RO_CGEN_PUBLIC(config_stats, stats_arenas_i_hpa_shard_full_slabs_npageslabs_huge,
|
||||
ctl_arenas_i(mib[2])->astats->hpastats.psset_stats.full_slabs[1].npageslabs,
|
||||
size_t)
|
||||
CTL_RO_CGEN_PUBLIC(config_stats, stats_arenas_i_hpa_shard_full_slabs_nactive_huge,
|
||||
ctl_arenas_i(mib[2])->astats->hpastats.psset_stats.full_slabs[1].nactive,
|
||||
size_t)
|
||||
CTL_RO_CGEN_PUBLIC(config_stats, stats_arenas_i_hpa_shard_full_slabs_ndirty_huge,
|
||||
ctl_arenas_i(mib[2])->astats->hpastats.psset_stats.full_slabs[1].ndirty,
|
||||
size_t)
|
||||
|
||||
/* Empty, nonhuge */
|
||||
CTL_RO_CGEN_PUBLIC(config_stats,
|
||||
stats_arenas_i_hpa_shard_empty_slabs_npageslabs_nonhuge,
|
||||
ctl_arenas_i(mib[2])->astats->hpastats.psset_stats.empty_slabs[0].npageslabs,
|
||||
size_t)
|
||||
CTL_RO_CGEN_PUBLIC(config_stats, stats_arenas_i_hpa_shard_empty_slabs_nactive_nonhuge,
|
||||
ctl_arenas_i(mib[2])->astats->hpastats.psset_stats.empty_slabs[0].nactive,
|
||||
size_t)
|
||||
CTL_RO_CGEN_PUBLIC(config_stats, stats_arenas_i_hpa_shard_empty_slabs_ndirty_nonhuge,
|
||||
ctl_arenas_i(mib[2])->astats->hpastats.psset_stats.empty_slabs[0].ndirty,
|
||||
size_t)
|
||||
|
||||
/* Empty, huge */
|
||||
CTL_RO_CGEN_PUBLIC(config_stats, stats_arenas_i_hpa_shard_empty_slabs_npageslabs_huge,
|
||||
ctl_arenas_i(mib[2])->astats->hpastats.psset_stats.empty_slabs[1].npageslabs,
|
||||
size_t)
|
||||
CTL_RO_CGEN_PUBLIC(config_stats, stats_arenas_i_hpa_shard_empty_slabs_nactive_huge,
|
||||
ctl_arenas_i(mib[2])->astats->hpastats.psset_stats.empty_slabs[1].nactive,
|
||||
size_t)
|
||||
CTL_RO_CGEN_PUBLIC(config_stats, stats_arenas_i_hpa_shard_empty_slabs_ndirty_huge,
|
||||
ctl_arenas_i(mib[2])->astats->hpastats.psset_stats.empty_slabs[1].ndirty,
|
||||
size_t)
|
||||
|
||||
/* Nonfull, nonhuge */
|
||||
CTL_RO_CGEN_PUBLIC(config_stats,
|
||||
stats_arenas_i_hpa_shard_nonfull_slabs_j_npageslabs_nonhuge,
|
||||
ctl_arenas_i(mib[2])
|
||||
->astats->hpastats.psset_stats.nonfull_slabs[mib[5]][0]
|
||||
.npageslabs,
|
||||
size_t)
|
||||
CTL_RO_CGEN_PUBLIC(config_stats,
|
||||
stats_arenas_i_hpa_shard_nonfull_slabs_j_nactive_nonhuge,
|
||||
ctl_arenas_i(mib[2])
|
||||
->astats->hpastats.psset_stats.nonfull_slabs[mib[5]][0]
|
||||
.nactive,
|
||||
size_t)
|
||||
CTL_RO_CGEN_PUBLIC(config_stats,
|
||||
stats_arenas_i_hpa_shard_nonfull_slabs_j_ndirty_nonhuge,
|
||||
ctl_arenas_i(mib[2])
|
||||
->astats->hpastats.psset_stats.nonfull_slabs[mib[5]][0]
|
||||
.ndirty,
|
||||
size_t)
|
||||
|
||||
/* Nonfull, huge */
|
||||
CTL_RO_CGEN_PUBLIC(config_stats,
|
||||
stats_arenas_i_hpa_shard_nonfull_slabs_j_npageslabs_huge,
|
||||
ctl_arenas_i(mib[2])
|
||||
->astats->hpastats.psset_stats.nonfull_slabs[mib[5]][1]
|
||||
.npageslabs,
|
||||
size_t)
|
||||
CTL_RO_CGEN_PUBLIC(config_stats, stats_arenas_i_hpa_shard_nonfull_slabs_j_nactive_huge,
|
||||
ctl_arenas_i(mib[2])
|
||||
->astats->hpastats.psset_stats.nonfull_slabs[mib[5]][1]
|
||||
.nactive,
|
||||
size_t)
|
||||
CTL_RO_CGEN_PUBLIC(config_stats, stats_arenas_i_hpa_shard_nonfull_slabs_j_ndirty_huge,
|
||||
ctl_arenas_i(mib[2])
|
||||
->astats->hpastats.psset_stats.nonfull_slabs[mib[5]][1]
|
||||
.ndirty,
|
||||
size_t)
|
||||
56
src/ctl_tcache.c
Normal file
56
src/ctl_tcache.c
Normal file
|
|
@ -0,0 +1,56 @@
|
|||
#include "jemalloc/internal/jemalloc_preamble.h"
|
||||
#include "jemalloc/internal/jemalloc_internal_includes.h"
|
||||
|
||||
#include "jemalloc/internal/ctl_tcache.h"
|
||||
|
||||
/******************************************************************************/
|
||||
/* tcache.* mallctl handlers. */
|
||||
|
||||
int
|
||||
tcache_create_ctl(tsd_t *tsd, const size_t *mib, size_t miblen, void *oldp,
|
||||
size_t *oldlenp, void *newp, size_t newlen) {
|
||||
int ret;
|
||||
unsigned tcache_ind;
|
||||
|
||||
READONLY();
|
||||
VERIFY_READ(unsigned);
|
||||
if (tcaches_create(tsd, b0get(), &tcache_ind)) {
|
||||
ret = EFAULT;
|
||||
goto label_return;
|
||||
}
|
||||
READ(tcache_ind, unsigned);
|
||||
|
||||
ret = 0;
|
||||
label_return:
|
||||
return ret;
|
||||
}
|
||||
|
||||
int
|
||||
tcache_flush_ctl(tsd_t *tsd, const size_t *mib, size_t miblen, void *oldp,
|
||||
size_t *oldlenp, void *newp, size_t newlen) {
|
||||
int ret;
|
||||
unsigned tcache_ind;
|
||||
|
||||
WRITEONLY();
|
||||
ASSURED_WRITE(tcache_ind, unsigned);
|
||||
tcaches_flush(tsd, tcache_ind);
|
||||
|
||||
ret = 0;
|
||||
label_return:
|
||||
return ret;
|
||||
}
|
||||
|
||||
int
|
||||
tcache_destroy_ctl(tsd_t *tsd, const size_t *mib, size_t miblen, void *oldp,
|
||||
size_t *oldlenp, void *newp, size_t newlen) {
|
||||
int ret;
|
||||
unsigned tcache_ind;
|
||||
|
||||
WRITEONLY();
|
||||
ASSURED_WRITE(tcache_ind, unsigned);
|
||||
tcaches_destroy(tsd, tcache_ind);
|
||||
|
||||
ret = 0;
|
||||
label_return:
|
||||
return ret;
|
||||
}
|
||||
353
src/ctl_thread.c
Normal file
353
src/ctl_thread.c
Normal file
|
|
@ -0,0 +1,353 @@
|
|||
#include "jemalloc/internal/jemalloc_preamble.h"
|
||||
#include "jemalloc/internal/jemalloc_internal_includes.h"
|
||||
|
||||
#include "jemalloc/internal/assert.h"
|
||||
#include "jemalloc/internal/ctl_thread.h"
|
||||
#include "jemalloc/internal/peak_event.h"
|
||||
#include "jemalloc/internal/prof_data.h"
|
||||
#include "jemalloc/internal/sc.h"
|
||||
#include "jemalloc/internal/thread_event_registry.h"
|
||||
|
||||
/*******************************************************************************/
|
||||
/* thread.* mallctl handlers. */
|
||||
|
||||
int
|
||||
thread_arena_ctl(tsd_t *tsd, const size_t *mib, size_t miblen, void *oldp,
|
||||
size_t *oldlenp, void *newp, size_t newlen) {
|
||||
int ret;
|
||||
arena_t *oldarena;
|
||||
unsigned newind, oldind;
|
||||
|
||||
oldarena = arena_choose(tsd, NULL);
|
||||
if (oldarena == NULL) {
|
||||
return EAGAIN;
|
||||
}
|
||||
newind = oldind = arena_ind_get(oldarena);
|
||||
WRITE(newind, unsigned);
|
||||
READ(oldind, unsigned);
|
||||
|
||||
if (newind != oldind) {
|
||||
arena_t *newarena;
|
||||
|
||||
if (newind >= narenas_total_get()) {
|
||||
/* New arena index is out of range. */
|
||||
ret = EFAULT;
|
||||
goto label_return;
|
||||
}
|
||||
|
||||
if (have_percpu_arena
|
||||
&& PERCPU_ARENA_ENABLED(opt_percpu_arena)) {
|
||||
if (newind < percpu_arena_ind_limit(opt_percpu_arena)) {
|
||||
/*
|
||||
* If perCPU arena is enabled, thread_arena
|
||||
* control is not allowed for the auto arena
|
||||
* range.
|
||||
*/
|
||||
ret = EPERM;
|
||||
goto label_return;
|
||||
}
|
||||
}
|
||||
|
||||
/* Initialize arena if necessary. */
|
||||
newarena = arena_get(tsd_tsdn(tsd), newind, true);
|
||||
if (newarena == NULL) {
|
||||
ret = EAGAIN;
|
||||
goto label_return;
|
||||
}
|
||||
thread_migrate_arena(tsd, oldarena, newarena);
|
||||
}
|
||||
|
||||
ret = 0;
|
||||
label_return:
|
||||
return ret;
|
||||
}
|
||||
CTL_RO_NL_GEN_PUBLIC(thread_allocated, tsd_thread_allocated_get(tsd), uint64_t)
|
||||
CTL_RO_NL_GEN_PUBLIC(thread_allocatedp, tsd_thread_allocatedp_get(tsd), uint64_t *)
|
||||
|
||||
int
|
||||
thread_tcache_ncached_max_read_sizeclass_ctl(tsd_t *tsd, const size_t *mib,
|
||||
size_t miblen, void *oldp, size_t *oldlenp, void *newp, size_t newlen) {
|
||||
int ret;
|
||||
size_t bin_size = 0;
|
||||
|
||||
/* Read the bin size from newp. */
|
||||
if (newp == NULL) {
|
||||
ret = EINVAL;
|
||||
goto label_return;
|
||||
}
|
||||
WRITE(bin_size, size_t);
|
||||
|
||||
cache_bin_sz_t ncached_max = 0;
|
||||
if (tcache_bin_ncached_max_read(tsd, bin_size, &ncached_max)) {
|
||||
ret = EINVAL;
|
||||
goto label_return;
|
||||
}
|
||||
size_t result = (size_t)ncached_max;
|
||||
READ(result, size_t);
|
||||
ret = 0;
|
||||
label_return:
|
||||
return ret;
|
||||
}
|
||||
|
||||
int
|
||||
thread_tcache_ncached_max_write_ctl(tsd_t *tsd, const size_t *mib,
|
||||
size_t miblen, void *oldp, size_t *oldlenp, void *newp, size_t newlen) {
|
||||
int ret;
|
||||
WRITEONLY();
|
||||
if (newp != NULL) {
|
||||
if (!tcache_available(tsd)) {
|
||||
ret = ENOENT;
|
||||
goto label_return;
|
||||
}
|
||||
char *settings = NULL;
|
||||
WRITE(settings, char *);
|
||||
if (settings == NULL) {
|
||||
ret = EINVAL;
|
||||
goto label_return;
|
||||
}
|
||||
/* Get the length of the setting string safely. */
|
||||
char *end = (char *)memchr(
|
||||
settings, '\0', CTL_MULTI_SETTING_MAX_LEN);
|
||||
if (end == NULL) {
|
||||
ret = EINVAL;
|
||||
goto label_return;
|
||||
}
|
||||
/*
|
||||
* Exclude the last '\0' for len since it is not handled by
|
||||
* multi_setting_parse_next.
|
||||
*/
|
||||
size_t len = (uintptr_t)end - (uintptr_t)settings;
|
||||
if (len == 0) {
|
||||
ret = 0;
|
||||
goto label_return;
|
||||
}
|
||||
|
||||
if (tcache_bins_ncached_max_write(tsd, settings, len)) {
|
||||
ret = EINVAL;
|
||||
goto label_return;
|
||||
}
|
||||
}
|
||||
|
||||
ret = 0;
|
||||
label_return:
|
||||
return ret;
|
||||
}
|
||||
|
||||
CTL_RO_NL_GEN_PUBLIC(thread_deallocated, tsd_thread_deallocated_get(tsd), uint64_t)
|
||||
CTL_RO_NL_GEN_PUBLIC(thread_deallocatedp, tsd_thread_deallocatedp_get(tsd), uint64_t *)
|
||||
|
||||
int
|
||||
thread_tcache_enabled_ctl(tsd_t *tsd, const size_t *mib, size_t miblen,
|
||||
void *oldp, size_t *oldlenp, void *newp, size_t newlen) {
|
||||
int ret;
|
||||
bool oldval;
|
||||
|
||||
oldval = tcache_enabled_get(tsd);
|
||||
if (newp != NULL) {
|
||||
if (newlen != sizeof(bool)) {
|
||||
ret = EINVAL;
|
||||
goto label_return;
|
||||
}
|
||||
tcache_enabled_set(tsd, *(bool *)newp);
|
||||
}
|
||||
READ(oldval, bool);
|
||||
|
||||
ret = 0;
|
||||
label_return:
|
||||
return ret;
|
||||
}
|
||||
|
||||
int
|
||||
thread_tcache_max_ctl(tsd_t *tsd, const size_t *mib, size_t miblen, void *oldp,
|
||||
size_t *oldlenp, void *newp, size_t newlen) {
|
||||
int ret;
|
||||
size_t oldval;
|
||||
|
||||
/* pointer to tcache_t always exists even with tcache disabled. */
|
||||
tcache_t *tcache = tsd_tcachep_get(tsd);
|
||||
assert(tcache != NULL);
|
||||
oldval = tcache_max_get(tcache->tcache_slow);
|
||||
READ(oldval, size_t);
|
||||
|
||||
if (newp != NULL) {
|
||||
if (newlen != sizeof(size_t)) {
|
||||
ret = EINVAL;
|
||||
goto label_return;
|
||||
}
|
||||
size_t new_tcache_max = oldval;
|
||||
WRITE(new_tcache_max, size_t);
|
||||
if (new_tcache_max > TCACHE_MAXCLASS_LIMIT) {
|
||||
new_tcache_max = TCACHE_MAXCLASS_LIMIT;
|
||||
}
|
||||
new_tcache_max = sz_s2u(new_tcache_max);
|
||||
if (new_tcache_max != oldval) {
|
||||
thread_tcache_max_set(tsd, new_tcache_max);
|
||||
}
|
||||
}
|
||||
|
||||
ret = 0;
|
||||
label_return:
|
||||
return ret;
|
||||
}
|
||||
|
||||
int
|
||||
thread_tcache_flush_ctl(tsd_t *tsd, const size_t *mib, size_t miblen,
|
||||
void *oldp, size_t *oldlenp, void *newp, size_t newlen) {
|
||||
int ret;
|
||||
|
||||
if (!tcache_available(tsd)) {
|
||||
ret = EFAULT;
|
||||
goto label_return;
|
||||
}
|
||||
|
||||
NEITHER_READ_NOR_WRITE();
|
||||
|
||||
tcache_flush(tsd);
|
||||
|
||||
ret = 0;
|
||||
label_return:
|
||||
return ret;
|
||||
}
|
||||
|
||||
int
|
||||
thread_peak_read_ctl(tsd_t *tsd, const size_t *mib, size_t miblen, void *oldp,
|
||||
size_t *oldlenp, void *newp, size_t newlen) {
|
||||
int ret;
|
||||
if (!config_stats) {
|
||||
return ENOENT;
|
||||
}
|
||||
READONLY();
|
||||
peak_event_update(tsd);
|
||||
uint64_t result = peak_event_max(tsd);
|
||||
READ(result, uint64_t);
|
||||
ret = 0;
|
||||
label_return:
|
||||
return ret;
|
||||
}
|
||||
|
||||
int
|
||||
thread_peak_reset_ctl(tsd_t *tsd, const size_t *mib, size_t miblen, void *oldp,
|
||||
size_t *oldlenp, void *newp, size_t newlen) {
|
||||
int ret;
|
||||
if (!config_stats) {
|
||||
return ENOENT;
|
||||
}
|
||||
NEITHER_READ_NOR_WRITE();
|
||||
peak_event_zero(tsd);
|
||||
ret = 0;
|
||||
label_return:
|
||||
return ret;
|
||||
}
|
||||
|
||||
int
|
||||
thread_prof_name_ctl(tsd_t *tsd, const size_t *mib, size_t miblen, void *oldp,
|
||||
size_t *oldlenp, void *newp, size_t newlen) {
|
||||
int ret;
|
||||
|
||||
if (!config_prof || !opt_prof) {
|
||||
return ENOENT;
|
||||
}
|
||||
|
||||
READ_XOR_WRITE();
|
||||
|
||||
if (newp != NULL) {
|
||||
const char *newval = *(const char **)newp;
|
||||
if (newlen != sizeof(const char *) || newval == NULL) {
|
||||
ret = EINVAL;
|
||||
goto label_return;
|
||||
}
|
||||
|
||||
if ((ret = prof_thread_name_set(tsd, newval)) != 0) {
|
||||
goto label_return;
|
||||
}
|
||||
} else {
|
||||
const char *oldname = prof_thread_name_get(tsd);
|
||||
READ(oldname, const char *);
|
||||
}
|
||||
|
||||
ret = 0;
|
||||
label_return:
|
||||
return ret;
|
||||
}
|
||||
|
||||
int
|
||||
thread_prof_active_ctl(tsd_t *tsd, const size_t *mib, size_t miblen, void *oldp,
|
||||
size_t *oldlenp, void *newp, size_t newlen) {
|
||||
int ret;
|
||||
bool oldval;
|
||||
|
||||
if (!config_prof) {
|
||||
return ENOENT;
|
||||
}
|
||||
|
||||
oldval = opt_prof ? prof_thread_active_get(tsd) : false;
|
||||
if (newp != NULL) {
|
||||
if (!opt_prof) {
|
||||
ret = ENOENT;
|
||||
goto label_return;
|
||||
}
|
||||
if (newlen != sizeof(bool)) {
|
||||
ret = EINVAL;
|
||||
goto label_return;
|
||||
}
|
||||
if (prof_thread_active_set(tsd, *(bool *)newp)) {
|
||||
ret = EAGAIN;
|
||||
goto label_return;
|
||||
}
|
||||
}
|
||||
READ(oldval, bool);
|
||||
|
||||
ret = 0;
|
||||
label_return:
|
||||
return ret;
|
||||
}
|
||||
|
||||
int
|
||||
thread_idle_ctl(tsd_t *tsd, const size_t *mib, size_t miblen, void *oldp,
|
||||
size_t *oldlenp, void *newp, size_t newlen) {
|
||||
int ret;
|
||||
|
||||
NEITHER_READ_NOR_WRITE();
|
||||
|
||||
if (tcache_available(tsd)) {
|
||||
tcache_flush(tsd);
|
||||
}
|
||||
/*
|
||||
* This heuristic is perhaps not the most well-considered. But it
|
||||
* matches the only idling policy we have experience with in the status
|
||||
* quo. Over time we should investigate more principled approaches.
|
||||
*/
|
||||
if (opt_narenas > ncpus * 2) {
|
||||
arena_t *arena = arena_choose(tsd, NULL);
|
||||
if (arena != NULL) {
|
||||
arena_decay(tsd_tsdn(tsd), arena, false, true);
|
||||
}
|
||||
/*
|
||||
* The missing arena case is not actually an error; a thread
|
||||
* might be idle before it associates itself to one. This is
|
||||
* unusual, but not wrong.
|
||||
*/
|
||||
}
|
||||
|
||||
ret = 0;
|
||||
label_return:
|
||||
return ret;
|
||||
}
|
||||
|
||||
int
|
||||
experimental_hooks_thread_event_ctl(tsd_t *tsd, const size_t *mib,
|
||||
size_t miblen, void *oldp, size_t *oldlenp, void *newp, size_t newlen) {
|
||||
int ret;
|
||||
|
||||
if (newp == NULL) {
|
||||
ret = EINVAL;
|
||||
goto label_return;
|
||||
}
|
||||
|
||||
user_hook_object_t t_new = {NULL, 0, false};
|
||||
WRITE(t_new, user_hook_object_t);
|
||||
ret = te_register_user_handler(tsd_tsdn(tsd), &t_new);
|
||||
|
||||
label_return:
|
||||
return ret;
|
||||
}
|
||||
51
src/ctl_utilization.c
Normal file
51
src/ctl_utilization.c
Normal file
|
|
@ -0,0 +1,51 @@
|
|||
#include "jemalloc/internal/jemalloc_preamble.h"
|
||||
#include "jemalloc/internal/jemalloc_internal_includes.h"
|
||||
|
||||
#include "jemalloc/internal/assert.h"
|
||||
#include "jemalloc/internal/ctl_utilization.h"
|
||||
#include "jemalloc/internal/inspect.h"
|
||||
|
||||
/******************************************************************************/
|
||||
/* experimental.utilization.* mallctl handlers. */
|
||||
|
||||
/*
|
||||
* Given an input array of pointers, output three memory utilization entries of
|
||||
* type size_t for each input pointer about the extent it resides in:
|
||||
*
|
||||
* (a) number of free regions in the extent,
|
||||
* (b) number of regions in the extent, and
|
||||
* (c) size of the extent in terms of bytes.
|
||||
*
|
||||
* This API is mainly intended for small class allocations, where extents are
|
||||
* used as slab. In case of large class allocations, the outputs are trivial:
|
||||
* "(a)" will be 0, "(b)" will be 1, and "(c)" will be the usable size.
|
||||
*/
|
||||
int
|
||||
experimental_utilization_batch_query_ctl(tsd_t *tsd, const size_t *mib,
|
||||
size_t miblen, void *oldp, size_t *oldlenp, void *newp, size_t newlen) {
|
||||
int ret;
|
||||
|
||||
assert(sizeof(inspect_extent_util_stats_t) == sizeof(size_t) * 3);
|
||||
|
||||
const size_t len = newlen / sizeof(const void *);
|
||||
if (oldp == NULL || oldlenp == NULL || newp == NULL || newlen == 0
|
||||
|| newlen != len * sizeof(const void *)
|
||||
|| *oldlenp != len * sizeof(inspect_extent_util_stats_t)) {
|
||||
ret = EINVAL;
|
||||
goto label_return;
|
||||
}
|
||||
|
||||
void **ptrs = (void **)newp;
|
||||
inspect_extent_util_stats_t *util_stats =
|
||||
(inspect_extent_util_stats_t *)oldp;
|
||||
size_t i;
|
||||
for (i = 0; i < len; ++i) {
|
||||
inspect_extent_util_stats_get(tsd_tsdn(tsd), ptrs[i],
|
||||
&util_stats[i].nfree, &util_stats[i].nregs,
|
||||
&util_stats[i].size);
|
||||
}
|
||||
ret = 0;
|
||||
|
||||
label_return:
|
||||
return ret;
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue