From de676ee5825a426dc4b85536fd747db540e705fb Mon Sep 17 00:00:00 2001 From: Ivan Maidanski Date: Fri, 21 Jul 2017 20:27:12 +0300 Subject: [PATCH] Fix deadlock in GC_suspend_thread when thread is rebuilding free list (fix commits 62097c3, 59e2bcf) * pthread_stop_world.c [GC_ENABLE_SUSPEND_THREAD] (GC_suspend_thread): Move DISABLE_CANCEL() upper to cover also GC_wait_for_reclaim() and RAISE_SIGNAL() calls. * pthread_stop_world.c [GC_ENABLE_SUSPEND_THREAD && PARALLEL_MARK] (GC_suspend_thread): If GC_parallel then call GC_wait_for_reclaim() holding the allocation lock before RAISE_SIGNAL() call; add comment. --- pthread_stop_world.c | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/pthread_stop_world.c b/pthread_stop_world.c index 07a2309e..b866e4a2 100644 --- a/pthread_stop_world.c +++ b/pthread_stop_world.c @@ -439,6 +439,20 @@ STATIC void GC_restart_handler(int sig) return; } + DISABLE_CANCEL(cancel_state); + /* GC_suspend_thread is not a cancellation point. */ +# ifdef PARALLEL_MARK + /* Ensure we do not suspend a thread while it is rebuilding */ + /* a free list, otherwise such a dead-lock is possible: */ + /* thread 1 is blocked in GC_wait_for_reclaim holding */ + /* the allocation lock, thread 2 is suspended in */ + /* GC_reclaim_generic invoked from GC_generic_malloc_many */ + /* (with GC_fl_builder_count > 0), and thread 3 is blocked */ + /* acquiring the allocation lock in GC_resume_thread. */ + if (GC_parallel) + GC_wait_for_reclaim(); +# endif + /* TODO: Support GC_retry_signals */ switch (RAISE_SIGNAL(t, GC_sig_suspend)) { /* ESRCH cannot happen as terminated threads are handled above. */ @@ -451,8 +465,6 @@ STATIC void GC_restart_handler(int sig) /* Wait for the thread to complete threads table lookup and */ /* stack_ptr assignment. */ GC_ASSERT(GC_thr_initialized); - DISABLE_CANCEL(cancel_state); - /* GC_suspend_thread is not a cancellation point. */ while (sem_wait(&GC_suspend_ack_sem) != 0) { if (errno != EINTR) ABORT("sem_wait for handler failed (suspend_self)"); -- 2.40.0