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);
+}
_______________________________________________
svn-src-head@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/svn-src-head
To unsubscribe, send any mail to "svn-src-head-unsubscr...@freebsd.org"

Reply via email to