summaryrefslogtreecommitdiff
path: root/lib/librthread
diff options
context:
space:
mode:
Diffstat (limited to 'lib/librthread')
-rw-r--r--lib/librthread/Makefile5
-rw-r--r--lib/librthread/rthread_sem.c202
-rw-r--r--lib/librthread/rthread_sync.c180
3 files changed, 207 insertions, 180 deletions
diff --git a/lib/librthread/Makefile b/lib/librthread/Makefile
index 3586e8179a7..83f692d9290 100644
--- a/lib/librthread/Makefile
+++ b/lib/librthread/Makefile
@@ -1,4 +1,4 @@
-# $OpenBSD: Makefile,v 1.22 2011/12/22 00:42:07 guenther Exp $
+# $OpenBSD: Makefile,v 1.23 2012/01/04 17:43:34 mpi Exp $
LIB=rthread
WANTLINT=
@@ -15,7 +15,8 @@ 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_once.c \
- rthread_rwlock.c rthread_rwlockattr.c rthread_mutex_prio.c
+ rthread_rwlock.c rthread_rwlockattr.c rthread_mutex_prio.c \
+ rthread_sem.c
OBJS+= _atomic_lock.o rfork_thread.o cerror.o
diff --git a/lib/librthread/rthread_sem.c b/lib/librthread/rthread_sem.c
new file mode 100644
index 00000000000..ea855d5d1d3
--- /dev/null
+++ b/lib/librthread/rthread_sem.c
@@ -0,0 +1,202 @@
+/* $OpenBSD */
+/*
+ * 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 <stdlib.h>
+#include <unistd.h>
+#include <errno.h>
+
+#include <pthread.h>
+
+#include "rthread.h"
+
+/*
+ * Internal implementation of semaphores
+ */
+int
+_sem_wait(sem_t sem, int tryonly)
+{
+
+ _spinlock(&sem->lock);
+ return (_sem_waitl(sem, tryonly, 0, NULL));
+}
+
+int
+_sem_waitl(sem_t sem, int tryonly, clockid_t clock_id,
+ const struct timespec *abstime)
+{
+ int do_sleep;
+
+again:
+ if (sem->value == 0) {
+ if (tryonly) {
+ _spinunlock(&sem->lock);
+ return (0);
+ }
+ sem->waitcount++;
+ do_sleep = 1;
+ } else {
+ sem->value--;
+ do_sleep = 0;
+ }
+
+ if (do_sleep) {
+ if (thrsleep(sem, clock_id, abstime, &sem->lock) == -1 &&
+ errno == EWOULDBLOCK)
+ return (0);
+ _spinlock(&sem->lock);
+ sem->waitcount--;
+ goto again;
+ }
+ _spinunlock(&sem->lock);
+ return (1);
+}
+
+/* always increment count */
+int
+_sem_post(sem_t sem)
+{
+ int rv = 0;
+
+ _spinlock(&sem->lock);
+ sem->value++;
+ if (sem->waitcount) {
+ thrwakeup(sem, 1);
+ rv = 1;
+ }
+ _spinunlock(&sem->lock);
+ return (rv);
+}
+
+/* only increment count if a waiter */
+int
+_sem_wakeup(sem_t sem)
+{
+ int rv = 0;
+
+ _spinlock(&sem->lock);
+ if (sem->waitcount) {
+ sem->value++;
+ thrwakeup(sem, 1);
+ rv = 1;
+ }
+ _spinunlock(&sem->lock);
+ return (rv);
+}
+
+
+int
+_sem_wakeall(sem_t sem)
+{
+ int rv;
+
+ _spinlock(&sem->lock);
+ rv = sem->waitcount;
+ sem->value += rv;
+ thrwakeup(sem, 0);
+ _spinunlock(&sem->lock);
+
+ return (rv);
+}
+
+/*
+ * exported semaphores
+ */
+int
+sem_init(sem_t *semp, int pshared, unsigned int value)
+{
+ sem_t sem;
+
+ if (pshared) {
+ errno = EPERM;
+ return (-1);
+ }
+
+ sem = calloc(1, sizeof(*sem));
+ if (!sem)
+ return (-1);
+ sem->value = value;
+ *semp = sem;
+
+ return (0);
+}
+
+int
+sem_destroy(sem_t *semp)
+{
+ if (!*semp)
+ return (EINVAL);
+ if ((*semp)->waitcount) {
+#define MSG "sem_destroy on semaphore with waiters!\n"
+ write(2, MSG, sizeof(MSG) - 1);
+#undef MSG
+ return (EBUSY);
+ }
+ free(*semp);
+ *semp = NULL;
+
+ return (0);
+}
+
+int
+sem_getvalue(sem_t *semp, int *sval)
+{
+ sem_t sem = *semp;
+
+ _spinlock(&sem->lock);
+ *sval = sem->value;
+ _spinunlock(&sem->lock);
+
+ return (0);
+}
+
+int
+sem_post(sem_t *semp)
+{
+ sem_t sem = *semp;
+
+ _sem_post(sem);
+
+ return (0);
+}
+
+int
+sem_wait(sem_t *semp)
+{
+ sem_t sem = *semp;
+
+ _sem_wait(sem, 0);
+
+ return (0);
+}
+
+int
+sem_trywait(sem_t *semp)
+{
+ sem_t sem = *semp;
+ int rv;
+
+ rv = _sem_wait(sem, 1);
+
+ if (!rv) {
+ errno = EAGAIN;
+ return (-1);
+ }
+
+ return (0);
+}
+
diff --git a/lib/librthread/rthread_sync.c b/lib/librthread/rthread_sync.c
index 1cc9aa0aa0b..cbe529a83aa 100644
--- a/lib/librthread/rthread_sync.c
+++ b/lib/librthread/rthread_sync.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: rthread_sync.c,v 1.27 2011/12/21 23:59:03 guenther Exp $ */
+/* $OpenBSD: rthread_sync.c,v 1.28 2012/01/04 17:43:34 mpi 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, and semaphores - synchronization functions.
+ * Mutexes and conditions - synchronization functions.
*/
@@ -31,182 +31,6 @@
static _spinlock_lock_t static_init_lock = _SPINLOCK_UNLOCKED;
/*
- * Internal implementation of semaphores
- */
-int
-_sem_wait(sem_t sem, int tryonly)
-{
-
- _spinlock(&sem->lock);
- return (_sem_waitl(sem, tryonly, 0, NULL));
-}
-
-int
-_sem_waitl(sem_t sem, int tryonly, clockid_t clock_id,
- const struct timespec *abstime)
-{
- int do_sleep;
-
-again:
- if (sem->value == 0) {
- if (tryonly) {
- _spinunlock(&sem->lock);
- return (0);
- }
- sem->waitcount++;
- do_sleep = 1;
- } else {
- sem->value--;
- do_sleep = 0;
- }
-
- if (do_sleep) {
- if (thrsleep(sem, clock_id, abstime, &sem->lock) == -1 &&
- errno == EWOULDBLOCK)
- return (0);
- _spinlock(&sem->lock);
- sem->waitcount--;
- goto again;
- }
- _spinunlock(&sem->lock);
- return (1);
-}
-
-/* always increment count */
-int
-_sem_post(sem_t sem)
-{
- int rv = 0;
-
- _spinlock(&sem->lock);
- sem->value++;
- if (sem->waitcount) {
- thrwakeup(sem, 1);
- rv = 1;
- }
- _spinunlock(&sem->lock);
- return (rv);
-}
-
-/* only increment count if a waiter */
-int
-_sem_wakeup(sem_t sem)
-{
- int rv = 0;
-
- _spinlock(&sem->lock);
- if (sem->waitcount) {
- sem->value++;
- thrwakeup(sem, 1);
- rv = 1;
- }
- _spinunlock(&sem->lock);
- return (rv);
-}
-
-
-int
-_sem_wakeall(sem_t sem)
-{
- int rv;
-
- _spinlock(&sem->lock);
- rv = sem->waitcount;
- sem->value += rv;
- thrwakeup(sem, 0);
- _spinunlock(&sem->lock);
-
- return (rv);
-}
-
-/*
- * exported semaphores
- */
-int
-sem_init(sem_t *semp, int pshared, unsigned int value)
-{
- sem_t sem;
-
- if (pshared) {
- errno = EPERM;
- return (-1);
- }
-
- sem = calloc(1, sizeof(*sem));
- if (!sem)
- return (-1);
- sem->value = value;
- *semp = sem;
-
- return (0);
-}
-
-int
-sem_destroy(sem_t *semp)
-{
- if (!*semp)
- return (EINVAL);
- if ((*semp)->waitcount) {
-#define MSG "sem_destroy on semaphore with waiters!\n"
- write(2, MSG, sizeof(MSG) - 1);
-#undef MSG
- return (EBUSY);
- }
- free(*semp);
- *semp = NULL;
-
- return (0);
-}
-
-int
-sem_getvalue(sem_t *semp, int *sval)
-{
- sem_t sem = *semp;
-
- _spinlock(&sem->lock);
- *sval = sem->value;
- _spinunlock(&sem->lock);
-
- return (0);
-}
-
-int
-sem_post(sem_t *semp)
-{
- sem_t sem = *semp;
-
- _sem_post(sem);
-
- return (0);
-}
-
-int
-sem_wait(sem_t *semp)
-{
- sem_t sem = *semp;
-
- _sem_wait(sem, 0);
-
- return (0);
-}
-
-int
-sem_trywait(sem_t *semp)
-{
- sem_t sem = *semp;
- int rv;
-
- rv = _sem_wait(sem, 1);
-
- if (!rv) {
- errno = EAGAIN;
- return (-1);
- }
-
- return (0);
-}
-
-/*
* mutexen
*/
int