summaryrefslogtreecommitdiff
path: root/pthread_stop_world.c
diff options
context:
space:
mode:
authorivmai <ivmai>2011-05-16 15:12:14 +0200
committerIvan Maidanski <ivmai@mail.ru>2011-07-26 19:06:59 +0200
commit8349c09ecc42401ec8388c4f8eefeb46a22697ef (patch)
treee84d29188c4b756b05009eb91999cf83376ca29c /pthread_stop_world.c
parent31fc0f694f439b23c47431fc7a976691e67a3331 (diff)
2011-05-16 Ivan Maidanski <ivmai@mail.ru>
* pthread_stop_world.c (pthread_sigmask): Undefine even if not DEBUG_THREADS. * pthread_stop_world.c (GC_unblock_gc_signals): New function (only if GC_EXPLICIT_SIGNALS_UNBLOCK). * pthread_support.c (GC_unblock_gc_signals): New prototype. * pthread_support.c (GC_register_my_thread_inner, GC_register_my_thread): Call GC_unblock_gc_signals (only if GC_EXPLICIT_SIGNALS_UNBLOCK); add comment. * include/private/gcconfig.h (GC_EXPLICIT_SIGNALS_UNBLOCK): New macro.
Diffstat (limited to 'pthread_stop_world.c')
-rw-r--r--pthread_stop_world.c36
1 files changed, 26 insertions, 10 deletions
diff --git a/pthread_stop_world.c b/pthread_stop_world.c
index dfb0d8a..9302f93 100644
--- a/pthread_stop_world.c
+++ b/pthread_stop_world.c
@@ -43,6 +43,9 @@ int GC_nacl_thread_used[MAX_NACL_GC_THREADS];
#include <unistd.h>
#include "atomic_ops.h"
+/* It's safe to call original pthread_sigmask() here. */
+#undef pthread_sigmask
+
#ifdef DEBUG_THREADS
# ifndef NSIG
# if defined(MAXSIG)
@@ -56,9 +59,6 @@ int GC_nacl_thread_used[MAX_NACL_GC_THREADS];
# endif
# endif /* NSIG */
- /* It's safe to call original pthread_sigmask() here. */
-# undef pthread_sigmask
-
void GC_print_sig_mask(void)
{
sigset_t blocked;
@@ -141,6 +141,20 @@ STATIC volatile AO_t GC_world_is_stopped = FALSE;
# endif
#endif
+#ifdef GC_EXPLICIT_SIGNALS_UNBLOCK
+ /* Some targets (eg., Solaris) might require this to be called when */
+ /* doing thread registering from the thread destructor. */
+ GC_INNER void GC_unblock_gc_signals(void)
+ {
+ sigset_t set;
+ sigemptyset(&set);
+ sigaddset(&set, SIG_SUSPEND);
+ sigaddset(&set, SIG_THR_RESTART);
+ if (pthread_sigmask(SIG_UNBLOCK, &set, NULL) != 0)
+ ABORT("pthread_sigmask failed");
+ }
+#endif /* GC_EXPLICIT_SIGNALS_UNBLOCK */
+
STATIC sem_t GC_suspend_ack_sem;
#ifdef GC_NETBSD_THREADS
@@ -769,13 +783,15 @@ GC_INNER void GC_start_world(void)
}
}
# ifdef GC_NETBSD_THREADS_WORKAROUND
- for (i = 0; i < n_live_threads; i++)
- while (0 != (code = sem_wait(&GC_restart_ack_sem)))
- if (errno != EINTR) {
- if (GC_print_stats)
- GC_log_printf("sem_wait() returned %d\n", code);
- ABORT("sem_wait() for restart handler failed");
- }
+ for (i = 0; i < n_live_threads; i++) {
+ while (0 != (code = sem_wait(&GC_restart_ack_sem))) {
+ if (errno != EINTR) {
+ if (GC_print_stats)
+ GC_log_printf("sem_wait() returned %d\n", code);
+ ABORT("sem_wait() for restart handler failed");
+ }
+ }
+ }
# endif
# ifdef DEBUG_THREADS
GC_log_printf("World started\n");