diff options
-rw-r--r-- | include/jemalloc/internal/private_symbols.txt | 3 | ||||
-rw-r--r-- | include/jemalloc/internal/witness.h | 3 | ||||
-rw-r--r-- | src/jemalloc.c | 6 | ||||
-rw-r--r-- | src/witness.c | 14 | ||||
-rw-r--r-- | test/unit/fork.c | 25 |
5 files changed, 42 insertions, 9 deletions
diff --git a/include/jemalloc/internal/private_symbols.txt b/include/jemalloc/internal/private_symbols.txt index 0eb7778..de884fc 100644 --- a/include/jemalloc/internal/private_symbols.txt +++ b/include/jemalloc/internal/private_symbols.txt @@ -594,7 +594,8 @@ witness_lock_error witness_lockless_error witness_not_owner_error witness_owner_error -witness_postfork +witness_postfork_child +witness_postfork_parent witness_prefork witness_unlock witnesses_cleanup diff --git a/include/jemalloc/internal/witness.h b/include/jemalloc/internal/witness.h index ecdc034..b2e6e82 100644 --- a/include/jemalloc/internal/witness.h +++ b/include/jemalloc/internal/witness.h @@ -96,7 +96,8 @@ void witness_assert_lockless(tsd_t *tsd); void witnesses_cleanup(tsd_t *tsd); void witness_fork_cleanup(tsd_t *tsd); void witness_prefork(tsd_t *tsd); -void witness_postfork(tsd_t *tsd); +void witness_postfork_parent(tsd_t *tsd); +void witness_postfork_child(tsd_t *tsd); #endif /* JEMALLOC_H_EXTERNS */ /******************************************************************************/ diff --git a/src/jemalloc.c b/src/jemalloc.c index a7acf5f..cd97ea1 100644 --- a/src/jemalloc.c +++ b/src/jemalloc.c @@ -2770,8 +2770,8 @@ _malloc_prefork(void) narenas = narenas_total_get(); - /* Acquire all mutexes in a safe order. */ witness_prefork(tsd); + /* Acquire all mutexes in a safe order. */ ctl_prefork(tsd); malloc_mutex_prefork(tsd, &arenas_lock); prof_prefork0(tsd); @@ -2815,6 +2815,7 @@ _malloc_postfork(void) tsd = tsd_fetch(); + witness_postfork_parent(tsd); /* Release all mutexes, now that fork() has completed. */ chunk_postfork_parent(tsd); base_postfork_parent(tsd); @@ -2827,7 +2828,6 @@ _malloc_postfork(void) prof_postfork_parent(tsd); malloc_mutex_postfork_parent(tsd, &arenas_lock); ctl_postfork_parent(tsd); - witness_postfork(tsd); } void @@ -2840,6 +2840,7 @@ jemalloc_postfork_child(void) tsd = tsd_fetch(); + witness_postfork_child(tsd); /* Release all mutexes, now that fork() has completed. */ chunk_postfork_child(tsd); base_postfork_child(tsd); @@ -2852,7 +2853,6 @@ jemalloc_postfork_child(void) prof_postfork_child(tsd); malloc_mutex_postfork_child(tsd, &arenas_lock); ctl_postfork_child(tsd); - witness_postfork(tsd); } /******************************************************************************/ diff --git a/src/witness.c b/src/witness.c index b5384a2..31c36a2 100644 --- a/src/witness.c +++ b/src/witness.c @@ -222,8 +222,20 @@ witness_prefork(tsd_t *tsd) } void -witness_postfork(tsd_t *tsd) +witness_postfork_parent(tsd_t *tsd) { tsd_witness_fork_set(tsd, false); } + +void +witness_postfork_child(tsd_t *tsd) +{ +#ifndef JEMALLOC_MUTEX_INIT_CB + witness_list_t *witnesses; + + witnesses = tsd_witnessesp_get(tsd); + ql_new(witnesses); +#endif + tsd_witness_fork_set(tsd, false); +} diff --git a/test/unit/fork.c b/test/unit/fork.c index 890bc86..d64f2e0 100644 --- a/test/unit/fork.c +++ b/test/unit/fork.c @@ -11,6 +11,13 @@ TEST_BEGIN(test_fork) assert_ptr_not_null(p, "Unexpected malloc() failure"); pid = fork(); + + free(p); + + p = malloc(64); + assert_ptr_not_null(p, "Unexpected malloc() failure"); + free(p); + if (pid == -1) { /* Error. */ test_fail("Unexpected fork() failure"); @@ -21,11 +28,23 @@ TEST_BEGIN(test_fork) int status; /* Parent. */ - free(p); - do { + while (true) { if (waitpid(pid, &status, 0) == -1) test_fail("Unexpected waitpid() failure"); - } while (!WIFEXITED(status) && !WIFSIGNALED(status)); + if (WIFSIGNALED(status)) { + test_fail("Unexpected child termination due to " + "signal %d", WTERMSIG(status)); + break; + } + if (WIFEXITED(status)) { + if (WEXITSTATUS(status) != 0) { + test_fail( + "Unexpected child exit value %d", + WEXITSTATUS(status)); + } + break; + } + } } } TEST_END |