diff options
author | Ivan Maidanski <ivmai@mail.ru> | 2022-03-28 21:32:34 +0300 |
---|---|---|
committer | Ivan Maidanski <ivmai@mail.ru> | 2022-03-28 22:19:41 +0300 |
commit | 1aebf1e327195a4ab7d39c1d6105f70204b92dbe (patch) | |
tree | b6d448b847019d929271b8381d733c46ec2ae2f7 /pthread_stop_world.c | |
parent | c27705368638e175debed598507666d9be872e16 (diff) | |
download | bdwgc-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.c | 35 |
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 */ |