Avoid arena_prof_accum()-related locking when possible.
Refactor arena_prof_accum() and its callers to avoid arena locking when prof_interval is 0 (as when profiling is disabled). Reported by Ben Maurer.
This commit is contained in:
parent
556ddc7fa9
commit
a3b3386ddd
@ -400,7 +400,6 @@ extern arena_bin_info_t arena_bin_info[NBINS];
|
|||||||
#define nlclasses (chunk_npages - map_bias)
|
#define nlclasses (chunk_npages - map_bias)
|
||||||
|
|
||||||
void arena_purge_all(arena_t *arena);
|
void arena_purge_all(arena_t *arena);
|
||||||
void arena_prof_accum(arena_t *arena, uint64_t accumbytes);
|
|
||||||
void arena_tcache_fill_small(arena_t *arena, tcache_bin_t *tbin,
|
void arena_tcache_fill_small(arena_t *arena, tcache_bin_t *tbin,
|
||||||
size_t binind, uint64_t prof_accumbytes);
|
size_t binind, uint64_t prof_accumbytes);
|
||||||
void arena_alloc_junk_small(void *ptr, arena_bin_info_t *bin_info,
|
void arena_alloc_junk_small(void *ptr, arena_bin_info_t *bin_info,
|
||||||
@ -464,6 +463,9 @@ void arena_mapbits_small_set(arena_chunk_t *chunk, size_t pageind,
|
|||||||
size_t runind, size_t binind, size_t flags);
|
size_t runind, size_t binind, size_t flags);
|
||||||
void arena_mapbits_unzeroed_set(arena_chunk_t *chunk, size_t pageind,
|
void arena_mapbits_unzeroed_set(arena_chunk_t *chunk, size_t pageind,
|
||||||
size_t unzeroed);
|
size_t unzeroed);
|
||||||
|
void arena_prof_accum_impl(arena_t *arena, uint64_t accumbytes);
|
||||||
|
void arena_prof_accum_locked(arena_t *arena, uint64_t accumbytes);
|
||||||
|
void arena_prof_accum(arena_t *arena, uint64_t accumbytes);
|
||||||
size_t arena_ptr_small_binind_get(const void *ptr, size_t mapbits);
|
size_t arena_ptr_small_binind_get(const void *ptr, size_t mapbits);
|
||||||
size_t arena_bin_index(arena_t *arena, arena_bin_t *bin);
|
size_t arena_bin_index(arena_t *arena, arena_bin_t *bin);
|
||||||
unsigned arena_run_regind(arena_run_t *run, arena_bin_info_t *bin_info,
|
unsigned arena_run_regind(arena_run_t *run, arena_bin_info_t *bin_info,
|
||||||
@ -661,6 +663,44 @@ arena_mapbits_unzeroed_set(arena_chunk_t *chunk, size_t pageind,
|
|||||||
*mapbitsp = (*mapbitsp & ~CHUNK_MAP_UNZEROED) | unzeroed;
|
*mapbitsp = (*mapbitsp & ~CHUNK_MAP_UNZEROED) | unzeroed;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
JEMALLOC_INLINE void
|
||||||
|
arena_prof_accum_impl(arena_t *arena, uint64_t accumbytes)
|
||||||
|
{
|
||||||
|
|
||||||
|
cassert(config_prof);
|
||||||
|
assert(prof_interval != 0);
|
||||||
|
|
||||||
|
arena->prof_accumbytes += accumbytes;
|
||||||
|
if (arena->prof_accumbytes >= prof_interval) {
|
||||||
|
prof_idump();
|
||||||
|
arena->prof_accumbytes -= prof_interval;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
JEMALLOC_INLINE void
|
||||||
|
arena_prof_accum_locked(arena_t *arena, uint64_t accumbytes)
|
||||||
|
{
|
||||||
|
|
||||||
|
cassert(config_prof);
|
||||||
|
|
||||||
|
if (prof_interval == 0)
|
||||||
|
return;
|
||||||
|
arena_prof_accum_impl(arena, accumbytes);
|
||||||
|
}
|
||||||
|
|
||||||
|
JEMALLOC_INLINE void
|
||||||
|
arena_prof_accum(arena_t *arena, uint64_t accumbytes)
|
||||||
|
{
|
||||||
|
|
||||||
|
cassert(config_prof);
|
||||||
|
|
||||||
|
if (prof_interval == 0)
|
||||||
|
return;
|
||||||
|
malloc_mutex_lock(&arena->lock);
|
||||||
|
arena_prof_accum_impl(arena, accumbytes);
|
||||||
|
malloc_mutex_unlock(&arena->lock);
|
||||||
|
}
|
||||||
|
|
||||||
JEMALLOC_INLINE size_t
|
JEMALLOC_INLINE size_t
|
||||||
arena_ptr_small_binind_get(const void *ptr, size_t mapbits)
|
arena_ptr_small_binind_get(const void *ptr, size_t mapbits)
|
||||||
{
|
{
|
||||||
|
@ -41,6 +41,8 @@
|
|||||||
#define arena_postfork_parent JEMALLOC_N(arena_postfork_parent)
|
#define arena_postfork_parent JEMALLOC_N(arena_postfork_parent)
|
||||||
#define arena_prefork JEMALLOC_N(arena_prefork)
|
#define arena_prefork JEMALLOC_N(arena_prefork)
|
||||||
#define arena_prof_accum JEMALLOC_N(arena_prof_accum)
|
#define arena_prof_accum JEMALLOC_N(arena_prof_accum)
|
||||||
|
#define arena_prof_accum_impl JEMALLOC_N(arena_prof_accum_impl)
|
||||||
|
#define arena_prof_accum_locked JEMALLOC_N(arena_prof_accum_locked)
|
||||||
#define arena_prof_ctx_get JEMALLOC_N(arena_prof_ctx_get)
|
#define arena_prof_ctx_get JEMALLOC_N(arena_prof_ctx_get)
|
||||||
#define arena_prof_ctx_set JEMALLOC_N(arena_prof_ctx_set)
|
#define arena_prof_ctx_set JEMALLOC_N(arena_prof_ctx_set)
|
||||||
#define arena_prof_promoted JEMALLOC_N(arena_prof_promoted)
|
#define arena_prof_promoted JEMALLOC_N(arena_prof_promoted)
|
||||||
|
27
src/arena.c
27
src/arena.c
@ -1321,21 +1321,6 @@ arena_bin_malloc_hard(arena_t *arena, arena_bin_t *bin)
|
|||||||
return (arena_run_reg_alloc(bin->runcur, bin_info));
|
return (arena_run_reg_alloc(bin->runcur, bin_info));
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
|
||||||
arena_prof_accum(arena_t *arena, uint64_t accumbytes)
|
|
||||||
{
|
|
||||||
|
|
||||||
cassert(config_prof);
|
|
||||||
|
|
||||||
if (config_prof && prof_interval != 0) {
|
|
||||||
arena->prof_accumbytes += accumbytes;
|
|
||||||
if (arena->prof_accumbytes >= prof_interval) {
|
|
||||||
prof_idump();
|
|
||||||
arena->prof_accumbytes -= prof_interval;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
void
|
||||||
arena_tcache_fill_small(arena_t *arena, tcache_bin_t *tbin, size_t binind,
|
arena_tcache_fill_small(arena_t *arena, tcache_bin_t *tbin, size_t binind,
|
||||||
uint64_t prof_accumbytes)
|
uint64_t prof_accumbytes)
|
||||||
@ -1347,11 +1332,8 @@ arena_tcache_fill_small(arena_t *arena, tcache_bin_t *tbin, size_t binind,
|
|||||||
|
|
||||||
assert(tbin->ncached == 0);
|
assert(tbin->ncached == 0);
|
||||||
|
|
||||||
if (config_prof) {
|
if (config_prof)
|
||||||
malloc_mutex_lock(&arena->lock);
|
|
||||||
arena_prof_accum(arena, prof_accumbytes);
|
arena_prof_accum(arena, prof_accumbytes);
|
||||||
malloc_mutex_unlock(&arena->lock);
|
|
||||||
}
|
|
||||||
bin = &arena->bins[binind];
|
bin = &arena->bins[binind];
|
||||||
malloc_mutex_lock(&bin->lock);
|
malloc_mutex_lock(&bin->lock);
|
||||||
for (i = 0, nfill = (tcache_bin_info[binind].ncached_max >>
|
for (i = 0, nfill = (tcache_bin_info[binind].ncached_max >>
|
||||||
@ -1459,11 +1441,8 @@ arena_malloc_small(arena_t *arena, size_t size, bool zero)
|
|||||||
bin->stats.nrequests++;
|
bin->stats.nrequests++;
|
||||||
}
|
}
|
||||||
malloc_mutex_unlock(&bin->lock);
|
malloc_mutex_unlock(&bin->lock);
|
||||||
if (config_prof && isthreaded == false) {
|
if (config_prof && isthreaded == false)
|
||||||
malloc_mutex_lock(&arena->lock);
|
|
||||||
arena_prof_accum(arena, size);
|
arena_prof_accum(arena, size);
|
||||||
malloc_mutex_unlock(&arena->lock);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (zero == false) {
|
if (zero == false) {
|
||||||
if (config_fill) {
|
if (config_fill) {
|
||||||
@ -1507,7 +1486,7 @@ arena_malloc_large(arena_t *arena, size_t size, bool zero)
|
|||||||
arena->stats.lstats[(size >> LG_PAGE) - 1].curruns++;
|
arena->stats.lstats[(size >> LG_PAGE) - 1].curruns++;
|
||||||
}
|
}
|
||||||
if (config_prof)
|
if (config_prof)
|
||||||
arena_prof_accum(arena, size);
|
arena_prof_accum_locked(arena, size);
|
||||||
malloc_mutex_unlock(&arena->lock);
|
malloc_mutex_unlock(&arena->lock);
|
||||||
|
|
||||||
if (zero == false) {
|
if (zero == false) {
|
||||||
|
@ -26,7 +26,7 @@ bool opt_prof_leak = false;
|
|||||||
bool opt_prof_accum = false;
|
bool opt_prof_accum = false;
|
||||||
char opt_prof_prefix[PATH_MAX + 1];
|
char opt_prof_prefix[PATH_MAX + 1];
|
||||||
|
|
||||||
uint64_t prof_interval;
|
uint64_t prof_interval = 0;
|
||||||
bool prof_promote;
|
bool prof_promote;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -1206,13 +1206,11 @@ prof_boot1(void)
|
|||||||
*/
|
*/
|
||||||
opt_prof = true;
|
opt_prof = true;
|
||||||
opt_prof_gdump = false;
|
opt_prof_gdump = false;
|
||||||
prof_interval = 0;
|
|
||||||
} else if (opt_prof) {
|
} else if (opt_prof) {
|
||||||
if (opt_lg_prof_interval >= 0) {
|
if (opt_lg_prof_interval >= 0) {
|
||||||
prof_interval = (((uint64_t)1U) <<
|
prof_interval = (((uint64_t)1U) <<
|
||||||
opt_lg_prof_interval);
|
opt_lg_prof_interval);
|
||||||
} else
|
}
|
||||||
prof_interval = 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
prof_promote = (opt_prof && opt_lg_prof_sample > LG_PAGE);
|
prof_promote = (opt_prof && opt_lg_prof_sample > LG_PAGE);
|
||||||
|
@ -97,9 +97,7 @@ tcache_bin_flush_small(tcache_bin_t *tbin, size_t binind, unsigned rem,
|
|||||||
arena_bin_t *bin = &arena->bins[binind];
|
arena_bin_t *bin = &arena->bins[binind];
|
||||||
|
|
||||||
if (config_prof && arena == tcache->arena) {
|
if (config_prof && arena == tcache->arena) {
|
||||||
malloc_mutex_lock(&arena->lock);
|
|
||||||
arena_prof_accum(arena, tcache->prof_accumbytes);
|
arena_prof_accum(arena, tcache->prof_accumbytes);
|
||||||
malloc_mutex_unlock(&arena->lock);
|
|
||||||
tcache->prof_accumbytes = 0;
|
tcache->prof_accumbytes = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -180,7 +178,7 @@ tcache_bin_flush_large(tcache_bin_t *tbin, size_t binind, unsigned rem,
|
|||||||
malloc_mutex_lock(&arena->lock);
|
malloc_mutex_lock(&arena->lock);
|
||||||
if ((config_prof || config_stats) && arena == tcache->arena) {
|
if ((config_prof || config_stats) && arena == tcache->arena) {
|
||||||
if (config_prof) {
|
if (config_prof) {
|
||||||
arena_prof_accum(arena,
|
arena_prof_accum_locked(arena,
|
||||||
tcache->prof_accumbytes);
|
tcache->prof_accumbytes);
|
||||||
tcache->prof_accumbytes = 0;
|
tcache->prof_accumbytes = 0;
|
||||||
}
|
}
|
||||||
@ -343,11 +341,8 @@ tcache_destroy(tcache_t *tcache)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (config_prof && tcache->prof_accumbytes > 0) {
|
if (config_prof && tcache->prof_accumbytes > 0)
|
||||||
malloc_mutex_lock(&tcache->arena->lock);
|
|
||||||
arena_prof_accum(tcache->arena, tcache->prof_accumbytes);
|
arena_prof_accum(tcache->arena, tcache->prof_accumbytes);
|
||||||
malloc_mutex_unlock(&tcache->arena->lock);
|
|
||||||
}
|
|
||||||
|
|
||||||
tcache_size = arena_salloc(tcache, false);
|
tcache_size = arena_salloc(tcache, false);
|
||||||
if (tcache_size <= SMALL_MAXCLASS) {
|
if (tcache_size <= SMALL_MAXCLASS) {
|
||||||
|
Loading…
Reference in New Issue
Block a user