summaryrefslogtreecommitdiff
path: root/lib
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
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')
-rw-r--r--lib/librthread/Makefile5
-rw-r--r--lib/librthread/rthread_once.c32
-rw-r--r--lib/librthread/rthread_rwlock.c262
-rw-r--r--lib/librthread/rthread_rwlockattr.c51
-rw-r--r--lib/librthread/rthread_sync.c277
5 files changed, 350 insertions, 277 deletions
diff --git a/lib/librthread/Makefile b/lib/librthread/Makefile
index 3e5bfd8e64a..768cd36dadd 100644
--- a/lib/librthread/Makefile
+++ b/lib/librthread/Makefile
@@ -1,4 +1,4 @@
-# $OpenBSD: Makefile,v 1.20 2011/12/21 00:49:47 guenther Exp $
+# $OpenBSD: Makefile,v 1.21 2011/12/21 23:59:03 guenther Exp $
LIB=rthread
WANTLINT=
@@ -14,7 +14,8 @@ LDADD = -Wl,-znodelete,-zinitfirst
SRCS= rthread.c rthread_attr.c rthread_sched.c rthread_sync.c rthread_tls.c \
rthread_sig.c rthread_np.c rthread_debug.c rthread_stack.c \
rthread_libc.c rthread_fork.c rthread_file.c sched_prio.c \
- rthread_cancel.c rthread_mutexattr.c
+ rthread_cancel.c rthread_mutexattr.c rthread_once.c \
+ rthread_rwlock.c rthread_rwlockattr.c
OBJS+= _atomic_lock.o rfork_thread.o cerror.o
diff --git a/lib/librthread/rthread_once.c b/lib/librthread/rthread_once.c
new file mode 100644
index 00000000000..cb5ea8a948f
--- /dev/null
+++ b/lib/librthread/rthread_once.c
@@ -0,0 +1,32 @@
+/* $OpenBSD: rthread_once.c,v 1.1 2011/12/21 23:59:03 guenther Exp $ */
+/*
+ * Copyright (c) 2004,2005 Ted Unangst <tedu@openbsd.org>
+ * All Rights Reserved.
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#include <pthread.h>
+
+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);
+}
diff --git a/lib/librthread/rthread_rwlock.c b/lib/librthread/rthread_rwlock.c
new file mode 100644
index 00000000000..0d391fe9afd
--- /dev/null
+++ b/lib/librthread/rthread_rwlock.c
@@ -0,0 +1,262 @@
+/* $OpenBSD: rthread_rwlock.c,v 1.1 2011/12/21 23:59:03 guenther Exp $ */
+/*
+ * Copyright (c) 2004,2005 Ted Unangst <tedu@openbsd.org>
+ * All Rights Reserved.
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+/*
+ * rwlocks
+ */
+
+
+#include <stdlib.h>
+#include <unistd.h>
+#include <errno.h>
+
+#include <pthread.h>
+
+#include "rthread.h"
+
+
+static _spinlock_lock_t rwlock_init_lock = _SPINLOCK_UNLOCKED;
+
+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(&rwlock_init_lock);
+ if (*lockp == NULL)
+ ret = pthread_rwlock_init(lockp, NULL);
+ _spinunlock(&rwlock_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);
+}
diff --git a/lib/librthread/rthread_rwlockattr.c b/lib/librthread/rthread_rwlockattr.c
new file mode 100644
index 00000000000..2c611758ce9
--- /dev/null
+++ b/lib/librthread/rthread_rwlockattr.c
@@ -0,0 +1,51 @@
+/* $OpenBSD: rthread_rwlockattr.c,v 1.1 2011/12/21 23:59:03 guenther Exp $ */
+/*
+ * Copyright (c) 2004,2005 Ted Unangst <tedu@openbsd.org>
+ * All Rights Reserved.
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+/*
+ * rwlock attributes
+ */
+
+
+#include <stdlib.h>
+#include <unistd.h>
+#include <errno.h>
+
+#include <pthread.h>
+
+#include "rthread.h"
+
+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);
+}
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);
-}