svn commit: r214007 - in head: include lib/libthr lib/libthr/thread
David Xu
davidxu at FreeBSD.org
Mon Oct 18 05:09:23 UTC 2010
Author: davidxu
Date: Mon Oct 18 05:09:22 2010
New Revision: 214007
URL: http://svn.freebsd.org/changeset/base/214007
Log:
Add pthread_rwlockattr_setkind_np and pthread_rwlockattr_getkind_np, the
functions set or get pthread_rwlock type, current supported types are:
PTHREAD_RWLOCK_PREFER_READER_NP,
PTHREAD_RWLOCK_PREFER_WRITER_NONRECURSIVE_NP,
PTHREAD_RWLOCK_PREFER_WRITER_NP,
default is PTHREAD_RWLOCK_PREFER_WRITER_NONCECURSIVE_NP, this maintains
binary compatible with old code.
Modified:
head/include/pthread.h
head/lib/libthr/pthread.map
head/lib/libthr/thread/thr_private.h
head/lib/libthr/thread/thr_rwlock.c
head/lib/libthr/thread/thr_rwlockattr.c
Modified: head/include/pthread.h
==============================================================================
--- head/include/pthread.h Mon Oct 18 05:01:53 2010 (r214006)
+++ head/include/pthread.h Mon Oct 18 05:09:22 2010 (r214007)
@@ -135,6 +135,15 @@ enum pthread_mutextype {
#define PTHREAD_MUTEX_DEFAULT PTHREAD_MUTEX_ERRORCHECK
+enum pthread_rwlocktype_np
+{
+ PTHREAD_RWLOCK_PREFER_READER_NP,
+ PTHREAD_RWLOCK_PREFER_WRITER_NONRECURSIVE_NP,
+ PTHREAD_RWLOCK_PREFER_WRITER_NP,
+ PTHREAD_RWLOCK_DEFAULT_NP =
+ PTHREAD_RWLOCK_PREFER_WRITER_NONRECURSIVE_NP
+};
+
struct _pthread_cleanup_info {
__uintptr_t pthread_cleanup_pad[8];
};
@@ -233,11 +242,14 @@ int pthread_rwlock_tryrdlock(pthread_rw
int pthread_rwlock_trywrlock(pthread_rwlock_t *);
int pthread_rwlock_unlock(pthread_rwlock_t *);
int pthread_rwlock_wrlock(pthread_rwlock_t *);
-int pthread_rwlockattr_init(pthread_rwlockattr_t *);
+int pthread_rwlockattr_destroy(pthread_rwlockattr_t *);
+int pthread_rwlockattr_getkind_np(const pthread_rwlockattr_t *,
+ int *);
int pthread_rwlockattr_getpshared(const pthread_rwlockattr_t *,
int *);
+int pthread_rwlockattr_init(pthread_rwlockattr_t *);
+int pthread_rwlockattr_setkind_np(pthread_rwlockattr_t *, int);
int pthread_rwlockattr_setpshared(pthread_rwlockattr_t *, int);
-int pthread_rwlockattr_destroy(pthread_rwlockattr_t *);
pthread_t pthread_self(void);
int pthread_setspecific(pthread_key_t, const void *);
Modified: head/lib/libthr/pthread.map
==============================================================================
--- head/lib/libthr/pthread.map Mon Oct 18 05:01:53 2010 (r214006)
+++ head/lib/libthr/pthread.map Mon Oct 18 05:09:22 2010 (r214007)
@@ -318,7 +318,9 @@ FBSDprivate_1.0 {
_pthread_rwlock_wrlock;
_pthread_rwlockattr_destroy;
_pthread_rwlockattr_getpshared;
+ _pthread_rwlockattr_getkind_np;
_pthread_rwlockattr_init;
+ _pthread_rwlockattr_setkind_np;
_pthread_rwlockattr_setpshared;
_pthread_self;
_pthread_set_name_np;
@@ -403,4 +405,6 @@ FBSD_1.2 {
openat;
setcontext;
swapcontext;
+ pthread_rwlockattr_getkind_np;
+ pthread_rwlockattr_setkind_np;
};
Modified: head/lib/libthr/thread/thr_private.h
==============================================================================
--- head/lib/libthr/thread/thr_private.h Mon Oct 18 05:01:53 2010 (r214006)
+++ head/lib/libthr/thread/thr_private.h Mon Oct 18 05:09:22 2010 (r214007)
@@ -285,11 +285,14 @@ struct pthread_prio {
struct pthread_rwlockattr {
int pshared;
+ int kind;
};
struct pthread_rwlock {
struct urwlock lock;
struct pthread *owner;
+ int recurse;
+ int kind;
};
/*
Modified: head/lib/libthr/thread/thr_rwlock.c
==============================================================================
--- head/lib/libthr/thread/thr_rwlock.c Mon Oct 18 05:01:53 2010 (r214006)
+++ head/lib/libthr/thread/thr_rwlock.c Mon Oct 18 05:09:22 2010 (r214007)
@@ -63,13 +63,19 @@ __weak_reference(_pthread_rwlock_timedwr
*/
static int
-rwlock_init(pthread_rwlock_t *rwlock, const pthread_rwlockattr_t *attr __unused)
+rwlock_init(pthread_rwlock_t *rwlock, const pthread_rwlockattr_t *attr)
{
pthread_rwlock_t prwlock;
prwlock = (pthread_rwlock_t)calloc(1, sizeof(struct pthread_rwlock));
if (prwlock == NULL)
return (ENOMEM);
+ if (attr != NULL)
+ prwlock->kind = (*attr)->kind;
+ else
+ prwlock->kind = PTHREAD_RWLOCK_DEFAULT_NP;
+ if (prwlock->kind == PTHREAD_RWLOCK_PREFER_READER_NP)
+ prwlock->lock.rw_flags |= URWLOCK_PREFER_READER;
*rwlock = prwlock;
return (0);
}
@@ -112,7 +118,7 @@ init_static(struct pthread *thread, pthr
}
int
-_pthread_rwlock_init (pthread_rwlock_t *rwlock, const pthread_rwlockattr_t *attr)
+_pthread_rwlock_init(pthread_rwlock_t *rwlock, const pthread_rwlockattr_t *attr)
{
*rwlock = NULL;
return (rwlock_init(rwlock, attr));
@@ -260,6 +266,14 @@ rwlock_wrlock_common (pthread_rwlock_t *
CHECK_AND_INIT_RWLOCK
+ if (__predict_false(prwlock->owner == curthread)) {
+ if (__predict_false(
+ prwlock->kind == PTHREAD_RWLOCK_PREFER_WRITER_NP)) {
+ prwlock->recurse++;
+ return (0);
+ }
+ }
+
/*
* POSIX said the validity of the abstimeout parameter need
* not be checked if the lock can be immediately acquired.
@@ -335,6 +349,13 @@ _pthread_rwlock_unlock (pthread_rwlock_t
if (state & URWLOCK_WRITE_OWNER) {
if (__predict_false(prwlock->owner != curthread))
return (EPERM);
+ if (__predict_false(
+ prwlock->kind == PTHREAD_RWLOCK_PREFER_WRITER_NP)) {
+ if (prwlock->recurse > 0) {
+ prwlock->recurse--;
+ return (0);
+ }
+ }
prwlock->owner = NULL;
}
Modified: head/lib/libthr/thread/thr_rwlockattr.c
==============================================================================
--- head/lib/libthr/thread/thr_rwlockattr.c Mon Oct 18 05:01:53 2010 (r214006)
+++ head/lib/libthr/thread/thr_rwlockattr.c Mon Oct 18 05:09:22 2010 (r214007)
@@ -36,8 +36,10 @@
__weak_reference(_pthread_rwlockattr_destroy, pthread_rwlockattr_destroy);
__weak_reference(_pthread_rwlockattr_getpshared, pthread_rwlockattr_getpshared);
+__weak_reference(_pthread_rwlockattr_getkind_np, pthread_rwlockattr_getkind_np);
__weak_reference(_pthread_rwlockattr_init, pthread_rwlockattr_init);
__weak_reference(_pthread_rwlockattr_setpshared, pthread_rwlockattr_setpshared);
+__weak_reference(_pthread_rwlockattr_setkind_np, pthread_rwlockattr_setkind_np);
int
_pthread_rwlockattr_destroy(pthread_rwlockattr_t *rwlockattr)
@@ -98,3 +100,21 @@ _pthread_rwlockattr_setpshared(pthread_r
return(0);
}
+int
+_pthread_rwlockattr_setkind_np(pthread_rwlockattr_t *attr, int kind)
+{
+ if (kind != PTHREAD_RWLOCK_PREFER_READER_NP ||
+ kind != PTHREAD_RWLOCK_PREFER_WRITER_NONRECURSIVE_NP ||
+ kind != PTHREAD_RWLOCK_PREFER_WRITER_NP) {
+ return (EINVAL);
+ }
+ (*attr)->kind = kind;
+ return (0);
+}
+
+int
+_pthread_rwlockattr_getkind_np(const pthread_rwlockattr_t *attr, int *kind)
+{
+ *kind = (*attr)->kind;
+ return (0);
+}
More information about the svn-src-all
mailing list