diff options
author | dim <dim@FreeBSD.org> | 2010-10-19 21:02:05 +0000 |
---|---|---|
committer | dim <dim@FreeBSD.org> | 2010-10-19 21:02:05 +0000 |
commit | acc1b913a3297e19f9ffe7d2b7b8a3142926d3b4 (patch) | |
tree | 3ba42afae5a4abd129ca596650d0c27112d3953e /lib/libthr/thread/thr_rwlock.c | |
parent | ba43e0ffe7a883f062e502acf73190ce6534b0fe (diff) | |
parent | f0ce9e3f305fe6039937eade02551429beef30ac (diff) | |
download | FreeBSD-src-acc1b913a3297e19f9ffe7d2b7b8a3142926d3b4.zip FreeBSD-src-acc1b913a3297e19f9ffe7d2b7b8a3142926d3b4.tar.gz |
Sync: merge r213992 through r214076 from ^/head.
Diffstat (limited to 'lib/libthr/thread/thr_rwlock.c')
-rw-r--r-- | lib/libthr/thread/thr_rwlock.c | 25 |
1 files changed, 23 insertions, 2 deletions
diff --git a/lib/libthr/thread/thr_rwlock.c b/lib/libthr/thread/thr_rwlock.c index ebdeae7..20b9b79 100644 --- a/lib/libthr/thread/thr_rwlock.c +++ b/lib/libthr/thread/thr_rwlock.c @@ -63,13 +63,19 @@ __weak_reference(_pthread_rwlock_timedwrlock, pthread_rwlock_timedwrlock); */ 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, pthread_rwlock_t *rwlock) } 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 *rwlock, const struct timespec *abstime) 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 *rwlock) 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; } |