diff options
author | Greg Steuck <greg@nest.cx> | 2022-11-22 22:49:34 -0800 |
---|---|---|
committer | Ivan Maidanski <ivmai@mail.ru> | 2022-11-25 11:13:10 +0300 |
commit | 2c1ae2ea45bd662c74a15b9e1d68be845d366783 (patch) | |
tree | f116a43ee210d293a3e2529029ead8172223000f /pthread_stop_world.c | |
parent | 840bbcf603bc75e0b2da21ea9cbd84d1d63f14cf (diff) | |
download | bdwgc-2c1ae2ea45bd662c74a15b9e1d68be845d366783.tar.gz |
Remove OpenBSD uthreads (GC_OPENBSD_UTHREADS) support
Issue #512 (bdwgc).
Userland threads were replaced by rthreads on OpenBSD about a decade
ago. Prior to OpenBSD 5.2 release (2012), the OS had user threads
and required special handling.
* include/private/gc_priv.h [GC_OPENBSD_THREADS
&& !GC_USESIGRT_SIGNALS] (SIG_SUSPEND): Do not check
GC_OPENBSD_UTHREADS (assume not defined).
* include/private/gcconfig.h [OPENBSD] (NEED_FIND_LIMIT): Likewise.
* include/private/gcconfig.h [PTHREAD_STOP_WORLD_IMPL && !NACL]
(SIGNAL_BASED_STOP_WORLD): Likewise.
* os_dep.c [OPENBSD] (GC_register_data_segments): Likewise.
* pthread_stop_world.c (GC_usleep, GC_suspend_all, GC_stop_world,
GC_start_world, GC_stop_init): Likewise.
* tests/initfromthread.c (main): Likewise.
* include/private/gcconfig.h [GC_OPENBSD_THREADS && OpenBSD<201211]
(GC_OPENBSD_UTHREADS): Do not define.
* os_dep.c [OPENBSD && GC_OPENBSD_UTHREADS]: Do not include
sys/syscall.h.
* os_dep.c [OPENBSD && GC_OPENBSD_UTHREADS] (__syscall): Do not
declare.
* os_dep.c [OPENBSD && GC_OPENBSD_UTHREADS] (GC_find_limit_openbsd):
Remove.
* os_dep.c [NEED_FIND_LIMIT || USE_PROC_FOR_LIBRARIES && THREADS]
(GC_find_limit_with_bound): Move comment from GC_find_limit_openbsd.
* pthread_stop_world.c [!NACL && GC_OPENBSD_UTHREADS]: Do not include
pthread_np.h.
Co-authored-by: Kurt Miller <bsdkurt@gmail.com>
Diffstat (limited to 'pthread_stop_world.c')
-rw-r--r-- | pthread_stop_world.c | 106 |
1 files changed, 32 insertions, 74 deletions
diff --git a/pthread_stop_world.c b/pthread_stop_world.c index f9e78ad7..5cbb6aea 100644 --- a/pthread_stop_world.c +++ b/pthread_stop_world.c @@ -23,19 +23,16 @@ #ifdef NACL # include <unistd.h> # include <sys/time.h> -#elif defined(GC_OPENBSD_UTHREADS) -# include <pthread_np.h> #else # include <signal.h> # include <semaphore.h> # include <errno.h> # include <time.h> /* for nanosleep() */ # include <unistd.h> -#endif /* !GC_OPENBSD_UTHREADS && !NACL */ +#endif /* !NACL */ -#ifndef GC_OPENBSD_UTHREADS - GC_INLINE void GC_usleep(unsigned us) - { +GC_INLINE void GC_usleep(unsigned us) +{ # if defined(LINT2) || defined(THREAD_SANITIZER) /* Workaround "waiting while holding a lock" static analyzer warning. */ /* Workaround a rare hang in usleep() trying to acquire TSan Lock. */ @@ -51,8 +48,7 @@ # else usleep(us); # endif - } -#endif /* !GC_OPENBSD_UTHREADS */ +} #ifdef NACL @@ -66,7 +62,7 @@ volatile int GC_nacl_thread_parked[MAX_NACL_GC_THREADS]; int GC_nacl_thread_used[MAX_NACL_GC_THREADS]; -#elif !defined(GC_OPENBSD_UTHREADS) +#else #if (!defined(AO_HAVE_load_acquire) || !defined(AO_HAVE_store_release)) \ && !defined(CPPCHECK) @@ -769,7 +765,7 @@ STATIC void GC_restart_handler(int sig) # undef ao_load_async # undef ao_store_async # undef ao_store_release_async -#endif /* !GC_OPENBSD_UTHREADS && !NACL */ +#endif /* !NACL */ /* Should do exactly the right thing if the world is stopped; should */ /* not fail if it is not. */ @@ -923,51 +919,31 @@ STATIC int GC_suspend_all(void) # ifndef NACL GC_thread p; pthread_t self = pthread_self(); -# ifndef GC_OPENBSD_UTHREADS - int result; + int result; - GC_ASSERT((GC_stop_count & THREAD_RESTARTED) == 0); -# endif + GC_ASSERT((GC_stop_count & THREAD_RESTARTED) == 0); GC_ASSERT(I_HOLD_LOCK()); for (i = 0; i < THREAD_TABLE_SZ; i++) { for (p = GC_threads[i]; p != NULL; p = p -> tm.next) { if (!THREAD_EQUAL(p -> id, self)) { if ((p -> flags & (FINISHED | DO_BLOCKING)) != 0) continue; -# ifndef GC_OPENBSD_UTHREADS -# ifdef GC_ENABLE_SUSPEND_THREAD +# ifdef GC_ENABLE_SUSPEND_THREAD if ((p -> ext_suspend_cnt & 1) != 0) continue; -# endif - if (AO_load(&(p -> last_stop_count)) == GC_stop_count) - continue; /* matters only if GC_retry_signals */ - n_live_threads++; # endif + if (AO_load(&(p -> last_stop_count)) == GC_stop_count) + continue; /* matters only if GC_retry_signals */ + n_live_threads++; # ifdef DEBUG_THREADS GC_log_printf("Sending suspend signal to %p\n", (void *)p->id); # endif -# ifdef GC_OPENBSD_UTHREADS - { - stack_t stack; - - GC_acquire_dirty_lock(); - if (pthread_suspend_np(p -> id) != 0) - ABORT("pthread_suspend_np failed"); - GC_release_dirty_lock(); - if (pthread_stackseg_np(p->id, &stack)) - ABORT("pthread_stackseg_np failed"); - p -> stack_ptr = (ptr_t)stack.ss_sp - stack.ss_size; - if (GC_on_thread_event) - GC_on_thread_event(GC_EVENT_THREAD_SUSPENDED, - (void *)p->id); - } -# else /* The synchronization between GC_dirty (based on */ /* test-and-set) and the signal-based thread suspension */ /* is performed in GC_stop_world because */ /* GC_release_dirty_lock cannot be called before */ /* acknowledging the thread is really suspended. */ - result = raise_signal(p, GC_sig_suspend); - switch(result) { + result = raise_signal(p, GC_sig_suspend); + switch (result) { case ESRCH: /* Not really there anymore. Possible? */ n_live_threads--; @@ -981,8 +957,7 @@ STATIC int GC_suspend_all(void) default: ABORT_ARG1("pthread_kill failed at suspend", ": errcode= %d", result); - } -# endif + } } } } @@ -1042,7 +1017,7 @@ STATIC int GC_suspend_all(void) GC_INNER void GC_stop_world(void) { -# if !defined(GC_OPENBSD_UTHREADS) && !defined(NACL) +# if !defined(NACL) int n_live_threads; # endif GC_ASSERT(I_HOLD_LOCK()); @@ -1065,7 +1040,7 @@ GC_INNER void GC_stop_world(void) } # endif /* PARALLEL_MARK */ -# if defined(GC_OPENBSD_UTHREADS) || defined(NACL) +# if defined(NACL) (void)GC_suspend_all(); # else AO_store(&GC_stop_count, GC_stop_count + THREAD_RESTARTED); @@ -1259,35 +1234,25 @@ GC_INNER void GC_stop_world(void) int i; pthread_t self = pthread_self(); GC_thread p; -# ifndef GC_OPENBSD_UTHREADS - int result; + int result; - GC_ASSERT((GC_stop_count & THREAD_RESTARTED) != 0); -# endif + GC_ASSERT((GC_stop_count & THREAD_RESTARTED) != 0); for (i = 0; i < THREAD_TABLE_SZ; i++) { for (p = GC_threads[i]; p != NULL; p = p -> tm.next) { if (!THREAD_EQUAL(p -> id, self)) { if ((p -> flags & (FINISHED | DO_BLOCKING)) != 0) continue; -# ifndef GC_OPENBSD_UTHREADS -# ifdef GC_ENABLE_SUSPEND_THREAD +# ifdef GC_ENABLE_SUSPEND_THREAD if ((p -> ext_suspend_cnt & 1) != 0) continue; -# endif - if (GC_retry_signals +# endif + if (GC_retry_signals && AO_load(&(p -> last_stop_count)) == GC_stop_count) continue; /* The thread has been restarted. */ - n_live_threads++; -# endif + n_live_threads++; # ifdef DEBUG_THREADS GC_log_printf("Sending restart signal to %p\n", (void *)p->id); # endif -# ifdef GC_OPENBSD_UTHREADS - if (pthread_resume_np(p -> id) != 0) - ABORT("pthread_resume_np failed"); - if (GC_on_thread_event) - GC_on_thread_event(GC_EVENT_THREAD_UNSUSPENDED, (void *)p->id); -# else - result = raise_signal(p, GC_sig_thr_restart); - switch(result) { + result = raise_signal(p, GC_sig_thr_restart); + switch (result) { case ESRCH: /* Not really there anymore. Possible? */ n_live_threads--; @@ -1300,8 +1265,7 @@ GC_INNER void GC_stop_world(void) default: ABORT_ARG1("pthread_kill failed at resume", ": errcode= %d", result); - } -# endif + } } } } @@ -1318,27 +1282,21 @@ GC_INNER void GC_start_world(void) # ifdef DEBUG_THREADS GC_log_printf("World starting\n"); # endif -# ifndef GC_OPENBSD_UTHREADS - AO_store_release(&GC_stop_count, GC_stop_count + THREAD_RESTARTED); + AO_store_release(&GC_stop_count, GC_stop_count + THREAD_RESTARTED); /* The updated value should now be visible to the */ /* signal handler (note that pthread_kill is not on */ /* the list of functions which synchronize memory). */ -# endif n_live_threads = GC_restart_all(); -# ifdef GC_OPENBSD_UTHREADS - (void)n_live_threads; -# else - if (GC_retry_signals) { + if (GC_retry_signals) { resend_lost_signals_retry(n_live_threads, GC_restart_all); - } else { + } else { # ifndef GC_NETBSD_THREADS_WORKAROUND if (GC_sig_suspend == GC_sig_thr_restart) # endif { suspend_restart_barrier(n_live_threads); } - } -# endif + } # ifdef DEBUG_THREADS GC_log_printf("World started\n"); # endif @@ -1355,7 +1313,7 @@ GC_INNER void GC_start_world(void) GC_INNER void GC_stop_init(void) { -# if !defined(GC_OPENBSD_UTHREADS) && !defined(NACL) +# if !defined(NACL) struct sigaction act; char *str; @@ -1433,7 +1391,7 @@ GC_INNER void GC_stop_init(void) /* Explicitly unblock the signals once before new threads creation. */ GC_unblock_gc_signals(); # endif -# endif /* !GC_OPENBSD_UTHREADS && !NACL */ +# endif /* !NACL */ } #endif /* PTHREAD_STOP_WORLD_IMPL */ |