summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTed Unangst <tedu@cvs.openbsd.org>2010-04-12 01:54:24 +0000
committerTed Unangst <tedu@cvs.openbsd.org>2010-04-12 01:54:24 +0000
commit41c1a3e3e6683fe9b4edf023cd5a862fd79746b0 (patch)
treeefce53ab5ec5de44259e6fae7768cc9358cbce71
parent46975a2a516f3489a5273d971ef327e5c5fd681e (diff)
Add support for pthread_rwlock_timed locks.
from brad. ok kurt, who's too busy to commit
-rw-r--r--lib/libpthread/include/pthread.h6
-rw-r--r--lib/libpthread/man/Makefile.inc4
-rw-r--r--lib/libpthread/man/pthread_rwlock_rdlock.340
-rw-r--r--lib/libpthread/man/pthread_rwlock_wrlock.339
-rw-r--r--lib/libpthread/shlib_version2
-rw-r--r--lib/libpthread/uthread/uthread_rwlock.c54
6 files changed, 118 insertions, 27 deletions
diff --git a/lib/libpthread/include/pthread.h b/lib/libpthread/include/pthread.h
index e572fae8f73..42367b1bfaf 100644
--- a/lib/libpthread/include/pthread.h
+++ b/lib/libpthread/include/pthread.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: pthread.h,v 1.29 2008/12/18 09:30:32 guenther Exp $ */
+/* $OpenBSD: pthread.h,v 1.30 2010/04/12 01:54:23 tedu Exp $ */
/*
* Copyright (c) 1993, 1994 by Chris Provenzano, proven@mit.edu
@@ -250,6 +250,10 @@ int pthread_rwlock_destroy(pthread_rwlock_t *);
int pthread_rwlock_init(pthread_rwlock_t *,
const pthread_rwlockattr_t *);
int pthread_rwlock_rdlock(pthread_rwlock_t *);
+int pthread_rwlock_timedrdlock(pthread_rwlock_t *,
+ const struct timespec *);
+int pthread_rwlock_timedwrlock(pthread_rwlock_t *,
+ const struct timespec *);
int pthread_rwlock_tryrdlock(pthread_rwlock_t *);
int pthread_rwlock_trywrlock(pthread_rwlock_t *);
int pthread_rwlock_unlock(pthread_rwlock_t *);
diff --git a/lib/libpthread/man/Makefile.inc b/lib/libpthread/man/Makefile.inc
index 327457260ac..959b9b16264 100644
--- a/lib/libpthread/man/Makefile.inc
+++ b/lib/libpthread/man/Makefile.inc
@@ -1,4 +1,4 @@
-# $OpenBSD: Makefile.inc,v 1.23 2008/12/18 09:30:32 guenther Exp $
+# $OpenBSD: Makefile.inc,v 1.24 2010/04/12 01:54:23 tedu Exp $
# $FreeBSD: Makefile.inc,v 1.6 1999/08/28 00:03:02 peter Exp $
# POSIX thread man files
@@ -74,6 +74,8 @@ MAN+= pthreads.3 \
MLINKS+=flockfile.3 funlockfile.3 \
flockfile.3 ftrylockfile.3 \
+ pthread_rwlock_rdlock.3 pthread_rwlock_timedrdlock.3 \
+ pthread_rwlock_wrlock.3 pthread_rwlock_timedwrlock.3 \
pthread_rwlock_rdlock.3 pthread_rwlock_tryrdlock.3 \
pthread_rwlock_wrlock.3 pthread_rwlock_trywrlock.3 \
getc_unlocked.3 getchar_unlocked.3 \
diff --git a/lib/libpthread/man/pthread_rwlock_rdlock.3 b/lib/libpthread/man/pthread_rwlock_rdlock.3
index 2102c6a74a9..5be678b7675 100644
--- a/lib/libpthread/man/pthread_rwlock_rdlock.3
+++ b/lib/libpthread/man/pthread_rwlock_rdlock.3
@@ -1,4 +1,4 @@
-.\" $OpenBSD: pthread_rwlock_rdlock.3,v 1.8 2007/05/31 19:19:37 jmc Exp $
+.\" $OpenBSD: pthread_rwlock_rdlock.3,v 1.9 2010/04/12 01:54:23 tedu Exp $
.\" Copyright (c) 1998 Alex Nash
.\" All rights reserved.
.\"
@@ -25,11 +25,12 @@
.\"
.\" $FreeBSD: pthread_rwlock_rdlock.3,v 1.2 1999/08/28 00:03:09 peter Exp $
.\"
-.Dd $Mdocdate: May 31 2007 $
+.Dd $Mdocdate: April 12 2010 $
.Dt PTHREAD_RWLOCK_RDLOCK 3
.Os
.Sh NAME
.Nm pthread_rwlock_rdlock ,
+.Nm pthread_rwlock_timedrdlock ,
.Nm pthread_rwlock_tryrdlock
.Nd acquire a read/write lock for reading
.Sh SYNOPSIS
@@ -37,6 +38,8 @@
.Ft int
.Fn pthread_rwlock_rdlock "pthread_rwlock_t *lock"
.Ft int
+.Fn pthread_rwlock_timedrdlock "pthread_rwlock_t *lock" "const struct timespec *abstime"
+.Ft int
.Fn pthread_rwlock_tryrdlock "pthread_rwlock_t *lock"
.Sh DESCRIPTION
The
@@ -51,10 +54,18 @@ If the read lock cannot be immediately acquired,
the calling thread blocks until it can acquire the lock.
.Pp
The
+.Fn pthread_rwlock_timedrdlock
+function performs the same action,
+but will not wait beyond
+.Fa abstime
+to obtain the lock before returning.
+.Pp
+The
.Fn pthread_rwlock_tryrdlock
-function performs the same action, but does not block if the lock
-cannot be immediately obtained (i.e., the lock is held for writing
-or there are waiting writers).
+function performs the same action as
+.Fn pthread_rwlock_rdlock ,
+but does not block if the lock cannot be immediately obtained
+(i.e., the lock is held for writing or there are writers waiting).
.Pp
A thread may hold multiple concurrent read locks.
If so,
@@ -67,7 +78,8 @@ a write lock are undefined.
To prevent writer starvation, writers are favored over readers.
.Sh RETURN VALUES
If successful, the
-.Fn pthread_rwlock_rdlock
+.Fn pthread_rwlock_rdlock ,
+.Fn pthread_rwlock_timedrdlock ,
and
.Fn pthread_rwlock_tryrdlock
functions will return zero.
@@ -83,7 +95,18 @@ was blocked on it.
.El
.Pp
The
-.Fn pthread_rwlock_rdlock
+.Fn pthread_rwlock_timedrdlock
+function will fail if:
+.Bl -tag -width Er
+.It Bq Er ETIMEDOUT
+The time specified by
+.Fa abstime
+was reached before the lock could be obtained.
+.El
+.Pp
+The
+.Fn pthread_rwlock_rdlock ,
+.Fn pthread_rwlock_timedrdlock ,
and
.Fn pthread_rwlock_tryrdlock
functions may fail if:
@@ -112,7 +135,8 @@ statically initialized locks only).
.Xr pthread_rwlock_wrlock 3
.Sh STANDARDS
The
-.Fn pthread_rwlock_rdlock
+.Fn pthread_rwlock_rdlock ,
+.Fn pthread_rwlock_timedrdlock ,
and
.Fn pthread_rwlock_tryrdlock
functions are expected to conform to
diff --git a/lib/libpthread/man/pthread_rwlock_wrlock.3 b/lib/libpthread/man/pthread_rwlock_wrlock.3
index 247c0c91d9c..f79b29f8d67 100644
--- a/lib/libpthread/man/pthread_rwlock_wrlock.3
+++ b/lib/libpthread/man/pthread_rwlock_wrlock.3
@@ -1,4 +1,4 @@
-.\" $OpenBSD: pthread_rwlock_wrlock.3,v 1.7 2007/05/31 19:19:37 jmc Exp $
+.\" $OpenBSD: pthread_rwlock_wrlock.3,v 1.8 2010/04/12 01:54:23 tedu Exp $
.\" Copyright (c) 1998 Alex Nash
.\" All rights reserved.
.\"
@@ -25,11 +25,12 @@
.\"
.\" $FreeBSD: pthread_rwlock_wrlock.3,v 1.2 1999/08/28 00:03:10 peter Exp $
.\"
-.Dd $Mdocdate: May 31 2007 $
+.Dd $Mdocdate: April 12 2010 $
.Dt PTHREAD_RWLOCK_WRLOCK 3
.Os
.Sh NAME
.Nm pthread_rwlock_wrlock ,
+.Nm pthread_rwlock_timedwrlock ,
.Nm pthread_rwlock_trywrlock
.Nd acquire a read/write lock for writing
.Sh SYNOPSIS
@@ -37,16 +38,27 @@
.Ft int
.Fn pthread_rwlock_wrlock "pthread_rwlock_t *lock"
.Ft int
+.Fn pthread_rwlock_timedwrlock "pthread_rwlock_t *lock" "const struct timespec *abstime"
+.Ft int
.Fn pthread_rwlock_trywrlock "pthread_rwlock_t *lock"
.Sh DESCRIPTION
The
.Fn pthread_rwlock_wrlock
function blocks until a write lock can be acquired against
.Fa lock .
+.Pp
+The
+.Fn pthread_rwlock_timedwrlock
+function performs the same action,
+but will not wait beyond
+.Fa abstime
+to obtain the lock before returning.
+.Pp
The
.Fn pthread_rwlock_trywrlock
-function performs the same action, but does not block if the lock
-cannot be immediately obtained.
+function performs the same action as
+.Fn pthread_rwlock_wrlock ,
+but does not block if the lock cannot be immediately obtained.
.Pp
The results are undefined if the calling thread already holds the
lock at the time the call is made.
@@ -54,7 +66,8 @@ lock at the time the call is made.
To prevent writer starvation, writers are favored over readers.
.Sh RETURN VALUES
If successful, the
-.Fn pthread_rwlock_wrlock
+.Fn pthread_rwlock_wrlock ,
+.Fn pthread_rwlock_timedwrlock ,
and
.Fn pthread_rwlock_trywrlock
functions will return zero.
@@ -69,7 +82,18 @@ The calling thread is not able to acquire the lock without blocking.
.El
.Pp
The
-.Fn pthread_rwlock_wrlock
+.Fn pthread_rwlock_timedwrlock
+function will fail if:
+.Bl -tag -width Er
+.It Bq Er ETIMEDOUT
+The time specified by
+.Fa abstime
+was reached before the lock could be obtained.
+.El
+.Pp
+The
+.Fn pthread_rwlock_wrlock ,
+.Fn pthread_rwlock_timedwrlock ,
and
.Fn pthread_rwlock_trywrlock
functions may fail if:
@@ -89,7 +113,8 @@ statically initialized locks only).
.Xr pthread_rwlock_unlock 3
.Sh STANDARDS
The
-.Fn pthread_rwlock_wrlock
+.Fn pthread_rwlock_wrlock ,
+.Fn pthread_rwlock_timedwrlock ,
and
.Fn pthread_rwlock_trywrlock
functions are expected to conform to
diff --git a/lib/libpthread/shlib_version b/lib/libpthread/shlib_version
index 56246d02b24..eb2c603aec0 100644
--- a/lib/libpthread/shlib_version
+++ b/lib/libpthread/shlib_version
@@ -1,2 +1,2 @@
major=12
-minor=0
+minor=1
diff --git a/lib/libpthread/uthread/uthread_rwlock.c b/lib/libpthread/uthread/uthread_rwlock.c
index b5c2d4da339..cf6edf5e6d7 100644
--- a/lib/libpthread/uthread/uthread_rwlock.c
+++ b/lib/libpthread/uthread/uthread_rwlock.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: uthread_rwlock.c,v 1.6 2007/05/18 19:28:50 kurt Exp $ */
+/* $OpenBSD: uthread_rwlock.c,v 1.7 2010/04/12 01:54:23 tedu Exp $ */
/*-
* Copyright (c) 1998 Alex Nash
* All rights reserved.
@@ -127,8 +127,8 @@ pthread_rwlock_init (pthread_rwlock_t *rwlock, const pthread_rwlockattr_t *attr)
return (ret);
}
-int
-pthread_rwlock_rdlock (pthread_rwlock_t *rwlock)
+static int
+rwlock_rdlock_common (pthread_rwlock_t *rwlock, const struct timespec *abstime)
{
pthread_rwlock_t prwlock;
struct pthread *curthread;
@@ -175,8 +175,13 @@ pthread_rwlock_rdlock (pthread_rwlock_t *rwlock)
} else {
/* give writers priority over readers */
while (prwlock->blocked_writers || prwlock->state < 0) {
- ret = pthread_cond_wait(&prwlock->read_signal,
- &prwlock->lock);
+ if (abstime) {
+ ret = pthread_cond_timedwait(&prwlock->read_signal,
+ &prwlock->lock, abstime);
+ } else {
+ ret = pthread_cond_wait(&prwlock->read_signal,
+ &prwlock->lock);
+ }
if (ret != 0) {
/* can't do a whole lot if this fails */
@@ -201,6 +206,19 @@ pthread_rwlock_rdlock (pthread_rwlock_t *rwlock)
}
int
+pthread_rwlock_rdlock (pthread_rwlock_t *rwlock)
+{
+ return rwlock_rdlock_common (rwlock, NULL);
+}
+
+int
+pthread_rwlock_timedrdlock (pthread_rwlock_t *rwlock,
+ const struct timespec *abstime)
+{
+ return rwlock_rdlock_common(rwlock, abstime);
+}
+
+int
pthread_rwlock_tryrdlock (pthread_rwlock_t *rwlock)
{
pthread_rwlock_t prwlock;
@@ -322,8 +340,8 @@ pthread_rwlock_unlock (pthread_rwlock_t *rwlock)
return (ret);
}
-int
-pthread_rwlock_wrlock (pthread_rwlock_t *rwlock)
+static int
+rwlock_wrlock_common (pthread_rwlock_t *rwlock, const struct timespec *abstime)
{
pthread_rwlock_t prwlock;
int ret;
@@ -348,8 +366,13 @@ pthread_rwlock_wrlock (pthread_rwlock_t *rwlock)
while (prwlock->state != 0) {
prwlock->blocked_writers++;
- ret = pthread_cond_wait(&prwlock->write_signal,
- &prwlock->lock);
+ if (abstime != NULL) {
+ ret = pthread_cond_timedwait(&prwlock->write_signal,
+ &prwlock->lock, abstime);
+ } else {
+ ret = pthread_cond_wait(&prwlock->write_signal,
+ &prwlock->lock);
+ }
if (ret != 0) {
prwlock->blocked_writers--;
@@ -369,4 +392,17 @@ pthread_rwlock_wrlock (pthread_rwlock_t *rwlock)
return (ret);
}
+int
+pthread_rwlock_wrlock (pthread_rwlock_t *rwlock)
+{
+ return rwlock_wrlock_common (rwlock, NULL);
+}
+
+int
+pthread_rwlock_timedwrlock (pthread_rwlock_t *rwlock,
+ const struct timespec *abstime)
+{
+ return rwlock_wrlock_common (rwlock, abstime);
+}
+
#endif /* _THREAD_SAFE */