summaryrefslogtreecommitdiffstats
path: root/lib/librthread/rthread.c
diff options
context:
space:
mode:
authorguenther <guenther@openbsd.org>2017-09-05 02:40:54 +0000
committerguenther <guenther@openbsd.org>2017-09-05 02:40:54 +0000
commita5511fa9f431600dbd6dc2b46fc4e6b73e7d239c (patch)
treebf9e27f29ab35e6599d4c1362a9902d7e7bfdc74 /lib/librthread/rthread.c
parentSerialize access to IP reassembly queue with a mutex. This lets (diff)
downloadwireguard-openbsd-a5511fa9f431600dbd6dc2b46fc4e6b73e7d239c.tar.xz
wireguard-openbsd-a5511fa9f431600dbd6dc2b46fc4e6b73e7d239c.zip
Move mutex, condvar, and thread-specific data routes, pthread_once, and
pthread_exit from libpthread to libc, along with low-level bits to support them. Major bump to both libc and libpthread. Requested by libressl team. Ports testing by naddy@ ok kettenis@
Diffstat (limited to 'lib/librthread/rthread.c')
-rw-r--r--lib/librthread/rthread.c173
1 files changed, 46 insertions, 127 deletions
diff --git a/lib/librthread/rthread.c b/lib/librthread/rthread.c
index b9aa60ef77b..c3eec97d2fa 100644
--- a/lib/librthread/rthread.c
+++ b/lib/librthread/rthread.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: rthread.c,v 1.95 2017/07/27 16:35:08 tedu Exp $ */
+/* $OpenBSD: rthread.c,v 1.96 2017/09/05 02:40:54 guenther Exp $ */
/*
* Copyright (c) 2004,2005 Ted Unangst <tedu@openbsd.org>
* All Rights Reserved.
@@ -38,7 +38,6 @@
#include <pthread.h>
#include "cancel.h" /* in libc/include */
-#include "thread_private.h"
#include "rthread.h"
#include "rthread_cb.h"
@@ -87,24 +86,6 @@ struct pthread_attr _rthread_attr_default = {
/*
* internal support functions
*/
-void
-_spinlock(volatile _atomic_lock_t *lock)
-{
- while (_atomic_lock(lock))
- sched_yield();
-}
-
-int
-_spinlocktry(volatile _atomic_lock_t *lock)
-{
- return 0 == _atomic_lock(lock);
-}
-
-void
-_spinunlock(volatile _atomic_lock_t *lock)
-{
- *lock = _ATOMIC_LOCK_UNLOCKED;
-}
static void
_rthread_start(void *v)
@@ -169,29 +150,56 @@ multi_threaded_tcb(void)
}
#endif /* TCB_HAVE_MD_GET */
-void
-_thread_canceled(void)
+static void
+_rthread_free(pthread_t thread)
+{
+ _spinlock(&_thread_gc_lock);
+ TAILQ_INSERT_TAIL(&_thread_gc_list, thread, waiting);
+ _spinunlock(&_thread_gc_lock);
+}
+
+static void
+_thread_release(pthread_t thread)
+{
+ _spinlock(&_thread_lock);
+ LIST_REMOVE(thread, threads);
+ _spinunlock(&_thread_lock);
+
+ _spinlock(&thread->flags_lock);
+ if (thread->flags & THREAD_DETACHED) {
+ _spinunlock(&thread->flags_lock);
+ _rthread_free(thread);
+ } else {
+ thread->flags |= THREAD_DONE;
+ _spinunlock(&thread->flags_lock);
+ _sem_post(&thread->donesem);
+ }
+}
+
+static void
+_thread_key_zero(int key)
{
- pthread_exit(PTHREAD_CANCELED);
+ pthread_t thread;
+ struct rthread_storage *rs;
+
+ LIST_FOREACH(thread, &_thread_list, threads) {
+ for (rs = thread->local_storage; rs; rs = rs->next) {
+ if (rs->keyid == key)
+ rs->data = NULL;
+ }
+ }
}
void
_rthread_init(void)
{
- pthread_t thread = &_initial_thread;
- struct tib *tib;
+ pthread_t thread = pthread_self();
struct sigaction sa;
- tib = TIB_GET();
- tib->tib_thread = thread;
- thread->tib = tib;
+ if (_threads_ready)
+ return;
- thread->donesem.lock = _SPINLOCK_UNLOCKED;
- tib->tib_thread_flags = TIB_THREAD_INITIAL_STACK;
- thread->flags_lock = _SPINLOCK_UNLOCKED;
- strlcpy(thread->name, "Main process", sizeof(thread->name));
LIST_INSERT_HEAD(&_thread_list, thread, threads);
- _rthread_debug_init();
_thread_pagesize = (size_t)sysconf(_SC_PAGESIZE);
_rthread_attr_default.guard_size = _thread_pagesize;
@@ -205,26 +213,10 @@ _rthread_init(void)
cb.tc_errnoptr = multi_threaded_errnoptr;
cb.tc_tcb = multi_threaded_tcb;
#endif
- cb.tc_canceled = _thread_canceled;
- cb.tc_flockfile = _thread_flockfile;
- cb.tc_ftrylockfile = _thread_ftrylockfile;
- cb.tc_funlockfile = _thread_funlockfile;
- cb.tc_malloc_lock = _thread_malloc_lock;
- cb.tc_malloc_unlock = _thread_malloc_unlock;
- cb.tc_atexit_lock = _thread_atexit_lock;
- cb.tc_atexit_unlock = _thread_atexit_unlock;
- cb.tc_atfork_lock = _thread_atfork_lock;
- cb.tc_atfork_unlock = _thread_atfork_unlock;
- cb.tc_arc4_lock = _thread_arc4_lock;
- cb.tc_arc4_unlock = _thread_arc4_unlock;
- cb.tc_mutex_lock = _thread_mutex_lock;
- cb.tc_mutex_unlock = _thread_mutex_unlock;
- cb.tc_mutex_destroy = _thread_mutex_destroy;
- cb.tc_tag_lock = _thread_tag_lock;
- cb.tc_tag_unlock = _thread_tag_unlock;
- cb.tc_tag_storage = _thread_tag_storage;
cb.tc_fork = _thread_fork;
cb.tc_vfork = _thread_vfork;
+ cb.tc_thread_release = _thread_release;
+ cb.tc_thread_key_zero = _thread_key_zero;
_thread_set_callbacks(&cb, sizeof(cb));
}
@@ -253,27 +245,6 @@ _rthread_init(void)
}
static void
-_rthread_free(pthread_t thread)
-{
- _spinlock(&_thread_gc_lock);
- TAILQ_INSERT_TAIL(&_thread_gc_list, thread, waiting);
- _spinunlock(&_thread_gc_lock);
-}
-
-/*
- * real pthread functions
- */
-pthread_t
-pthread_self(void)
-{
- if (!_threads_ready)
- _rthread_init();
-
- return (TIB_GET()->tib_thread);
-}
-DEF_STD(pthread_self);
-
-static void
_rthread_reaper(void)
{
pthread_t thread;
@@ -301,55 +272,9 @@ restart:
_spinunlock(&_thread_gc_lock);
}
-void
-pthread_exit(void *retval)
-{
- struct rthread_cleanup_fn *clfn;
- struct tib *tib = TIB_GET();
- pthread_t thread;
-
- if (!_threads_ready)
- _rthread_init();
- thread = tib->tib_thread;
-
- if (tib->tib_cantcancel & CANCEL_DYING) {
- /*
- * Called pthread_exit() from destructor or cancelation
- * handler: blow up. XXX write something to stderr?
- */
- abort();
- //_exit(42);
- }
-
- tib->tib_cantcancel |= CANCEL_DYING;
-
- thread->retval = retval;
-
- for (clfn = thread->cleanup_fns; clfn; ) {
- struct rthread_cleanup_fn *oclfn = clfn;
- clfn = clfn->next;
- oclfn->fn(oclfn->arg);
- free(oclfn);
- }
- _rthread_tls_destructors(thread);
- _spinlock(&_thread_lock);
- LIST_REMOVE(thread, threads);
- _spinunlock(&_thread_lock);
-
- _spinlock(&thread->flags_lock);
- if (thread->flags & THREAD_DETACHED) {
- _spinunlock(&thread->flags_lock);
- _rthread_free(thread);
- } else {
- thread->flags |= THREAD_DONE;
- _spinunlock(&thread->flags_lock);
- _sem_post(&thread->donesem);
- }
-
- __threxit(&tib->tib_tid);
- for(;;);
-}
-DEF_STD(pthread_exit);
+/*
+ * real pthread functions
+ */
int
pthread_join(pthread_t thread, void **retval)
@@ -500,12 +425,6 @@ pthread_kill(pthread_t thread, int sig)
}
int
-pthread_equal(pthread_t t1, pthread_t t2)
-{
- return (t1 == t2);
-}
-
-int
pthread_cancel(pthread_t thread)
{
struct tib *tib = thread->tib;