summaryrefslogtreecommitdiff
path: root/tests
diff options
context:
space:
mode:
authorIvan Maidanski <ivmai@mail.ru>2022-06-01 21:12:40 +0300
committerIvan Maidanski <ivmai@mail.ru>2022-06-01 21:15:32 +0300
commit020b05d7d567926a023dc428cde7b6add246cd65 (patch)
tree4eecedcef1c80113981f5c6ad65bca316ec97617 /tests
parentcdcbc1cee7a9b0d9d6d33ba239d06a7b7898f179 (diff)
downloadbdwgc-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.c4
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);