summaryrefslogtreecommitdiff
path: root/pthread_stop_world.c
diff options
context:
space:
mode:
authorIvan Maidanski <ivmai@mail.ru>2022-04-13 08:38:58 +0300
committerIvan Maidanski <ivmai@mail.ru>2022-04-17 12:50:43 +0300
commit7f97528c5c3e657629eb407b45fc858436f0af80 (patch)
tree52a9b47d643b9522e3cb2137de402ddf84105afb /pthread_stop_world.c
parent995cfbc066fe7edebf6a60d674f82a3788de2cc0 (diff)
downloadbdwgc-7f97528c5c3e657629eb407b45fc858436f0af80.tar.gz
Workaround race defect FP regarding thread_blocked in do_blocking_locked
(fix of commit b3af80d5f) * include/private/pthread_stop_world.h [GC_ENABLE_SUSPEND_THREAD && SIGNAL_BASED_STOP_WORLD] (GC_suspend_self_inner): Move to pthread_support.h. * include/private/pthread_support.h [GC_ENABLE_SUSPEND_THREAD && SIGNAL_BASED_STOP_WORLD] (GC_suspend_self_inner): Change return type from void* to void; remove GC_CALLBACK; change argument type from void* to GC_thread. * pthread_stop_world.c [!GC_OPENBSD_UTHREADS && !NACL && SIGNAL_BASED_STOP_WORLD] (GC_suspend_self_inner): Likewise. * include/private/pthread_support.h [GC_ENABLE_SUSPEND_THREAD && SIGNAL_BASED_STOP_WORLD] (GC_suspend_self_blocked): Add comment. * pthread_support.c (do_blocking_locked): Replace static function with do_blocking_enter() and do_blocking_leave() ones; add assertion that the GC lock is held; declare topOfStackUnset variable unconditionally. * pthread_support.c (GC_do_blocking_inner): Add GC_ATTR_UNUSED to context argument; declare topOfStackUnset local variable; do not use do_blocking_locked(). * pthread_support.c [GC_ENABLE_SUSPEND_THREAD && SIGNAL_BASED_STOP_WORLD] (GC_suspend_self_blocked): Likewise. * pthread_support.c (GC_do_blocking_inner): Call do_blocking_enter(), then unlock, then call d->fn(), then lock, then call GC_suspend_self_inner() w/o lock while suspended_ext, then call do_blocking_leave(). * pthread_support.c [GC_ENABLE_SUSPEND_THREAD && SIGNAL_BASED_STOP_WORLD] (GC_suspend_self_blocked): Add comment; declare and use "me" local variable; remove assert that GC is locked; call do_blocking_enter(), then call GC_suspend_self_inner() w/o lock while suspended_ext, then call do_blocking_leave().
Diffstat (limited to 'pthread_stop_world.c')
-rw-r--r--pthread_stop_world.c5
1 files changed, 1 insertions, 4 deletions
diff --git a/pthread_stop_world.c b/pthread_stop_world.c
index 281fb352..6e02502f 100644
--- a/pthread_stop_world.c
+++ b/pthread_stop_world.c
@@ -626,14 +626,11 @@ STATIC void GC_restart_handler(int sig)
(void)select(0, 0, 0, 0, &tv);
}
- GC_INNER void *GC_CALLBACK GC_suspend_self_inner(void *thread_me) {
- GC_thread me = (GC_thread)thread_me;
-
+ GC_INNER void GC_suspend_self_inner(GC_thread me) {
while (ao_load_acquire_async(&me->suspended_ext)) {
/* TODO: Use sigsuspend() instead. */
GC_brief_async_signal_safe_sleep();
}
- return NULL;
}
GC_API void GC_CALL GC_suspend_thread(GC_SUSPEND_THREAD_ID thread) {