diff options
author | Ivan Maidanski <ivmai@mail.ru> | 2022-05-19 09:38:30 +0300 |
---|---|---|
committer | Ivan Maidanski <ivmai@mail.ru> | 2022-06-15 22:50:43 +0300 |
commit | c5fb8828c247373200c80d33771bfa3c5956b8ed (patch) | |
tree | e92033169a2d5cbb3fcc3725c2f740812c0f3ee4 | |
parent | cbb38ea627b43703a81b38f1ef5f5b262cbba53b (diff) | |
download | bdwgc-c5fb8828c247373200c80d33771bfa3c5956b8ed.tar.gz |
Prevent changing of GC_markers_m1 value while collection in progress
GC_markers_m1 (GC_parallel) value affects some logic in the garbage
collector, e.g. GC_clear_fl_marks, so it would be safer to wait for any
ongoing collection before proceeding with marker threads creation (in
the child).
* pthread_support.c [PARALLEL_MARK && CAN_HANDLE_FORK]
(GC_wait_for_gc_completion): Declare (before
GC_start_mark_threads_inner).
* pthread_support.c [PARALLEL_MARK] (GC_start_mark_threads_inner): Add
assertion that cancellation is disabled.
* win32_threads.c [PARALLEL_MARK] (GC_start_mark_threads_inner):
Likewise.
* pthread_support.c [PARALLEL_MARK && CAN_HANDLE_FORK]
(GC_start_mark_threads_inner): Call GC_wait_for_gc_completion(TRUE)
before initialization of mark_cv.
* win32_threads.c [PARALLEL_MARK && GC_PTHREADS_PARAMARK
&& CAN_HANDLE_FORK] (GC_start_mark_threads_inner): Likewise.
-rw-r--r-- | pthread_support.c | 3 | ||||
-rw-r--r-- | win32_threads.c | 3 |
2 files changed, 6 insertions, 0 deletions
diff --git a/pthread_support.c b/pthread_support.c index fefb1ed6..7e6a13a3 100644 --- a/pthread_support.c +++ b/pthread_support.c @@ -383,6 +383,7 @@ STATIC pthread_t GC_mark_threads[MAX_MARKERS]; static int available_markers_m1 = 0; static pthread_cond_t mark_cv; /* initialized by GC_start_mark_threads_inner */ + STATIC void GC_wait_for_gc_completion(GC_bool wait_for_all); #else # define available_markers_m1 GC_markers_m1 static pthread_cond_t mark_cv = PTHREAD_COND_INITIALIZER; @@ -397,10 +398,12 @@ GC_INNER void GC_start_mark_threads_inner(void) # endif GC_ASSERT(I_HOLD_LOCK()); + ASSERT_CANCEL_DISABLED(); if (available_markers_m1 <= 0) return; /* Skip if parallel markers disabled or already started. */ # ifdef CAN_HANDLE_FORK if (GC_parallel) return; + GC_wait_for_gc_completion(TRUE); /* Initialize mark_cv (for the first time), or cleanup its value */ /* after forking in the child process. All the marker threads in */ diff --git a/win32_threads.c b/win32_threads.c index 7fcee339..196bc7bf 100644 --- a/win32_threads.c +++ b/win32_threads.c @@ -2008,10 +2008,12 @@ GC_INNER void GC_get_next_stack(char *start, char *limit, # endif GC_ASSERT(I_HOLD_LOCK()); + ASSERT_CANCEL_DISABLED(); if (available_markers_m1 <= 0) return; /* Skip if parallel markers disabled or already started. */ # ifdef CAN_HANDLE_FORK if (GC_parallel) return; + GC_wait_for_gc_completion(TRUE); /* Reset mark_cv state after forking (as in pthread_support.c). */ { @@ -2181,6 +2183,7 @@ GC_INNER void GC_get_next_stack(char *start, char *limit, int i; GC_ASSERT(I_HOLD_LOCK()); + ASSERT_CANCEL_DISABLED(); if (available_markers_m1 <= 0) return; GC_ASSERT(GC_fl_builder_count == 0); |