summaryrefslogtreecommitdiff
path: root/win32_threads.c
diff options
context:
space:
mode:
authorIvan Maidanski <ivmai@mail.ru>2018-09-24 09:54:03 +0300
committerIvan Maidanski <ivmai@mail.ru>2018-09-25 23:21:04 +0300
commit0c0e4cd0b90569e5aae726743f1f636724c2f4a4 (patch)
tree8bcb51dc13989041ae23ec0e7cddb5c58e83a2dd /win32_threads.c
parent7305e56195a53958cf3e3f9d3f155048b1446e21 (diff)
downloadbdwgc-0c0e4cd0b90569e5aae726743f1f636724c2f4a4.tar.gz
Fix concurrent bitmap update in GC_dirty
Issue #235 (bdwgc). * darwin_stop_world.c [!GC_NO_THREADS_DISCOVERY] (GC_suspend_thread_list): Call GC_acquire_dirty_lock and GC_release_dirty_lock around thread_suspend(). * darwin_stop_world.c (GC_stop_world): Likewise. * include/private/gc_priv.h (set_pht_entry_from_index_safe): Remove unused macro. * include/private/gc_priv.h [THREADS] (GC_acquire_dirty_lock, GC_release_dirty_lock): Define new macro; move comment from win32_threads.c. * include/private/gc_priv.h [THREADS && !GC_DISABLE_INCREMENTAL] (GC_fault_handler_lock): Declare global variable (even if not MPROTECT_VDB). * os_dep.c [!GC_DISABLE_INCREMENTAL] (async_set_pht_entry_from_index): Define even if not MPROTECT_VDB; reformat comments. * os_dep.c [!GC_DISABLE_INCREMENTAL && AO_HAVE_test_and_set_acquire] (GC_fault_handler_lock): Likewise. * os_dep.c [THREADS && AO_HAVE_test_and_set_acquire] (async_set_pht_entry_from_index): Use GC_acquire_dirty_lock and GC_release_dirty_lock; remove wrong comment. * os_dep.c [THREADS && !AO_HAVE_test_and_set_acquire] (currently_updating, async_set_pht_entry_from_index): Remove incorrect implementation. * os_dep.c [!GC_DISABLE_INCREMENTAL] (GC_dirty_inner): Call async_set_pht_entry_from_index instead of set_pht_entry_from_index; remove FIXME. * pthread_stop_world.c [GC_ENABLE_SUSPEND_THREAD] (GC_suspend_thread): Refine comment for AO_store_release call; call GC_acquire_dirty_lock and GC_release_dirty_lock around a block of RAISE_SIGNAL() and sem_wait(). * pthread_stop_world.c [GC_OPENBSD_UTHREADS] (GC_suspend_all): Call GC_acquire_dirty_lock and GC_release_dirty_lock around pthread_suspend_np(). * pthread_stop_world.c [!GC_OPENBSD_UTHREADS] (GC_suspend_all): Add comment. * pthread_stop_world.c [!GC_OPENBSD_UTHREADS && !NACL] (GC_stop_world): If GC_manual_vdb then call GC_acquire_dirty_lock and GC_release_dirty_lock around a block of GC_suspend_all() and suspend_restart_barrier(); add comment. * win32_threads.c (GC_suspend): Use GC_acquire_dirty_lock and GC_release_dirty_lock (regardless of MPROTECT_VDB).
Diffstat (limited to 'win32_threads.c')
-rw-r--r--win32_threads.c14
1 files changed, 2 insertions, 12 deletions
diff --git a/win32_threads.c b/win32_threads.c
index 2701b11c..225d8e0d 100644
--- a/win32_threads.c
+++ b/win32_threads.c
@@ -1186,15 +1186,7 @@ STATIC void GC_suspend(GC_thread t)
return;
}
# endif
-# if defined(MPROTECT_VDB)
- /* Acquire the spin lock we use to update dirty bits. */
- /* Threads shouldn't get stopped holding it. But we may */
- /* acquire and release it in the UNPROTECT_THREAD call. */
- while (AO_test_and_set_acquire(&GC_fault_handler_lock) == AO_TS_SET) {
- /* empty */
- }
-# endif
-
+ GC_acquire_dirty_lock();
# ifdef MSWINCE
/* SuspendThread() will fail if thread is running kernel code. */
while (SuspendThread(THREAD_HANDLE(t)) == (DWORD)-1)
@@ -1204,9 +1196,7 @@ STATIC void GC_suspend(GC_thread t)
ABORT("SuspendThread failed");
# endif /* !MSWINCE */
t -> suspended = (unsigned char)TRUE;
-# if defined(MPROTECT_VDB)
- AO_CLEAR(&GC_fault_handler_lock);
-# endif
+ GC_release_dirty_lock();
if (GC_on_thread_event)
GC_on_thread_event(GC_EVENT_THREAD_SUSPENDED, THREAD_HANDLE(t));
}