summaryrefslogtreecommitdiffstats
path: root/lib/librthread/rthread.c
diff options
context:
space:
mode:
authortedu <tedu@openbsd.org>2013-06-01 20:47:40 +0000
committertedu <tedu@openbsd.org>2013-06-01 20:47:40 +0000
commit7ff8e670fdcebc6357ff73a15e02d91577802ab6 (patch)
treeed53d42fedbc32a6eba99a84f0405645632bc508 /lib/librthread/rthread.c
parentFilter out route messages we don't need and log kernel messages in (diff)
downloadwireguard-openbsd-7ff8e670fdcebc6357ff73a15e02d91577802ab6.tar.xz
wireguard-openbsd-7ff8e670fdcebc6357ff73a15e02d91577802ab6.zip
cleanup and consolidate the spinlock_lock (what a name!) code.
it's now atomic_lock to better reflect its usage, and librthread now features a new spinlock that's really a ticket lock. thrlseep can handle both types of lock via a flag in the clock arg. (temp back compat hack) remove some old stuff that's accumulated along the way and no longer used. some feedback from dlg, who is concerned with all things ticket lock. (you need to boot a new kernel before installing librthread)
Diffstat (limited to 'lib/librthread/rthread.c')
-rw-r--r--lib/librthread/rthread.c59
1 files changed, 44 insertions, 15 deletions
diff --git a/lib/librthread/rthread.c b/lib/librthread/rthread.c
index 49b4f1ddd14..3a2e6bf55b2 100644
--- a/lib/librthread/rthread.c
+++ b/lib/librthread/rthread.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: rthread.c,v 1.69 2013/04/06 04:25:01 tedu Exp $ */
+/* $OpenBSD: rthread.c,v 1.70 2013/06/01 20:47:40 tedu Exp $ */
/*
* Copyright (c) 2004,2005 Ted Unangst <tedu@openbsd.org>
* All Rights Reserved.
@@ -49,13 +49,15 @@
static int concurrency_level; /* not used */
+struct _spinlock _SPINLOCK_UNLOCKED_ASSIGN = _SPINLOCK_UNLOCKED;
+
int _threads_ready;
size_t _thread_pagesize;
struct listhead _thread_list = LIST_HEAD_INITIALIZER(_thread_list);
-_spinlock_lock_t _thread_lock = _SPINLOCK_UNLOCKED;
+struct _spinlock _thread_lock = _SPINLOCK_UNLOCKED;
static struct pthread_queue _thread_gc_list
= TAILQ_HEAD_INITIALIZER(_thread_gc_list);
-static _spinlock_lock_t _thread_gc_lock = _SPINLOCK_UNLOCKED;
+static struct _spinlock _thread_gc_lock = _SPINLOCK_UNLOCKED;
struct pthread _initial_thread;
struct thread_control_block _initial_thread_tcb;
@@ -78,18 +80,45 @@ struct pthread_attr _rthread_attr_default = {
* internal support functions
*/
void
-_spinlock(_spinlock_lock_t *lock)
+_spinlock(volatile struct _spinlock *lock)
{
+ uint32_t me;
- while (_atomic_lock(lock))
+ while (_atomic_lock(&lock->atomiclock))
sched_yield();
+ me = lock->waiter++;
+ lock->atomiclock = _ATOMIC_LOCK_UNLOCKED;
+ while (me != lock->ready) {
+ if (me < lock->ready) {
+ _rthread_debug(0, "SPINLOCK FAIL: %d %d\n",
+ me, lock->ready);
+ _exit(1);
+ }
+ if (me > lock->ready + 1)
+ sched_yield();
+ }
}
-void
-_spinunlock(_spinlock_lock_t *lock)
+int
+_spinlocktry(volatile struct _spinlock *lock)
{
+ int gotit = 0;
+
+ while (_atomic_lock(&lock->atomiclock))
+ sched_yield();
+ if (lock->waiter == lock->ready) {
+ lock->waiter++;
+ gotit = 1;
+ }
+ lock->atomiclock = _ATOMIC_LOCK_UNLOCKED;
+
+ return gotit;
+}
- *lock = _SPINLOCK_UNLOCKED;
+void
+_spinunlock(volatile struct _spinlock *lock)
+{
+ lock->ready++;
}
/*
@@ -164,9 +193,9 @@ _rthread_init(void)
struct sigaction sa;
thread->tid = getthrid();
- thread->donesem.lock = _SPINLOCK_UNLOCKED;
+ thread->donesem.lock = _SPINLOCK_UNLOCKED_ASSIGN;
thread->flags |= THREAD_CANCEL_ENABLE|THREAD_CANCEL_DEFERRED;
- thread->flags_lock = _SPINLOCK_UNLOCKED;
+ thread->flags_lock = _SPINLOCK_UNLOCKED_ASSIGN;
strlcpy(thread->name, "Main process", sizeof(thread->name));
LIST_INSERT_HEAD(&_thread_list, thread, threads);
_rthread_debug_init();
@@ -403,8 +432,8 @@ pthread_create(pthread_t *threadp, const pthread_attr_t *attr,
thread = calloc(1, sizeof(*thread));
if (!thread)
return (errno);
- thread->donesem.lock = _SPINLOCK_UNLOCKED;
- thread->flags_lock = _SPINLOCK_UNLOCKED;
+ thread->donesem.lock = _SPINLOCK_UNLOCKED_ASSIGN;
+ thread->flags_lock = _SPINLOCK_UNLOCKED_ASSIGN;
thread->fn = start_routine;
thread->arg = arg;
thread->tid = -1;
@@ -603,7 +632,7 @@ _thread_dump_info(void)
void
_rthread_dl_lock(int what)
{
- static _spinlock_lock_t lock = _SPINLOCK_UNLOCKED;
+ static struct _spinlock lock = _SPINLOCK_UNLOCKED;
static pthread_t owner = NULL;
static struct pthread_queue lockers = TAILQ_HEAD_INITIALIZER(lockers);
static int count = 0;
@@ -619,7 +648,7 @@ _rthread_dl_lock(int what)
} else if (owner != self) {
TAILQ_INSERT_TAIL(&lockers, self, waiting);
while (owner != self) {
- __thrsleep(self, 0, NULL, &lock, NULL);
+ __thrsleep(self, 0 | 0x8, NULL, &lock.ready, NULL);
_spinlock(&lock);
}
}
@@ -646,7 +675,7 @@ _rthread_dl_lock(int what)
void
_rthread_bind_lock(int what)
{
- static _spinlock_lock_t lock = _SPINLOCK_UNLOCKED;
+ static struct _spinlock lock = _SPINLOCK_UNLOCKED;
if (what == 0)
_spinlock(&lock);