about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog5
-rw-r--r--nptl/ChangeLog9
-rw-r--r--nptl/DESIGN-rwlock.txt4
-rw-r--r--nptl/sysdeps/pthread/pthread_rwlock_unlock.c21
-rw-r--r--nptl/sysdeps/unix/sysv/linux/i386/i486/pthread_rwlock_unlock.S26
-rw-r--r--sysdeps/unix/sysv/linux/ia64/sysdep.S13
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.