mirror of
https://github.com/jemalloc/jemalloc.git
synced 2026-07-24 22:03:07 +00:00
Pass surviving descriptor through jemalloc_postfork_child orchestrator
The orchestrator looks up the surviving descriptor via tcache_postfork_arena_descriptor and threads it into arena_postfork_child, eliminating arena's call into tcache. Also reset cache_bin_array_descriptor_ql_mtx right before the queue rebuild it protects.
This commit is contained in:
@@ -129,6 +129,7 @@ void arena_prefork6(tsdn_t *tsdn, arena_t *arena);
|
|||||||
void arena_prefork7(tsdn_t *tsdn, arena_t *arena);
|
void arena_prefork7(tsdn_t *tsdn, arena_t *arena);
|
||||||
void arena_prefork8(tsdn_t *tsdn, arena_t *arena);
|
void arena_prefork8(tsdn_t *tsdn, arena_t *arena);
|
||||||
void arena_postfork_parent(tsdn_t *tsdn, arena_t *arena);
|
void arena_postfork_parent(tsdn_t *tsdn, arena_t *arena);
|
||||||
void arena_postfork_child(tsdn_t *tsdn, arena_t *arena);
|
void arena_postfork_child(tsdn_t *tsdn, arena_t *arena,
|
||||||
|
cache_bin_array_descriptor_t *surviving_desc);
|
||||||
|
|
||||||
#endif /* JEMALLOC_INTERNAL_ARENA_EXTERNS_H */
|
#endif /* JEMALLOC_INTERNAL_ARENA_EXTERNS_H */
|
||||||
|
|||||||
@@ -72,7 +72,8 @@ void tcaches_destroy(tsd_t *tsd, unsigned ind);
|
|||||||
bool tcache_boot(tsdn_t *tsdn, base_t *base);
|
bool tcache_boot(tsdn_t *tsdn, base_t *base);
|
||||||
void tcache_arena_associate(
|
void tcache_arena_associate(
|
||||||
tsdn_t *tsdn, tcache_slow_t *tcache_slow, arena_t *arena);
|
tsdn_t *tsdn, tcache_slow_t *tcache_slow, arena_t *arena);
|
||||||
void tcache_arena_postfork_child(tsdn_t *tsdn, arena_t *arena);
|
cache_bin_array_descriptor_t *tcache_postfork_arena_descriptor(
|
||||||
|
tsdn_t *tsdn, arena_t *arena);
|
||||||
void tcache_prefork(tsdn_t *tsdn);
|
void tcache_prefork(tsdn_t *tsdn);
|
||||||
void tcache_postfork_parent(tsdn_t *tsdn);
|
void tcache_postfork_parent(tsdn_t *tsdn);
|
||||||
void tcache_postfork_child(tsdn_t *tsdn);
|
void tcache_postfork_child(tsdn_t *tsdn);
|
||||||
|
|||||||
19
src/arena.c
19
src/arena.c
@@ -271,10 +271,9 @@ arena_cache_bin_array_unregister(tsdn_t *tsdn, arena_t *arena,
|
|||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Postfork-child entry: child is single-threaded and the queue is rebuilt
|
* Postfork-child entry: child is single-threaded, so the queue is rebuilt
|
||||||
* from scratch (descriptors held by other threads at fork time are gone).
|
* from scratch (descriptors held by other threads at fork time are gone)
|
||||||
* The mutex itself is reinitialized later in arena_postfork_child, so we
|
* without locking.
|
||||||
* cannot lock here.
|
|
||||||
*/
|
*/
|
||||||
void
|
void
|
||||||
arena_cache_bin_array_postfork_child(arena_t *arena,
|
arena_cache_bin_array_postfork_child(arena_t *arena,
|
||||||
@@ -2160,7 +2159,8 @@ arena_postfork_parent(tsdn_t *tsdn, arena_t *arena) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
arena_postfork_child(tsdn_t *tsdn, arena_t *arena) {
|
arena_postfork_child(tsdn_t *tsdn, arena_t *arena,
|
||||||
|
cache_bin_array_descriptor_t *surviving_desc) {
|
||||||
atomic_store_u(&arena->nthreads[0], 0, ATOMIC_RELAXED);
|
atomic_store_u(&arena->nthreads[0], 0, ATOMIC_RELAXED);
|
||||||
atomic_store_u(&arena->nthreads[1], 0, ATOMIC_RELAXED);
|
atomic_store_u(&arena->nthreads[1], 0, ATOMIC_RELAXED);
|
||||||
if (tsd_arena_get(tsdn_tsd(tsdn)) == arena) {
|
if (tsd_arena_get(tsdn_tsd(tsdn)) == arena) {
|
||||||
@@ -2169,7 +2169,11 @@ arena_postfork_child(tsdn_t *tsdn, arena_t *arena) {
|
|||||||
if (tsd_iarena_get(tsdn_tsd(tsdn)) == arena) {
|
if (tsd_iarena_get(tsdn_tsd(tsdn)) == arena) {
|
||||||
arena_nthreads_inc(arena, true);
|
arena_nthreads_inc(arena, true);
|
||||||
}
|
}
|
||||||
tcache_arena_postfork_child(tsdn, arena);
|
if (config_stats) {
|
||||||
|
malloc_mutex_postfork_child(tsdn,
|
||||||
|
&arena->cache_bin_array_descriptor_ql_mtx);
|
||||||
|
arena_cache_bin_array_postfork_child(arena, surviving_desc);
|
||||||
|
}
|
||||||
|
|
||||||
for (unsigned i = 0; i < nbins_total; i++) {
|
for (unsigned i = 0; i < nbins_total; i++) {
|
||||||
JEMALLOC_SUPPRESS_WARN_ON_USAGE(
|
JEMALLOC_SUPPRESS_WARN_ON_USAGE(
|
||||||
@@ -2179,7 +2183,4 @@ arena_postfork_child(tsdn_t *tsdn, arena_t *arena) {
|
|||||||
malloc_mutex_postfork_child(tsdn, &arena->large_mtx);
|
malloc_mutex_postfork_child(tsdn, &arena->large_mtx);
|
||||||
base_postfork_child(tsdn, arena->base);
|
base_postfork_child(tsdn, arena->base);
|
||||||
pa_shard_postfork_child(tsdn, &arena->pa_shard);
|
pa_shard_postfork_child(tsdn, &arena->pa_shard);
|
||||||
if (config_stats) {
|
|
||||||
malloc_mutex_postfork_child(tsdn, &arena->cache_bin_array_descriptor_ql_mtx);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -150,7 +150,10 @@ jemalloc_postfork_child(void) {
|
|||||||
arena_t *arena;
|
arena_t *arena;
|
||||||
|
|
||||||
if ((arena = arena_get(tsd_tsdn(tsd), i, false)) != NULL) {
|
if ((arena = arena_get(tsd_tsdn(tsd), i, false)) != NULL) {
|
||||||
arena_postfork_child(tsd_tsdn(tsd), arena);
|
cache_bin_array_descriptor_t *desc =
|
||||||
|
tcache_postfork_arena_descriptor(
|
||||||
|
tsd_tsdn(tsd), arena);
|
||||||
|
arena_postfork_child(tsd_tsdn(tsd), arena, desc);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
prof_postfork_child(tsd_tsdn(tsd));
|
prof_postfork_child(tsd_tsdn(tsd));
|
||||||
|
|||||||
15
src/tcache.c
15
src/tcache.c
@@ -754,21 +754,20 @@ tcache_arena_reassociate(tsdn_t *tsdn, tcache_slow_t *tcache_slow,
|
|||||||
tcache_arena_associate(tsdn, tcache_slow, arena);
|
tcache_arena_associate(tsdn, tcache_slow, arena);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
cache_bin_array_descriptor_t *
|
||||||
tcache_arena_postfork_child(tsdn_t *tsdn, arena_t *arena) {
|
tcache_postfork_arena_descriptor(tsdn_t *tsdn, arena_t *arena) {
|
||||||
if (!config_stats) {
|
if (!config_stats) {
|
||||||
return;
|
return NULL;
|
||||||
}
|
}
|
||||||
cache_bin_array_descriptor_t *desc = NULL;
|
|
||||||
tcache_slow_t *tcache_slow = tcache_slow_get(tsdn_tsd(tsdn));
|
tcache_slow_t *tcache_slow = tcache_slow_get(tsdn_tsd(tsdn));
|
||||||
if (tcache_slow != NULL && tcache_slow->arena == arena) {
|
if (tcache_slow == NULL || tcache_slow->arena != arena) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
assert(tcache_slow->tcache != NULL);
|
assert(tcache_slow->tcache != NULL);
|
||||||
cache_bin_array_descriptor_init(
|
cache_bin_array_descriptor_init(
|
||||||
&tcache_slow->cache_bin_array_descriptor,
|
&tcache_slow->cache_bin_array_descriptor,
|
||||||
tcache_slow->tcache->bins);
|
tcache_slow->tcache->bins);
|
||||||
desc = &tcache_slow->cache_bin_array_descriptor;
|
return &tcache_slow->cache_bin_array_descriptor;
|
||||||
}
|
|
||||||
arena_cache_bin_array_postfork_child(arena, desc);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
|||||||
Reference in New Issue
Block a user