mirror of
https://github.com/jemalloc/jemalloc.git
synced 2026-07-11 08:17:16 +03:00
Fix fork()-related lock rank ordering reversals.
This commit is contained in:
parent
de35328a10
commit
2687a72087
8 changed files with 139 additions and 39 deletions
32
src/arena.c
32
src/arena.c
|
|
@ -3646,16 +3646,34 @@ arena_boot(void)
|
|||
}
|
||||
|
||||
void
|
||||
arena_prefork(arena_t *arena)
|
||||
arena_prefork0(arena_t *arena)
|
||||
{
|
||||
|
||||
malloc_mutex_prefork(&arena->lock);
|
||||
}
|
||||
|
||||
void
|
||||
arena_prefork1(arena_t *arena)
|
||||
{
|
||||
|
||||
malloc_mutex_prefork(&arena->chunks_mtx);
|
||||
}
|
||||
|
||||
void
|
||||
arena_prefork2(arena_t *arena)
|
||||
{
|
||||
|
||||
malloc_mutex_prefork(&arena->node_cache_mtx);
|
||||
}
|
||||
|
||||
void
|
||||
arena_prefork3(arena_t *arena)
|
||||
{
|
||||
unsigned i;
|
||||
|
||||
malloc_mutex_prefork(&arena->lock);
|
||||
malloc_mutex_prefork(&arena->huge_mtx);
|
||||
malloc_mutex_prefork(&arena->chunks_mtx);
|
||||
malloc_mutex_prefork(&arena->node_cache_mtx);
|
||||
for (i = 0; i < NBINS; i++)
|
||||
malloc_mutex_prefork(&arena->bins[i].lock);
|
||||
malloc_mutex_prefork(&arena->huge_mtx);
|
||||
}
|
||||
|
||||
void
|
||||
|
|
@ -3663,11 +3681,11 @@ arena_postfork_parent(arena_t *arena)
|
|||
{
|
||||
unsigned i;
|
||||
|
||||
malloc_mutex_postfork_parent(&arena->huge_mtx);
|
||||
for (i = 0; i < NBINS; i++)
|
||||
malloc_mutex_postfork_parent(&arena->bins[i].lock);
|
||||
malloc_mutex_postfork_parent(&arena->node_cache_mtx);
|
||||
malloc_mutex_postfork_parent(&arena->chunks_mtx);
|
||||
malloc_mutex_postfork_parent(&arena->huge_mtx);
|
||||
malloc_mutex_postfork_parent(&arena->lock);
|
||||
}
|
||||
|
||||
|
|
@ -3676,10 +3694,10 @@ arena_postfork_child(arena_t *arena)
|
|||
{
|
||||
unsigned i;
|
||||
|
||||
malloc_mutex_postfork_child(&arena->huge_mtx);
|
||||
for (i = 0; i < NBINS; i++)
|
||||
malloc_mutex_postfork_child(&arena->bins[i].lock);
|
||||
malloc_mutex_postfork_child(&arena->node_cache_mtx);
|
||||
malloc_mutex_postfork_child(&arena->chunks_mtx);
|
||||
malloc_mutex_postfork_child(&arena->huge_mtx);
|
||||
malloc_mutex_postfork_child(&arena->lock);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2644,7 +2644,8 @@ JEMALLOC_EXPORT void
|
|||
_malloc_prefork(void)
|
||||
#endif
|
||||
{
|
||||
unsigned i, narenas;
|
||||
unsigned i, j, narenas;
|
||||
arena_t *arena;
|
||||
|
||||
#ifdef JEMALLOC_MUTEX_INIT_CB
|
||||
if (!malloc_initialized())
|
||||
|
|
@ -2652,18 +2653,31 @@ _malloc_prefork(void)
|
|||
#endif
|
||||
assert(malloc_initialized());
|
||||
|
||||
narenas = narenas_total_get();
|
||||
|
||||
/* Acquire all mutexes in a safe order. */
|
||||
ctl_prefork();
|
||||
prof_prefork();
|
||||
malloc_mutex_prefork(&arenas_lock);
|
||||
for (i = 0, narenas = narenas_total_get(); i < narenas; i++) {
|
||||
arena_t *arena;
|
||||
|
||||
if ((arena = arena_get(i, false)) != NULL)
|
||||
arena_prefork(arena);
|
||||
prof_prefork0();
|
||||
for (i = 0; i < 3; i++) {
|
||||
for (j = 0; j < narenas; j++) {
|
||||
if ((arena = arena_get(j, false)) != NULL) {
|
||||
switch (i) {
|
||||
case 0: arena_prefork0(arena); break;
|
||||
case 1: arena_prefork1(arena); break;
|
||||
case 2: arena_prefork2(arena); break;
|
||||
default: not_reached();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
chunk_prefork();
|
||||
base_prefork();
|
||||
chunk_prefork();
|
||||
for (i = 0; i < narenas; i++) {
|
||||
if ((arena = arena_get(i, false)) != NULL)
|
||||
arena_prefork3(arena);
|
||||
}
|
||||
prof_prefork1();
|
||||
}
|
||||
|
||||
#ifndef JEMALLOC_MUTEX_INIT_CB
|
||||
|
|
@ -2683,16 +2697,16 @@ _malloc_postfork(void)
|
|||
assert(malloc_initialized());
|
||||
|
||||
/* Release all mutexes, now that fork() has completed. */
|
||||
base_postfork_parent();
|
||||
chunk_postfork_parent();
|
||||
base_postfork_parent();
|
||||
for (i = 0, narenas = narenas_total_get(); i < narenas; i++) {
|
||||
arena_t *arena;
|
||||
|
||||
if ((arena = arena_get(i, false)) != NULL)
|
||||
arena_postfork_parent(arena);
|
||||
}
|
||||
malloc_mutex_postfork_parent(&arenas_lock);
|
||||
prof_postfork_parent();
|
||||
malloc_mutex_postfork_parent(&arenas_lock);
|
||||
ctl_postfork_parent();
|
||||
}
|
||||
|
||||
|
|
@ -2704,16 +2718,16 @@ jemalloc_postfork_child(void)
|
|||
assert(malloc_initialized());
|
||||
|
||||
/* Release all mutexes, now that fork() has completed. */
|
||||
base_postfork_child();
|
||||
chunk_postfork_child();
|
||||
base_postfork_child();
|
||||
for (i = 0, narenas = narenas_total_get(); i < narenas; i++) {
|
||||
arena_t *arena;
|
||||
|
||||
if ((arena = arena_get(i, false)) != NULL)
|
||||
arena_postfork_child(arena);
|
||||
}
|
||||
malloc_mutex_postfork_child(&arenas_lock);
|
||||
prof_postfork_child();
|
||||
malloc_mutex_postfork_child(&arenas_lock);
|
||||
ctl_postfork_child();
|
||||
}
|
||||
|
||||
|
|
|
|||
52
src/prof.c
52
src/prof.c
|
|
@ -2198,20 +2198,32 @@ prof_boot2(void)
|
|||
}
|
||||
|
||||
void
|
||||
prof_prefork(void)
|
||||
prof_prefork0(void)
|
||||
{
|
||||
|
||||
if (opt_prof) {
|
||||
unsigned i;
|
||||
|
||||
malloc_mutex_prefork(&tdatas_mtx);
|
||||
malloc_mutex_prefork(&prof_dump_mtx);
|
||||
malloc_mutex_prefork(&bt2gctx_mtx);
|
||||
malloc_mutex_prefork(&next_thr_uid_mtx);
|
||||
malloc_mutex_prefork(&prof_dump_seq_mtx);
|
||||
for (i = 0; i < PROF_NCTX_LOCKS; i++)
|
||||
malloc_mutex_prefork(&gctx_locks[i]);
|
||||
malloc_mutex_prefork(&tdatas_mtx);
|
||||
for (i = 0; i < PROF_NTDATA_LOCKS; i++)
|
||||
malloc_mutex_prefork(&tdata_locks[i]);
|
||||
for (i = 0; i < PROF_NCTX_LOCKS; i++)
|
||||
malloc_mutex_prefork(&gctx_locks[i]);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
prof_prefork1(void)
|
||||
{
|
||||
|
||||
if (opt_prof) {
|
||||
malloc_mutex_prefork(&prof_active_mtx);
|
||||
malloc_mutex_prefork(&prof_dump_seq_mtx);
|
||||
malloc_mutex_prefork(&prof_gdump_mtx);
|
||||
malloc_mutex_prefork(&next_thr_uid_mtx);
|
||||
malloc_mutex_prefork(&prof_thread_active_init_mtx);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -2222,14 +2234,18 @@ prof_postfork_parent(void)
|
|||
if (opt_prof) {
|
||||
unsigned i;
|
||||
|
||||
for (i = 0; i < PROF_NTDATA_LOCKS; i++)
|
||||
malloc_mutex_postfork_parent(&tdata_locks[i]);
|
||||
malloc_mutex_postfork_parent(&prof_thread_active_init_mtx);
|
||||
malloc_mutex_postfork_parent(&next_thr_uid_mtx);
|
||||
malloc_mutex_postfork_parent(&prof_gdump_mtx);
|
||||
malloc_mutex_postfork_parent(&prof_dump_seq_mtx);
|
||||
malloc_mutex_postfork_parent(&prof_active_mtx);
|
||||
for (i = 0; i < PROF_NCTX_LOCKS; i++)
|
||||
malloc_mutex_postfork_parent(&gctx_locks[i]);
|
||||
malloc_mutex_postfork_parent(&prof_dump_seq_mtx);
|
||||
malloc_mutex_postfork_parent(&next_thr_uid_mtx);
|
||||
malloc_mutex_postfork_parent(&bt2gctx_mtx);
|
||||
for (i = 0; i < PROF_NTDATA_LOCKS; i++)
|
||||
malloc_mutex_postfork_parent(&tdata_locks[i]);
|
||||
malloc_mutex_postfork_parent(&tdatas_mtx);
|
||||
malloc_mutex_postfork_parent(&bt2gctx_mtx);
|
||||
malloc_mutex_postfork_parent(&prof_dump_mtx);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -2240,14 +2256,18 @@ prof_postfork_child(void)
|
|||
if (opt_prof) {
|
||||
unsigned i;
|
||||
|
||||
for (i = 0; i < PROF_NTDATA_LOCKS; i++)
|
||||
malloc_mutex_postfork_child(&tdata_locks[i]);
|
||||
malloc_mutex_postfork_child(&prof_thread_active_init_mtx);
|
||||
malloc_mutex_postfork_child(&next_thr_uid_mtx);
|
||||
malloc_mutex_postfork_child(&prof_gdump_mtx);
|
||||
malloc_mutex_postfork_child(&prof_dump_seq_mtx);
|
||||
malloc_mutex_postfork_child(&prof_active_mtx);
|
||||
for (i = 0; i < PROF_NCTX_LOCKS; i++)
|
||||
malloc_mutex_postfork_child(&gctx_locks[i]);
|
||||
malloc_mutex_postfork_child(&prof_dump_seq_mtx);
|
||||
malloc_mutex_postfork_child(&next_thr_uid_mtx);
|
||||
malloc_mutex_postfork_child(&bt2gctx_mtx);
|
||||
for (i = 0; i < PROF_NTDATA_LOCKS; i++)
|
||||
malloc_mutex_postfork_child(&tdata_locks[i]);
|
||||
malloc_mutex_postfork_child(&tdatas_mtx);
|
||||
malloc_mutex_postfork_child(&bt2gctx_mtx);
|
||||
malloc_mutex_postfork_child(&prof_dump_mtx);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue