diff options
author | Ivan Maidanski <ivmai@mail.ru> | 2018-09-24 09:54:03 +0300 |
---|---|---|
committer | Ivan Maidanski <ivmai@mail.ru> | 2018-09-25 23:21:04 +0300 |
commit | 0c0e4cd0b90569e5aae726743f1f636724c2f4a4 (patch) | |
tree | 8bcb51dc13989041ae23ec0e7cddb5c58e83a2dd /darwin_stop_world.c | |
parent | 7305e56195a53958cf3e3f9d3f155048b1446e21 (diff) | |
download | bdwgc-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 'darwin_stop_world.c')
-rw-r--r-- | darwin_stop_world.c | 5 |
1 files changed, 4 insertions, 1 deletions
diff --git a/darwin_stop_world.c b/darwin_stop_world.c index 547bf3f4..ab0be9d8 100644 --- a/darwin_stop_world.c +++ b/darwin_stop_world.c @@ -517,9 +517,11 @@ STATIC GC_bool GC_suspend_thread_list(thread_act_array_t act_list, int count, # endif /* Unconditionally suspend the thread. It will do no */ /* harm if it is already suspended by the client logic. */ + GC_acquire_dirty_lock(); do { kern_result = thread_suspend(thread); } while (kern_result == KERN_ABORTED); + GC_release_dirty_lock(); if (kern_result != KERN_SUCCESS) { /* The thread may have quit since the thread_threads() call we */ /* mark already suspended so it's not dealt with anymore later. */ @@ -618,10 +620,11 @@ GC_INNER void GC_stop_world(void) for (p = GC_threads[i]; p != NULL; p = p->next) { if ((p->flags & FINISHED) == 0 && !p->thread_blocked && p->stop_info.mach_thread != my_thread) { - + GC_acquire_dirty_lock(); do { kern_result = thread_suspend(p->stop_info.mach_thread); } while (kern_result == KERN_ABORTED); + GC_release_dirty_lock(); if (kern_result != KERN_SUCCESS) ABORT("thread_suspend failed"); if (GC_on_thread_event) |