OSDN Git Service

mass sync with glibc nptl
[uclinux-h8/uClibc.git] / libpthread / nptl / sysdeps / unix / sysv / linux / i386 / i486 / sem_post.S
index a0dc39c..b077a20 100644 (file)
@@ -1,4 +1,4 @@
-/* Copyright (C) 2002, 2003, 2005 Free Software Foundation, Inc.
+/* Copyright (C) 2002, 2003, 2005, 2007, 2008 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
    Contributed by Ulrich Drepper <drepper@redhat.com>, 2002.
 
 
 #include <sysdep.h>
 #include <pthread-errnos.h>
-#include <tls.h>
-
-#ifndef UP
-# define LOCK lock
-#else
-# define
-#endif
-
-#define FUTEX_WAKE             1
+#include <structsem.h>
+#include <lowlevellock.h>
 
 
        .text
        .type   __new_sem_post,@function
        .align  16
 __new_sem_post:
+       cfi_startproc
        pushl   %ebx
+       cfi_adjust_cfa_offset(4)
+       cfi_offset(%ebx, -8)
 
        movl    8(%esp), %ebx
-       movl    $1, %edx
+
+#if VALUE == 0
+       movl    (%ebx), %eax
+#else
+       movl    VALUE(%ebx), %eax
+#endif
+0:     cmpl    $SEM_VALUE_MAX, %eax
+       je      3f
+       leal    1(%eax), %edx
        LOCK
-       xaddl   %edx, (%ebx)
+#if VALUE == 0
+       cmpxchgl %edx, (%ebx)
+#else
+       cmpxchgl %edx, VALUE(%ebx)
+#endif
+       jnz     0b
+
+       cmpl    $0, NWAITERS(%ebx)
+       je      2f
 
-       movl    $SYS_futex, %eax
        movl    $FUTEX_WAKE, %ecx
-       addl    $1, %edx
+       orl     PRIVATE(%ebx), %ecx
+       movl    $1, %edx
+       movl    $SYS_futex, %eax
        ENTER_KERNEL
 
        testl   %eax, %eax
        js      1f
 
-       xorl    %eax, %eax
+2:     xorl    %eax, %eax
        popl    %ebx
+       cfi_adjust_cfa_offset(-4)
+       cfi_restore(%ebx)
        ret
 
+       cfi_adjust_cfa_offset(4)
+       cfi_offset(%ebx, -8)
 1:
 #ifdef __PIC__
        call    __x86.get_pc_thunk.bx
@@ -80,6 +97,35 @@ __new_sem_post:
        orl     $-1, %eax
        popl    %ebx
        ret
+
+3:
+#ifdef __PIC__
+       call    __x86.get_pc_thunk.bx
+#else
+       movl    $5f, %ebx
+5:
+#endif
+       addl    $_GLOBAL_OFFSET_TABLE_, %ebx
+#if USE___THREAD
+# ifdef NO_TLS_DIRECT_SEG_REFS
+       movl    errno@gotntpoff(%ebx), %edx
+       addl    %gs:0, %edx
+       movl    $EOVERFLOW, (%edx)
+# else
+       movl    errno@gotntpoff(%ebx), %edx
+       movl    $EOVERFLOW, %gs:(%edx)
+# endif
+#else
+       call    __errno_location@plt
+       movl    $EOVERFLOW, (%eax)
+#endif
+
+       orl     $-1, %eax
+       popl    %ebx
+       cfi_adjust_cfa_offset(-4)
+       cfi_restore(%ebx)
+       ret
+       cfi_endproc
        .size   __new_sem_post,.-__new_sem_post
 weak_alias(__new_sem_post, sem_post)