diff options
author | Ted Unangst <tedu@cvs.openbsd.org> | 2010-04-12 01:54:24 +0000 |
---|---|---|
committer | Ted Unangst <tedu@cvs.openbsd.org> | 2010-04-12 01:54:24 +0000 |
commit | 41c1a3e3e6683fe9b4edf023cd5a862fd79746b0 (patch) | |
tree | efce53ab5ec5de44259e6fae7768cc9358cbce71 | |
parent | 46975a2a516f3489a5273d971ef327e5c5fd681e (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.h | 6 | ||||
-rw-r--r-- | lib/libpthread/man/Makefile.inc | 4 | ||||
-rw-r--r-- | lib/libpthread/man/pthread_rwlock_rdlock.3 | 40 | ||||
-rw-r--r-- | lib/libpthread/man/pthread_rwlock_wrlock.3 | 39 | ||||
-rw-r--r-- | lib/libpthread/shlib_version | 2 | ||||
-rw-r--r-- | lib/libpthread/uthread/uthread_rwlock.c | 54 |
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 */ |