diff options
author | Ivan Maidanski <ivmai@mail.ru> | 2022-06-01 21:12:40 +0300 |
---|---|---|
committer | Ivan Maidanski <ivmai@mail.ru> | 2022-06-01 21:15:32 +0300 |
commit | 020b05d7d567926a023dc428cde7b6add246cd65 (patch) | |
tree | 4eecedcef1c80113981f5c6ad65bca316ec97617 /tests | |
parent | cdcbc1cee7a9b0d9d6d33ba239d06a7b7898f179 (diff) | |
download | bdwgc-020b05d7d567926a023dc428cde7b6add246cd65.tar.gz |
Prevent (fix) parallel custom mark procs run in single-threaded clients
If the collector is built with parallel marker support then marking
is performed in parallel on multi-core targets. Thus, if the client
provides custom mark procedures, then they could be executed in
parallel. In case of a single-threaded client (developed for the
older libgc version with the parallel mark support off), its custom
mark procedures might not be prepared to be launched in parallel.
Now, the parallel mark threads are not launched, even if available,
until the client starts a (user) thread (e.g. calls pthread_create or
GC_allow_register_threads) or tells the collector explicitly to start
the mark threads (by calling GC_start_mark_threads).
* doc/README.macros (GC_ALWAYS_MULTITHREADED): Update documentation.
* doc/scale.md (Options for enhanced scalability): Likewise.
* include/gc/gc.h [GC_THREADS] (GC_parallel,
GC_allow_register_threads): Update comment.
* include/gc/gc.h (GC_set_markers_count, GC_start_mark_threads):
Likewise.
* include/gc/gc_mark.h (GC_mark_proc): Likewise.
* include/gc/gc_mark.h (GC_PROC_BYTES, GC_ms_entry): Move upper to be
before the comment belonging to GC_mark_proc.
* misc.c [THREADS && PARALLEL_MARK] (GC_init): Do not call
GC_start_mark_threads_inner().
* misc.c [PARALLEL_MARK] (GC_start_mark_threads): Call
GC_start_mark_threads_inner() even if THREAD_SANITIZER or
no CAN_HANDLE_FORK.
* misc.c [THREADS] (GC_get_parallel): Remove comment.
* pthread_support.c [PARALLEL_MARK && !CAN_HANDLE_FORK]
(available_markers_m1): Define as a variable.
* win32_threads.c [PARALLEL_MARK && !CAN_HANDLE_FORK]
(available_markers_m1): Likewise.
* pthread_support.c [PARALLEL_MARK && !CAN_HANDLE_FORK]
(GC_wait_for_gc_completion): Declare.
* pthread_support.c [PARALLEL_MARK && !CAN_HANDLE_FORK]
(GC_start_mark_threads_inner): If GC_parallel then return; call
GC_wait_for_gc_completion(); set GC_markers_m1 value from
available_markers_m1.
* win32_threads.c [PARALLEL_MARK && (!GC_PTHREADS_PARAMARK
|| !CAN_HANDLE_FORK)] (GC_start_mark_threads_inner): Likewise.
* pthread_support.c [CAN_HANDLE_FORK && PARALLEL_MARK
&& THREAD_SANITIZER] (fork_child_proc): Set available_markers_m1 to 0.
* pthread_support.c [CAN_HANDLE_FORK]: Move
GC_remove_all_threads_but_me() call to be after setting
available_markers_m1.
* pthread_support.c (GC_allow_register_threads): Call
GC_start_mark_threads().
* tests/middle.c (main): Likewise.
* win32_threads.c (GC_allow_register_threads): Likewise.
* pthread_support.c [PARALLEL_MARK] (pthread_create): Call
GC_start_mark_threads() unless GC_parallel or available_markers_m1<=0.
* win32_threads.c (START_MARK_THREADS): Define macro (to call
GC_start_mark_threads() if PARALLEL_MARK).
* win32_threads.c (GC_CreateThread): Call START_MARK_THREADS() (right
before set_need_to_lock).
* win32_threads.c [!CYGWIN32 && !MSWINCE && !MSWIN_XBOX1 && !NO_CRT]
(GC_beginthreadex): Likewise.
* win32_threads.c [GC_PTHREADS] (GC_pthread_create): Likewise.
Diffstat (limited to 'tests')
-rw-r--r-- | tests/middle.c | 4 |
1 files changed, 4 insertions, 0 deletions
diff --git a/tests/middle.c b/tests/middle.c index 67c974ae..ffbb3a46 100644 --- a/tests/middle.c +++ b/tests/middle.c @@ -21,6 +21,10 @@ int main (void) (void)GC_malloc_atomic(ALLOC_SZ); (void)GC_malloc(ALLOC_SZ); } + + /* Test delayed start of marker threads, if they are enabled. */ + GC_start_mark_threads(); + for (i = 0; i < N_TESTS; ++i) { (void)GC_malloc_atomic(ALLOC_SZ/2); (void)GC_malloc(ALLOC_SZ/2); |