summaryrefslogtreecommitdiff
path: root/pthread_stop_world.c
diff options
context:
space:
mode:
authorhboehm <hboehm>2006-03-10 06:24:07 +0100
committerIvan Maidanski <ivmai@mail.ru>2011-07-26 19:06:36 +0200
commit65c2804e5bea35c0e3158c063644994d9239a8ab (patch)
tree894ec2e3323aa9ac0113b72ea0c13d6f886f1dad /pthread_stop_world.c
parent541151996c2ec4b2168538796f3516a31279b806 (diff)
2006-03-09 Hans Boehm <Hans.Boehm@hp.com>
Merge various gc6.7 changes (see doc/README.changes for contributors): * configure.ac, pthread_stop_world.c, pthread_support.c, threadlibs.c, include/gc_config_macros.h, include/gc_pthread_redirects.h, include/leak_detector.h, include/private/gcconfig.h, include/private/thread_local_alloc.h: Add NetBSD threads support. * dbg_mlc.c, malloc.c, include/gc.h: add GC_debug_str_dup, GC_str_dup. * os_dep.c (GC_init_win32), dyn_load.c (win32 GC_register_dynamic_libraries): accept MEM_PRIVATE for Windows 98 etc. * doc/gcinterface.html: Add warnings about thread locals and in-flight exceptions. * tests/tests.am: Add EXE extensions. * Makefile.in, configure: rebuild
Diffstat (limited to 'pthread_stop_world.c')
-rw-r--r--pthread_stop_world.c28
1 files changed, 27 insertions, 1 deletions
diff --git a/pthread_stop_world.c b/pthread_stop_world.c
index 33cc9e0..301c97b 100644
--- a/pthread_stop_world.c
+++ b/pthread_stop_world.c
@@ -93,7 +93,7 @@ volatile AO_t GC_world_is_stopped = FALSE;
*/
#ifndef SIG_THR_RESTART
-# if defined(GC_HPUX_THREADS) || defined(GC_OSF1_THREADS)
+# if defined(GC_HPUX_THREADS) || defined(GC_OSF1_THREADS) || defined(GC_NETBSD_THREADS)
# ifdef _SIGRTMIN
# define SIG_THR_RESTART _SIGRTMIN + 5
# else
@@ -106,6 +106,13 @@ volatile AO_t GC_world_is_stopped = FALSE;
sem_t GC_suspend_ack_sem;
+#ifdef GC_NETBSD_THREADS
+# define GC_NETBSD_THREADS_WORKAROUND
+ /* It seems to be necessary to wait until threads have restarted. */
+ /* But it is unclear why that is the case. */
+ sem_t GC_restart_ack_sem;
+#endif
+
void GC_suspend_handler_inner(ptr_t sig_arg, void *context);
#if defined(IA64) || defined(HP_PA)
@@ -208,6 +215,10 @@ void GC_restart_handler(int sig)
if (sig != SIG_THR_RESTART) ABORT("Bad signal in suspend_handler");
+#ifdef GC_NETBSD_THREADS_WORKAROUND
+ sem_post(&GC_restart_ack_sem);
+#endif
+
/*
** Note: even if we don't do anything useful here,
** it would still be necessary to have a signal handler,
@@ -424,6 +435,9 @@ void GC_start_world()
register GC_thread p;
register int n_live_threads = 0;
register int result;
+#ifdef GC_NETBSD_THREADS_WORKAROUND
+ int code;
+#endif
# if DEBUG_THREADS
GC_printf("World starting\n");
@@ -455,6 +469,14 @@ void GC_start_world()
}
}
}
+#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) {
+ GC_err_printf1("sem_wait() returned %ld\n", (unsigned long)code);
+ ABORT("sem_wait() for restart handler failed");
+ }
+#endif
#if DEBUG_THREADS
GC_printf("World started\n");
#endif
@@ -465,6 +487,10 @@ void GC_stop_init() {
if (sem_init(&GC_suspend_ack_sem, 0, 0) != 0)
ABORT("sem_init failed");
+#ifdef GC_NETBSD_THREADS_WORKAROUND
+ if (sem_init(&GC_restart_ack_sem, 0, 0) != 0)
+ ABORT("sem_init failed");
+#endif
act.sa_flags = SA_RESTART | SA_SIGINFO;
if (sigfillset(&act.sa_mask) != 0) {