Back to index

glibc  2.9
pthread_rwlock_init.c
Go to the documentation of this file.
00001 /* Copyright (C) 2002, 2007 Free Software Foundation, Inc.
00002    This file is part of the GNU C Library.
00003    Contributed by Ulrich Drepper <drepper@redhat.com>, 2002.
00004 
00005    The GNU C Library is free software; you can redistribute it and/or
00006    modify it under the terms of the GNU Lesser General Public
00007    License as published by the Free Software Foundation; either
00008    version 2.1 of the License, or (at your option) any later version.
00009 
00010    The GNU C Library is distributed in the hope that it will be useful,
00011    but WITHOUT ANY WARRANTY; without even the implied warranty of
00012    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00013    Lesser General Public License for more details.
00014 
00015    You should have received a copy of the GNU Lesser General Public
00016    License along with the GNU C Library; if not, write to the Free
00017    Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
00018    02111-1307 USA.  */
00019 
00020 #include "pthreadP.h"
00021 #include <kernel-features.h>
00022 
00023 
00024 static const struct pthread_rwlockattr default_attr =
00025   {
00026     .lockkind = PTHREAD_RWLOCK_DEFAULT_NP,
00027     .pshared = PTHREAD_PROCESS_PRIVATE
00028   };
00029 
00030 
00031 int
00032 __pthread_rwlock_init (rwlock, attr)
00033      pthread_rwlock_t *rwlock;
00034      const pthread_rwlockattr_t *attr;
00035 {
00036   const struct pthread_rwlockattr *iattr;
00037 
00038   iattr = ((const struct pthread_rwlockattr *) attr) ?: &default_attr;
00039 
00040   rwlock->__data.__lock = 0;
00041   rwlock->__data.__nr_readers = 0;
00042   rwlock->__data.__readers_wakeup = 0;
00043   rwlock->__data.__writer_wakeup = 0;
00044   rwlock->__data.__nr_readers_queued = 0;
00045   rwlock->__data.__nr_writers_queued = 0;
00046   rwlock->__data.__writer = 0;
00047 
00048   rwlock->__data.__flags
00049     = iattr->lockkind == PTHREAD_RWLOCK_PREFER_WRITER_NONRECURSIVE_NP;
00050 
00051   /* The __SHARED field is computed to minimize the work that needs to
00052      be done while handling the futex.  There are two inputs: the
00053      availability of private futexes and whether the rwlock is shared
00054      or private.  Unfortunately the value of a private rwlock is
00055      fixed: it must be zero.  The PRIVATE_FUTEX flag has the value
00056      0x80 in case private futexes are available and zero otherwise.
00057      This leads to the following table:
00058 
00059                  |     pshared     |     result
00060                  | shared  private | shared  private |
00061      ------------+-----------------+-----------------+
00062      !avail 0    |     0       0   |     0       0   |
00063       avail 0x80 |  0x80       0   |     0    0x80   |
00064 
00065      If the pshared value is in locking functions XORed with avail
00066      we get the expected result.  */
00067 #ifdef __ASSUME_PRIVATE_FUTEX
00068   rwlock->__data.__shared = (iattr->pshared == PTHREAD_PROCESS_PRIVATE
00069                           ? 0 : FUTEX_PRIVATE_FLAG);
00070 #else
00071   rwlock->__data.__shared = (iattr->pshared == PTHREAD_PROCESS_PRIVATE
00072                           ? 0
00073                           : THREAD_GETMEM (THREAD_SELF,
00074                                          header.private_futex));
00075 #endif
00076 
00077   rwlock->__data.__pad1 = 0;
00078   rwlock->__data.__pad2 = 0;
00079 
00080   return 0;
00081 }
00082 strong_alias (__pthread_rwlock_init, pthread_rwlock_init)