diff options
author | Ivan Maidanski <ivmai@mail.ru> | 2022-05-19 09:38:30 +0300 |
---|---|---|
committer | Ivan Maidanski <ivmai@mail.ru> | 2022-05-19 13:39:23 +0300 |
commit | 0eeb939afc780d838e346b70ff26dd43c82bb26e (patch) | |
tree | a81ec25ffb97f88fdf3223c9731231842d144320 /pthread_support.c | |
parent | a8b96ed7655169757765433dee919824ccc62c36 (diff) | |
download | bdwgc-0eeb939afc780d838e346b70ff26dd43c82bb26e.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.
Diffstat (limited to 'pthread_support.c')
-rw-r--r-- | pthread_support.c | 3 |
1 files changed, 3 insertions, 0 deletions
diff --git a/pthread_support.c b/pthread_support.c index 34cf21f2..b351b909 100644 --- a/pthread_support.c +++ b/pthread_support.c @@ -444,6 +444,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; @@ -458,10 +459,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 */ |