From: ivmai Date: Mon, 16 May 2011 13:12:14 +0000 (+0000) Subject: 2011-05-16 Ivan Maidanski X-Git-Tag: gc7_2alpha6~24 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=8349c09ecc42401ec8388c4f8eefeb46a22697ef;p=gc 2011-05-16 Ivan Maidanski * 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. --- diff --git a/ChangeLog b/ChangeLog index d96748e4..3eef9290 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,16 @@ +2011-05-16 Ivan Maidanski + + * 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. + 2011-05-16 Ivan Maidanski * pthread_stop_world.c (GC_suspend_handler_inner): Remove "dummy", diff --git a/include/private/gcconfig.h b/include/private/gcconfig.h index 54d93645..9e277e5b 100644 --- a/include/private/gcconfig.h +++ b/include/private/gcconfig.h @@ -2324,6 +2324,11 @@ # define SUNOS5SIGS #endif +#if !defined(GC_EXPLICIT_SIGNALS_UNBLOCK) && defined(SUNOS5SIGS) \ + && !defined(GC_NO_PTHREAD_SIGMASK) +# define GC_EXPLICIT_SIGNALS_UNBLOCK +#endif + #ifdef GC_NETBSD_THREADS # define SIGRTMIN 33 # define SIGRTMAX 63 diff --git a/pthread_stop_world.c b/pthread_stop_world.c index dfb0d8ad..9302f93f 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 #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"); diff --git a/pthread_support.c b/pthread_support.c index 175663c0..4f3be43f 100644 --- a/pthread_support.c +++ b/pthread_support.c @@ -1358,6 +1358,10 @@ GC_INLINE void GC_record_stack_base(GC_thread me, # endif } +#ifdef GC_EXPLICIT_SIGNALS_UNBLOCK + GC_INNER void GC_unblock_gc_signals(void); /* from pthread_stop_world.c */ +#endif + STATIC GC_thread GC_register_my_thread_inner(const struct GC_stack_base *sb, pthread_t my_pthread) { @@ -1372,6 +1376,11 @@ STATIC GC_thread GC_register_my_thread_inner(const struct GC_stack_base *sb, me -> stop_info.mach_thread = mach_thread_self(); # endif GC_record_stack_base(me, sb); +# ifdef GC_EXPLICIT_SIGNALS_UNBLOCK + /* Since this could be executed from a detached thread */ + /* destructor, our signals might already be blocked. */ + GC_unblock_gc_signals(); +# endif return me; } @@ -1398,8 +1407,15 @@ GC_API int GC_CALL GC_register_my_thread(const struct GC_stack_base *sb) if (me == 0) { me = GC_register_my_thread_inner(sb, self); } else { + /* This code is executed when a thread is registered from the */ + /* client thread key destructor. */ GC_record_stack_base(me, sb); me -> flags &= ~FINISHED; +# ifdef GC_EXPLICIT_SIGNALS_UNBLOCK + /* Since this could be executed from a thread destructor, */ + /* our signals might be blocked. */ + GC_unblock_gc_signals(); +# endif } me -> flags |= DETACHED; /* Treat as detached, since we do not need to worry about */