summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authoralex <alex@FreeBSD.org>1998-09-07 19:01:43 +0000
committeralex <alex@FreeBSD.org>1998-09-07 19:01:43 +0000
commitfe02148d3f8adf07ccb0cd4f4491ed4eadc9a710 (patch)
treebe26836ebbbdc58cff84aa54c1c720ab317da73d
parent06f84d5212709c1fffd29e99fe45de2c81683197 (diff)
downloadFreeBSD-src-fe02148d3f8adf07ccb0cd4f4491ed4eadc9a710.zip
FreeBSD-src-fe02148d3f8adf07ccb0cd4f4491ed4eadc9a710.tar.gz
Implement pthread read/write locks as defined by Version 2 of the Single
UNIX Specification. As with our standard mutexes, process shared locks are not supported at this time.
-rw-r--r--include/pthread.h25
-rw-r--r--lib/libc_r/man/Makefile.inc11
-rw-r--r--lib/libc_r/man/pthread_rwlock_destroy.380
-rw-r--r--lib/libc_r/man/pthread_rwlock_init.399
-rw-r--r--lib/libc_r/man/pthread_rwlock_rdlock.3122
-rw-r--r--lib/libc_r/man/pthread_rwlock_unlock.379
-rw-r--r--lib/libc_r/man/pthread_rwlock_wrlock.3102
-rw-r--r--lib/libc_r/man/pthread_rwlockattr_destroy.368
-rw-r--r--lib/libc_r/man/pthread_rwlockattr_getpshared.380
-rw-r--r--lib/libc_r/man/pthread_rwlockattr_init.367
-rw-r--r--lib/libc_r/man/pthread_rwlockattr_setpshared.386
-rw-r--r--lib/libc_r/uthread/Makefile.inc4
-rw-r--r--lib/libc_r/uthread/pthread_private.h12
-rw-r--r--lib/libc_r/uthread/uthread_rwlock.c333
-rw-r--r--lib/libc_r/uthread/uthread_rwlockattr.c97
-rw-r--r--lib/libkse/thread/Makefile.inc4
-rw-r--r--lib/libkse/thread/thr_private.h12
-rw-r--r--lib/libkse/thread/thr_rwlock.c333
-rw-r--r--lib/libkse/thread/thr_rwlockattr.c97
-rw-r--r--lib/libpthread/man/Makefile.inc11
-rw-r--r--lib/libpthread/man/pthread_rwlock_destroy.380
-rw-r--r--lib/libpthread/man/pthread_rwlock_init.399
-rw-r--r--lib/libpthread/man/pthread_rwlock_rdlock.3122
-rw-r--r--lib/libpthread/man/pthread_rwlock_unlock.379
-rw-r--r--lib/libpthread/man/pthread_rwlock_wrlock.3102
-rw-r--r--lib/libpthread/man/pthread_rwlockattr_destroy.368
-rw-r--r--lib/libpthread/man/pthread_rwlockattr_getpshared.380
-rw-r--r--lib/libpthread/man/pthread_rwlockattr_init.367
-rw-r--r--lib/libpthread/man/pthread_rwlockattr_setpshared.386
-rw-r--r--lib/libpthread/thread/Makefile.inc4
-rw-r--r--lib/libpthread/thread/thr_private.h12
-rw-r--r--lib/libpthread/thread/thr_rwlock.c333
-rw-r--r--lib/libpthread/thread/thr_rwlockattr.c97
-rw-r--r--share/man/man3/pthread_rwlock_destroy.380
-rw-r--r--share/man/man3/pthread_rwlock_init.399
-rw-r--r--share/man/man3/pthread_rwlock_rdlock.3122
-rw-r--r--share/man/man3/pthread_rwlock_unlock.379
-rw-r--r--share/man/man3/pthread_rwlock_wrlock.3102
-rw-r--r--share/man/man3/pthread_rwlockattr_destroy.368
-rw-r--r--share/man/man3/pthread_rwlockattr_getpshared.380
-rw-r--r--share/man/man3/pthread_rwlockattr_init.367
-rw-r--r--share/man/man3/pthread_rwlockattr_setpshared.386
42 files changed, 3729 insertions, 5 deletions
diff --git a/include/pthread.h b/include/pthread.h
index 701328b..0c38271 100644
--- a/include/pthread.h
+++ b/include/pthread.h
@@ -80,6 +80,12 @@
#define PTHREAD_EXPLICIT_SCHED 0
/*
+ * Flags for read/write lock attributes
+ */
+#define PTHREAD_PROCESS_PRIVATE 0
+#define PTHREAD_PROCESS_SHARED 1
+
+/*
* Forward structure definitions.
*
* These are mostly opaque to the user.
@@ -91,6 +97,8 @@ struct pthread_cond_attr;
struct pthread_mutex;
struct pthread_mutex_attr;
struct pthread_once;
+struct pthread_rwlock;
+struct pthread_rwlockattr;
struct sched_param;
/*
@@ -108,6 +116,8 @@ typedef struct pthread_cond *pthread_cond_t;
typedef struct pthread_cond_attr *pthread_condattr_t;
typedef int pthread_key_t;
typedef struct pthread_once pthread_once_t;
+typedef struct pthread_rwlock *pthread_rwlock_t;
+typedef struct pthread_rwlockattr *pthread_rwlockattr_t;
/*
* Additional type definitions:
@@ -142,6 +152,7 @@ struct pthread_once {
*/
#define PTHREAD_MUTEX_INITIALIZER NULL
#define PTHREAD_COND_INITIALIZER NULL
+#define PTHREAD_RWLOCK_INITIALIZER NULL
/*
* Default attribute arguments (draft 4, deprecated).
@@ -232,6 +243,20 @@ int pthread_mutex_trylock __P((pthread_mutex_t *));
int pthread_mutex_unlock __P((pthread_mutex_t *));
int pthread_once __P((pthread_once_t *,
void (*init_routine) (void)));
+int pthread_rwlock_destroy __P((pthread_rwlock_t *));
+int pthread_rwlock_init __P((pthread_rwlock_t *,
+ const pthread_rwlockattr_t *));
+int pthread_rwlock_rdlock __P((pthread_rwlock_t *));
+int pthread_rwlock_tryrdlock __P((pthread_rwlock_t *));
+int pthread_rwlock_trywrlock __P((pthread_rwlock_t *));
+int pthread_rwlock_unlock __P((pthread_rwlock_t *));
+int pthread_rwlock_wrlock __P((pthread_rwlock_t *));
+int pthread_rwlockattr_init __P((pthread_rwlockattr_t *));
+int pthread_rwlockattr_getpshared __P((const pthread_rwlockattr_t *,
+ int *));
+int pthread_rwlockattr_setpshared __P((pthread_rwlockattr_t *,
+ int *));
+int pthread_rwlockattr_destroy __P((pthread_rwlockattr_t *));
pthread_t pthread_self __P((void));
int pthread_setcancelstate __P((int, int *));
int pthread_setcanceltype __P((int, int *));
diff --git a/lib/libc_r/man/Makefile.inc b/lib/libc_r/man/Makefile.inc
index e6bb8a5..f92f3df 100644
--- a/lib/libc_r/man/Makefile.inc
+++ b/lib/libc_r/man/Makefile.inc
@@ -1,4 +1,4 @@
-# $Id: Makefile.inc,v 1.3 1997/02/22 15:05:23 peter Exp $
+# $Id: Makefile.inc,v 1.4 1998/07/31 09:09:19 phk Exp $
# POSIX thread man files
@@ -26,5 +26,14 @@ MAN3+= pthread_cleanup_pop.3 \
pthread_mutex_trylock.3 \
pthread_mutex_unlock.3 \
pthread_once.3 \
+ pthread_rwlock_destroy.3 \
+ pthread_rwlock_init.3 \
+ pthread_rwlock_rdlock.3 \
+ pthread_rwlock_unlock.3 \
+ pthread_rwlock_wrlock.3 \
+ pthread_rwlockattr_destroy.3 \
+ pthread_rwlockattr_getpshared.3 \
+ pthread_rwlockattr_init.3 \
+ pthread_rwlockattr_setpshared.3 \
pthread_self.3 \
pthread_setspecific.3
diff --git a/lib/libc_r/man/pthread_rwlock_destroy.3 b/lib/libc_r/man/pthread_rwlock_destroy.3
new file mode 100644
index 0000000..7453274
--- /dev/null
+++ b/lib/libc_r/man/pthread_rwlock_destroy.3
@@ -0,0 +1,80 @@
+.\" Copyright (c) 1998 Alex Nash
+.\" All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" $Id$
+.\"
+.Dd August 4, 1998
+.Dt PTHREAD_RWLOCK_DESTROY 3
+.Os
+.Sh NAME
+.Nm pthread_rwlock_destroy
+.Nd destroy a read/write lock
+.Sh SYNOPSIS
+.Fd #include <pthread.h>
+.Ft int
+.Fn pthread_rwlock_destroy "pthread_rwlock_t *lock"
+.Sh DESCRIPTION
+The
+.Fn pthread_rwlock_destroy
+function is used to destroy a read/write lock previously created with
+.Fn pthread_rwlock_init .
+.Sh RETURN VALUES
+If successful, the
+.Fn pthread_rwlock_destroy
+function will return zero. Otherwise an error number will be returned
+to indicate the error.
+.Sh SEE ALSO
+.Xr pthread_rwlock_init 3 ,
+.Sh STANDARDS
+The
+.Fn pthread_rwlock_destroy
+function is expected to conform to
+.St -susv2 .
+.Sh ERRORS
+The
+.Fn pthread_rwlock_destroy
+function will fail if:
+.Bl -tag -width Er
+.It Bq Er EPERM
+The caller does not have the privilege to perform the operation.
+.El
+.Pp
+The
+.Fn pthread_rwlock_destroy
+function may fail if:
+.Bl -tag -width Er
+.It Bq Er EBUSY
+The system has detected an attempt to destroy the object referenced by
+.Fa lock
+while it is locked.
+.It Bq Er EINVAL
+The value specified by
+.Fa lock
+is invalid.
+.El
+.Sh HISTORY
+The
+.Fn pthread_rwlock_destroy
+function first appeared in
+.Fx 3.0 .
diff --git a/lib/libc_r/man/pthread_rwlock_init.3 b/lib/libc_r/man/pthread_rwlock_init.3
new file mode 100644
index 0000000..a561695
--- /dev/null
+++ b/lib/libc_r/man/pthread_rwlock_init.3
@@ -0,0 +1,99 @@
+.\" Copyright (c) 1998 Alex Nash
+.\" All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" $Id$
+.\"
+.Dd August 4, 1998
+.Dt PTHREAD_RWLOCK_INIT 3
+.Os
+.Sh NAME
+.Nm pthread_rwlock_init
+.Nd initialize a read/write lock
+.Sh SYNOPSIS
+.Fd #include <pthread.h>
+.Ft int
+.Fn pthread_rwlock_init "pthread_rwlock_t *lock" "const pthread_rwlockattr_t *attr"
+.Sh DESCRIPTION
+The
+.Fn pthread_rwlock_init
+function is used to initialize a read/write lock, with attributes
+specified by
+.Fa attr .
+If
+.Fa attr
+is NULL, the default read/write lock attributes are used.
+.Pp
+The results of calling
+.Fn pthread_rwlock_init
+with an already initialized lock are undefined.
+.Sh RETURN VALUES
+If successful, the
+.Fn pthread_rwlock_init
+function will return zero. Otherwise an error number will be returned
+to indicate the error.
+.Sh SEE ALSO
+.Xr pthread_rwlock_destroy 3 ,
+.Xr pthread_rwlockattr_init 3 ,
+.Xr pthread_rwlockattr_setpshared 3
+.Sh STANDARDS
+The
+.Fn pthread_rwlock_init
+function is expected to conform to
+.St -susv2 .
+.Sh ERRORS
+The
+.Fn pthread_rwlock_init
+function will fail if:
+.Bl -tag -width Er
+.It Bq Er EAGAIN
+The system lacked the necessary resources (other than memory) to
+initialize the lock.
+.It Bq Er ENOMEM
+Insufficient memory exists to initialize the lock.
+.It Bq Er EPERM
+The caller does not have sufficient privilege to perform the
+operation.
+.El
+.Pp
+The
+.Fn pthread_rwlock_init
+function may fail if:
+.Bl -tag -width Er
+.It Bq Er EBUSY
+The system has detected an attempt to re-initialize the object
+referenced by
+.Fa lock ,
+a previously initialized but not yet destroyed read/write lock.
+.It Bq Er EINVAL
+The value specified by
+.Fa attr
+is invalid.
+.El
+.Sh HISTORY
+The
+.Fn pthread_rwlock_init
+function first appeared in
+.Fx 3.0 .
+.Sh BUGS
+The PTHREAD_PROCESS_SHARED attribute is not supported.
diff --git a/lib/libc_r/man/pthread_rwlock_rdlock.3 b/lib/libc_r/man/pthread_rwlock_rdlock.3
new file mode 100644
index 0000000..9181be9
--- /dev/null
+++ b/lib/libc_r/man/pthread_rwlock_rdlock.3
@@ -0,0 +1,122 @@
+.\" Copyright (c) 1998 Alex Nash
+.\" All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" $Id$
+.\"
+.Dd August 4, 1998
+.Dt PTHREAD_RWLOCK_RDLOCK 3
+.Os
+.Sh NAME
+.Nm pthread_rwlock_rdlock ,
+.Nm pthread_rwlock_tryrdlock
+.Nd acquire a read/write lock for reading
+.Sh SYNOPSIS
+.Fd #include <pthread.h>
+.Ft int
+.Fn pthread_rwlock_rdlock "pthread_rwlock_t *lock"
+.Ft int
+.Fn pthread_rwlock_tryrdlock "pthread_rwlock_t *lock"
+.Sh DESCRIPTION
+The
+.Fn pthread_rwlock_rdlock
+function acquires a read lock on
+.Fa lock
+provided that
+.Fa lock
+is not presently held for writing and no writer threads are
+presently blocked on the lock. If the read lock cannot be
+immediately acquired, the calling thread blocks until it can
+acquire the lock.
+.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).
+.Pp
+A thread may hold multiple concurrent read locks. If so,
+.Fn pthread_rwlock_unlock
+must be called once for each lock obtained.
+.Pp
+The results of acquiring a read lock while the calling thread holds
+a write lock are undefined.
+.Sh IMPLEMENTATION NOTES
+To prevent writer starvation, writers are favored over readers.
+.Sh RETURN VALUES
+If successful, the
+.Fn pthread_rwlock_rdlock
+and
+.Fn pthread_rwlock_tryrdlock
+functions will return zero. Otherwise an error number will be returned
+to indicate the error.
+.Sh SEE ALSO
+.Xr pthread_rwlock_init 3 ,
+.Xr pthread_rwlock_trywrlock 3 ,
+.Xr pthread_rwlock_unlock 3 ,
+.Xr pthread_rwlock_wrlock 3
+.Sh STANDARDS
+The
+.Fn pthread_rwlock_rdlock
+and
+.Fn pthread_rwlock_tryrdlock
+functions are expected to conform to
+.St -susv2 .
+.Sh ERRORS
+The
+.Fn pthread_rwlock_tryrdlock
+function will fail if:
+.Bl -tag -width Er
+.It Bq Er EBUSY
+The lock could not be acquired because a writer holds the lock or
+was blocked on it.
+.El
+.Pp
+The
+.Fn pthread_rwlock_rdlock
+and
+.Fn pthread_rwlock_tryrdlock
+functions may fail if:
+.Bl -tag -width Er
+.It Bq Er EAGAIN
+The lock could not be acquired because the maximum number of read locks
+against
+.Fa lock
+has been exceeded.
+.It Bq Er EDEADLK
+The current thread already owns
+.Fa lock
+for writing.
+.It Bq Er EINVAL
+The value specified by
+.Fa lock
+is invalid.
+.It Bq Er ENOMEM
+Insufficient memory exists to initialize the lock (applies to
+statically initialized locks only).
+.El
+.Sh HISTORY
+The
+.Fn pthread_rwlock_rdlock
+function first appeared in
+.Fx 3.0 .
diff --git a/lib/libc_r/man/pthread_rwlock_unlock.3 b/lib/libc_r/man/pthread_rwlock_unlock.3
new file mode 100644
index 0000000..1c9fd05
--- /dev/null
+++ b/lib/libc_r/man/pthread_rwlock_unlock.3
@@ -0,0 +1,79 @@
+.\" Copyright (c) 1998 Alex Nash
+.\" All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" $Id$
+.\"
+.Dd August 4, 1998
+.Dt PTHREAD_RWLOCK_UNLOCK 3
+.Os
+.Sh NAME
+.Nm pthread_rwlock_unlock
+.Nd release a read/write lock
+.Sh SYNOPSIS
+.Fd #include <pthread.h>
+.Ft int
+.Fn pthread_rwlock_unlock "pthread_rwlock_t *lock"
+.Sh DESCRIPTION
+The
+.Fn pthread_rwlock_unlock
+function is used to release the read/write lock previously obtained by
+.Fn pthread_rwlock_rdlock ,
+.Fn pthread_rwlock_wrlock ,
+.Fn pthread_rwlock_tryrdlock ,
+or
+.Fn pthread_rwlock_trywrlock .
+.Sh RETURN VALUES
+If successful, the
+.Fn pthread_rwlock_unlock
+function will return zero. Otherwise an error number will be returned
+to indicate the error.
+.Pp
+The results are undefined if
+.Fa lock
+is not held by the calling thread.
+.Sh SEE ALSO
+.Xr pthread_rwlock_rdlock 3 ,
+.Xr pthread_rwlock_wrlock 3
+.Sh STANDARDS
+The
+.Fn pthread_rwlock_unlock
+function is expected to conform to
+.St -susv2 .
+.Sh ERRORS
+The
+.Fn pthread_rwlock_unlock
+function may fail if:
+.Bl -tag -width Er
+.It Bq Er EINVAL
+The value specified by
+.Fa lock
+is invalid.
+.It Bq Er EPERM
+The current thread does not own the read/write lock.
+.El
+.Sh HISTORY
+The
+.Fn pthread_rwlock_unlock
+function first appeared in
+.Fx 3.0 .
diff --git a/lib/libc_r/man/pthread_rwlock_wrlock.3 b/lib/libc_r/man/pthread_rwlock_wrlock.3
new file mode 100644
index 0000000..a5a3674
--- /dev/null
+++ b/lib/libc_r/man/pthread_rwlock_wrlock.3
@@ -0,0 +1,102 @@
+.\" Copyright (c) 1998 Alex Nash
+.\" All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" $Id$
+.\"
+.Dd August 4, 1998
+.Dt PTHREAD_RWLOCK_WRLOCK 3
+.Os
+.Sh NAME
+.Nm pthread_rwlock_wrlock ,
+.Nm pthread_rwlock_trywrlock
+.Nd acquire a read/write lock for writing
+.Sh SYNOPSIS
+.Fd #include <pthread.h>
+.Ft int
+.Fn pthread_rwlock_wrlock "pthread_rwlock_t *lock"
+.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 .
+The
+.Fn pthread_rwlock_trywrlock
+function performs the same action, 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.
+.Sh IMPLEMENTATION NOTES
+To prevent writer starvation, writers are favored over readers.
+.Sh RETURN VALUES
+If successful, the
+.Fn pthread_rwlock_wrlock
+and
+.Fn pthread_rwlock_trywrlock
+functions will return zero. Otherwise an error number will be returned
+to indicate the error.
+.Sh SEE ALSO
+.Xr pthread_rwlock_trywrlock 3 ,
+.Xr pthread_rwlock_unlock 3 ,
+.Xr pthread_rwlock_wrlock 3
+.Sh STANDARDS
+The
+.Fn pthread_rwlock_wrlock
+and
+.Fn pthread_rwlock_trywrlock
+functions are expected to conform to
+.St -susv2 .
+.Sh ERRORS
+The
+.Fn pthread_rwlock_trywrlock
+function will fail if:
+.Bl -tag -width Er
+.It Bq Er EBUSY
+The calling thread is not able to acquire the lock without blocking.
+.El
+.Pp
+The
+.Fn pthread_rwlock_wrlock
+and
+.Fn pthread_rwlock_trywrlock
+functions may fail if:
+.Bl -tag -width Er
+.It Bq Er EDEADLK
+The calling thread already owns the read/write lock (for reading
+or writing).
+.It Bq Er EINVAL
+The value specified by
+.Fa lock
+is invalid.
+.It Bq Er ENOMEM
+Insufficient memory exists to initialize the lock (applies to
+statically initialized locks only).
+.El
+.Sh HISTORY
+The
+.Fn pthread_rwlock_wrlock
+function first appeared in
+.Fx 3.0 .
diff --git a/lib/libc_r/man/pthread_rwlockattr_destroy.3 b/lib/libc_r/man/pthread_rwlockattr_destroy.3
new file mode 100644
index 0000000..ee3c405
--- /dev/null
+++ b/lib/libc_r/man/pthread_rwlockattr_destroy.3
@@ -0,0 +1,68 @@
+.\" Copyright (c) 1998 Alex Nash
+.\" All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" $Id$
+.\"
+.Dd August 4, 1998
+.Dt PTHREAD_RWLOCKATTR_DESTROY 3
+.Os
+.Sh NAME
+.Nm pthread_rwlockattr_destroy
+.Nd destroy a read/write lock
+.Sh SYNOPSIS
+.Fd #include <pthread.h>
+.Ft int
+.Fn pthread_rwlockattr_destroy "pthread_rwlockattr_t *attr"
+.Sh DESCRIPTION
+The
+.Fn pthread_rwlockattr_destroy
+function is used to destroy a read/write lock attribute object
+previously created with
+.Fn pthread_rwlockattr_init .
+.Sh RETURN VALUES
+If successful, the
+.Fn pthread_rwlockattr_destroy
+function will return zero. Otherwise an error number will be returned
+to indicate the error.
+.Sh SEE ALSO
+.Xr pthread_rwlockattr_init 3 ,
+.Sh STANDARDS
+The
+.Fn pthread_rwlockattr_destroy
+function is expected to conform to
+.St -susv2 .
+.Sh ERRORS
+.Fn pthread_rwlockattr_destroy
+may fail if:
+.Bl -tag -width Er
+.It Bq Er EINVAL
+The value specified by
+.Fa attr
+is invalid.
+.El
+.Sh HISTORY
+The
+.Fn pthread_rwlockattr_destroy
+function first appeared in
+.Fx 3.0 .
diff --git a/lib/libc_r/man/pthread_rwlockattr_getpshared.3 b/lib/libc_r/man/pthread_rwlockattr_getpshared.3
new file mode 100644
index 0000000..8e8160b
--- /dev/null
+++ b/lib/libc_r/man/pthread_rwlockattr_getpshared.3
@@ -0,0 +1,80 @@
+.\" Copyright (c) 1998 Alex Nash
+.\" All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" $Id$
+.\"
+.Dd August 4, 1998
+.Dt PTHREAD_RWLOCKATTR_GETPSHARED 3
+.Os
+.Sh NAME
+.Nm pthread_rwlockattr_getpshared
+.Nd set the process shared attribute
+.Sh SYNOPSIS
+.Fd #include <pthread.h>
+.Ft int
+.Fn pthread_rwlockattr_getpshared "pthread_rwlockattr_t *attr" "int *pshared"
+.Sh DESCRIPTION
+The
+.Fn pthread_rwlockattr_getpshared
+function is used to get the process shared setting of a read/write
+lock attribute object. The setting is returned via
+.Fa pshared ,
+and may be one of two values:
+.Bl -hang -offset flag -width 123456789012345678901234
+.It Ar PTHREAD_PROCESS_SHARED
+Any thread of any process that has access to the memory where the
+read/write lock resides can manipulate the lock.
+.It Ar PTHREAD_PROCESS_PRIVATE
+Only threads created within the same process as the thread that
+initialized the read/write lock can manipulate the lock. This is
+the default value.
+.El
+.Sh RETURN VALUES
+If successful, the
+.Fn pthread_rwlockattr_getpshared
+function will return zero. Otherwise an error number will be returned
+to indicate the error.
+.Sh SEE ALSO
+.Xr pthread_rwlock_init 3 ,
+.Xr pthread_rwlockattr_init 3 ,
+.Xr pthread_rwlockattr_setpshared 3
+.Sh STANDARDS
+The
+.Fn pthread_rwlockattr_getpshared
+function is expected to conform to
+.St -susv2 .
+.Sh ERRORS
+.Fn pthread_rwlockattr_getpshared
+may fail if:
+.Bl -tag -width Er
+.It Bq Er EINVAL
+The value specified by
+.Fa attr
+is invalid.
+.El
+.Sh HISTORY
+The
+.Fn pthread_rwlockattr_getpshared
+function first appeared in
+.Fx 3.0 .
diff --git a/lib/libc_r/man/pthread_rwlockattr_init.3 b/lib/libc_r/man/pthread_rwlockattr_init.3
new file mode 100644
index 0000000..8827121
--- /dev/null
+++ b/lib/libc_r/man/pthread_rwlockattr_init.3
@@ -0,0 +1,67 @@
+.\" Copyright (c) 1998 Alex Nash
+.\" All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" $Id$
+.\"
+.Dd August 4, 1998
+.Dt PTHREAD_RWLOCKATTR_INIT 3
+.Os
+.Sh NAME
+.Nm pthread_rwlockattr_init
+.Nd initialize a read/write lock
+.Sh SYNOPSIS
+.Fd #include <pthread.h>
+.Ft int
+.Fn pthread_rwlockattr_init "pthread_rwlockattr_t *attr"
+.Sh DESCRIPTION
+The
+.Fn pthread_rwlockattr_init
+function is used to initialize a read/write lock attributes object.
+.Sh RETURN VALUES
+If successful, the
+.Fn pthread_rwlockattr_init
+function will return zero. Otherwise an error number will be returned
+to indicate the error.
+.Sh SEE ALSO
+.Xr pthread_rwlock_init 3 ,
+.Xr pthread_rwlockattr_destroy 3 ,
+.Xr pthread_rwlockattr_getpshared 3
+.Xr pthread_rwlockattr_setpshared 3
+.Sh STANDARDS
+The
+.Fn pthread_rwlockattr_init
+function is expected to conform to
+.St -susv2 .
+.Sh ERRORS
+.Fn pthread_rwlockattr_init
+will fail if:
+.Bl -tag -width Er
+.It Bq Er ENOMEM
+Insufficient memory exists to initialize the attribute object.
+.El
+.Sh HISTORY
+The
+.Fn pthread_rwlockattr_init
+function first appeared in
+.Fx 3.0 .
diff --git a/lib/libc_r/man/pthread_rwlockattr_setpshared.3 b/lib/libc_r/man/pthread_rwlockattr_setpshared.3
new file mode 100644
index 0000000..e63debf
--- /dev/null
+++ b/lib/libc_r/man/pthread_rwlockattr_setpshared.3
@@ -0,0 +1,86 @@
+.\" Copyright (c) 1998 Alex Nash
+.\" All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" $Id$
+.\"
+.Dd August 4, 1998
+.Dt PTHREAD_RWLOCKATTR_SETPSHARED 3
+.Os
+.Sh NAME
+.Nm pthread_rwlockattr_setpshared
+.Nd set the process shared attribute
+.Sh SYNOPSIS
+.Fd #include <pthread.h>
+.Ft int
+.Fn pthread_rwlockattr_setpshared "pthread_rwlockattr_t *attr" "int *pshared"
+.Sh DESCRIPTION
+The
+.Fn pthread_rwlockattr_setpshared
+function sets the process shared attribute of
+.Fa attr
+to the value referenced by
+.Fa pshared .
+.Fa pshared
+may be one of two values:
+.Bl -hang -offset flag -width 123456789012345678901234
+.It Ar PTHREAD_PROCESS_SHARED
+Any thread of any process that has access to the memory where the
+read/write lock resides can manipulate the lock.
+.It Ar PTHREAD_PROCESS_PRIVATE
+Only threads created within the same process as the thread that
+initialized the read/write lock can manipulate the lock. This is
+the default value.
+.El
+.Sh RETURN VALUES
+If successful, the
+.Fn pthread_rwlockattr_setpshared
+function will return zero. Otherwise an error number will be returned
+to indicate the error.
+.Sh SEE ALSO
+.Xr pthread_rwlock_init 3 ,
+.Xr pthread_rwlockattr_init 3 ,
+.Xr pthread_rwlockattr_setpshared 3
+.Sh STANDARDS
+The
+.Fn pthread_rwlockattr_setpshared
+function is expected to conform to
+.St -susv2 .
+.Sh ERRORS
+.Fn pthread_rwlockattr_setpshared
+will fail if:
+.Bl -tag -width Er
+.It Bq Er EINVAL
+The value specified by
+.Fa attr
+or
+.Fa pshared
+is invalid.
+.El
+.Sh HISTORY
+The
+.Fn pthread_rwlockattr_setpshared
+function first appeared in
+.Fx 3.0 .
+.Sh BUGS
+The PTHREAD_PROCESS_SHARED attribute is not supported.
diff --git a/lib/libc_r/uthread/Makefile.inc b/lib/libc_r/uthread/Makefile.inc
index dc46af9..4fd3034 100644
--- a/lib/libc_r/uthread/Makefile.inc
+++ b/lib/libc_r/uthread/Makefile.inc
@@ -1,4 +1,4 @@
-# $Id: Makefile.inc,v 1.12 1998/05/31 23:48:26 jb Exp $
+# $Id: Makefile.inc,v 1.13 1998/06/01 02:14:34 jb Exp $
# uthread sources
.PATH: ${.CURDIR}/uthread
@@ -67,6 +67,8 @@ SRCS+= \
uthread_recvfrom.c \
uthread_recvmsg.c \
uthread_resume_np.c \
+ uthread_rwlock.c \
+ uthread_rwlockattr.c \
uthread_select.c \
uthread_self.c \
uthread_sendmsg.c \
diff --git a/lib/libc_r/uthread/pthread_private.h b/lib/libc_r/uthread/pthread_private.h
index 39ce14d..5b76a86 100644
--- a/lib/libc_r/uthread/pthread_private.h
+++ b/lib/libc_r/uthread/pthread_private.h
@@ -224,6 +224,18 @@ struct pthread_key {
void (*destructor) ();
};
+struct pthread_rwlockattr {
+ int pshared;
+};
+
+struct pthread_rwlock {
+ pthread_mutex_t lock; /* monitor lock */
+ int state; /* 0 = idle >0 = # of readers -1 = writer */
+ pthread_cond_t read_signal;
+ pthread_cond_t write_signal;
+ int blocked_writers;
+};
+
/*
* Thread states.
*/
diff --git a/lib/libc_r/uthread/uthread_rwlock.c b/lib/libc_r/uthread/uthread_rwlock.c
new file mode 100644
index 0000000..356eb29
--- /dev/null
+++ b/lib/libc_r/uthread/uthread_rwlock.c
@@ -0,0 +1,333 @@
+/*-
+ * Copyright (c) 1998 Alex Nash
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $Id$
+ */
+
+#ifdef _THREAD_SAFE
+#include <errno.h>
+#include <limits.h>
+#include <stdlib.h>
+
+#include <pthread.h>
+#include "pthread_private.h"
+
+/* maximum number of times a read lock may be obtained */
+#define MAX_READ_LOCKS (INT_MAX - 1)
+
+static int init_static (pthread_rwlock_t *rwlock);
+
+static spinlock_t static_init_lock = _SPINLOCK_INITIALIZER;
+
+static int
+init_static (pthread_rwlock_t *rwlock)
+{
+ int ret;
+
+ _SPINLOCK(&static_init_lock);
+
+ if (*rwlock == NULL)
+ ret = pthread_rwlock_init(rwlock, NULL);
+ else
+ ret = 0;
+
+ _SPINUNLOCK(&static_init_lock);
+
+ return(ret);
+}
+
+int
+pthread_rwlock_destroy (pthread_rwlock_t *rwlock)
+{
+ int ret;
+
+ if (rwlock == NULL)
+ ret = EINVAL;
+ else {
+ pthread_rwlock_t prwlock;
+
+ prwlock = *rwlock;
+
+ pthread_mutex_destroy(&prwlock->lock);
+ pthread_cond_destroy(&prwlock->read_signal);
+ pthread_cond_destroy(&prwlock->write_signal);
+ free(prwlock);
+
+ *rwlock = NULL;
+ }
+
+ return(ret);
+}
+
+int
+pthread_rwlock_init (pthread_rwlock_t *rwlock, const pthread_rwlockattr_t *attr)
+{
+ pthread_rwlock_t prwlock;
+ int ret;
+
+ /* allocate rwlock object */
+ prwlock = (pthread_rwlock_t)malloc(sizeof(struct pthread_rwlock));
+
+ if (prwlock == NULL)
+ return(ENOMEM);
+
+ /* initialize the lock */
+ if ((ret = pthread_mutex_init(&prwlock->lock, NULL)) != 0)
+ free(prwlock);
+ else {
+ /* initialize the read condition signal */
+ ret = pthread_cond_init(&prwlock->read_signal, NULL);
+
+ if (ret != 0) {
+ pthread_mutex_destroy(&prwlock->lock);
+ free(prwlock);
+ } else {
+ /* initialize the write condition signal */
+ ret = pthread_cond_init(&prwlock->write_signal, NULL);
+
+ if (ret != 0) {
+ pthread_cond_destroy(&prwlock->read_signal);
+ pthread_mutex_destroy(&prwlock->lock);
+ free(prwlock);
+ } else {
+ /* success */
+ prwlock->state = 0;
+ prwlock->blocked_writers = 0;
+
+ *rwlock = prwlock;
+ }
+ }
+ }
+
+ return(ret);
+}
+
+int
+pthread_rwlock_rdlock (pthread_rwlock_t *rwlock)
+{
+ pthread_rwlock_t prwlock;
+ int ret = 0;
+
+ if (rwlock == NULL)
+ return(EINVAL);
+
+ prwlock = *rwlock;
+
+ /* check for static initialization */
+ if (prwlock == NULL) {
+ if ((ret = init_static(rwlock)) != 0)
+ return(ret);
+
+ prwlock = *rwlock;
+ }
+
+ /* grab the monitor lock */
+ if ((ret = pthread_mutex_lock(&prwlock->lock)) != 0)
+ return(ret);
+
+ /* give writers priority over readers */
+ while (prwlock->blocked_writers || prwlock->state < 0) {
+ ret = pthread_cond_wait(&prwlock->read_signal, &prwlock->lock);
+
+ if (ret != 0) {
+ /* can't do a whole lot if this fails */
+ pthread_mutex_unlock(&prwlock->lock);
+ return(ret);
+ }
+ }
+
+ /* check lock count */
+ if (prwlock->state == MAX_READ_LOCKS)
+ ret = EAGAIN;
+ else
+ ++prwlock->state; /* indicate we are locked for reading */
+
+ /*
+ * Something is really wrong if this call fails. Returning
+ * error won't do because we've already obtained the read
+ * lock. Decrementing 'state' is no good because we probably
+ * don't have the monitor lock.
+ */
+ pthread_mutex_unlock(&prwlock->lock);
+
+ return(ret);
+}
+
+int
+pthread_rwlock_tryrdlock (pthread_rwlock_t *rwlock)
+{
+ pthread_rwlock_t prwlock;
+ int ret = 0;
+
+ if (rwlock == NULL)
+ return(EINVAL);
+
+ prwlock = *rwlock;
+
+ /* check for static initialization */
+ if (prwlock == NULL) {
+ if ((ret = init_static(rwlock)) != 0)
+ return(ret);
+
+ prwlock = *rwlock;
+ }
+
+ /* grab the monitor lock */
+ if ((ret = pthread_mutex_lock(&prwlock->lock)) != 0)
+ return(ret);
+
+ /* give writers priority over readers */
+ if (prwlock->blocked_writers || prwlock->state < 0)
+ ret = EWOULDBLOCK;
+ else if (prwlock->state == MAX_READ_LOCKS)
+ ret = EAGAIN; /* too many read locks acquired */
+ else
+ ++prwlock->state; /* indicate we are locked for reading */
+
+ /* see the comment on this in pthread_rwlock_rdlock */
+ pthread_mutex_unlock(&prwlock->lock);
+
+ return(ret);
+}
+
+int
+pthread_rwlock_trywrlock (pthread_rwlock_t *rwlock)
+{
+ pthread_rwlock_t prwlock;
+ int ret = 0;
+
+ if (rwlock == NULL)
+ return(EINVAL);
+
+ prwlock = *rwlock;
+
+ /* check for static initialization */
+ if (prwlock == NULL) {
+ if ((ret = init_static(rwlock)) != 0)
+ return(ret);
+
+ prwlock = *rwlock;
+ }
+
+ /* grab the monitor lock */
+ if ((ret = pthread_mutex_lock(&prwlock->lock)) != 0)
+ return(ret);
+
+ if (prwlock->state != 0)
+ ret = EWOULDBLOCK;
+ else
+ /* indicate we are locked for writing */
+ prwlock->state = -1;
+
+ /* see the comment on this in pthread_rwlock_rdlock */
+ pthread_mutex_unlock(&prwlock->lock);
+
+ return(ret);
+}
+
+int
+pthread_rwlock_unlock (pthread_rwlock_t *rwlock)
+{
+ pthread_rwlock_t prwlock;
+ int ret = 0;
+
+ if (rwlock == NULL)
+ return(EINVAL);
+
+ prwlock = *rwlock;
+
+ if (prwlock == NULL)
+ return(EINVAL);
+
+ /* grab the monitor lock */
+ if ((ret = pthread_mutex_lock(&prwlock->lock)) != 0)
+ return(ret);
+
+ if (prwlock->state > 0) {
+ if (--prwlock->state == 0 && prwlock->blocked_writers)
+ ret = pthread_cond_signal(&prwlock->write_signal);
+ } else if (prwlock->state < 0) {
+ prwlock->state = 0;
+
+ if (prwlock->blocked_writers)
+ ret = pthread_cond_signal(&prwlock->write_signal);
+ else
+ ret = pthread_cond_broadcast(&prwlock->read_signal);
+ } else
+ ret = EINVAL;
+
+ /* see the comment on this in pthread_rwlock_rdlock */
+ pthread_mutex_unlock(&prwlock->lock);
+
+ return(ret);
+}
+
+int
+pthread_rwlock_wrlock (pthread_rwlock_t *rwlock)
+{
+ pthread_rwlock_t prwlock;
+ int ret = 0;
+
+ if (rwlock == NULL)
+ return(EINVAL);
+
+ prwlock = *rwlock;
+
+ /* check for static initialization */
+ if (prwlock == NULL) {
+ if ((ret = init_static(rwlock)) != 0)
+ return(ret);
+
+ prwlock = *rwlock;
+ }
+
+ /* grab the monitor lock */
+ if ((ret = pthread_mutex_lock(&prwlock->lock)) != 0)
+ return(ret);
+
+ while (prwlock->state != 0) {
+ ++prwlock->blocked_writers;
+
+ ret = pthread_cond_wait(&prwlock->write_signal, &prwlock->lock);
+
+ if (ret != 0) {
+ --prwlock->blocked_writers;
+ pthread_mutex_unlock(&prwlock->lock);
+ return(ret);
+ }
+
+ --prwlock->blocked_writers;
+ }
+
+ /* indicate we are locked for writing */
+ prwlock->state = -1;
+
+ /* see the comment on this in pthread_rwlock_rdlock */
+ pthread_mutex_unlock(&prwlock->lock);
+
+ return(ret);
+}
+
+#endif /* _THREAD_SAFE */
diff --git a/lib/libc_r/uthread/uthread_rwlockattr.c b/lib/libc_r/uthread/uthread_rwlockattr.c
new file mode 100644
index 0000000..a3683bc
--- /dev/null
+++ b/lib/libc_r/uthread/uthread_rwlockattr.c
@@ -0,0 +1,97 @@
+/*-
+ * Copyright (c) 1998 Alex Nash
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $Id$
+ */
+
+#ifdef _THREAD_SAFE
+#include <errno.h>
+
+#include <pthread.h>
+#include "pthread_private.h"
+
+int
+pthread_rwlockattr_destroy (pthread_rwlockattr_t *rwlockattr)
+{
+ pthread_rwlockattr_t prwlockattr;
+
+ if (rwlockattr == NULL)
+ return(EINVAL);
+
+ prwlockattr = *rwlockattr;
+
+ if (prwlockattr == NULL)
+ return(EINVAL);
+
+ free(prwlockattr);
+
+ return(0);
+}
+
+int
+pthread_rwlockattr_getpshared (const pthread_rwlockattr_t *rwlockattr,
+ int *pshared)
+{
+ *pshared = (*rwlockattr)->pshared;
+
+ return(0);
+}
+
+int
+pthread_rwlockattr_init (pthread_rwlockattr_t *rwlockattr)
+{
+ pthread_rwlockattr_t prwlockattr;
+
+ if (rwlockattr == NULL)
+ return(EINVAL);
+
+ prwlockattr = (pthread_rwlockattr_t)
+ malloc(sizeof(struct pthread_rwlockattr));
+
+ if (prwlockattr == NULL)
+ return(ENOMEM);
+
+ prwlockattr->pshared = PTHREAD_PROCESS_PRIVATE;
+ *rwlockattr = prwlockattr;
+
+ return(0);
+}
+
+int
+pthread_rwlockattr_setpshared (pthread_rwlockattr_t *rwlockattr,
+ int *pshared)
+{
+ int ps = *pshared;
+
+ /* only PTHREAD_PROCESS_PRIVATE is supported */
+ if (ps != PTHREAD_PROCESS_PRIVATE)
+ return(EINVAL);
+
+ (*rwlockattr)->pshared = ps;
+
+ return(0);
+}
+
+#endif /* _THREAD_SAFE */
diff --git a/lib/libkse/thread/Makefile.inc b/lib/libkse/thread/Makefile.inc
index dc46af9..4fd3034 100644
--- a/lib/libkse/thread/Makefile.inc
+++ b/lib/libkse/thread/Makefile.inc
@@ -1,4 +1,4 @@
-# $Id: Makefile.inc,v 1.12 1998/05/31 23:48:26 jb Exp $
+# $Id: Makefile.inc,v 1.13 1998/06/01 02:14:34 jb Exp $
# uthread sources
.PATH: ${.CURDIR}/uthread
@@ -67,6 +67,8 @@ SRCS+= \
uthread_recvfrom.c \
uthread_recvmsg.c \
uthread_resume_np.c \
+ uthread_rwlock.c \
+ uthread_rwlockattr.c \
uthread_select.c \
uthread_self.c \
uthread_sendmsg.c \
diff --git a/lib/libkse/thread/thr_private.h b/lib/libkse/thread/thr_private.h
index 39ce14d..5b76a86 100644
--- a/lib/libkse/thread/thr_private.h
+++ b/lib/libkse/thread/thr_private.h
@@ -224,6 +224,18 @@ struct pthread_key {
void (*destructor) ();
};
+struct pthread_rwlockattr {
+ int pshared;
+};
+
+struct pthread_rwlock {
+ pthread_mutex_t lock; /* monitor lock */
+ int state; /* 0 = idle >0 = # of readers -1 = writer */
+ pthread_cond_t read_signal;
+ pthread_cond_t write_signal;
+ int blocked_writers;
+};
+
/*
* Thread states.
*/
diff --git a/lib/libkse/thread/thr_rwlock.c b/lib/libkse/thread/thr_rwlock.c
new file mode 100644
index 0000000..356eb29
--- /dev/null
+++ b/lib/libkse/thread/thr_rwlock.c
@@ -0,0 +1,333 @@
+/*-
+ * Copyright (c) 1998 Alex Nash
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $Id$
+ */
+
+#ifdef _THREAD_SAFE
+#include <errno.h>
+#include <limits.h>
+#include <stdlib.h>
+
+#include <pthread.h>
+#include "pthread_private.h"
+
+/* maximum number of times a read lock may be obtained */
+#define MAX_READ_LOCKS (INT_MAX - 1)
+
+static int init_static (pthread_rwlock_t *rwlock);
+
+static spinlock_t static_init_lock = _SPINLOCK_INITIALIZER;
+
+static int
+init_static (pthread_rwlock_t *rwlock)
+{
+ int ret;
+
+ _SPINLOCK(&static_init_lock);
+
+ if (*rwlock == NULL)
+ ret = pthread_rwlock_init(rwlock, NULL);
+ else
+ ret = 0;
+
+ _SPINUNLOCK(&static_init_lock);
+
+ return(ret);
+}
+
+int
+pthread_rwlock_destroy (pthread_rwlock_t *rwlock)
+{
+ int ret;
+
+ if (rwlock == NULL)
+ ret = EINVAL;
+ else {
+ pthread_rwlock_t prwlock;
+
+ prwlock = *rwlock;
+
+ pthread_mutex_destroy(&prwlock->lock);
+ pthread_cond_destroy(&prwlock->read_signal);
+ pthread_cond_destroy(&prwlock->write_signal);
+ free(prwlock);
+
+ *rwlock = NULL;
+ }
+
+ return(ret);
+}
+
+int
+pthread_rwlock_init (pthread_rwlock_t *rwlock, const pthread_rwlockattr_t *attr)
+{
+ pthread_rwlock_t prwlock;
+ int ret;
+
+ /* allocate rwlock object */
+ prwlock = (pthread_rwlock_t)malloc(sizeof(struct pthread_rwlock));
+
+ if (prwlock == NULL)
+ return(ENOMEM);
+
+ /* initialize the lock */
+ if ((ret = pthread_mutex_init(&prwlock->lock, NULL)) != 0)
+ free(prwlock);
+ else {
+ /* initialize the read condition signal */
+ ret = pthread_cond_init(&prwlock->read_signal, NULL);
+
+ if (ret != 0) {
+ pthread_mutex_destroy(&prwlock->lock);
+ free(prwlock);
+ } else {
+ /* initialize the write condition signal */
+ ret = pthread_cond_init(&prwlock->write_signal, NULL);
+
+ if (ret != 0) {
+ pthread_cond_destroy(&prwlock->read_signal);
+ pthread_mutex_destroy(&prwlock->lock);
+ free(prwlock);
+ } else {
+ /* success */
+ prwlock->state = 0;
+ prwlock->blocked_writers = 0;
+
+ *rwlock = prwlock;
+ }
+ }
+ }
+
+ return(ret);
+}
+
+int
+pthread_rwlock_rdlock (pthread_rwlock_t *rwlock)
+{
+ pthread_rwlock_t prwlock;
+ int ret = 0;
+
+ if (rwlock == NULL)
+ return(EINVAL);
+
+ prwlock = *rwlock;
+
+ /* check for static initialization */
+ if (prwlock == NULL) {
+ if ((ret = init_static(rwlock)) != 0)
+ return(ret);
+
+ prwlock = *rwlock;
+ }
+
+ /* grab the monitor lock */
+ if ((ret = pthread_mutex_lock(&prwlock->lock)) != 0)
+ return(ret);
+
+ /* give writers priority over readers */
+ while (prwlock->blocked_writers || prwlock->state < 0) {
+ ret = pthread_cond_wait(&prwlock->read_signal, &prwlock->lock);
+
+ if (ret != 0) {
+ /* can't do a whole lot if this fails */
+ pthread_mutex_unlock(&prwlock->lock);
+ return(ret);
+ }
+ }
+
+ /* check lock count */
+ if (prwlock->state == MAX_READ_LOCKS)
+ ret = EAGAIN;
+ else
+ ++prwlock->state; /* indicate we are locked for reading */
+
+ /*
+ * Something is really wrong if this call fails. Returning
+ * error won't do because we've already obtained the read
+ * lock. Decrementing 'state' is no good because we probably
+ * don't have the monitor lock.
+ */
+ pthread_mutex_unlock(&prwlock->lock);
+
+ return(ret);
+}
+
+int
+pthread_rwlock_tryrdlock (pthread_rwlock_t *rwlock)
+{
+ pthread_rwlock_t prwlock;
+ int ret = 0;
+
+ if (rwlock == NULL)
+ return(EINVAL);
+
+ prwlock = *rwlock;
+
+ /* check for static initialization */
+ if (prwlock == NULL) {
+ if ((ret = init_static(rwlock)) != 0)
+ return(ret);
+
+ prwlock = *rwlock;
+ }
+
+ /* grab the monitor lock */
+ if ((ret = pthread_mutex_lock(&prwlock->lock)) != 0)
+ return(ret);
+
+ /* give writers priority over readers */
+ if (prwlock->blocked_writers || prwlock->state < 0)
+ ret = EWOULDBLOCK;
+ else if (prwlock->state == MAX_READ_LOCKS)
+ ret = EAGAIN; /* too many read locks acquired */
+ else
+ ++prwlock->state; /* indicate we are locked for reading */
+
+ /* see the comment on this in pthread_rwlock_rdlock */
+ pthread_mutex_unlock(&prwlock->lock);
+
+ return(ret);
+}
+
+int
+pthread_rwlock_trywrlock (pthread_rwlock_t *rwlock)
+{
+ pthread_rwlock_t prwlock;
+ int ret = 0;
+
+ if (rwlock == NULL)
+ return(EINVAL);
+
+ prwlock = *rwlock;
+
+ /* check for static initialization */
+ if (prwlock == NULL) {
+ if ((ret = init_static(rwlock)) != 0)
+ return(ret);
+
+ prwlock = *rwlock;
+ }
+
+ /* grab the monitor lock */
+ if ((ret = pthread_mutex_lock(&prwlock->lock)) != 0)
+ return(ret);
+
+ if (prwlock->state != 0)
+ ret = EWOULDBLOCK;
+ else
+ /* indicate we are locked for writing */
+ prwlock->state = -1;
+
+ /* see the comment on this in pthread_rwlock_rdlock */
+ pthread_mutex_unlock(&prwlock->lock);
+
+ return(ret);
+}
+
+int
+pthread_rwlock_unlock (pthread_rwlock_t *rwlock)
+{
+ pthread_rwlock_t prwlock;
+ int ret = 0;
+
+ if (rwlock == NULL)
+ return(EINVAL);
+
+ prwlock = *rwlock;
+
+ if (prwlock == NULL)
+ return(EINVAL);
+
+ /* grab the monitor lock */
+ if ((ret = pthread_mutex_lock(&prwlock->lock)) != 0)
+ return(ret);
+
+ if (prwlock->state > 0) {
+ if (--prwlock->state == 0 && prwlock->blocked_writers)
+ ret = pthread_cond_signal(&prwlock->write_signal);
+ } else if (prwlock->state < 0) {
+ prwlock->state = 0;
+
+ if (prwlock->blocked_writers)
+ ret = pthread_cond_signal(&prwlock->write_signal);
+ else
+ ret = pthread_cond_broadcast(&prwlock->read_signal);
+ } else
+ ret = EINVAL;
+
+ /* see the comment on this in pthread_rwlock_rdlock */
+ pthread_mutex_unlock(&prwlock->lock);
+
+ return(ret);
+}
+
+int
+pthread_rwlock_wrlock (pthread_rwlock_t *rwlock)
+{
+ pthread_rwlock_t prwlock;
+ int ret = 0;
+
+ if (rwlock == NULL)
+ return(EINVAL);
+
+ prwlock = *rwlock;
+
+ /* check for static initialization */
+ if (prwlock == NULL) {
+ if ((ret = init_static(rwlock)) != 0)
+ return(ret);
+
+ prwlock = *rwlock;
+ }
+
+ /* grab the monitor lock */
+ if ((ret = pthread_mutex_lock(&prwlock->lock)) != 0)
+ return(ret);
+
+ while (prwlock->state != 0) {
+ ++prwlock->blocked_writers;
+
+ ret = pthread_cond_wait(&prwlock->write_signal, &prwlock->lock);
+
+ if (ret != 0) {
+ --prwlock->blocked_writers;
+ pthread_mutex_unlock(&prwlock->lock);
+ return(ret);
+ }
+
+ --prwlock->blocked_writers;
+ }
+
+ /* indicate we are locked for writing */
+ prwlock->state = -1;
+
+ /* see the comment on this in pthread_rwlock_rdlock */
+ pthread_mutex_unlock(&prwlock->lock);
+
+ return(ret);
+}
+
+#endif /* _THREAD_SAFE */
diff --git a/lib/libkse/thread/thr_rwlockattr.c b/lib/libkse/thread/thr_rwlockattr.c
new file mode 100644
index 0000000..a3683bc
--- /dev/null
+++ b/lib/libkse/thread/thr_rwlockattr.c
@@ -0,0 +1,97 @@
+/*-
+ * Copyright (c) 1998 Alex Nash
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $Id$
+ */
+
+#ifdef _THREAD_SAFE
+#include <errno.h>
+
+#include <pthread.h>
+#include "pthread_private.h"
+
+int
+pthread_rwlockattr_destroy (pthread_rwlockattr_t *rwlockattr)
+{
+ pthread_rwlockattr_t prwlockattr;
+
+ if (rwlockattr == NULL)
+ return(EINVAL);
+
+ prwlockattr = *rwlockattr;
+
+ if (prwlockattr == NULL)
+ return(EINVAL);
+
+ free(prwlockattr);
+
+ return(0);
+}
+
+int
+pthread_rwlockattr_getpshared (const pthread_rwlockattr_t *rwlockattr,
+ int *pshared)
+{
+ *pshared = (*rwlockattr)->pshared;
+
+ return(0);
+}
+
+int
+pthread_rwlockattr_init (pthread_rwlockattr_t *rwlockattr)
+{
+ pthread_rwlockattr_t prwlockattr;
+
+ if (rwlockattr == NULL)
+ return(EINVAL);
+
+ prwlockattr = (pthread_rwlockattr_t)
+ malloc(sizeof(struct pthread_rwlockattr));
+
+ if (prwlockattr == NULL)
+ return(ENOMEM);
+
+ prwlockattr->pshared = PTHREAD_PROCESS_PRIVATE;
+ *rwlockattr = prwlockattr;
+
+ return(0);
+}
+
+int
+pthread_rwlockattr_setpshared (pthread_rwlockattr_t *rwlockattr,
+ int *pshared)
+{
+ int ps = *pshared;
+
+ /* only PTHREAD_PROCESS_PRIVATE is supported */
+ if (ps != PTHREAD_PROCESS_PRIVATE)
+ return(EINVAL);
+
+ (*rwlockattr)->pshared = ps;
+
+ return(0);
+}
+
+#endif /* _THREAD_SAFE */
diff --git a/lib/libpthread/man/Makefile.inc b/lib/libpthread/man/Makefile.inc
index e6bb8a5..f92f3df 100644
--- a/lib/libpthread/man/Makefile.inc
+++ b/lib/libpthread/man/Makefile.inc
@@ -1,4 +1,4 @@
-# $Id: Makefile.inc,v 1.3 1997/02/22 15:05:23 peter Exp $
+# $Id: Makefile.inc,v 1.4 1998/07/31 09:09:19 phk Exp $
# POSIX thread man files
@@ -26,5 +26,14 @@ MAN3+= pthread_cleanup_pop.3 \
pthread_mutex_trylock.3 \
pthread_mutex_unlock.3 \
pthread_once.3 \
+ pthread_rwlock_destroy.3 \
+ pthread_rwlock_init.3 \
+ pthread_rwlock_rdlock.3 \
+ pthread_rwlock_unlock.3 \
+ pthread_rwlock_wrlock.3 \
+ pthread_rwlockattr_destroy.3 \
+ pthread_rwlockattr_getpshared.3 \
+ pthread_rwlockattr_init.3 \
+ pthread_rwlockattr_setpshared.3 \
pthread_self.3 \
pthread_setspecific.3
diff --git a/lib/libpthread/man/pthread_rwlock_destroy.3 b/lib/libpthread/man/pthread_rwlock_destroy.3
new file mode 100644
index 0000000..7453274
--- /dev/null
+++ b/lib/libpthread/man/pthread_rwlock_destroy.3
@@ -0,0 +1,80 @@
+.\" Copyright (c) 1998 Alex Nash
+.\" All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" $Id$
+.\"
+.Dd August 4, 1998
+.Dt PTHREAD_RWLOCK_DESTROY 3
+.Os
+.Sh NAME
+.Nm pthread_rwlock_destroy
+.Nd destroy a read/write lock
+.Sh SYNOPSIS
+.Fd #include <pthread.h>
+.Ft int
+.Fn pthread_rwlock_destroy "pthread_rwlock_t *lock"
+.Sh DESCRIPTION
+The
+.Fn pthread_rwlock_destroy
+function is used to destroy a read/write lock previously created with
+.Fn pthread_rwlock_init .
+.Sh RETURN VALUES
+If successful, the
+.Fn pthread_rwlock_destroy
+function will return zero. Otherwise an error number will be returned
+to indicate the error.
+.Sh SEE ALSO
+.Xr pthread_rwlock_init 3 ,
+.Sh STANDARDS
+The
+.Fn pthread_rwlock_destroy
+function is expected to conform to
+.St -susv2 .
+.Sh ERRORS
+The
+.Fn pthread_rwlock_destroy
+function will fail if:
+.Bl -tag -width Er
+.It Bq Er EPERM
+The caller does not have the privilege to perform the operation.
+.El
+.Pp
+The
+.Fn pthread_rwlock_destroy
+function may fail if:
+.Bl -tag -width Er
+.It Bq Er EBUSY
+The system has detected an attempt to destroy the object referenced by
+.Fa lock
+while it is locked.
+.It Bq Er EINVAL
+The value specified by
+.Fa lock
+is invalid.
+.El
+.Sh HISTORY
+The
+.Fn pthread_rwlock_destroy
+function first appeared in
+.Fx 3.0 .
diff --git a/lib/libpthread/man/pthread_rwlock_init.3 b/lib/libpthread/man/pthread_rwlock_init.3
new file mode 100644
index 0000000..a561695
--- /dev/null
+++ b/lib/libpthread/man/pthread_rwlock_init.3
@@ -0,0 +1,99 @@
+.\" Copyright (c) 1998 Alex Nash
+.\" All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" $Id$
+.\"
+.Dd August 4, 1998
+.Dt PTHREAD_RWLOCK_INIT 3
+.Os
+.Sh NAME
+.Nm pthread_rwlock_init
+.Nd initialize a read/write lock
+.Sh SYNOPSIS
+.Fd #include <pthread.h>
+.Ft int
+.Fn pthread_rwlock_init "pthread_rwlock_t *lock" "const pthread_rwlockattr_t *attr"
+.Sh DESCRIPTION
+The
+.Fn pthread_rwlock_init
+function is used to initialize a read/write lock, with attributes
+specified by
+.Fa attr .
+If
+.Fa attr
+is NULL, the default read/write lock attributes are used.
+.Pp
+The results of calling
+.Fn pthread_rwlock_init
+with an already initialized lock are undefined.
+.Sh RETURN VALUES
+If successful, the
+.Fn pthread_rwlock_init
+function will return zero. Otherwise an error number will be returned
+to indicate the error.
+.Sh SEE ALSO
+.Xr pthread_rwlock_destroy 3 ,
+.Xr pthread_rwlockattr_init 3 ,
+.Xr pthread_rwlockattr_setpshared 3
+.Sh STANDARDS
+The
+.Fn pthread_rwlock_init
+function is expected to conform to
+.St -susv2 .
+.Sh ERRORS
+The
+.Fn pthread_rwlock_init
+function will fail if:
+.Bl -tag -width Er
+.It Bq Er EAGAIN
+The system lacked the necessary resources (other than memory) to
+initialize the lock.
+.It Bq Er ENOMEM
+Insufficient memory exists to initialize the lock.
+.It Bq Er EPERM
+The caller does not have sufficient privilege to perform the
+operation.
+.El
+.Pp
+The
+.Fn pthread_rwlock_init
+function may fail if:
+.Bl -tag -width Er
+.It Bq Er EBUSY
+The system has detected an attempt to re-initialize the object
+referenced by
+.Fa lock ,
+a previously initialized but not yet destroyed read/write lock.
+.It Bq Er EINVAL
+The value specified by
+.Fa attr
+is invalid.
+.El
+.Sh HISTORY
+The
+.Fn pthread_rwlock_init
+function first appeared in
+.Fx 3.0 .
+.Sh BUGS
+The PTHREAD_PROCESS_SHARED attribute is not supported.
diff --git a/lib/libpthread/man/pthread_rwlock_rdlock.3 b/lib/libpthread/man/pthread_rwlock_rdlock.3
new file mode 100644
index 0000000..9181be9
--- /dev/null
+++ b/lib/libpthread/man/pthread_rwlock_rdlock.3
@@ -0,0 +1,122 @@
+.\" Copyright (c) 1998 Alex Nash
+.\" All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" $Id$
+.\"
+.Dd August 4, 1998
+.Dt PTHREAD_RWLOCK_RDLOCK 3
+.Os
+.Sh NAME
+.Nm pthread_rwlock_rdlock ,
+.Nm pthread_rwlock_tryrdlock
+.Nd acquire a read/write lock for reading
+.Sh SYNOPSIS
+.Fd #include <pthread.h>
+.Ft int
+.Fn pthread_rwlock_rdlock "pthread_rwlock_t *lock"
+.Ft int
+.Fn pthread_rwlock_tryrdlock "pthread_rwlock_t *lock"
+.Sh DESCRIPTION
+The
+.Fn pthread_rwlock_rdlock
+function acquires a read lock on
+.Fa lock
+provided that
+.Fa lock
+is not presently held for writing and no writer threads are
+presently blocked on the lock. If the read lock cannot be
+immediately acquired, the calling thread blocks until it can
+acquire the lock.
+.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).
+.Pp
+A thread may hold multiple concurrent read locks. If so,
+.Fn pthread_rwlock_unlock
+must be called once for each lock obtained.
+.Pp
+The results of acquiring a read lock while the calling thread holds
+a write lock are undefined.
+.Sh IMPLEMENTATION NOTES
+To prevent writer starvation, writers are favored over readers.
+.Sh RETURN VALUES
+If successful, the
+.Fn pthread_rwlock_rdlock
+and
+.Fn pthread_rwlock_tryrdlock
+functions will return zero. Otherwise an error number will be returned
+to indicate the error.
+.Sh SEE ALSO
+.Xr pthread_rwlock_init 3 ,
+.Xr pthread_rwlock_trywrlock 3 ,
+.Xr pthread_rwlock_unlock 3 ,
+.Xr pthread_rwlock_wrlock 3
+.Sh STANDARDS
+The
+.Fn pthread_rwlock_rdlock
+and
+.Fn pthread_rwlock_tryrdlock
+functions are expected to conform to
+.St -susv2 .
+.Sh ERRORS
+The
+.Fn pthread_rwlock_tryrdlock
+function will fail if:
+.Bl -tag -width Er
+.It Bq Er EBUSY
+The lock could not be acquired because a writer holds the lock or
+was blocked on it.
+.El
+.Pp
+The
+.Fn pthread_rwlock_rdlock
+and
+.Fn pthread_rwlock_tryrdlock
+functions may fail if:
+.Bl -tag -width Er
+.It Bq Er EAGAIN
+The lock could not be acquired because the maximum number of read locks
+against
+.Fa lock
+has been exceeded.
+.It Bq Er EDEADLK
+The current thread already owns
+.Fa lock
+for writing.
+.It Bq Er EINVAL
+The value specified by
+.Fa lock
+is invalid.
+.It Bq Er ENOMEM
+Insufficient memory exists to initialize the lock (applies to
+statically initialized locks only).
+.El
+.Sh HISTORY
+The
+.Fn pthread_rwlock_rdlock
+function first appeared in
+.Fx 3.0 .
diff --git a/lib/libpthread/man/pthread_rwlock_unlock.3 b/lib/libpthread/man/pthread_rwlock_unlock.3
new file mode 100644
index 0000000..1c9fd05
--- /dev/null
+++ b/lib/libpthread/man/pthread_rwlock_unlock.3
@@ -0,0 +1,79 @@
+.\" Copyright (c) 1998 Alex Nash
+.\" All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" $Id$
+.\"
+.Dd August 4, 1998
+.Dt PTHREAD_RWLOCK_UNLOCK 3
+.Os
+.Sh NAME
+.Nm pthread_rwlock_unlock
+.Nd release a read/write lock
+.Sh SYNOPSIS
+.Fd #include <pthread.h>
+.Ft int
+.Fn pthread_rwlock_unlock "pthread_rwlock_t *lock"
+.Sh DESCRIPTION
+The
+.Fn pthread_rwlock_unlock
+function is used to release the read/write lock previously obtained by
+.Fn pthread_rwlock_rdlock ,
+.Fn pthread_rwlock_wrlock ,
+.Fn pthread_rwlock_tryrdlock ,
+or
+.Fn pthread_rwlock_trywrlock .
+.Sh RETURN VALUES
+If successful, the
+.Fn pthread_rwlock_unlock
+function will return zero. Otherwise an error number will be returned
+to indicate the error.
+.Pp
+The results are undefined if
+.Fa lock
+is not held by the calling thread.
+.Sh SEE ALSO
+.Xr pthread_rwlock_rdlock 3 ,
+.Xr pthread_rwlock_wrlock 3
+.Sh STANDARDS
+The
+.Fn pthread_rwlock_unlock
+function is expected to conform to
+.St -susv2 .
+.Sh ERRORS
+The
+.Fn pthread_rwlock_unlock
+function may fail if:
+.Bl -tag -width Er
+.It Bq Er EINVAL
+The value specified by
+.Fa lock
+is invalid.
+.It Bq Er EPERM
+The current thread does not own the read/write lock.
+.El
+.Sh HISTORY
+The
+.Fn pthread_rwlock_unlock
+function first appeared in
+.Fx 3.0 .
diff --git a/lib/libpthread/man/pthread_rwlock_wrlock.3 b/lib/libpthread/man/pthread_rwlock_wrlock.3
new file mode 100644
index 0000000..a5a3674
--- /dev/null
+++ b/lib/libpthread/man/pthread_rwlock_wrlock.3
@@ -0,0 +1,102 @@
+.\" Copyright (c) 1998 Alex Nash
+.\" All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" $Id$
+.\"
+.Dd August 4, 1998
+.Dt PTHREAD_RWLOCK_WRLOCK 3
+.Os
+.Sh NAME
+.Nm pthread_rwlock_wrlock ,
+.Nm pthread_rwlock_trywrlock
+.Nd acquire a read/write lock for writing
+.Sh SYNOPSIS
+.Fd #include <pthread.h>
+.Ft int
+.Fn pthread_rwlock_wrlock "pthread_rwlock_t *lock"
+.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 .
+The
+.Fn pthread_rwlock_trywrlock
+function performs the same action, 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.
+.Sh IMPLEMENTATION NOTES
+To prevent writer starvation, writers are favored over readers.
+.Sh RETURN VALUES
+If successful, the
+.Fn pthread_rwlock_wrlock
+and
+.Fn pthread_rwlock_trywrlock
+functions will return zero. Otherwise an error number will be returned
+to indicate the error.
+.Sh SEE ALSO
+.Xr pthread_rwlock_trywrlock 3 ,
+.Xr pthread_rwlock_unlock 3 ,
+.Xr pthread_rwlock_wrlock 3
+.Sh STANDARDS
+The
+.Fn pthread_rwlock_wrlock
+and
+.Fn pthread_rwlock_trywrlock
+functions are expected to conform to
+.St -susv2 .
+.Sh ERRORS
+The
+.Fn pthread_rwlock_trywrlock
+function will fail if:
+.Bl -tag -width Er
+.It Bq Er EBUSY
+The calling thread is not able to acquire the lock without blocking.
+.El
+.Pp
+The
+.Fn pthread_rwlock_wrlock
+and
+.Fn pthread_rwlock_trywrlock
+functions may fail if:
+.Bl -tag -width Er
+.It Bq Er EDEADLK
+The calling thread already owns the read/write lock (for reading
+or writing).
+.It Bq Er EINVAL
+The value specified by
+.Fa lock
+is invalid.
+.It Bq Er ENOMEM
+Insufficient memory exists to initialize the lock (applies to
+statically initialized locks only).
+.El
+.Sh HISTORY
+The
+.Fn pthread_rwlock_wrlock
+function first appeared in
+.Fx 3.0 .
diff --git a/lib/libpthread/man/pthread_rwlockattr_destroy.3 b/lib/libpthread/man/pthread_rwlockattr_destroy.3
new file mode 100644
index 0000000..ee3c405
--- /dev/null
+++ b/lib/libpthread/man/pthread_rwlockattr_destroy.3
@@ -0,0 +1,68 @@
+.\" Copyright (c) 1998 Alex Nash
+.\" All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" $Id$
+.\"
+.Dd August 4, 1998
+.Dt PTHREAD_RWLOCKATTR_DESTROY 3
+.Os
+.Sh NAME
+.Nm pthread_rwlockattr_destroy
+.Nd destroy a read/write lock
+.Sh SYNOPSIS
+.Fd #include <pthread.h>
+.Ft int
+.Fn pthread_rwlockattr_destroy "pthread_rwlockattr_t *attr"
+.Sh DESCRIPTION
+The
+.Fn pthread_rwlockattr_destroy
+function is used to destroy a read/write lock attribute object
+previously created with
+.Fn pthread_rwlockattr_init .
+.Sh RETURN VALUES
+If successful, the
+.Fn pthread_rwlockattr_destroy
+function will return zero. Otherwise an error number will be returned
+to indicate the error.
+.Sh SEE ALSO
+.Xr pthread_rwlockattr_init 3 ,
+.Sh STANDARDS
+The
+.Fn pthread_rwlockattr_destroy
+function is expected to conform to
+.St -susv2 .
+.Sh ERRORS
+.Fn pthread_rwlockattr_destroy
+may fail if:
+.Bl -tag -width Er
+.It Bq Er EINVAL
+The value specified by
+.Fa attr
+is invalid.
+.El
+.Sh HISTORY
+The
+.Fn pthread_rwlockattr_destroy
+function first appeared in
+.Fx 3.0 .
diff --git a/lib/libpthread/man/pthread_rwlockattr_getpshared.3 b/lib/libpthread/man/pthread_rwlockattr_getpshared.3
new file mode 100644
index 0000000..8e8160b
--- /dev/null
+++ b/lib/libpthread/man/pthread_rwlockattr_getpshared.3
@@ -0,0 +1,80 @@
+.\" Copyright (c) 1998 Alex Nash
+.\" All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" $Id$
+.\"
+.Dd August 4, 1998
+.Dt PTHREAD_RWLOCKATTR_GETPSHARED 3
+.Os
+.Sh NAME
+.Nm pthread_rwlockattr_getpshared
+.Nd set the process shared attribute
+.Sh SYNOPSIS
+.Fd #include <pthread.h>
+.Ft int
+.Fn pthread_rwlockattr_getpshared "pthread_rwlockattr_t *attr" "int *pshared"
+.Sh DESCRIPTION
+The
+.Fn pthread_rwlockattr_getpshared
+function is used to get the process shared setting of a read/write
+lock attribute object. The setting is returned via
+.Fa pshared ,
+and may be one of two values:
+.Bl -hang -offset flag -width 123456789012345678901234
+.It Ar PTHREAD_PROCESS_SHARED
+Any thread of any process that has access to the memory where the
+read/write lock resides can manipulate the lock.
+.It Ar PTHREAD_PROCESS_PRIVATE
+Only threads created within the same process as the thread that
+initialized the read/write lock can manipulate the lock. This is
+the default value.
+.El
+.Sh RETURN VALUES
+If successful, the
+.Fn pthread_rwlockattr_getpshared
+function will return zero. Otherwise an error number will be returned
+to indicate the error.
+.Sh SEE ALSO
+.Xr pthread_rwlock_init 3 ,
+.Xr pthread_rwlockattr_init 3 ,
+.Xr pthread_rwlockattr_setpshared 3
+.Sh STANDARDS
+The
+.Fn pthread_rwlockattr_getpshared
+function is expected to conform to
+.St -susv2 .
+.Sh ERRORS
+.Fn pthread_rwlockattr_getpshared
+may fail if:
+.Bl -tag -width Er
+.It Bq Er EINVAL
+The value specified by
+.Fa attr
+is invalid.
+.El
+.Sh HISTORY
+The
+.Fn pthread_rwlockattr_getpshared
+function first appeared in
+.Fx 3.0 .
diff --git a/lib/libpthread/man/pthread_rwlockattr_init.3 b/lib/libpthread/man/pthread_rwlockattr_init.3
new file mode 100644
index 0000000..8827121
--- /dev/null
+++ b/lib/libpthread/man/pthread_rwlockattr_init.3
@@ -0,0 +1,67 @@
+.\" Copyright (c) 1998 Alex Nash
+.\" All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" $Id$
+.\"
+.Dd August 4, 1998
+.Dt PTHREAD_RWLOCKATTR_INIT 3
+.Os
+.Sh NAME
+.Nm pthread_rwlockattr_init
+.Nd initialize a read/write lock
+.Sh SYNOPSIS
+.Fd #include <pthread.h>
+.Ft int
+.Fn pthread_rwlockattr_init "pthread_rwlockattr_t *attr"
+.Sh DESCRIPTION
+The
+.Fn pthread_rwlockattr_init
+function is used to initialize a read/write lock attributes object.
+.Sh RETURN VALUES
+If successful, the
+.Fn pthread_rwlockattr_init
+function will return zero. Otherwise an error number will be returned
+to indicate the error.
+.Sh SEE ALSO
+.Xr pthread_rwlock_init 3 ,
+.Xr pthread_rwlockattr_destroy 3 ,
+.Xr pthread_rwlockattr_getpshared 3
+.Xr pthread_rwlockattr_setpshared 3
+.Sh STANDARDS
+The
+.Fn pthread_rwlockattr_init
+function is expected to conform to
+.St -susv2 .
+.Sh ERRORS
+.Fn pthread_rwlockattr_init
+will fail if:
+.Bl -tag -width Er
+.It Bq Er ENOMEM
+Insufficient memory exists to initialize the attribute object.
+.El
+.Sh HISTORY
+The
+.Fn pthread_rwlockattr_init
+function first appeared in
+.Fx 3.0 .
diff --git a/lib/libpthread/man/pthread_rwlockattr_setpshared.3 b/lib/libpthread/man/pthread_rwlockattr_setpshared.3
new file mode 100644
index 0000000..e63debf
--- /dev/null
+++ b/lib/libpthread/man/pthread_rwlockattr_setpshared.3
@@ -0,0 +1,86 @@
+.\" Copyright (c) 1998 Alex Nash
+.\" All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" $Id$
+.\"
+.Dd August 4, 1998
+.Dt PTHREAD_RWLOCKATTR_SETPSHARED 3
+.Os
+.Sh NAME
+.Nm pthread_rwlockattr_setpshared
+.Nd set the process shared attribute
+.Sh SYNOPSIS
+.Fd #include <pthread.h>
+.Ft int
+.Fn pthread_rwlockattr_setpshared "pthread_rwlockattr_t *attr" "int *pshared"
+.Sh DESCRIPTION
+The
+.Fn pthread_rwlockattr_setpshared
+function sets the process shared attribute of
+.Fa attr
+to the value referenced by
+.Fa pshared .
+.Fa pshared
+may be one of two values:
+.Bl -hang -offset flag -width 123456789012345678901234
+.It Ar PTHREAD_PROCESS_SHARED
+Any thread of any process that has access to the memory where the
+read/write lock resides can manipulate the lock.
+.It Ar PTHREAD_PROCESS_PRIVATE
+Only threads created within the same process as the thread that
+initialized the read/write lock can manipulate the lock. This is
+the default value.
+.El
+.Sh RETURN VALUES
+If successful, the
+.Fn pthread_rwlockattr_setpshared
+function will return zero. Otherwise an error number will be returned
+to indicate the error.
+.Sh SEE ALSO
+.Xr pthread_rwlock_init 3 ,
+.Xr pthread_rwlockattr_init 3 ,
+.Xr pthread_rwlockattr_setpshared 3
+.Sh STANDARDS
+The
+.Fn pthread_rwlockattr_setpshared
+function is expected to conform to
+.St -susv2 .
+.Sh ERRORS
+.Fn pthread_rwlockattr_setpshared
+will fail if:
+.Bl -tag -width Er
+.It Bq Er EINVAL
+The value specified by
+.Fa attr
+or
+.Fa pshared
+is invalid.
+.El
+.Sh HISTORY
+The
+.Fn pthread_rwlockattr_setpshared
+function first appeared in
+.Fx 3.0 .
+.Sh BUGS
+The PTHREAD_PROCESS_SHARED attribute is not supported.
diff --git a/lib/libpthread/thread/Makefile.inc b/lib/libpthread/thread/Makefile.inc
index dc46af9..4fd3034 100644
--- a/lib/libpthread/thread/Makefile.inc
+++ b/lib/libpthread/thread/Makefile.inc
@@ -1,4 +1,4 @@
-# $Id: Makefile.inc,v 1.12 1998/05/31 23:48:26 jb Exp $
+# $Id: Makefile.inc,v 1.13 1998/06/01 02:14:34 jb Exp $
# uthread sources
.PATH: ${.CURDIR}/uthread
@@ -67,6 +67,8 @@ SRCS+= \
uthread_recvfrom.c \
uthread_recvmsg.c \
uthread_resume_np.c \
+ uthread_rwlock.c \
+ uthread_rwlockattr.c \
uthread_select.c \
uthread_self.c \
uthread_sendmsg.c \
diff --git a/lib/libpthread/thread/thr_private.h b/lib/libpthread/thread/thr_private.h
index 39ce14d..5b76a86 100644
--- a/lib/libpthread/thread/thr_private.h
+++ b/lib/libpthread/thread/thr_private.h
@@ -224,6 +224,18 @@ struct pthread_key {
void (*destructor) ();
};
+struct pthread_rwlockattr {
+ int pshared;
+};
+
+struct pthread_rwlock {
+ pthread_mutex_t lock; /* monitor lock */
+ int state; /* 0 = idle >0 = # of readers -1 = writer */
+ pthread_cond_t read_signal;
+ pthread_cond_t write_signal;
+ int blocked_writers;
+};
+
/*
* Thread states.
*/
diff --git a/lib/libpthread/thread/thr_rwlock.c b/lib/libpthread/thread/thr_rwlock.c
new file mode 100644
index 0000000..356eb29
--- /dev/null
+++ b/lib/libpthread/thread/thr_rwlock.c
@@ -0,0 +1,333 @@
+/*-
+ * Copyright (c) 1998 Alex Nash
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $Id$
+ */
+
+#ifdef _THREAD_SAFE
+#include <errno.h>
+#include <limits.h>
+#include <stdlib.h>
+
+#include <pthread.h>
+#include "pthread_private.h"
+
+/* maximum number of times a read lock may be obtained */
+#define MAX_READ_LOCKS (INT_MAX - 1)
+
+static int init_static (pthread_rwlock_t *rwlock);
+
+static spinlock_t static_init_lock = _SPINLOCK_INITIALIZER;
+
+static int
+init_static (pthread_rwlock_t *rwlock)
+{
+ int ret;
+
+ _SPINLOCK(&static_init_lock);
+
+ if (*rwlock == NULL)
+ ret = pthread_rwlock_init(rwlock, NULL);
+ else
+ ret = 0;
+
+ _SPINUNLOCK(&static_init_lock);
+
+ return(ret);
+}
+
+int
+pthread_rwlock_destroy (pthread_rwlock_t *rwlock)
+{
+ int ret;
+
+ if (rwlock == NULL)
+ ret = EINVAL;
+ else {
+ pthread_rwlock_t prwlock;
+
+ prwlock = *rwlock;
+
+ pthread_mutex_destroy(&prwlock->lock);
+ pthread_cond_destroy(&prwlock->read_signal);
+ pthread_cond_destroy(&prwlock->write_signal);
+ free(prwlock);
+
+ *rwlock = NULL;
+ }
+
+ return(ret);
+}
+
+int
+pthread_rwlock_init (pthread_rwlock_t *rwlock, const pthread_rwlockattr_t *attr)
+{
+ pthread_rwlock_t prwlock;
+ int ret;
+
+ /* allocate rwlock object */
+ prwlock = (pthread_rwlock_t)malloc(sizeof(struct pthread_rwlock));
+
+ if (prwlock == NULL)
+ return(ENOMEM);
+
+ /* initialize the lock */
+ if ((ret = pthread_mutex_init(&prwlock->lock, NULL)) != 0)
+ free(prwlock);
+ else {
+ /* initialize the read condition signal */
+ ret = pthread_cond_init(&prwlock->read_signal, NULL);
+
+ if (ret != 0) {
+ pthread_mutex_destroy(&prwlock->lock);
+ free(prwlock);
+ } else {
+ /* initialize the write condition signal */
+ ret = pthread_cond_init(&prwlock->write_signal, NULL);
+
+ if (ret != 0) {
+ pthread_cond_destroy(&prwlock->read_signal);
+ pthread_mutex_destroy(&prwlock->lock);
+ free(prwlock);
+ } else {
+ /* success */
+ prwlock->state = 0;
+ prwlock->blocked_writers = 0;
+
+ *rwlock = prwlock;
+ }
+ }
+ }
+
+ return(ret);
+}
+
+int
+pthread_rwlock_rdlock (pthread_rwlock_t *rwlock)
+{
+ pthread_rwlock_t prwlock;
+ int ret = 0;
+
+ if (rwlock == NULL)
+ return(EINVAL);
+
+ prwlock = *rwlock;
+
+ /* check for static initialization */
+ if (prwlock == NULL) {
+ if ((ret = init_static(rwlock)) != 0)
+ return(ret);
+
+ prwlock = *rwlock;
+ }
+
+ /* grab the monitor lock */
+ if ((ret = pthread_mutex_lock(&prwlock->lock)) != 0)
+ return(ret);
+
+ /* give writers priority over readers */
+ while (prwlock->blocked_writers || prwlock->state < 0) {
+ ret = pthread_cond_wait(&prwlock->read_signal, &prwlock->lock);
+
+ if (ret != 0) {
+ /* can't do a whole lot if this fails */
+ pthread_mutex_unlock(&prwlock->lock);
+ return(ret);
+ }
+ }
+
+ /* check lock count */
+ if (prwlock->state == MAX_READ_LOCKS)
+ ret = EAGAIN;
+ else
+ ++prwlock->state; /* indicate we are locked for reading */
+
+ /*
+ * Something is really wrong if this call fails. Returning
+ * error won't do because we've already obtained the read
+ * lock. Decrementing 'state' is no good because we probably
+ * don't have the monitor lock.
+ */
+ pthread_mutex_unlock(&prwlock->lock);
+
+ return(ret);
+}
+
+int
+pthread_rwlock_tryrdlock (pthread_rwlock_t *rwlock)
+{
+ pthread_rwlock_t prwlock;
+ int ret = 0;
+
+ if (rwlock == NULL)
+ return(EINVAL);
+
+ prwlock = *rwlock;
+
+ /* check for static initialization */
+ if (prwlock == NULL) {
+ if ((ret = init_static(rwlock)) != 0)
+ return(ret);
+
+ prwlock = *rwlock;
+ }
+
+ /* grab the monitor lock */
+ if ((ret = pthread_mutex_lock(&prwlock->lock)) != 0)
+ return(ret);
+
+ /* give writers priority over readers */
+ if (prwlock->blocked_writers || prwlock->state < 0)
+ ret = EWOULDBLOCK;
+ else if (prwlock->state == MAX_READ_LOCKS)
+ ret = EAGAIN; /* too many read locks acquired */
+ else
+ ++prwlock->state; /* indicate we are locked for reading */
+
+ /* see the comment on this in pthread_rwlock_rdlock */
+ pthread_mutex_unlock(&prwlock->lock);
+
+ return(ret);
+}
+
+int
+pthread_rwlock_trywrlock (pthread_rwlock_t *rwlock)
+{
+ pthread_rwlock_t prwlock;
+ int ret = 0;
+
+ if (rwlock == NULL)
+ return(EINVAL);
+
+ prwlock = *rwlock;
+
+ /* check for static initialization */
+ if (prwlock == NULL) {
+ if ((ret = init_static(rwlock)) != 0)
+ return(ret);
+
+ prwlock = *rwlock;
+ }
+
+ /* grab the monitor lock */
+ if ((ret = pthread_mutex_lock(&prwlock->lock)) != 0)
+ return(ret);
+
+ if (prwlock->state != 0)
+ ret = EWOULDBLOCK;
+ else
+ /* indicate we are locked for writing */
+ prwlock->state = -1;
+
+ /* see the comment on this in pthread_rwlock_rdlock */
+ pthread_mutex_unlock(&prwlock->lock);
+
+ return(ret);
+}
+
+int
+pthread_rwlock_unlock (pthread_rwlock_t *rwlock)
+{
+ pthread_rwlock_t prwlock;
+ int ret = 0;
+
+ if (rwlock == NULL)
+ return(EINVAL);
+
+ prwlock = *rwlock;
+
+ if (prwlock == NULL)
+ return(EINVAL);
+
+ /* grab the monitor lock */
+ if ((ret = pthread_mutex_lock(&prwlock->lock)) != 0)
+ return(ret);
+
+ if (prwlock->state > 0) {
+ if (--prwlock->state == 0 && prwlock->blocked_writers)
+ ret = pthread_cond_signal(&prwlock->write_signal);
+ } else if (prwlock->state < 0) {
+ prwlock->state = 0;
+
+ if (prwlock->blocked_writers)
+ ret = pthread_cond_signal(&prwlock->write_signal);
+ else
+ ret = pthread_cond_broadcast(&prwlock->read_signal);
+ } else
+ ret = EINVAL;
+
+ /* see the comment on this in pthread_rwlock_rdlock */
+ pthread_mutex_unlock(&prwlock->lock);
+
+ return(ret);
+}
+
+int
+pthread_rwlock_wrlock (pthread_rwlock_t *rwlock)
+{
+ pthread_rwlock_t prwlock;
+ int ret = 0;
+
+ if (rwlock == NULL)
+ return(EINVAL);
+
+ prwlock = *rwlock;
+
+ /* check for static initialization */
+ if (prwlock == NULL) {
+ if ((ret = init_static(rwlock)) != 0)
+ return(ret);
+
+ prwlock = *rwlock;
+ }
+
+ /* grab the monitor lock */
+ if ((ret = pthread_mutex_lock(&prwlock->lock)) != 0)
+ return(ret);
+
+ while (prwlock->state != 0) {
+ ++prwlock->blocked_writers;
+
+ ret = pthread_cond_wait(&prwlock->write_signal, &prwlock->lock);
+
+ if (ret != 0) {
+ --prwlock->blocked_writers;
+ pthread_mutex_unlock(&prwlock->lock);
+ return(ret);
+ }
+
+ --prwlock->blocked_writers;
+ }
+
+ /* indicate we are locked for writing */
+ prwlock->state = -1;
+
+ /* see the comment on this in pthread_rwlock_rdlock */
+ pthread_mutex_unlock(&prwlock->lock);
+
+ return(ret);
+}
+
+#endif /* _THREAD_SAFE */
diff --git a/lib/libpthread/thread/thr_rwlockattr.c b/lib/libpthread/thread/thr_rwlockattr.c
new file mode 100644
index 0000000..a3683bc
--- /dev/null
+++ b/lib/libpthread/thread/thr_rwlockattr.c
@@ -0,0 +1,97 @@
+/*-
+ * Copyright (c) 1998 Alex Nash
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $Id$
+ */
+
+#ifdef _THREAD_SAFE
+#include <errno.h>
+
+#include <pthread.h>
+#include "pthread_private.h"
+
+int
+pthread_rwlockattr_destroy (pthread_rwlockattr_t *rwlockattr)
+{
+ pthread_rwlockattr_t prwlockattr;
+
+ if (rwlockattr == NULL)
+ return(EINVAL);
+
+ prwlockattr = *rwlockattr;
+
+ if (prwlockattr == NULL)
+ return(EINVAL);
+
+ free(prwlockattr);
+
+ return(0);
+}
+
+int
+pthread_rwlockattr_getpshared (const pthread_rwlockattr_t *rwlockattr,
+ int *pshared)
+{
+ *pshared = (*rwlockattr)->pshared;
+
+ return(0);
+}
+
+int
+pthread_rwlockattr_init (pthread_rwlockattr_t *rwlockattr)
+{
+ pthread_rwlockattr_t prwlockattr;
+
+ if (rwlockattr == NULL)
+ return(EINVAL);
+
+ prwlockattr = (pthread_rwlockattr_t)
+ malloc(sizeof(struct pthread_rwlockattr));
+
+ if (prwlockattr == NULL)
+ return(ENOMEM);
+
+ prwlockattr->pshared = PTHREAD_PROCESS_PRIVATE;
+ *rwlockattr = prwlockattr;
+
+ return(0);
+}
+
+int
+pthread_rwlockattr_setpshared (pthread_rwlockattr_t *rwlockattr,
+ int *pshared)
+{
+ int ps = *pshared;
+
+ /* only PTHREAD_PROCESS_PRIVATE is supported */
+ if (ps != PTHREAD_PROCESS_PRIVATE)
+ return(EINVAL);
+
+ (*rwlockattr)->pshared = ps;
+
+ return(0);
+}
+
+#endif /* _THREAD_SAFE */
diff --git a/share/man/man3/pthread_rwlock_destroy.3 b/share/man/man3/pthread_rwlock_destroy.3
new file mode 100644
index 0000000..7453274
--- /dev/null
+++ b/share/man/man3/pthread_rwlock_destroy.3
@@ -0,0 +1,80 @@
+.\" Copyright (c) 1998 Alex Nash
+.\" All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" $Id$
+.\"
+.Dd August 4, 1998
+.Dt PTHREAD_RWLOCK_DESTROY 3
+.Os
+.Sh NAME
+.Nm pthread_rwlock_destroy
+.Nd destroy a read/write lock
+.Sh SYNOPSIS
+.Fd #include <pthread.h>
+.Ft int
+.Fn pthread_rwlock_destroy "pthread_rwlock_t *lock"
+.Sh DESCRIPTION
+The
+.Fn pthread_rwlock_destroy
+function is used to destroy a read/write lock previously created with
+.Fn pthread_rwlock_init .
+.Sh RETURN VALUES
+If successful, the
+.Fn pthread_rwlock_destroy
+function will return zero. Otherwise an error number will be returned
+to indicate the error.
+.Sh SEE ALSO
+.Xr pthread_rwlock_init 3 ,
+.Sh STANDARDS
+The
+.Fn pthread_rwlock_destroy
+function is expected to conform to
+.St -susv2 .
+.Sh ERRORS
+The
+.Fn pthread_rwlock_destroy
+function will fail if:
+.Bl -tag -width Er
+.It Bq Er EPERM
+The caller does not have the privilege to perform the operation.
+.El
+.Pp
+The
+.Fn pthread_rwlock_destroy
+function may fail if:
+.Bl -tag -width Er
+.It Bq Er EBUSY
+The system has detected an attempt to destroy the object referenced by
+.Fa lock
+while it is locked.
+.It Bq Er EINVAL
+The value specified by
+.Fa lock
+is invalid.
+.El
+.Sh HISTORY
+The
+.Fn pthread_rwlock_destroy
+function first appeared in
+.Fx 3.0 .
diff --git a/share/man/man3/pthread_rwlock_init.3 b/share/man/man3/pthread_rwlock_init.3
new file mode 100644
index 0000000..a561695
--- /dev/null
+++ b/share/man/man3/pthread_rwlock_init.3
@@ -0,0 +1,99 @@
+.\" Copyright (c) 1998 Alex Nash
+.\" All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" $Id$
+.\"
+.Dd August 4, 1998
+.Dt PTHREAD_RWLOCK_INIT 3
+.Os
+.Sh NAME
+.Nm pthread_rwlock_init
+.Nd initialize a read/write lock
+.Sh SYNOPSIS
+.Fd #include <pthread.h>
+.Ft int
+.Fn pthread_rwlock_init "pthread_rwlock_t *lock" "const pthread_rwlockattr_t *attr"
+.Sh DESCRIPTION
+The
+.Fn pthread_rwlock_init
+function is used to initialize a read/write lock, with attributes
+specified by
+.Fa attr .
+If
+.Fa attr
+is NULL, the default read/write lock attributes are used.
+.Pp
+The results of calling
+.Fn pthread_rwlock_init
+with an already initialized lock are undefined.
+.Sh RETURN VALUES
+If successful, the
+.Fn pthread_rwlock_init
+function will return zero. Otherwise an error number will be returned
+to indicate the error.
+.Sh SEE ALSO
+.Xr pthread_rwlock_destroy 3 ,
+.Xr pthread_rwlockattr_init 3 ,
+.Xr pthread_rwlockattr_setpshared 3
+.Sh STANDARDS
+The
+.Fn pthread_rwlock_init
+function is expected to conform to
+.St -susv2 .
+.Sh ERRORS
+The
+.Fn pthread_rwlock_init
+function will fail if:
+.Bl -tag -width Er
+.It Bq Er EAGAIN
+The system lacked the necessary resources (other than memory) to
+initialize the lock.
+.It Bq Er ENOMEM
+Insufficient memory exists to initialize the lock.
+.It Bq Er EPERM
+The caller does not have sufficient privilege to perform the
+operation.
+.El
+.Pp
+The
+.Fn pthread_rwlock_init
+function may fail if:
+.Bl -tag -width Er
+.It Bq Er EBUSY
+The system has detected an attempt to re-initialize the object
+referenced by
+.Fa lock ,
+a previously initialized but not yet destroyed read/write lock.
+.It Bq Er EINVAL
+The value specified by
+.Fa attr
+is invalid.
+.El
+.Sh HISTORY
+The
+.Fn pthread_rwlock_init
+function first appeared in
+.Fx 3.0 .
+.Sh BUGS
+The PTHREAD_PROCESS_SHARED attribute is not supported.
diff --git a/share/man/man3/pthread_rwlock_rdlock.3 b/share/man/man3/pthread_rwlock_rdlock.3
new file mode 100644
index 0000000..9181be9
--- /dev/null
+++ b/share/man/man3/pthread_rwlock_rdlock.3
@@ -0,0 +1,122 @@
+.\" Copyright (c) 1998 Alex Nash
+.\" All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" $Id$
+.\"
+.Dd August 4, 1998
+.Dt PTHREAD_RWLOCK_RDLOCK 3
+.Os
+.Sh NAME
+.Nm pthread_rwlock_rdlock ,
+.Nm pthread_rwlock_tryrdlock
+.Nd acquire a read/write lock for reading
+.Sh SYNOPSIS
+.Fd #include <pthread.h>
+.Ft int
+.Fn pthread_rwlock_rdlock "pthread_rwlock_t *lock"
+.Ft int
+.Fn pthread_rwlock_tryrdlock "pthread_rwlock_t *lock"
+.Sh DESCRIPTION
+The
+.Fn pthread_rwlock_rdlock
+function acquires a read lock on
+.Fa lock
+provided that
+.Fa lock
+is not presently held for writing and no writer threads are
+presently blocked on the lock. If the read lock cannot be
+immediately acquired, the calling thread blocks until it can
+acquire the lock.
+.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).
+.Pp
+A thread may hold multiple concurrent read locks. If so,
+.Fn pthread_rwlock_unlock
+must be called once for each lock obtained.
+.Pp
+The results of acquiring a read lock while the calling thread holds
+a write lock are undefined.
+.Sh IMPLEMENTATION NOTES
+To prevent writer starvation, writers are favored over readers.
+.Sh RETURN VALUES
+If successful, the
+.Fn pthread_rwlock_rdlock
+and
+.Fn pthread_rwlock_tryrdlock
+functions will return zero. Otherwise an error number will be returned
+to indicate the error.
+.Sh SEE ALSO
+.Xr pthread_rwlock_init 3 ,
+.Xr pthread_rwlock_trywrlock 3 ,
+.Xr pthread_rwlock_unlock 3 ,
+.Xr pthread_rwlock_wrlock 3
+.Sh STANDARDS
+The
+.Fn pthread_rwlock_rdlock
+and
+.Fn pthread_rwlock_tryrdlock
+functions are expected to conform to
+.St -susv2 .
+.Sh ERRORS
+The
+.Fn pthread_rwlock_tryrdlock
+function will fail if:
+.Bl -tag -width Er
+.It Bq Er EBUSY
+The lock could not be acquired because a writer holds the lock or
+was blocked on it.
+.El
+.Pp
+The
+.Fn pthread_rwlock_rdlock
+and
+.Fn pthread_rwlock_tryrdlock
+functions may fail if:
+.Bl -tag -width Er
+.It Bq Er EAGAIN
+The lock could not be acquired because the maximum number of read locks
+against
+.Fa lock
+has been exceeded.
+.It Bq Er EDEADLK
+The current thread already owns
+.Fa lock
+for writing.
+.It Bq Er EINVAL
+The value specified by
+.Fa lock
+is invalid.
+.It Bq Er ENOMEM
+Insufficient memory exists to initialize the lock (applies to
+statically initialized locks only).
+.El
+.Sh HISTORY
+The
+.Fn pthread_rwlock_rdlock
+function first appeared in
+.Fx 3.0 .
diff --git a/share/man/man3/pthread_rwlock_unlock.3 b/share/man/man3/pthread_rwlock_unlock.3
new file mode 100644
index 0000000..1c9fd05
--- /dev/null
+++ b/share/man/man3/pthread_rwlock_unlock.3
@@ -0,0 +1,79 @@
+.\" Copyright (c) 1998 Alex Nash
+.\" All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" $Id$
+.\"
+.Dd August 4, 1998
+.Dt PTHREAD_RWLOCK_UNLOCK 3
+.Os
+.Sh NAME
+.Nm pthread_rwlock_unlock
+.Nd release a read/write lock
+.Sh SYNOPSIS
+.Fd #include <pthread.h>
+.Ft int
+.Fn pthread_rwlock_unlock "pthread_rwlock_t *lock"
+.Sh DESCRIPTION
+The
+.Fn pthread_rwlock_unlock
+function is used to release the read/write lock previously obtained by
+.Fn pthread_rwlock_rdlock ,
+.Fn pthread_rwlock_wrlock ,
+.Fn pthread_rwlock_tryrdlock ,
+or
+.Fn pthread_rwlock_trywrlock .
+.Sh RETURN VALUES
+If successful, the
+.Fn pthread_rwlock_unlock
+function will return zero. Otherwise an error number will be returned
+to indicate the error.
+.Pp
+The results are undefined if
+.Fa lock
+is not held by the calling thread.
+.Sh SEE ALSO
+.Xr pthread_rwlock_rdlock 3 ,
+.Xr pthread_rwlock_wrlock 3
+.Sh STANDARDS
+The
+.Fn pthread_rwlock_unlock
+function is expected to conform to
+.St -susv2 .
+.Sh ERRORS
+The
+.Fn pthread_rwlock_unlock
+function may fail if:
+.Bl -tag -width Er
+.It Bq Er EINVAL
+The value specified by
+.Fa lock
+is invalid.
+.It Bq Er EPERM
+The current thread does not own the read/write lock.
+.El
+.Sh HISTORY
+The
+.Fn pthread_rwlock_unlock
+function first appeared in
+.Fx 3.0 .
diff --git a/share/man/man3/pthread_rwlock_wrlock.3 b/share/man/man3/pthread_rwlock_wrlock.3
new file mode 100644
index 0000000..a5a3674
--- /dev/null
+++ b/share/man/man3/pthread_rwlock_wrlock.3
@@ -0,0 +1,102 @@
+.\" Copyright (c) 1998 Alex Nash
+.\" All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" $Id$
+.\"
+.Dd August 4, 1998
+.Dt PTHREAD_RWLOCK_WRLOCK 3
+.Os
+.Sh NAME
+.Nm pthread_rwlock_wrlock ,
+.Nm pthread_rwlock_trywrlock
+.Nd acquire a read/write lock for writing
+.Sh SYNOPSIS
+.Fd #include <pthread.h>
+.Ft int
+.Fn pthread_rwlock_wrlock "pthread_rwlock_t *lock"
+.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 .
+The
+.Fn pthread_rwlock_trywrlock
+function performs the same action, 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.
+.Sh IMPLEMENTATION NOTES
+To prevent writer starvation, writers are favored over readers.
+.Sh RETURN VALUES
+If successful, the
+.Fn pthread_rwlock_wrlock
+and
+.Fn pthread_rwlock_trywrlock
+functions will return zero. Otherwise an error number will be returned
+to indicate the error.
+.Sh SEE ALSO
+.Xr pthread_rwlock_trywrlock 3 ,
+.Xr pthread_rwlock_unlock 3 ,
+.Xr pthread_rwlock_wrlock 3
+.Sh STANDARDS
+The
+.Fn pthread_rwlock_wrlock
+and
+.Fn pthread_rwlock_trywrlock
+functions are expected to conform to
+.St -susv2 .
+.Sh ERRORS
+The
+.Fn pthread_rwlock_trywrlock
+function will fail if:
+.Bl -tag -width Er
+.It Bq Er EBUSY
+The calling thread is not able to acquire the lock without blocking.
+.El
+.Pp
+The
+.Fn pthread_rwlock_wrlock
+and
+.Fn pthread_rwlock_trywrlock
+functions may fail if:
+.Bl -tag -width Er
+.It Bq Er EDEADLK
+The calling thread already owns the read/write lock (for reading
+or writing).
+.It Bq Er EINVAL
+The value specified by
+.Fa lock
+is invalid.
+.It Bq Er ENOMEM
+Insufficient memory exists to initialize the lock (applies to
+statically initialized locks only).
+.El
+.Sh HISTORY
+The
+.Fn pthread_rwlock_wrlock
+function first appeared in
+.Fx 3.0 .
diff --git a/share/man/man3/pthread_rwlockattr_destroy.3 b/share/man/man3/pthread_rwlockattr_destroy.3
new file mode 100644
index 0000000..ee3c405
--- /dev/null
+++ b/share/man/man3/pthread_rwlockattr_destroy.3
@@ -0,0 +1,68 @@
+.\" Copyright (c) 1998 Alex Nash
+.\" All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" $Id$
+.\"
+.Dd August 4, 1998
+.Dt PTHREAD_RWLOCKATTR_DESTROY 3
+.Os
+.Sh NAME
+.Nm pthread_rwlockattr_destroy
+.Nd destroy a read/write lock
+.Sh SYNOPSIS
+.Fd #include <pthread.h>
+.Ft int
+.Fn pthread_rwlockattr_destroy "pthread_rwlockattr_t *attr"
+.Sh DESCRIPTION
+The
+.Fn pthread_rwlockattr_destroy
+function is used to destroy a read/write lock attribute object
+previously created with
+.Fn pthread_rwlockattr_init .
+.Sh RETURN VALUES
+If successful, the
+.Fn pthread_rwlockattr_destroy
+function will return zero. Otherwise an error number will be returned
+to indicate the error.
+.Sh SEE ALSO
+.Xr pthread_rwlockattr_init 3 ,
+.Sh STANDARDS
+The
+.Fn pthread_rwlockattr_destroy
+function is expected to conform to
+.St -susv2 .
+.Sh ERRORS
+.Fn pthread_rwlockattr_destroy
+may fail if:
+.Bl -tag -width Er
+.It Bq Er EINVAL
+The value specified by
+.Fa attr
+is invalid.
+.El
+.Sh HISTORY
+The
+.Fn pthread_rwlockattr_destroy
+function first appeared in
+.Fx 3.0 .
diff --git a/share/man/man3/pthread_rwlockattr_getpshared.3 b/share/man/man3/pthread_rwlockattr_getpshared.3
new file mode 100644
index 0000000..8e8160b
--- /dev/null
+++ b/share/man/man3/pthread_rwlockattr_getpshared.3
@@ -0,0 +1,80 @@
+.\" Copyright (c) 1998 Alex Nash
+.\" All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" $Id$
+.\"
+.Dd August 4, 1998
+.Dt PTHREAD_RWLOCKATTR_GETPSHARED 3
+.Os
+.Sh NAME
+.Nm pthread_rwlockattr_getpshared
+.Nd set the process shared attribute
+.Sh SYNOPSIS
+.Fd #include <pthread.h>
+.Ft int
+.Fn pthread_rwlockattr_getpshared "pthread_rwlockattr_t *attr" "int *pshared"
+.Sh DESCRIPTION
+The
+.Fn pthread_rwlockattr_getpshared
+function is used to get the process shared setting of a read/write
+lock attribute object. The setting is returned via
+.Fa pshared ,
+and may be one of two values:
+.Bl -hang -offset flag -width 123456789012345678901234
+.It Ar PTHREAD_PROCESS_SHARED
+Any thread of any process that has access to the memory where the
+read/write lock resides can manipulate the lock.
+.It Ar PTHREAD_PROCESS_PRIVATE
+Only threads created within the same process as the thread that
+initialized the read/write lock can manipulate the lock. This is
+the default value.
+.El
+.Sh RETURN VALUES
+If successful, the
+.Fn pthread_rwlockattr_getpshared
+function will return zero. Otherwise an error number will be returned
+to indicate the error.
+.Sh SEE ALSO
+.Xr pthread_rwlock_init 3 ,
+.Xr pthread_rwlockattr_init 3 ,
+.Xr pthread_rwlockattr_setpshared 3
+.Sh STANDARDS
+The
+.Fn pthread_rwlockattr_getpshared
+function is expected to conform to
+.St -susv2 .
+.Sh ERRORS
+.Fn pthread_rwlockattr_getpshared
+may fail if:
+.Bl -tag -width Er
+.It Bq Er EINVAL
+The value specified by
+.Fa attr
+is invalid.
+.El
+.Sh HISTORY
+The
+.Fn pthread_rwlockattr_getpshared
+function first appeared in
+.Fx 3.0 .
diff --git a/share/man/man3/pthread_rwlockattr_init.3 b/share/man/man3/pthread_rwlockattr_init.3
new file mode 100644
index 0000000..8827121
--- /dev/null
+++ b/share/man/man3/pthread_rwlockattr_init.3
@@ -0,0 +1,67 @@
+.\" Copyright (c) 1998 Alex Nash
+.\" All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" $Id$
+.\"
+.Dd August 4, 1998
+.Dt PTHREAD_RWLOCKATTR_INIT 3
+.Os
+.Sh NAME
+.Nm pthread_rwlockattr_init
+.Nd initialize a read/write lock
+.Sh SYNOPSIS
+.Fd #include <pthread.h>
+.Ft int
+.Fn pthread_rwlockattr_init "pthread_rwlockattr_t *attr"
+.Sh DESCRIPTION
+The
+.Fn pthread_rwlockattr_init
+function is used to initialize a read/write lock attributes object.
+.Sh RETURN VALUES
+If successful, the
+.Fn pthread_rwlockattr_init
+function will return zero. Otherwise an error number will be returned
+to indicate the error.
+.Sh SEE ALSO
+.Xr pthread_rwlock_init 3 ,
+.Xr pthread_rwlockattr_destroy 3 ,
+.Xr pthread_rwlockattr_getpshared 3
+.Xr pthread_rwlockattr_setpshared 3
+.Sh STANDARDS
+The
+.Fn pthread_rwlockattr_init
+function is expected to conform to
+.St -susv2 .
+.Sh ERRORS
+.Fn pthread_rwlockattr_init
+will fail if:
+.Bl -tag -width Er
+.It Bq Er ENOMEM
+Insufficient memory exists to initialize the attribute object.
+.El
+.Sh HISTORY
+The
+.Fn pthread_rwlockattr_init
+function first appeared in
+.Fx 3.0 .
diff --git a/share/man/man3/pthread_rwlockattr_setpshared.3 b/share/man/man3/pthread_rwlockattr_setpshared.3
new file mode 100644
index 0000000..e63debf
--- /dev/null
+++ b/share/man/man3/pthread_rwlockattr_setpshared.3
@@ -0,0 +1,86 @@
+.\" Copyright (c) 1998 Alex Nash
+.\" All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" $Id$
+.\"
+.Dd August 4, 1998
+.Dt PTHREAD_RWLOCKATTR_SETPSHARED 3
+.Os
+.Sh NAME
+.Nm pthread_rwlockattr_setpshared
+.Nd set the process shared attribute
+.Sh SYNOPSIS
+.Fd #include <pthread.h>
+.Ft int
+.Fn pthread_rwlockattr_setpshared "pthread_rwlockattr_t *attr" "int *pshared"
+.Sh DESCRIPTION
+The
+.Fn pthread_rwlockattr_setpshared
+function sets the process shared attribute of
+.Fa attr
+to the value referenced by
+.Fa pshared .
+.Fa pshared
+may be one of two values:
+.Bl -hang -offset flag -width 123456789012345678901234
+.It Ar PTHREAD_PROCESS_SHARED
+Any thread of any process that has access to the memory where the
+read/write lock resides can manipulate the lock.
+.It Ar PTHREAD_PROCESS_PRIVATE
+Only threads created within the same process as the thread that
+initialized the read/write lock can manipulate the lock. This is
+the default value.
+.El
+.Sh RETURN VALUES
+If successful, the
+.Fn pthread_rwlockattr_setpshared
+function will return zero. Otherwise an error number will be returned
+to indicate the error.
+.Sh SEE ALSO
+.Xr pthread_rwlock_init 3 ,
+.Xr pthread_rwlockattr_init 3 ,
+.Xr pthread_rwlockattr_setpshared 3
+.Sh STANDARDS
+The
+.Fn pthread_rwlockattr_setpshared
+function is expected to conform to
+.St -susv2 .
+.Sh ERRORS
+.Fn pthread_rwlockattr_setpshared
+will fail if:
+.Bl -tag -width Er
+.It Bq Er EINVAL
+The value specified by
+.Fa attr
+or
+.Fa pshared
+is invalid.
+.El
+.Sh HISTORY
+The
+.Fn pthread_rwlockattr_setpshared
+function first appeared in
+.Fx 3.0 .
+.Sh BUGS
+The PTHREAD_PROCESS_SHARED attribute is not supported.
OpenPOWER on IntegriCloud