summaryrefslogtreecommitdiff
path: root/lib/librthread/rthread_sync.c
diff options
context:
space:
mode:
authorPhilip Guenthe <guenther@cvs.openbsd.org>2011-12-21 23:59:04 +0000
committerPhilip Guenthe <guenther@cvs.openbsd.org>2011-12-21 23:59:04 +0000
commitd9368ef69de420c7613a640d9d62c5376674eb5a (patch)
tree39cc4edd2d1d310b20b76d1f69f4df444a74e135 /lib/librthread/rthread_sync.c
parent479071d116be1efbac3dd9be5b49f5f2f3e24c64 (diff)
Split out the pthread_rwlock* and pthread_once() functions from rthread_sync.c
to new files rthread_rwlock.c, rthread_rwlockattr.c, and rthread_once.c
Diffstat (limited to 'lib/librthread/rthread_sync.c')
-rw-r--r--lib/librthread/rthread_sync.c277
1 files changed, 2 insertions, 275 deletions
diff --git a/lib/librthread/rthread_sync.c b/lib/librthread/rthread_sync.c
index 502ad04fe9e..1cc9aa0aa0b 100644
--- a/lib/librthread/rthread_sync.c
+++ b/lib/librthread/rthread_sync.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: rthread_sync.c,v 1.26 2011/12/21 00:49:47 guenther Exp $ */
+/* $OpenBSD: rthread_sync.c,v 1.27 2011/12/21 23:59:03 guenther Exp $ */
/*
* Copyright (c) 2004,2005 Ted Unangst <tedu@openbsd.org>
* All Rights Reserved.
@@ -16,7 +16,7 @@
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
/*
- * Mutexes, conditions, rwlocks, and semaphores - synchronization functions.
+ * Mutexes, conditions, and semaphores - synchronization functions.
*/
@@ -417,276 +417,3 @@ pthread_condattr_destroy(pthread_condattr_t *attrp)
return (0);
}
-/*
- * rwlocks
- */
-int
-pthread_rwlock_init(pthread_rwlock_t *lockp, const pthread_rwlockattr_t *attrp)
-{
- pthread_rwlock_t lock;
-
- lock = calloc(1, sizeof(*lock));
- if (!lock)
- return (errno);
- lock->lock = _SPINLOCK_UNLOCKED;
- lock->sem.lock = _SPINLOCK_UNLOCKED;
- *lockp = lock;
-
- return (0);
-}
-
-int
-pthread_rwlock_destroy(pthread_rwlock_t *lockp)
-{
- if ((*lockp) && ((*lockp)->readers || (*lockp)->writer)) {
-#define MSG "pthread_rwlock_destroy on rwlock with waiters!\n"
- write(2, MSG, sizeof(MSG) - 1);
-#undef MSG
- return (EBUSY);
- }
- free(*lockp);
- *lockp = NULL;
-
- return (0);
-}
-
-static int
-_rthread_rwlock_ensure_init(pthread_rwlock_t *lockp)
-{
- int ret = 0;
-
- /*
- * If the rwlock is statically initialized, perform the dynamic
- * initialization.
- */
- if (*lockp == NULL)
- {
- _spinlock(&static_init_lock);
- if (*lockp == NULL)
- ret = pthread_rwlock_init(lockp, NULL);
- _spinunlock(&static_init_lock);
- }
- return (ret);
-}
-
-
-int
-pthread_rwlock_rdlock(pthread_rwlock_t *lockp)
-{
- pthread_rwlock_t lock;
- int error;
-
- if ((error = _rthread_rwlock_ensure_init(lockp)))
- return (error);
-
- lock = *lockp;
-again:
- _spinlock(&lock->lock);
- if (lock->writer) {
- _spinlock(&lock->sem.lock);
- _spinunlock(&lock->lock);
- _sem_waitl(&lock->sem, 0, 0, NULL);
- goto again;
- }
- lock->readers++;
- _spinunlock(&lock->lock);
-
- return (0);
-}
-
-int
-pthread_rwlock_timedrdlock(pthread_rwlock_t *lockp,
- const struct timespec *abstime)
-{
- pthread_rwlock_t lock;
- int do_wait = 1;
- int error;
-
- if ((error = _rthread_rwlock_ensure_init(lockp)))
- return (error);
-
- lock = *lockp;
- _spinlock(&lock->lock);
- while (lock->writer && do_wait) {
- _spinlock(&lock->sem.lock);
- _spinunlock(&lock->lock);
- do_wait = _sem_waitl(&lock->sem, 0, CLOCK_REALTIME, abstime);
- _spinlock(&lock->lock);
- }
- if (lock->writer) {
- /* do_wait must be 0, so timed out */
- _spinunlock(&lock->lock);
- return (ETIMEDOUT);
- }
- lock->readers++;
- _spinunlock(&lock->lock);
-
- return (0);
-}
-
-int
-pthread_rwlock_tryrdlock(pthread_rwlock_t *lockp)
-{
- pthread_rwlock_t lock;
- int error;
-
- if ((error = _rthread_rwlock_ensure_init(lockp)))
- return (error);
-
- lock = *lockp;
-
- _spinlock(&lock->lock);
- if (lock->writer) {
- _spinunlock(&lock->lock);
- return (EBUSY);
- }
- lock->readers++;
- _spinunlock(&lock->lock);
-
- return (0);
-}
-
-int
-pthread_rwlock_wrlock(pthread_rwlock_t *lockp)
-{
- pthread_rwlock_t lock;
- int error;
-
- if ((error = _rthread_rwlock_ensure_init(lockp)))
- return (error);
-
- lock = *lockp;
-
- _spinlock(&lock->lock);
- lock->writer++;
- while (lock->readers) {
- _spinlock(&lock->sem.lock);
- _spinunlock(&lock->lock);
- _sem_waitl(&lock->sem, 0, 0, NULL);
- _spinlock(&lock->lock);
- }
- lock->readers = -pthread_self()->tid;
- _spinunlock(&lock->lock);
-
- return (0);
-}
-
-int
-pthread_rwlock_timedwrlock(pthread_rwlock_t *lockp,
- const struct timespec *abstime)
-{
- pthread_rwlock_t lock;
- int do_wait = 1;
- int error;
-
- if ((error = _rthread_rwlock_ensure_init(lockp)))
- return (error);
-
- lock = *lockp;
-
- _spinlock(&lock->lock);
- lock->writer++;
- while (lock->readers && do_wait) {
- _spinlock(&lock->sem.lock);
- _spinunlock(&lock->lock);
- do_wait = _sem_waitl(&lock->sem, 0, CLOCK_REALTIME, abstime);
- _spinlock(&lock->lock);
- }
- if (lock->readers) {
- /* do_wait must be 0, so timed out */
- lock->writer--;
- _spinunlock(&lock->lock);
- return (ETIMEDOUT);
- }
- lock->readers = -pthread_self()->tid;
- _spinunlock(&lock->lock);
-
- return (0);
-}
-
-int
-pthread_rwlock_trywrlock(pthread_rwlock_t *lockp)
-{
- pthread_rwlock_t lock;
- int error;
-
- if ((error = _rthread_rwlock_ensure_init(lockp)))
- return (error);
-
- lock = *lockp;
-
- _spinlock(&lock->lock);
- if (lock->readers || lock->writer) {
- _spinunlock(&lock->lock);
- return (EBUSY);
- }
- lock->writer = 1;
- lock->readers = -pthread_self()->tid;
- _spinunlock(&lock->lock);
-
- return (0);
-}
-
-int
-pthread_rwlock_unlock(pthread_rwlock_t *lockp)
-{
- pthread_rwlock_t lock;
-
- lock = *lockp;
-
- _spinlock(&lock->lock);
- if (lock->readers == -pthread_self()->tid) {
- lock->readers = 0;
- lock->writer--;
- } else if (lock->readers > 0) {
- lock->readers--;
- } else {
- _spinunlock(&lock->lock);
- return (EPERM);
- }
- _spinunlock(&lock->lock);
- _sem_wakeall(&lock->sem);
-
- return (0);
-}
-
-/*
- * rwlock attributes
- */
-int
-pthread_rwlockattr_init(pthread_rwlockattr_t *attrp)
-{
- pthread_rwlockattr_t attr;
-
- attr = calloc(1, sizeof(*attr));
- if (!attr)
- return (errno);
- *attrp = attr;
-
- return (0);
-}
-
-int
-pthread_rwlockattr_destroy(pthread_rwlockattr_t *attrp)
-{
- free(*attrp);
- *attrp = NULL;
-
- return (0);
-}
-
-/*
- * pthread_once
- */
-int
-pthread_once(pthread_once_t *once_control, void (*init_routine)(void))
-{
- pthread_mutex_lock(&once_control->mutex);
- if (once_control->state == PTHREAD_NEEDS_INIT) {
- init_routine();
- once_control->state = PTHREAD_DONE_INIT;
- }
- pthread_mutex_unlock(&once_control->mutex);
-
- return (0);
-}