From c5fb8828c247373200c80d33771bfa3c5956b8ed Mon Sep 17 00:00:00 2001 From: Ivan Maidanski Date: Thu, 19 May 2022 09:38:30 +0300 Subject: 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. --- pthread_support.c | 3 +++ win32_threads.c | 3 +++ 2 files changed, 6 insertions(+) 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); -- cgit v1.2.1