summaryrefslogtreecommitdiffstats
path: root/src/jemalloc.c
diff options
context:
space:
mode:
authorJason Evans <jasone@canonware.com>2016-04-26 06:14:40 (GMT)
committerJason Evans <jasone@canonware.com>2016-04-26 06:16:20 (GMT)
commit174c0c3a9c63b3a0bfa32381148b537e9b9af96d (patch)
treee8e8b7d7793e2bebee876edb1744f6db4d854f1a /src/jemalloc.c
parent0d970a054e5477cd6cf3639366bcc0a1a4f61b11 (diff)
downloadjemalloc-174c0c3a9c63b3a0bfa32381148b537e9b9af96d.zip
jemalloc-174c0c3a9c63b3a0bfa32381148b537e9b9af96d.tar.gz
jemalloc-174c0c3a9c63b3a0bfa32381148b537e9b9af96d.tar.bz2
Fix fork()-related lock rank ordering reversals.
Diffstat (limited to 'src/jemalloc.c')
-rw-r--r--src/jemalloc.c41
1 files changed, 29 insertions, 12 deletions
diff --git a/src/jemalloc.c b/src/jemalloc.c
index 8b744e6..a7acf5f 100644
--- a/src/jemalloc.c
+++ b/src/jemalloc.c
@@ -2757,7 +2757,8 @@ _malloc_prefork(void)
#endif
{
tsd_t *tsd;
- unsigned i, narenas;
+ unsigned i, j, narenas;
+ arena_t *arena;
#ifdef JEMALLOC_MUTEX_INIT_CB
if (!malloc_initialized())
@@ -2767,18 +2768,32 @@ _malloc_prefork(void)
tsd = tsd_fetch();
+ narenas = narenas_total_get();
+
/* Acquire all mutexes in a safe order. */
+ witness_prefork(tsd);
ctl_prefork(tsd);
- prof_prefork(tsd);
malloc_mutex_prefork(tsd, &arenas_lock);
- for (i = 0, narenas = narenas_total_get(); i < narenas; i++) {
- arena_t *arena;
-
- if ((arena = arena_get(tsd, i, false)) != NULL)
- arena_prefork(tsd, arena);
+ prof_prefork0(tsd);
+ for (i = 0; i < 3; i++) {
+ for (j = 0; j < narenas; j++) {
+ if ((arena = arena_get(tsd, j, false)) != NULL) {
+ switch (i) {
+ case 0: arena_prefork0(tsd, arena); break;
+ case 1: arena_prefork1(tsd, arena); break;
+ case 2: arena_prefork2(tsd, arena); break;
+ default: not_reached();
+ }
+ }
+ }
}
- chunk_prefork(tsd);
base_prefork(tsd);
+ chunk_prefork(tsd);
+ for (i = 0; i < narenas; i++) {
+ if ((arena = arena_get(tsd, i, false)) != NULL)
+ arena_prefork3(tsd, arena);
+ }
+ prof_prefork1(tsd);
}
#ifndef JEMALLOC_MUTEX_INIT_CB
@@ -2801,17 +2816,18 @@ _malloc_postfork(void)
tsd = tsd_fetch();
/* Release all mutexes, now that fork() has completed. */
- base_postfork_parent(tsd);
chunk_postfork_parent(tsd);
+ base_postfork_parent(tsd);
for (i = 0, narenas = narenas_total_get(); i < narenas; i++) {
arena_t *arena;
if ((arena = arena_get(tsd, i, false)) != NULL)
arena_postfork_parent(tsd, arena);
}
- malloc_mutex_postfork_parent(tsd, &arenas_lock);
prof_postfork_parent(tsd);
+ malloc_mutex_postfork_parent(tsd, &arenas_lock);
ctl_postfork_parent(tsd);
+ witness_postfork(tsd);
}
void
@@ -2825,17 +2841,18 @@ jemalloc_postfork_child(void)
tsd = tsd_fetch();
/* Release all mutexes, now that fork() has completed. */
- base_postfork_child(tsd);
chunk_postfork_child(tsd);
+ base_postfork_child(tsd);
for (i = 0, narenas = narenas_total_get(); i < narenas; i++) {
arena_t *arena;
if ((arena = arena_get(tsd, i, false)) != NULL)
arena_postfork_child(tsd, arena);
}
- malloc_mutex_postfork_child(tsd, &arenas_lock);
prof_postfork_child(tsd);
+ malloc_mutex_postfork_child(tsd, &arenas_lock);
ctl_postfork_child(tsd);
+ witness_postfork(tsd);
}
/******************************************************************************/