* sysdeps/unix/sysv/linux/powerpc/lowlevellock.h (FUTEX_WAKE_OP,
authorUlrich Drepper <drepper@redhat.com>
Thu, 8 Sep 2005 17:41:56 +0000 (17:41 +0000)
committerUlrich Drepper <drepper@redhat.com>
Thu, 8 Sep 2005 17:41:56 +0000 (17:41 +0000)
FUTEX_OP_CLEAR_WAKE_IF_GT_ONE): Define.
(lll_futex_wake_unlock): Define.
* sysdeps/unix/sysv/linux/alpha/lowlevellock.h (FUTEX_WAKE_OP,
FUTEX_OP_CLEAR_WAKE_IF_GT_ONE): Define.
(lll_futex_wake_unlock): Define.
* sysdeps/unix/sysv/linux/ia64/lowlevellock.h (FUTEX_WAKE_OP,
FUTEX_OP_CLEAR_WAKE_IF_GT_ONE): Define.
(lll_futex_wake_unlock): Define.
* sysdeps/unix/sysv/linux/s390/lowlevellock.h (FUTEX_WAKE_OP,
FUTEX_OP_CLEAR_WAKE_IF_GT_ONE): Define.
(lll_futex_wake_unlock): Define.
* sysdeps/unix/sysv/linux/sparc/lowlevellock.h (FUTEX_WAKE_OP,
FUTEX_OP_CLEAR_WAKE_IF_GT_ONE): Define.
(lll_futex_wake_unlock): Define.
* sysdeps/pthread/pthread_cond_signal.c (__pthread_cond_signal): Use
lll_futex_wake_unlock.
* sysdeps/unix/sysv/linux/i386/i486/pthread_cond_signal.S
(FUTEX_WAKE_OP, FUTEX_OP_CLEAR_WAKE_IF_GT_ONE): Define.
(__pthread_cond_signal): Use FUTEX_WAKE_OP.
* sysdeps/unix/sysv/linux/x86_64/pthread_cond_signal.S
(FUTEX_WAKE_OP, FUTEX_OP_CLEAR_WAKE_IF_GT_ONE): Define.
(__pthread_cond_signal): Use FUTEX_WAKE_OP.

nptl/ChangeLog
nptl/sysdeps/pthread/pthread_cond_signal.c
nptl/sysdeps/unix/sysv/linux/i386/i486/pthread_cond_signal.S
nptl/sysdeps/unix/sysv/linux/x86_64/pthread_cond_signal.S

index 2d63ed8..c1da34a 100644 (file)
@@ -1,3 +1,29 @@
+2005-08-29  Jakub Jelinek  <jakub@redhat.com>
+
+       * sysdeps/unix/sysv/linux/powerpc/lowlevellock.h (FUTEX_WAKE_OP,
+       FUTEX_OP_CLEAR_WAKE_IF_GT_ONE): Define.
+       (lll_futex_wake_unlock): Define.
+       * sysdeps/unix/sysv/linux/alpha/lowlevellock.h (FUTEX_WAKE_OP,
+       FUTEX_OP_CLEAR_WAKE_IF_GT_ONE): Define.
+       (lll_futex_wake_unlock): Define.
+       * sysdeps/unix/sysv/linux/ia64/lowlevellock.h (FUTEX_WAKE_OP,
+       FUTEX_OP_CLEAR_WAKE_IF_GT_ONE): Define.
+       (lll_futex_wake_unlock): Define.
+       * sysdeps/unix/sysv/linux/s390/lowlevellock.h (FUTEX_WAKE_OP,
+       FUTEX_OP_CLEAR_WAKE_IF_GT_ONE): Define.
+       (lll_futex_wake_unlock): Define.
+       * sysdeps/unix/sysv/linux/sparc/lowlevellock.h (FUTEX_WAKE_OP,
+       FUTEX_OP_CLEAR_WAKE_IF_GT_ONE): Define.
+       (lll_futex_wake_unlock): Define.
+       * sysdeps/pthread/pthread_cond_signal.c (__pthread_cond_signal): Use
+       lll_futex_wake_unlock.
+       * sysdeps/unix/sysv/linux/i386/i486/pthread_cond_signal.S
+       (FUTEX_WAKE_OP, FUTEX_OP_CLEAR_WAKE_IF_GT_ONE): Define.
+       (__pthread_cond_signal): Use FUTEX_WAKE_OP.
+       * sysdeps/unix/sysv/linux/x86_64/pthread_cond_signal.S
+       (FUTEX_WAKE_OP, FUTEX_OP_CLEAR_WAKE_IF_GT_ONE): Define.
+       (__pthread_cond_signal): Use FUTEX_WAKE_OP.
+
 2005-09-05  Kaz Kojima  <kkojima@rr.iij4u.or.jp>
 
        * sysdeps/unix/sysv/linux/sh/lowlevellock.S (__lll_mutex_lock_wait):
index f562348..5a9bbca 100644 (file)
@@ -43,6 +43,11 @@ __pthread_cond_signal (cond)
       ++cond->__data.__futex;
 
       /* Wake one.  */
+      if (! __builtin_expect (lll_futex_wake_unlock (&cond->__data.__futex, 1,
+                                                    1, &cond->__data.__lock),
+                                                    0))
+       return 0;
+
       lll_futex_wake (&cond->__data.__futex, 1);
     }
 
index 3c5a1db..d0f931f 100644 (file)
@@ -1,4 +1,4 @@
-/* Copyright (C) 2002, 2003, 2004 Free Software Foundation, Inc.
+/* Copyright (C) 2002, 2003, 2004, 2005 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
    Contributed by Ulrich Drepper <drepper@redhat.com>, 2002.
 
@@ -31,7 +31,9 @@
 #define SYS_futex              240
 #define FUTEX_WAIT             0
 #define FUTEX_WAKE             1
-#define FUTEX_REQUEUE          3
+#define FUTEX_WAKE_OP          5
+
+#define FUTEX_OP_CLEAR_WAKE_IF_GT_ONE  ((4 << 24) | 1)
 
 #define EINVAL                 22
 
@@ -79,21 +81,46 @@ __pthread_cond_signal:
        addl    $1, (%ebx)
 
        /* Wake up one thread.  */
-       movl    $FUTEX_WAKE, %ecx
+       pushl   %esi
+       pushl   %ebp
+       movl    $FUTEX_WAKE_OP, %ecx
        movl    $SYS_futex, %eax
        movl    $1, %edx
+       movl    $1, %esi
+       movl    $FUTEX_OP_CLEAR_WAKE_IF_GT_ONE, %ebp
+       /* FIXME: Until Ingo fixes 4G/4G vDSO, 6 arg syscalls are broken for
+          sysenter.
+       ENTER_KERNEL  */
+       int     $0x80
+       popl    %ebp
+       popl    %esi
+
+       /* For any kind of error, we try again with WAKE.
+          The general test also covers running on old kernels.  */
+       cmpl    $-4095, %eax
+       jae     7f
+
+6:     xorl    %eax, %eax
+       popl    %edi
+       popl    %ebx
+       ret
+
+7:     movl    $FUTEX_WAKE, %ecx
+       movl    $SYS_futex, %eax
+       /* %edx should be 1 already from $FUTEX_WAKE_OP syscall.
+       movl    $1, %edx  */
        ENTER_KERNEL
 
        /* Unlock.  Note that at this point %edi always points to
           cond_lock.  */
 4:     LOCK
        subl    $1, (%edi)
-       jne     5f
+       je      6b
 
-6:     xorl    %eax, %eax
-       popl    %edi
-       popl    %ebx
-       ret
+       /* Unlock in loop requires wakeup.  */
+5:     movl    %edi, %eax
+       call    __lll_mutex_unlock_wake
+       jmp     6b
 
        /* Initial locking failed.  */
 1:
@@ -105,10 +132,6 @@ __pthread_cond_signal:
        call    __lll_mutex_lock_wait
        jmp     2b
 
-       /* Unlock in loop requires wakeup.  */
-5:     movl    %edi, %eax
-       call    __lll_mutex_unlock_wake
-       jmp     6b
        .size   __pthread_cond_signal, .-__pthread_cond_signal
 versioned_symbol (libpthread, __pthread_cond_signal, pthread_cond_signal,
                  GLIBC_2_3_2)
index de9e109..3dbb9e8 100644 (file)
@@ -31,7 +31,9 @@
 #define SYS_futex              202
 #define FUTEX_WAIT             0
 #define FUTEX_WAKE             1
-#define FUTEX_REQUEUE          3
+#define FUTEX_WAKE_OP          5
+
+#define FUTEX_OP_CLEAR_WAKE_IF_GT_ONE  ((4 << 24) | 1)
 
 #define EINVAL                 22
 
@@ -66,9 +68,30 @@ __pthread_cond_signal:
        addl    $1, (%rdi)
 
        /* Wake up one thread.  */
-       movl    $FUTEX_WAKE, %esi
+       movl    $FUTEX_WAKE_OP, %esi
        movl    $SYS_futex, %eax
        movl    $1, %edx
+       movl    $1, %r10d
+#if cond_lock != 0
+       addq    $cond_lock, %r8
+#endif
+       movl    $FUTEX_OP_CLEAR_WAKE_IF_GT_ONE, %r9d
+       syscall
+#if cond_lock != 0
+       subq    $cond_lock, %r8
+#endif
+       /* For any kind of error, we try again with WAKE.
+          The general test also covers running on old kernels.  */
+       cmpq    $-4095, %rax
+       jae     7f
+
+       xorl    %eax, %eax
+       retq
+
+7:     movl    $FUTEX_WAKE, %esi
+       movl    $SYS_futex, %eax
+       /* %rdx should be 1 already from $FUTEX_WAKE_OP syscall.
+       movl    $1, %edx  */
        syscall
 
        /* Unlock.  */