fdwalk should return 0 on an empty directory
[kopensolaris-gnu/glibc.git] / nptl / sysdeps / unix / sysv / linux / i386 / i486 / pthread_barrier_wait.S
index 08c6e91..77d252d 100644 (file)
@@ -1,4 +1,4 @@
-/* Copyright (C) 2002, 2003 Free Software Foundation, Inc.
+/* Copyright (C) 2002, 2003, 2004, 2007 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
    Contributed by Ulrich Drepper <drepper@redhat.com>, 2002.
 
    02111-1307 USA.  */
 
 #include <sysdep.h>
+#include <lowlevellock.h>
 #include <lowlevelbarrier.h>
 
-#define SYS_futex      240
-#define FUTEX_WAIT     0
-#define FUTEX_WAKE     1
-
-#ifndef UP
-# define LOCK lock
-#else
-# define LOCK
-#endif
-
-
        .text
 
        .globl  pthread_barrier_wait
@@ -46,8 +36,7 @@ pthread_barrier_wait:
        xorl    %eax, %eax
        LOCK
        cmpxchgl %edx, MUTEX(%ebx)
-       testl   %eax, %eax
-       jne     1f
+       jnz     1f
 
        /* One less waiter.  If this was the last one needed wake
           everybody.  */
@@ -70,7 +59,13 @@ pthread_barrier_wait:
 
        /* Wait for the remaining threads.  The call will return immediately
           if the CURR_EVENT memory has meanwhile been changed.  */
-7:     xorl    %ecx, %ecx              /* movl $FUTEX_WAIT, %ecx */
+7:
+#if FUTEX_WAIT == 0
+       movl    PRIVATE(%ebx), %ecx
+#else
+       movl    $FUTEX_WAIT, %ecx
+       orl     PRIVATE(%ebx), %ecx
+#endif
        xorl    %esi, %esi
 8:     movl    $SYS_futex, %eax
        ENTER_KERNEL
@@ -83,18 +78,34 @@ pthread_barrier_wait:
 #else
        cmpl    %edx, CURR_EVENT(%ebx)
 #endif
-       je,pn   8b
+       je      8b
+
+       /* Increment LEFT.  If this brings the count back to the
+          initial count unlock the object.  */
+       movl    $1, %edx
+       movl    INIT_COUNT(%ebx), %ecx
+       LOCK
+       xaddl   %edx, LEFT(%ebx)
+       subl    $1, %ecx
+       cmpl    %ecx, %edx
+       jne     10f
+
+       /* Release the mutex.  We cannot release the lock before
+          waking the waiting threads since otherwise a new thread might
+          arrive and gets waken up, too.  */
+       LOCK
+       subl    $1, MUTEX(%ebx)
+       jne     9f
 
        /* Note: %esi is still zero.  */
-       movl    %esi, %eax              /* != PTHREAD_BARRIER_SERIAL_THREAD */
+10:    movl    %esi, %eax              /* != PTHREAD_BARRIER_SERIAL_THREAD */
 
        popl    %esi
        popl    %ebx
        ret
 
        /* The necessary number of threads arrived.  */
-3:     movl    INIT_COUNT(%ebx), %eax
-       movl    %eax, LEFT(%ebx)
+3:
 #if CURR_EVENT == 0
        addl    $1, (%ebx)
 #else
@@ -105,9 +116,20 @@ pthread_barrier_wait:
           so 0x7fffffff is the highest value.  */
        movl    $0x7fffffff, %edx
        movl    $FUTEX_WAKE, %ecx
+       orl     PRIVATE(%ebx), %ecx
        movl    $SYS_futex, %eax
        ENTER_KERNEL
 
+       /* Increment LEFT.  If this brings the count back to the
+          initial count unlock the object.  */
+       movl    $1, %edx
+       movl    INIT_COUNT(%ebx), %ecx
+       LOCK
+       xaddl   %edx, LEFT(%ebx)
+       subl    $1, %ecx
+       cmpl    %ecx, %edx
+       jne     5f
+
        /* Release the mutex.  We cannot release the lock before
           waking the waiting threads since otherwise a new thread might
           arrive and gets waken up, too.  */
@@ -120,15 +142,27 @@ pthread_barrier_wait:
        popl    %ebx
        ret
 
-1:     leal    MUTEX(%ebx), %ecx
-       call    __lll_mutex_lock_wait
+1:     movl    PRIVATE(%ebx), %ecx
+       leal    MUTEX(%ebx), %edx
+       xorl    $LLL_SHARED, %ecx
+       call    __lll_lock_wait
        jmp     2b
 
-4:     leal    MUTEX(%ebx), %eax
-       call    __lll_mutex_unlock_wake
+4:     movl    PRIVATE(%ebx), %ecx
+       leal    MUTEX(%ebx), %eax
+       xorl    $LLL_SHARED, %ecx
+       call    __lll_unlock_wake
        jmp     5b
 
-6:     leal    MUTEX(%ebx), %eax
-       call    __lll_mutex_unlock_wake
+6:     movl    PRIVATE(%ebx), %ecx
+       leal    MUTEX(%ebx), %eax
+       xorl    $LLL_SHARED, %ecx
+       call    __lll_unlock_wake
        jmp     7b
+
+9:     movl    PRIVATE(%ebx), %ecx
+       leal    MUTEX(%ebx), %eax
+       xorl    $LLL_SHARED, %ecx
+       call    __lll_unlock_wake
+       jmp     10b
        .size   pthread_barrier_wait,.-pthread_barrier_wait