From 012d17d56c985d0501fffd16eb606470e0c7e0ce Mon Sep 17 00:00:00 2001 From: Kurt Miller Date: Sat, 8 Jun 2013 16:45:23 +0400 Subject: [PATCH] Support rthreads introduced in OpenBSD 5.2+ * include/gc_config_macros.h (GC_OPENBSD_UTHREADS): New macro (defined only if OpenBSD prior to 5.2 release and threads). * include/private/gc_priv.h (SIG_SUSPEND): Define for OpenBSD (unless GC_OPENBSD_UTHREADS). * include/private/pthread_stop_world.h (thread_stop_info): Test GC_OPENBSD_UTHREADS macro instead of GC_OPENBSD_THREADS. * misc.c (GC_set_suspend_signal, GC_set_thr_restart_signal, GC_get_suspend_signal, GC_get_thr_restart_signal): Likewise. * os_dep.c (GC_dirty_init): Likewise. * pthread_stop_world.c: Likewise. * tests/initsecondarythread.c (main): Likewise. --- include/gc_config_macros.h | 9 +++++++++ include/private/gc_priv.h | 6 +++++- include/private/pthread_stop_world.h | 2 +- misc.c | 3 ++- os_dep.c | 2 +- pthread_stop_world.c | 28 ++++++++++++++-------------- tests/initsecondarythread.c | 2 +- 7 files changed, 33 insertions(+), 19 deletions(-) diff --git a/include/gc_config_macros.h b/include/gc_config_macros.h index 9d58900..be49b78 100644 --- a/include/gc_config_macros.h +++ b/include/gc_config_macros.h @@ -329,6 +329,15 @@ #ifdef GC_PTHREADS +# ifdef GC_OPENBSD_THREADS +# include + /* Prior to 5.2 release, OpenBSD had user threads and required */ + /* special handling. */ +# if OpenBSD < 201211 +# define GC_OPENBSD_UTHREADS 1 +# endif +# endif /* GC_OPENBSD_THREADS */ + # if (defined(GC_DARWIN_THREADS) || defined(GC_WIN32_PTHREADS) \ || defined(__native_client__) || defined(GC_RTEMS_PTHREADS)) \ && !defined(GC_NO_DLOPEN) diff --git a/include/private/gc_priv.h b/include/private/gc_priv.h index 55dc267..c477fae 100644 --- a/include/private/gc_priv.h +++ b/include/private/gc_priv.h @@ -2361,7 +2361,11 @@ GC_INNER ptr_t GC_store_debug_info(ptr_t p, word sz, const char *str, /* Linuxthreads itself uses SIGUSR1 and SIGUSR2. */ # define SIG_SUSPEND SIGPWR # endif -# elif !defined(GC_OPENBSD_THREADS) && !defined(GC_DARWIN_THREADS) +# elif defined(GC_OPENBSD_THREADS) +# ifndef GC_OPENBSD_UTHREADS +# define SIG_SUSPEND SIGXFSZ +# endif +# elif !defined(GC_DARWIN_THREADS) # if defined(_SIGRTMIN) # define SIG_SUSPEND _SIGRTMIN + 6 # else diff --git a/include/private/pthread_stop_world.h b/include/private/pthread_stop_world.h index cb67d23..4837428 100644 --- a/include/private/pthread_stop_world.h +++ b/include/private/pthread_stop_world.h @@ -19,7 +19,7 @@ #define GC_PTHREAD_STOP_WORLD_H struct thread_stop_info { -# ifndef GC_OPENBSD_THREADS +# ifndef GC_OPENBSD_UTHREADS word last_stop_count; /* GC_last_stop_count value when thread */ /* last successfully handled a suspend */ /* signal. */ diff --git a/misc.c b/misc.c index 0697890..d89babc 100644 --- a/misc.c +++ b/misc.c @@ -26,6 +26,7 @@ #ifdef GC_SOLARIS_THREADS # include #endif + #if defined(MSWIN32) || defined(MSWINCE) \ || (defined(CYGWIN32) && defined(GC_READ_ENV_FILE)) # ifndef WIN32_LEAN_AND_MEAN @@ -604,7 +605,7 @@ GC_API void GC_CALL GC_get_heap_usage_safe(GC_word *pheap_size, #endif /* !GC_GET_HEAP_USAGE_NOT_NEEDED */ -#if defined(GC_DARWIN_THREADS) || defined(GC_OPENBSD_THREADS) \ +#if defined(GC_DARWIN_THREADS) || defined(GC_OPENBSD_UTHREADS) \ || defined(GC_WIN32_THREADS) || (defined(NACL) && defined(THREADS)) /* GC does not use signals to suspend and restart threads. */ GC_API void GC_CALL GC_set_suspend_signal(int sig GC_ATTR_UNUSED) diff --git a/os_dep.c b/os_dep.c index 9fa401b..f835eaf 100644 --- a/os_dep.c +++ b/os_dep.c @@ -3269,7 +3269,7 @@ GC_INNER void GC_remove_protection(struct hblk *h, word nblocks, act.sa_flags = SA_RESTART | SA_SIGINFO; act.sa_sigaction = GC_write_fault_handler; (void)sigemptyset(&act.sa_mask); -# if defined(THREADS) && !defined(GC_OPENBSD_THREADS) \ +# if defined(THREADS) && !defined(GC_OPENBSD_UTHREADS) \ && !defined(GC_WIN32_THREADS) && !defined(NACL) /* Arrange to postpone the signal while we are in a write fault */ /* handler. This effectively makes the handler atomic w.r.t. */ diff --git a/pthread_stop_world.c b/pthread_stop_world.c index 7b0d016..9d31c14 100644 --- a/pthread_stop_world.c +++ b/pthread_stop_world.c @@ -35,11 +35,11 @@ GC_INNER __thread GC_thread GC_nacl_gc_thread_self = NULL; int GC_nacl_thread_parked[MAX_NACL_GC_THREADS]; int GC_nacl_thread_used[MAX_NACL_GC_THREADS]; -#elif defined(GC_OPENBSD_THREADS) +#elif defined(GC_OPENBSD_UTHREADS) # include -#else /* !GC_OPENBSD_THREADS && !NACL */ +#else /* !GC_OPENBSD_UTHREADS && !NACL */ #include #include @@ -325,7 +325,7 @@ STATIC void GC_restart_handler(int sig) # endif } -#endif /* !GC_OPENBSD_THREADS && !NACL */ +#endif /* !GC_OPENBSD_UTHREADS && !NACL */ #ifdef IA64 # define IF_IA64(x) x @@ -448,7 +448,7 @@ STATIC int GC_suspend_all(void) # ifndef NACL GC_thread p; -# ifndef GC_OPENBSD_THREADS +# ifndef GC_OPENBSD_UTHREADS int result; # endif pthread_t self = pthread_self(); @@ -462,7 +462,7 @@ STATIC int GC_suspend_all(void) if (!THREAD_EQUAL(p -> id, self)) { if (p -> flags & FINISHED) continue; if (p -> thread_blocked) /* Will wait */ continue; -# ifndef GC_OPENBSD_THREADS +# ifndef GC_OPENBSD_UTHREADS if (p -> stop_info.last_stop_count == GC_stop_count) continue; n_live_threads++; # endif @@ -470,7 +470,7 @@ STATIC int GC_suspend_all(void) GC_log_printf("Sending suspend signal to %p\n", (void *)p->id); # endif -# ifdef GC_OPENBSD_THREADS +# ifdef GC_OPENBSD_UTHREADS { stack_t stack; if (pthread_suspend_np(p -> id) != 0) @@ -558,7 +558,7 @@ STATIC int GC_suspend_all(void) GC_INNER void GC_stop_world(void) { -# if !defined(GC_OPENBSD_THREADS) && !defined(NACL) +# if !defined(GC_OPENBSD_UTHREADS) && !defined(NACL) int i; int n_live_threads; int code; @@ -580,7 +580,7 @@ GC_INNER void GC_stop_world(void) } # endif /* PARALLEL_MARK */ -# if defined(GC_OPENBSD_THREADS) || defined(NACL) +# if defined(GC_OPENBSD_UTHREADS) || defined(NACL) (void)GC_suspend_all(); # else AO_store(&GC_stop_count, GC_stop_count+1); @@ -772,7 +772,7 @@ GC_INNER void GC_start_world(void) pthread_t self = pthread_self(); register int i; register GC_thread p; -# ifndef GC_OPENBSD_THREADS +# ifndef GC_OPENBSD_UTHREADS register int n_live_threads = 0; register int result; # endif @@ -784,7 +784,7 @@ GC_INNER void GC_start_world(void) GC_log_printf("World starting\n"); # endif -# ifndef GC_OPENBSD_THREADS +# ifndef GC_OPENBSD_UTHREADS AO_store(&GC_world_is_stopped, FALSE); # endif for (i = 0; i < THREAD_TABLE_SZ; i++) { @@ -792,14 +792,14 @@ GC_INNER void GC_start_world(void) if (!THREAD_EQUAL(p -> id, self)) { if (p -> flags & FINISHED) continue; if (p -> thread_blocked) continue; -# ifndef GC_OPENBSD_THREADS +# ifndef GC_OPENBSD_UTHREADS n_live_threads++; # endif # ifdef DEBUG_THREADS GC_log_printf("Sending restart signal to %p\n", (void *)p->id); # endif -# ifdef GC_OPENBSD_THREADS +# ifdef GC_OPENBSD_UTHREADS if (pthread_resume_np(p -> id) != 0) ABORT("pthread_resume_np failed"); # else @@ -847,7 +847,7 @@ GC_INNER void GC_start_world(void) GC_INNER void GC_stop_init(void) { -# if !defined(GC_OPENBSD_THREADS) && !defined(NACL) +# if !defined(GC_OPENBSD_UTHREADS) && !defined(NACL) struct sigaction act; if (sem_init(&GC_suspend_ack_sem, GC_SEM_INIT_PSHARED, 0) != 0) @@ -911,7 +911,7 @@ GC_INNER void GC_stop_init(void) if (GC_retry_signals) { GC_COND_LOG_PRINTF("Will retry suspend signal if necessary\n"); } -# endif /* !GC_OPENBSD_THREADS && !NACL */ +# endif /* !GC_OPENBSD_UTHREADS && !NACL */ } #endif /* GC_PTHREADS && !GC_DARWIN_THREADS && !GC_WIN32_THREADS */ diff --git a/tests/initsecondarythread.c b/tests/initsecondarythread.c index 4a13ca9..5f21405 100644 --- a/tests/initsecondarythread.c +++ b/tests/initsecondarythread.c @@ -65,7 +65,7 @@ int main(void) DWORD thread_id; # endif # if !(defined(BEOS) || defined(MSWIN32) || defined(MSWINCE) \ - || defined(CYGWIN32) || defined(GC_OPENBSD_THREADS) \ + || defined(CYGWIN32) || defined(GC_OPENBSD_UTHREADS) \ || (defined(DARWIN) && !defined(NO_PTHREAD_GET_STACKADDR_NP)) \ || (defined(LINUX) && !defined(NACL)) \ || (defined(GC_SOLARIS_THREADS) && !defined(_STRICT_STDC)) \ -- 2.7.4