X-Git-Url: http://git.osdn.net/view?a=blobdiff_plain;f=libpthread%2Fnptl%2Fpthread_rwlock_init.c;h=c8fbc796af13efe3949bd6280236dd141800952e;hb=266bdc1f623fe6fe489e5115e0f8ef723705d949;hp=f664dd8104170dcc57d0ca82ce0306da3239b2d0;hpb=8359f22a288236613e64f2b3e96ef6e2ac2de097;p=uclinux-h8%2FuClibc.git diff --git a/libpthread/nptl/pthread_rwlock_init.c b/libpthread/nptl/pthread_rwlock_init.c index f664dd810..c8fbc796a 100644 --- a/libpthread/nptl/pthread_rwlock_init.c +++ b/libpthread/nptl/pthread_rwlock_init.c @@ -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 , 2002. @@ -13,12 +13,12 @@ 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 + . */ #include "pthreadP.h" - +#include +#include 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; }