OSDN Git Service

Replace FSF snail mail address with URLs
[uclinux-h8/uClibc.git] / libpthread / nptl / pthread_rwlock_init.c
index f664dd8..c8fbc79 100644 (file)
@@ -1,4 +1,4 @@
-/* Copyright (C) 2002 Free Software Foundation, Inc.
+/* Copyright (C) 2002, 2007, 2009 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
    Contributed by Ulrich Drepper <drepper@redhat.com>, 2002.
 
    Lesser General Public License for more details.
 
    You should have received a copy of the GNU Lesser General Public
-   License along with the GNU C Library; if not, write to the Free
-   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
-   02111-1307 USA.  */
+   License along with the GNU C Library; if not, see
+   <http://www.gnu.org/licenses/>.  */
 
 #include "pthreadP.h"
-
+#include <bits/kernel-features.h>
+#include <string.h>
 
 static const struct pthread_rwlockattr default_attr =
   {
@@ -28,23 +28,44 @@ static const struct pthread_rwlockattr default_attr =
 
 
 int
-__pthread_rwlock_init (rwlock, attr)
-     pthread_rwlock_t *rwlock;
-     const pthread_rwlockattr_t *attr;
+__pthread_rwlock_init (
+     pthread_rwlock_t *rwlock,
+     const pthread_rwlockattr_t *attr)
 {
   const struct pthread_rwlockattr *iattr;
 
   iattr = ((const struct pthread_rwlockattr *) attr) ?: &default_attr;
 
-  rwlock->__data.__lock = 0;
+  memset (rwlock, '\0', sizeof (*rwlock));
+
   rwlock->__data.__flags
     = iattr->lockkind == PTHREAD_RWLOCK_PREFER_WRITER_NONRECURSIVE_NP;
-  rwlock->__data.__nr_readers = 0;
-  rwlock->__data.__writer = 0;
-  rwlock->__data.__readers_wakeup = 0;
-  rwlock->__data.__writer_wakeup = 0;
-  rwlock->__data.__nr_readers_queued = 0;
-  rwlock->__data.__nr_writers_queued = 0;
+
+  /* The __SHARED field is computed to minimize the work that needs to
+     be done while handling the futex.  There are two inputs: the
+     availability of private futexes and whether the rwlock is shared
+     or private.  Unfortunately the value of a private rwlock is
+     fixed: it must be zero.  The PRIVATE_FUTEX flag has the value
+     0x80 in case private futexes are available and zero otherwise.
+     This leads to the following table:
+
+                |     pshared     |     result
+                | shared  private | shared  private |
+     ------------+-----------------+-----------------+
+     !avail 0    |     0       0   |     0       0   |
+      avail 0x80 |  0x80       0   |     0    0x80   |
+
+     If the pshared value is in locking functions XORed with avail
+     we get the expected result.  */
+#ifdef __ASSUME_PRIVATE_FUTEX
+  rwlock->__data.__shared = (iattr->pshared == PTHREAD_PROCESS_PRIVATE
+                            ? 0 : FUTEX_PRIVATE_FLAG);
+#else
+  rwlock->__data.__shared = (iattr->pshared == PTHREAD_PROCESS_PRIVATE
+                            ? 0
+                            : THREAD_GETMEM (THREAD_SELF,
+                                             header.private_futex));
+#endif
 
   return 0;
 }