Fix a thread cache stats merging bug.
When a thread cache flushes objects to their arenas due to an abundance of cached objects, it merges the allocation request count for the associated size class, and increments a flush counter. If none of the flushed objects came from the thread's assigned arena, then the merging wouldn't happen (though the counter would typically eventually be merged), nor would the flush counter be incremented (a hard bug). Fix this via extra conditional code just after the flush loop.
This commit is contained in:
parent
a7153a0d7d
commit
a8118233ec
@ -58,6 +58,9 @@ tcache_bin_flush_small(tcache_bin_t *tbin, size_t binind, unsigned rem
|
|||||||
void *flush, *deferred, *ptr;
|
void *flush, *deferred, *ptr;
|
||||||
unsigned i, nflush, ndeferred;
|
unsigned i, nflush, ndeferred;
|
||||||
bool first_pass;
|
bool first_pass;
|
||||||
|
#ifdef JEMALLOC_STATS
|
||||||
|
bool merged_stats = false;
|
||||||
|
#endif
|
||||||
|
|
||||||
assert(binind < nbins);
|
assert(binind < nbins);
|
||||||
assert(rem <= tbin->ncached);
|
assert(rem <= tbin->ncached);
|
||||||
@ -82,6 +85,8 @@ tcache_bin_flush_small(tcache_bin_t *tbin, size_t binind, unsigned rem
|
|||||||
malloc_mutex_lock(&bin->lock);
|
malloc_mutex_lock(&bin->lock);
|
||||||
#ifdef JEMALLOC_STATS
|
#ifdef JEMALLOC_STATS
|
||||||
if (arena == tcache->arena) {
|
if (arena == tcache->arena) {
|
||||||
|
assert(merged_stats == false);
|
||||||
|
merged_stats = true;
|
||||||
bin->stats.nflushes++;
|
bin->stats.nflushes++;
|
||||||
bin->stats.nrequests += tbin->tstats.nrequests;
|
bin->stats.nrequests += tbin->tstats.nrequests;
|
||||||
tbin->tstats.nrequests = 0;
|
tbin->tstats.nrequests = 0;
|
||||||
@ -119,6 +124,20 @@ tcache_bin_flush_small(tcache_bin_t *tbin, size_t binind, unsigned rem
|
|||||||
first_pass = false;
|
first_pass = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#ifdef JEMALLOC_STATS
|
||||||
|
if (merged_stats == false) {
|
||||||
|
/*
|
||||||
|
* The flush loop didn't happen to flush to this thread's
|
||||||
|
* arena, so the stats didn't get merged. Manually do so now.
|
||||||
|
*/
|
||||||
|
arena_bin_t *bin = &tcache->arena->bins[binind];
|
||||||
|
malloc_mutex_lock(&bin->lock);
|
||||||
|
bin->stats.nflushes++;
|
||||||
|
bin->stats.nrequests += tbin->tstats.nrequests;
|
||||||
|
tbin->tstats.nrequests = 0;
|
||||||
|
malloc_mutex_unlock(&bin->lock);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
tbin->ncached = rem;
|
tbin->ncached = rem;
|
||||||
if (tbin->ncached < tbin->low_water)
|
if (tbin->ncached < tbin->low_water)
|
||||||
|
Loading…
Reference in New Issue
Block a user