diff options
-rw-r--r-- | ChangeLog | 5 | ||||
-rw-r--r-- | nptl/ChangeLog | 9 | ||||
-rw-r--r-- | nptl/DESIGN-rwlock.txt | 4 | ||||
-rw-r--r-- | nptl/sysdeps/pthread/pthread_rwlock_unlock.c | 21 | ||||
-rw-r--r-- | nptl/sysdeps/unix/sysv/linux/i386/i486/pthread_rwlock_unlock.S | 26 | ||||
-rw-r--r-- | sysdeps/unix/sysv/linux/ia64/sysdep.S | 13 |
6 files changed, 63 insertions, 15 deletions
diff --git a/ChangeLog b/ChangeLog index b9e7b6c364..a7e4c09b71 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2003-02-24 David Mosberger <davidm@hpl.hp.com> + + * sysdeps/unix/sysv/linux/ia64/sysdep.S (__syscall_error): Fix + unwind info. + 2003-02-27 Ulrich Drepper <drepper@redhat.com> * resolv/res_libc.c [USE___THREAD] (_res): Don't need the diff --git a/nptl/ChangeLog b/nptl/ChangeLog index 11db7094ca..e81af68ce1 100644 --- a/nptl/ChangeLog +++ b/nptl/ChangeLog @@ -1,3 +1,12 @@ +2003-02-27 Ulrich Drepper <drepper@redhat.com> + + * sysdeps/pthread/pthread_rwlock_unlock.c + (__pthread_rwlock_unlock): Release internal lock early. Don't try + to wake up readers if there are none. + + * sysdeps/unix/sysv/linux/i386/i486/pthread_rwlock_unlock.S: + Release internal lock before wake threads. + 2003-02-26 Ulrich Drepper <drepper@redhat.com> * Makefile (tests): Add tst-rwlock10 and tst-rwlock11. diff --git a/nptl/DESIGN-rwlock.txt b/nptl/DESIGN-rwlock.txt index d97c084484..cdbd4ce9ef 100644 --- a/nptl/DESIGN-rwlock.txt +++ b/nptl/DESIGN-rwlock.txt @@ -96,11 +96,15 @@ pthread_rwlock_unlock(pthread_rwlock_t *rwlock) if (!rwlock->readers) { if (rwlock->nr_writers_queued) { ++rwlock->writer_wakeup; + lll_unlock(rwlock->lock); futex_wake(&rwlock->writer_wakeup, 1); + return; } else if (rwlock->nr_readers_queued) { ++rwlock->readers_wakeup; + lll_unlock(rwlock->lock); futex_wake(&rwlock->readers_wakeup, MAX_INT); + return; } } diff --git a/nptl/sysdeps/pthread/pthread_rwlock_unlock.c b/nptl/sysdeps/pthread/pthread_rwlock_unlock.c index 6e0c92ba3f..9cae8b6c22 100644 --- a/nptl/sysdeps/pthread/pthread_rwlock_unlock.c +++ b/nptl/sysdeps/pthread/pthread_rwlock_unlock.c @@ -24,27 +24,32 @@ #include <pthreadP.h> /* Unlock RWLOCK. */ -int __pthread_rwlock_unlock (pthread_rwlock_t *rwlock) +int +__pthread_rwlock_unlock (pthread_rwlock_t *rwlock) { - lll_mutex_lock(rwlock->__data.__lock); + lll_mutex_lock (rwlock->__data.__lock); if (rwlock->__data.__writer) rwlock->__data.__writer = 0; else - rwlock->__data.__nr_readers--; - if (!rwlock->__data.__nr_readers) + --rwlock->__data.__nr_readers; + if (rwlock->__data.__nr_readers == 0) { if (rwlock->__data.__nr_writers_queued) { ++rwlock->__data.__writer_wakeup; - lll_futex_wake(&rwlock->__data.__writer_wakeup, 1); + lll_mutex_unlock (rwlock->__data.__lock); + lll_futex_wake (&rwlock->__data.__writer_wakeup, 1); + return 0; } - else + else if (rwlock->__data.__nr_readers_queued) { ++rwlock->__data.__readers_wakeup; - lll_futex_wake(&rwlock->__data.__readers_wakeup, INT_MAX); + lll_mutex_unlock (rwlock->__data.__lock); + lll_futex_wake (&rwlock->__data.__readers_wakeup, INT_MAX); + return 0; } } - lll_mutex_unlock(rwlock->__data.__lock); + lll_mutex_unlock (rwlock->__data.__lock); return 0; } diff --git a/nptl/sysdeps/unix/sysv/linux/i386/i486/pthread_rwlock_unlock.S b/nptl/sysdeps/unix/sysv/linux/i386/i486/pthread_rwlock_unlock.S index bb5f8d1bc8..7dd97ba49e 100644 --- a/nptl/sysdeps/unix/sysv/linux/i386/i486/pthread_rwlock_unlock.S +++ b/nptl/sysdeps/unix/sysv/linux/i386/i486/pthread_rwlock_unlock.S @@ -76,10 +76,25 @@ __pthread_rwlock_unlock: leal READERS_WAKEUP(%edi), %ebx 0: incl (%ebx) - xorl %esi, %esi + LOCK +#if MUTEX == 0 + decl (%edi) +#else + decl MUTEX(%edi) +#endif + jne 7f + +8: xorl %esi, %esi movl $SYS_futex, %eax ENTER_KERNEL + xorl %eax, %eax + popl %edi + popl %esi + popl %ebx + ret + + .align 16 6: LOCK #if MUTEX == 0 decl (%edi) @@ -112,6 +127,15 @@ __pthread_rwlock_unlock: call __lll_mutex_unlock_wake jmp 4b +7: +#if MUTEX == 0 + movl %edi, %eax +#else + leal MUTEX(%edx), %eax +#endif + call __lll_mutex_unlock_wake + jmp 8b + .size __pthread_rwlock_unlock,.-__pthread_rwlock_unlock .globl pthread_rwlock_unlock diff --git a/sysdeps/unix/sysv/linux/ia64/sysdep.S b/sysdeps/unix/sysv/linux/ia64/sysdep.S index 31b5f9bde9..c053c3a053 100644 --- a/sysdeps/unix/sysv/linux/ia64/sysdep.S +++ b/sysdeps/unix/sysv/linux/ia64/sysdep.S @@ -1,4 +1,4 @@ -/* Copyright (C) 1999, 2000, 2001 Free Software Foundation, Inc. +/* Copyright (C) 1999, 2000, 2001, 2003 Free Software Foundation, Inc. This file is part of the GNU C Library. Contributed by David Mosberger-Tang <davidm@hpl.hp.com>. @@ -23,18 +23,19 @@ ENTRY(__syscall_error) #ifdef _LIBC_REENTRANT .prologue ASM_UNW_PRLG_RP|ASM_UNW_PRLG_PFS, ASM_UNW_PRLG_GRSAVE(0) - alloc r35=ar.pfs, 0, 4, 0, 0 + alloc r33=ar.pfs, 0, 4, 0, 0 mov r32=rp - mov r33=r8 + .body + mov r35=r8 mov r34=r1 ;; - br.call.sptk.many b0 = __errno_location# + br.call.sptk.many b0 = __errno_location .Lret0: /* force new bundle */ - st4 [r8]=r33 + st4 [r8]=r35 mov r1=r34 mov rp=r32 mov r8=-1 - mov ar.pfs=r35 + mov ar.pfs=r33 #else /* _LIBC_REENTRANT */ /* * Note that the gp has to be set properly for this to work. |