Use tsd offset_state instead of atomic
While working on #852, I noticed the prng state is atomic. This is the only atomic use of prng in all of jemalloc. Instead, use a threadlocal prng state if possible to avoid unnecessary cache line contention.
This commit is contained in:
parent
cb3b72b975
commit
d6feed6e66
@ -196,9 +196,16 @@ extent_addr_randomize(tsdn_t *tsdn, extent_t *extent, size_t alignment) {
|
|||||||
if (alignment < PAGE) {
|
if (alignment < PAGE) {
|
||||||
unsigned lg_range = LG_PAGE -
|
unsigned lg_range = LG_PAGE -
|
||||||
lg_floor(CACHELINE_CEILING(alignment));
|
lg_floor(CACHELINE_CEILING(alignment));
|
||||||
size_t r =
|
size_t r;
|
||||||
prng_lg_range_zu(&extent_arena_get(extent)->offset_state,
|
if (!tsdn_null(tsdn)) {
|
||||||
|
tsd_t *tsd = tsdn_tsd(tsdn);
|
||||||
|
r = (size_t)prng_lg_range_u64(
|
||||||
|
tsd_offset_statep_get(tsd), lg_range);
|
||||||
|
} else {
|
||||||
|
r = prng_lg_range_zu(
|
||||||
|
&extent_arena_get(extent)->offset_state,
|
||||||
lg_range, true);
|
lg_range, true);
|
||||||
|
}
|
||||||
uintptr_t random_offset = ((uintptr_t)r) << (LG_PAGE -
|
uintptr_t random_offset = ((uintptr_t)r) << (LG_PAGE -
|
||||||
lg_range);
|
lg_range);
|
||||||
extent->e_addr = (void *)((uintptr_t)extent->e_addr +
|
extent->e_addr = (void *)((uintptr_t)extent->e_addr +
|
||||||
|
@ -65,6 +65,7 @@ typedef void (*test_callback_t)(int *);
|
|||||||
O(arenas_tdata_bypass, bool, bool) \
|
O(arenas_tdata_bypass, bool, bool) \
|
||||||
O(reentrancy_level, int8_t, int8_t) \
|
O(reentrancy_level, int8_t, int8_t) \
|
||||||
O(narenas_tdata, uint32_t, uint32_t) \
|
O(narenas_tdata, uint32_t, uint32_t) \
|
||||||
|
O(offset_state, uint64_t, uint64_t) \
|
||||||
O(thread_allocated, uint64_t, uint64_t) \
|
O(thread_allocated, uint64_t, uint64_t) \
|
||||||
O(thread_deallocated, uint64_t, uint64_t) \
|
O(thread_deallocated, uint64_t, uint64_t) \
|
||||||
O(prof_tdata, prof_tdata_t *, prof_tdata_t *) \
|
O(prof_tdata, prof_tdata_t *, prof_tdata_t *) \
|
||||||
@ -84,6 +85,7 @@ typedef void (*test_callback_t)(int *);
|
|||||||
0, \
|
0, \
|
||||||
0, \
|
0, \
|
||||||
0, \
|
0, \
|
||||||
|
0, \
|
||||||
NULL, \
|
NULL, \
|
||||||
RTREE_CTX_ZERO_INITIALIZER, \
|
RTREE_CTX_ZERO_INITIALIZER, \
|
||||||
NULL, \
|
NULL, \
|
||||||
|
10
src/tsd.c
10
src/tsd.c
@ -71,6 +71,16 @@ tsd_data_init(tsd_t *tsd) {
|
|||||||
*/
|
*/
|
||||||
rtree_ctx_data_init(tsd_rtree_ctxp_get_unsafe(tsd));
|
rtree_ctx_data_init(tsd_rtree_ctxp_get_unsafe(tsd));
|
||||||
|
|
||||||
|
/*
|
||||||
|
* A nondeterministic seed based on the address of tsd reduces
|
||||||
|
* the likelihood of lockstep non-uniform cache index
|
||||||
|
* utilization among identical concurrent processes, but at the
|
||||||
|
* cost of test repeatability. For debug builds, instead use a
|
||||||
|
* deterministic seed.
|
||||||
|
*/
|
||||||
|
*tsd_offset_statep_get(tsd) = config_debug ? 0 :
|
||||||
|
(uint64_t)(uintptr_t)tsd;
|
||||||
|
|
||||||
return tsd_tcache_enabled_data_init(tsd);
|
return tsd_tcache_enabled_data_init(tsd);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user