Minimize delay between sem_post and sigsuspend in suspend_handler if TSan
authorIvan Maidanski <ivmai@mail.ru>
Thu, 29 Mar 2018 06:54:39 +0000 (09:54 +0300)
committerIvan Maidanski <ivmai@mail.ru>
Thu, 29 Mar 2018 06:55:00 +0000 (09:55 +0300)
(fix of commit af409e4)

Issue #181 (bdwgc).

This change is to do as less as possible (even in case of TSan usage)
between the sem_post and sigsuspend calls in GC_suspend_handler_inner
(to match the relevant comment after sigsuspend call).

* pthread_stop_world.c [!GC_OPENBSD_UTHREADS && !NACL
&& THREAD_SANITIZER] (GC_suspend_handler_inner): Move sigemptyset()
and pthread_sigmask() calls to be just before sem_post() call.

pthread_stop_world.c

index 5b5956d..82b2793 100644 (file)
@@ -333,12 +333,6 @@ STATIC void GC_suspend_handler_inner(ptr_t dummy GC_ATTR_UNUSED,
   }
   GC_store_stack_ptr(me);
 
-  /* Tell the thread that wants to stop the world that this     */
-  /* thread has been stopped.  Note that sem_post() is          */
-  /* the only async-signal-safe primitive in LinuxThreads.      */
-  sem_post(&GC_suspend_ack_sem);
-  AO_store_release(&me->stop_info.last_stop_count, my_stop_count);
-
 # ifdef THREAD_SANITIZER
     /* TSan disables signals around signal handlers.  Without   */
     /* a pthread_sigmask call, sigsuspend may block forever.    */
@@ -349,6 +343,11 @@ STATIC void GC_suspend_handler_inner(ptr_t dummy GC_ATTR_UNUSED,
         ABORT("pthread_sigmask(SIG_SETMASK) failed");
     }
 # endif
+  /* Tell the thread that wants to stop the world that this     */
+  /* thread has been stopped.  Note that sem_post() is          */
+  /* the only async-signal-safe primitive in LinuxThreads.      */
+  sem_post(&GC_suspend_ack_sem);
+  AO_store_release(&me->stop_info.last_stop_count, my_stop_count);
 
   /* Wait until that thread tells us to restart by sending      */
   /* this thread a GC_sig_thr_restart signal (should be masked  */