summaryrefslogtreecommitdiff
path: root/pthread_stop_world.c
diff options
context:
space:
mode:
authorIvan Maidanski <ivmai@mail.ru>2022-03-28 21:32:34 +0300
committerIvan Maidanski <ivmai@mail.ru>2022-03-28 22:19:41 +0300
commit1aebf1e327195a4ab7d39c1d6105f70204b92dbe (patch)
treeb6d448b847019d929271b8381d733c46ec2ae2f7 /pthread_stop_world.c
parentc27705368638e175debed598507666d9be872e16 (diff)
downloadbdwgc-1aebf1e327195a4ab7d39c1d6105f70204b92dbe.tar.gz
Do not call GC_with_callee_saves_pushed in suspend_handler if restarting
This matters only if the same signal is used for stopping and restarting the world. * pthread_stop_world.c [!GC_OPENBSD_UTHREADS && !NACL] (GC_suspend_ack_sem, GC_suspend_handler): Move down to be after ao_load_async() definition. * pthread_stop_world.c [!GC_OPENBSD_UTHREADS && !NACL && SUSPEND_HANDLER_NO_CONTEXT] (GC_suspend_handler): If THREAD_RESTARTED bit of GC_stop_count is set, then just return; add comment.
Diffstat (limited to 'pthread_stop_world.c')
-rw-r--r--pthread_stop_world.c35
1 files changed, 19 insertions, 16 deletions
diff --git a/pthread_stop_world.c b/pthread_stop_world.c
index 1fffc6b5..f92c4927 100644
--- a/pthread_stop_world.c
+++ b/pthread_stop_world.c
@@ -228,6 +228,22 @@ GC_API int GC_CALL GC_get_thr_restart_signal(void)
}
#endif /* GC_EXPLICIT_SIGNALS_UNBLOCK */
+#ifdef BASE_ATOMIC_OPS_EMULATED
+ /* The AO primitives emulated with locks cannot be used inside signal */
+ /* handlers as this could cause a deadlock or a double lock. */
+ /* The following "async" macro definitions are correct only for */
+ /* an uniprocessor case and are provided for a test purpose. */
+# define ao_load_acquire_async(p) (*(p))
+# define ao_load_async(p) ao_load_acquire_async(p)
+# define ao_store_release_async(p, v) (void)(*(p) = (v))
+# define ao_store_async(p, v) ao_store_release_async(p, v)
+#else
+# define ao_load_acquire_async(p) AO_load_acquire(p)
+# define ao_load_async(p) AO_load(p)
+# define ao_store_release_async(p, v) AO_store_release(p, v)
+# define ao_store_async(p, v) AO_store(p, v)
+#endif /* !BASE_ATOMIC_OPS_EMULATED */
+
STATIC sem_t GC_suspend_ack_sem; /* also used to acknowledge restart */
STATIC void GC_suspend_handler_inner(ptr_t dummy, void *context);
@@ -250,6 +266,9 @@ STATIC void GC_suspend_handler_inner(ptr_t dummy, void *context);
}
# ifdef SUSPEND_HANDLER_NO_CONTEXT
+ /* A quick check if the signal is called to restart the world. */
+ if ((ao_load_async(&GC_stop_count) & THREAD_RESTARTED) != 0)
+ return;
GC_with_callee_saves_pushed(GC_suspend_handler_inner, NULL);
# else
/* We believe that in this case the full context is already */
@@ -259,22 +278,6 @@ STATIC void GC_suspend_handler_inner(ptr_t dummy, void *context);
errno = old_errno;
}
-#ifdef BASE_ATOMIC_OPS_EMULATED
- /* The AO primitives emulated with locks cannot be used inside signal */
- /* handlers as this could cause a deadlock or a double lock. */
- /* The following "async" macro definitions are correct only for */
- /* an uniprocessor case and are provided for a test purpose. */
-# define ao_load_acquire_async(p) (*(p))
-# define ao_load_async(p) ao_load_acquire_async(p)
-# define ao_store_release_async(p, v) (void)(*(p) = (v))
-# define ao_store_async(p, v) ao_store_release_async(p, v)
-#else
-# define ao_load_acquire_async(p) AO_load_acquire(p)
-# define ao_load_async(p) AO_load(p)
-# define ao_store_release_async(p, v) AO_store_release(p, v)
-# define ao_store_async(p, v) AO_store(p, v)
-#endif /* !BASE_ATOMIC_OPS_EMULATED */
-
/* The lookup here is safe, since this is done on behalf */
/* of a thread which holds the allocation lock in order */
/* to stop the world. Thus concurrent modification of the */