From 04fd7b5309596423e4342502d3123028d836d551 Mon Sep 17 00:00:00 2001 From: Ivan Maidanski Date: Mon, 13 Nov 2017 09:04:04 +0300 Subject: [PATCH] Workaround a hang in sigsuspend if compiled with Thread Sanitizer Issue #181 (bdwgc). * pthread_stop_world.c [!GC_OPENBSD_UTHREADS && !NACL && THREAD_SANITIZER] (GC_suspend_handler_inner): Use sched_yield() instead of sigsuspend(&suspend_handler_mask); add TODO item. --- pthread_stop_world.c | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/pthread_stop_world.c b/pthread_stop_world.c index cfb4c1ae8..b30b9e16a 100644 --- a/pthread_stop_world.c +++ b/pthread_stop_world.c @@ -327,7 +327,16 @@ STATIC void GC_suspend_handler_inner(ptr_t dummy GC_ATTR_UNUSED, /* really safe to proceed. Under normal circumstances, */ /* this code should not be executed. */ do { +# ifdef THREAD_SANITIZER + /* TODO: A temporal workaround. Generally, signal handlers are */ + /* delayed until the next call to TSan ProcessPendingSignals, the */ + /* latter is called on interceptors, system calls, and atomic */ + /* operations only. Thus, the collector hangs sometimes (as of */ + /* now) if the signal occurs while waiting in sigsuspend(). */ + sched_yield(); +# else sigsuspend (&suspend_handler_mask); +# endif } while (AO_load_acquire(&GC_world_is_stopped) && AO_load(&GC_stop_count) == my_stop_count); /* If the RESTART signal gets lost, we can still lose. That should */