* semaphoreP.h: Declare __old_sem_init and __old_sem_wait.
authorUlrich Drepper <drepper@redhat.com>
Sat, 26 May 2007 01:31:40 +0000 (01:31 +0000)
committerUlrich Drepper <drepper@redhat.com>
Sat, 26 May 2007 01:31:40 +0000 (01:31 +0000)
* sem_init.c (__new_sem_init): Rewrite to initialize all three
fields in the structure.
(__old_sem_init): New function.
* sem_open.c: Initialize all fields of the structure.
* sem_getvalue.c: Adjust for renamed element.
* sysdeps/unix/sysv/linux/Makefile [subdir=nptl]
(gen-as-const-headers): Add structsem.sym.
* sysdeps/unix/sysv/linux/structsem.sym: New file.
* sysdeps/unix/sysv/linux/internaltypes.h: Rename struct sem to
struct new_sem.  Add struct old_sem.
* sysdeps/unix/sysv/linux/sem_post.c: Wake only when there are waiters.
* sysdeps/unix/sysv/linux/i386/i486/sem_post.S: Likewise.
* sysdeps/unix/sysv/linux/x86_64/sem_post.S: Likewise.
* sysdeps/unix/sysv/linux/sem_wait.c: Indicate that there are waiters.
* sysdeps/unix/sysv/linux/i386/i486/sem_wait.S: Likewise.
* sysdeps/unix/sysv/linux/x86_64/sem_wait.S: Likewise.
* sysdeps/unix/sysv/linux/sem_timedwait.c: Likewise.
* sysdeps/unix/sysv/linux/i386/i486/sem_timedwait.S: Likewise.
* sysdeps/unix/sysv/linux/x86_64/sem_timedwait.S: Likewise.
* Makefile (tests): Add tst-sem10, tst-sem11, tst-sem12.
* tst-sem10.c: New file.
* tst-sem11.c: New file.
* tst-sem12.c: New file.
* tst-typesizes.c: Test struct new_sem and struct old_sem instead
of struct sem.

2007-05-25  Ulrich Drepper  <drepper@redhat.com>

19 files changed:
nptl/ChangeLog
nptl/Makefile
nptl/sem_getvalue.c
nptl/sem_init.c
nptl/sem_open.c
nptl/semaphoreP.h
nptl/sysdeps/unix/sysv/linux/Makefile
nptl/sysdeps/unix/sysv/linux/i386/i486/sem_post.S
nptl/sysdeps/unix/sysv/linux/i386/i486/sem_timedwait.S
nptl/sysdeps/unix/sysv/linux/i386/i486/sem_wait.S
nptl/sysdeps/unix/sysv/linux/internaltypes.h
nptl/sysdeps/unix/sysv/linux/sem_post.c
nptl/sysdeps/unix/sysv/linux/sem_timedwait.c
nptl/sysdeps/unix/sysv/linux/sem_wait.c
nptl/sysdeps/unix/sysv/linux/structsem.sym [new file with mode: 0644]
nptl/sysdeps/unix/sysv/linux/x86_64/sem_post.S
nptl/sysdeps/unix/sysv/linux/x86_64/sem_timedwait.S
nptl/sysdeps/unix/sysv/linux/x86_64/sem_wait.S
nptl/tst-typesizes.c

index 923364c..4778511 100644 (file)
@@ -1,4 +1,33 @@
 2007-05-25  Ulrich Drepper  <drepper@redhat.com>
+
+       * semaphoreP.h: Declare __old_sem_init and __old_sem_wait.
+       * sem_init.c (__new_sem_init): Rewrite to initialize all three
+       fields in the structure.
+       (__old_sem_init): New function.
+       * sem_open.c: Initialize all fields of the structure.
+       * sem_getvalue.c: Adjust for renamed element.
+       * sysdeps/unix/sysv/linux/Makefile [subdir=nptl]
+       (gen-as-const-headers): Add structsem.sym.
+       * sysdeps/unix/sysv/linux/structsem.sym: New file.
+       * sysdeps/unix/sysv/linux/internaltypes.h: Rename struct sem to
+       struct new_sem.  Add struct old_sem.
+       * sysdeps/unix/sysv/linux/sem_post.c: Wake only when there are waiters.
+       * sysdeps/unix/sysv/linux/i386/i486/sem_post.S: Likewise.
+       * sysdeps/unix/sysv/linux/x86_64/sem_post.S: Likewise.
+       * sysdeps/unix/sysv/linux/sem_wait.c: Indicate that there are waiters.
+       * sysdeps/unix/sysv/linux/i386/i486/sem_wait.S: Likewise.
+       * sysdeps/unix/sysv/linux/x86_64/sem_wait.S: Likewise.
+       * sysdeps/unix/sysv/linux/sem_timedwait.c: Likewise.
+       * sysdeps/unix/sysv/linux/i386/i486/sem_timedwait.S: Likewise.
+       * sysdeps/unix/sysv/linux/x86_64/sem_timedwait.S: Likewise.
+       * Makefile (tests): Add tst-sem10, tst-sem11, tst-sem12.
+       * tst-sem10.c: New file.
+       * tst-sem11.c: New file.
+       * tst-sem12.c: New file.
+       * tst-typesizes.c: Test struct new_sem and struct old_sem instead
+       of struct sem.
+
+2007-05-25  Ulrich Drepper  <drepper@redhat.com>
            Jakub Jelinek  <jakub@redhat.com>
 
        * sysdeps/unix/sysv/linux/i386/i486/sem_timedwait.S (sem_timedwait):
index 42f2fe6..a9eac89 100644 (file)
@@ -218,7 +218,7 @@ tests = tst-typesizes \
        tst-once1 tst-once2 tst-once3 tst-once4 \
        tst-key1 tst-key2 tst-key3 tst-key4 \
        tst-sem1 tst-sem2 tst-sem3 tst-sem4 tst-sem5 tst-sem6 tst-sem7 \
-       tst-sem8 tst-sem9 \
+       tst-sem8 tst-sem9 tst-sem10 tst-sem11 tst-sem12 \
        tst-barrier1 tst-barrier2 tst-barrier3 tst-barrier4 \
        tst-align tst-align2 tst-align3 \
        tst-basic1 tst-basic2 tst-basic3 tst-basic4 tst-basic5 tst-basic6 \
index 6bc7ea8..3b17e59 100644 (file)
@@ -1,4 +1,4 @@
-/* Copyright (C) 2002 Free Software Foundation, Inc.
+/* Copyright (C) 2002, 2007 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
    Contributed by Ulrich Drepper <drepper@redhat.com>, 2002.
 
@@ -27,11 +27,11 @@ __new_sem_getvalue (sem, sval)
      sem_t *sem;
      int *sval;
 {
-  struct sem *isem = (struct sem *) sem;
+  struct new_sem *isem = (struct new_sem *) sem;
 
   /* XXX Check for valid SEM parameter.  */
 
-  *sval = isem->count;
+  *sval = isem->value;
 
   return 0;
 }
index 8709911..e29d900 100644 (file)
@@ -1,4 +1,4 @@
-/* Copyright (C) 2002 Free Software Foundation, Inc.
+/* Copyright (C) 2002, 2007 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
    Contributed by Ulrich Drepper <drepper@redhat.com>, 2002.
 
@@ -22,6 +22,7 @@
 #include <lowlevellock.h>
 #include <shlib-compat.h>
 #include "semaphoreP.h"
+#include <kernel-features.h>
 
 
 int
@@ -38,18 +39,50 @@ __new_sem_init (sem, pshared, value)
     }
 
   /* Map to the internal type.  */
-  struct sem *isem = (struct sem *) sem;
+  struct new_sem *isem = (struct new_sem *) sem;
 
-  /* Use the value the user provided.  */
-  isem->count = value;
+  /* Use the values the user provided.  */
+  isem->value = value;
+#ifdef __ASSUME_PRIVATE_FUTEX
+  isem->private = pshared ? 0 : FUTEX_PRIVATE_FLAG;
+#else
+  isem->private = pshared ? 0 : THREAD_GETMEM (THREAD_SELF,
+                                              header.private_futex);
+#endif
 
-  /* We can completely ignore the PSHARED parameter since inter-process
-     use needs no special preparation.  */
+  isem->nwaiters = 0;
 
   return 0;
 }
 versioned_symbol (libpthread, __new_sem_init, sem_init, GLIBC_2_1);
+
+
+
 #if SHLIB_COMPAT(libpthread, GLIBC_2_0, GLIBC_2_1)
-strong_alias (__new_sem_init, __old_sem_init)
+int
+attribute_compat_text_section
+__old_sem_init (sem, pshared, value)
+     sem_t *sem;
+     int pshared;
+     unsigned int value;
+{
+  /* Parameter sanity check.  */
+  if (__builtin_expect (value > SEM_VALUE_MAX, 0))
+    {
+      __set_errno (EINVAL);
+      return -1;
+    }
+
+  /* Map to the internal type.  */
+  struct old_sem *isem = (struct old_sem *) sem;
+
+  /* Use the value the user provided.  */
+  isem->value = value;
+
+  /* We cannot store the PSHARED attribute.  So we always use the
+     operations needed for shared semaphores.  */
+
+  return 0;
+}
 compat_symbol (libpthread, __old_sem_init, sem_init, GLIBC_2_0);
 #endif
index 66bcb13..27d308e 100644 (file)
@@ -1,4 +1,4 @@
-/* Copyright (C) 2002, 2003, 2006 Free Software Foundation, Inc.
+/* Copyright (C) 2002, 2003, 2006, 2007 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
    Contributed by Ulrich Drepper <drepper@redhat.com>, 2002.
 
@@ -304,12 +304,14 @@ sem_open (const char *name, int oflag, ...)
       /* Create the initial file content.  */
       sem_t initsem;
 
-      struct sem *iinitsem = (struct sem *) &initsem;
-      iinitsem->count = value;
+      struct new_sem *iinitsem = (struct new_sem *) &initsem;
+      iinitsem->value = value;
+      iinitsem->private = 0;
+      iinitsem->nwaiters = 0;
 
       /* Initialize the remaining bytes as well.  */
-      memset ((char *) &initsem + sizeof (struct sem), '\0',
-             sizeof (sem_t) - sizeof (struct sem));
+      memset ((char *) &initsem + sizeof (struct new_sem), '\0',
+             sizeof (sem_t) - sizeof (struct new_sem));
 
       tmpfname = (char *) alloca (mountpoint.dirlen + 6 + 1);
       char *xxxxxx = __mempcpy (tmpfname, mountpoint.dir, mountpoint.dirlen);
index 754609a..9659059 100644 (file)
@@ -1,4 +1,4 @@
-/* Copyright (C) 2002, 2003, 2006 Free Software Foundation, Inc.
+/* Copyright (C) 2002, 2003, 2006, 2007 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
    Contributed by Ulrich Drepper <drepper@redhat.com>, 2002.
 
@@ -60,8 +60,10 @@ extern int __sem_search (const void *a, const void *b) attribute_hidden;
 
 /* Prototypes of functions with multiple interfaces.  */
 extern int __new_sem_init (sem_t *sem, int pshared, unsigned int value);
+extern int __old_sem_init (sem_t *sem, int pshared, unsigned int value);
 extern int __new_sem_destroy (sem_t *sem);
 extern int __new_sem_post (sem_t *sem);
 extern int __new_sem_wait (sem_t *sem);
+extern int __old_sem_wait (sem_t *sem);
 extern int __new_sem_trywait (sem_t *sem);
 extern int __new_sem_getvalue (sem_t *sem, int *sval);
index cfcdb6d..ad5ae6a 100644 (file)
@@ -1,4 +1,4 @@
-# Copyright (C) 2002, 2003, 2004, 2005, 2006 Free Software Foundation, Inc.
+# Copyright (C) 2002,2003,2004,2005,2006,2007 Free Software Foundation, Inc.
 # This file is part of the GNU C Library.
 # Contributed by Ulrich Drepper <drepper@redhat.com>, 2002.
 
@@ -25,7 +25,8 @@ libpthread-sysdep_routines += pt-fork pthread_mutex_cond_lock
 
 gen-as-const-headers += lowlevelcond.sym lowlevelrwlock.sym \
                        lowlevelbarrier.sym unwindbuf.sym \
-                       lowlevelrobustlock.sym pthread-pi-defines.sym
+                       lowlevelrobustlock.sym pthread-pi-defines.sym \
+                       structsem.sym
 endif
 
 ifeq ($(subdir),posix)
index 71e96d2..e66db14 100644 (file)
@@ -1,4 +1,4 @@
-/* Copyright (C) 2002, 2003, 2005 Free Software Foundation, Inc.
+/* Copyright (C) 2002, 2003, 2005, 2007 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
    Contributed by Ulrich Drepper <drepper@redhat.com>, 2002.
 
@@ -20,6 +20,7 @@
 #include <sysdep.h>
 #include <shlib-compat.h>
 #include <pthread-errnos.h>
+#include <structsem.h>
 
 #ifndef UP
 # define LOCK lock
@@ -40,19 +41,26 @@ __new_sem_post:
        pushl   %ebx
 
        movl    8(%esp), %ebx
-       movl    $1, %edx
+
        LOCK
-       xaddl   %edx, (%ebx)
+#if VALUE == 0
+       addl    $1, (%ebx)
+#else
+       addl    $1, VALUE(%ebx)
+#endif
+
+       cmpl    $0, NWAITERS(%ebx)
+       je      2f
 
        movl    $SYS_futex, %eax
        movl    $FUTEX_WAKE, %ecx
-       addl    $1, %edx
+       movl    $1, %edx
        ENTER_KERNEL
 
        testl   %eax, %eax
        js      1f
 
-       xorl    %eax, %eax
+2:     xorl    %eax, %eax
        popl    %ebx
        ret
 
index bf70e17..3677ab3 100644 (file)
@@ -20,6 +20,7 @@
 #include <sysdep.h>
 #include <shlib-compat.h>
 #include <pthread-errnos.h>
+#include <structsem.h>
 
 #ifndef UP
 # define LOCK lock
 #define FUTEX_WAKE             1
 
 
+#if VALUE != 0
+# error "code needs to be rewritten for VALUE != 0"
+#endif
+
+
        .text
 
        .globl  sem_timedwait
        .type   sem_timedwait,@function
        .align  16
-       cfi_startproc
 sem_timedwait:
-       /* First check for cancellation.  */
-       movl    %gs:CANCELHANDLING, %eax
-       andl    $0xfffffff9, %eax
-       cmpl    $8, %eax
-       je      10f
-
+.LSTARTCODE:
        movl    4(%esp), %ecx
 
        movl    (%ecx), %eax
@@ -61,24 +61,24 @@ sem_timedwait:
 
        /* Check whether the timeout value is valid.  */
 1:     pushl   %esi
-       cfi_adjust_cfa_offset(4)
+.Lpush_esi:
        pushl   %edi
-       cfi_adjust_cfa_offset(4)
+.Lpush_edi:
        pushl   %ebx
-       cfi_adjust_cfa_offset(4)
+.Lpush_ebx:
        subl    $12, %esp
-       cfi_adjust_cfa_offset(12)
+.Lsub_esp:
 
        movl    32(%esp), %edi
-       cfi_offset(7, -12)              /* %edi */
 
        /* Check for invalid nanosecond field.  */
        cmpl    $1000000000, 4(%edi)
        movl    $EINVAL, %esi
-       cfi_offset(6, -8)               /* %esi */
        jae     6f
 
-       cfi_offset(3, -16)              /* %ebx */
+       LOCK
+       incl    NWAITERS(%ecx)
+
 7:     xorl    %ecx, %ecx
        movl    %esp, %ebx
        movl    %ecx, %edx
@@ -103,10 +103,11 @@ sem_timedwait:
        movl    %ecx, (%esp)    /* Store relative timeout.  */
        movl    %edx, 4(%esp)
 
+.LcleanupSTART:
        call    __pthread_enable_asynccancel
        movl    %eax, 8(%esp)
 
-       movl    28(%esp), %ebx
+       movl    28(%esp), %ebx  /* Load semaphore address.  */
        xorl    %ecx, %ecx
        movl    %esp, %esi
        movl    $SYS_futex, %eax
@@ -116,6 +117,7 @@ sem_timedwait:
 
        movl    8(%esp), %eax
        call    __pthread_disable_asynccancel
+.LcleanupEND:
 
        testl   %esi, %esi
        je      9f
@@ -131,24 +133,22 @@ sem_timedwait:
        cmpxchgl %ecx, (%ebx)
        jne     8b
 
-       addl    $12, %esp
-       cfi_adjust_cfa_offset(-12)
        xorl    %eax, %eax
+
+10:    LOCK
+       decl    NWAITERS(%ebx)
+
+       addl    $12, %esp
+.Ladd_esp:
        popl    %ebx
-       cfi_adjust_cfa_offset(-4)
-       cfi_restore(3)
+.Lpop_ebx:
        popl    %edi
-       cfi_adjust_cfa_offset(-4)
-       cfi_restore(7)
+.Lpop_edi:
        popl    %esi
-       cfi_adjust_cfa_offset(-4)
-       cfi_restore(6)
+.Lpop_esi:
        ret
 
-       cfi_adjust_cfa_offset(24)
-       cfi_offset(6, -8)               /* %esi */
-       cfi_offset(7, -12)              /* %edi */
-       cfi_offset(3, -16)              /* %ebx */
+.Lafter_ret:
 3:     negl    %esi
 6:
 #ifdef PIC
@@ -172,25 +172,163 @@ sem_timedwait:
        movl    %esi, (%eax)
 #endif
 
-       addl    $12, %esp
-       cfi_adjust_cfa_offset(-12)
+       movl    28(%esp), %ebx  /* Load semaphore address.  */
        orl     $-1, %eax
-       popl    %ebx
-       cfi_adjust_cfa_offset(-4)
-       cfi_restore(3)
-       popl    %edi
-       cfi_adjust_cfa_offset(-4)
-       cfi_restore(7)
-       popl    %esi
-       cfi_adjust_cfa_offset(-4)
-       cfi_restore(6)
-       ret
+       jmp     10b
+       .size   sem_timedwait,.-sem_timedwait
 
-10:    /* Canceled.  */
-       movl    $0xffffffff, %gs:RESULT
+
+       .type   sem_wait_cleanup,@function
+sem_wait_cleanup:
        LOCK
-       orl     $0x10, %gs:CANCELHANDLING
-       movl    %gs:CLEANUP_JMP_BUF, %eax
-       jmp     HIDDEN_JUMPTARGET (__pthread_unwind)
-       cfi_endproc
-       .size   sem_timedwait,.-sem_timedwait
+       decl    NWAITERS(%ebx)
+       movl    %eax, (%esp)
+.LcallUR:
+       call    _Unwind_Resume@PLT
+       hlt
+.LENDCODE:
+       .size   sem_wait_cleanup,.-sem_wait_cleanup
+
+
+       .section .gcc_except_table,"a",@progbits
+.LexceptSTART:
+       .byte   0xff                            # @LPStart format (omit)
+       .byte   0xff                            # @TType format (omit)
+       .byte   0x01                            # call-site format
+                                               # DW_EH_PE_uleb128
+       .uleb128 .Lcstend-.Lcstbegin
+.Lcstbegin:
+       .uleb128 .LcleanupSTART-.LSTARTCODE
+       .uleb128 .LcleanupEND-.LcleanupSTART
+       .uleb128 sem_wait_cleanup-.LSTARTCODE
+       .uleb128  0
+       .uleb128 .LcallUR-.LSTARTCODE
+       .uleb128 .LENDCODE-.LcallUR
+       .uleb128 0
+       .uleb128  0
+.Lcstend:
+
+
+       .section .eh_frame,"a",@progbits
+.LSTARTFRAME:
+       .long   .LENDCIE-.LSTARTCIE             # Length of the CIE.
+.LSTARTCIE:
+       .long   0                               # CIE ID.
+       .byte   1                               # Version number.
+#ifdef SHARED
+       .string "zPLR"                          # NUL-terminated augmentation
+                                               # string.
+#else
+       .string "zPL"                           # NUL-terminated augmentation
+                                               # string.
+#endif
+       .uleb128 1                              # Code alignment factor.
+       .sleb128 -4                             # Data alignment factor.
+       .byte   8                               # Return address register
+                                               # column.
+#ifdef SHARED
+       .uleb128 7                              # Augmentation value length.
+       .byte   0x9b                            # Personality: DW_EH_PE_pcrel
+                                               # + DW_EH_PE_sdata4
+                                               # + DW_EH_PE_indirect
+       .long   DW.ref.__gcc_personality_v0-.
+       .byte   0x1b                            # LSDA Encoding: DW_EH_PE_pcrel
+                                               # + DW_EH_PE_sdata4.
+       .byte   0x1b                            # FDE Encoding: DW_EH_PE_pcrel
+                                               # + DW_EH_PE_sdata4.
+#else
+       .uleb128 6                              # Augmentation value length.
+       .byte   0x0                             # Personality: absolute
+       .long   __gcc_personality_v0
+       .byte   0x0                             # LSDA Encoding: absolute
+#endif
+       .byte 0x0c                              # DW_CFA_def_cfa
+       .uleb128 4
+       .uleb128 4
+       .byte   0x88                            # DW_CFA_offset, column 0x10
+       .uleb128 1
+       .align 4
+.LENDCIE:
+
+       .long   .LENDFDE-.LSTARTFDE             # Length of the FDE.
+.LSTARTFDE:
+       .long   .LSTARTFDE-.LSTARTFRAME         # CIE pointer.
+#ifdef SHARED
+       .long   .LSTARTCODE-.                   # PC-relative start address
+                                               # of the code.
+#else
+       .long   .LSTARTCODE                     # Start address of the code.
+#endif
+       .long   .LENDCODE-.LSTARTCODE           # Length of the code.
+       .uleb128 4                              # Augmentation size
+#ifdef SHARED
+       .long   .LexceptSTART-.
+#else
+       .long   .LexceptSTART
+#endif
+
+       .byte   4                               # DW_CFA_advance_loc4
+       .long   .Lpush_esi-.LSTARTCODE
+       .byte   14                              # DW_CFA_def_cfa_offset
+       .uleb128 8
+       .byte   0x86                            # DW_CFA_offset %esi
+        .uleb128 2
+       .byte   4                               # DW_CFA_advance_loc4
+       .long   .Lpush_edi-.Lpush_esi
+       .byte   14                              # DW_CFA_def_cfa_offset
+       .uleb128 12
+       .byte   0x87                            # DW_CFA_offset %edi
+        .uleb128 3
+       .byte   4                               # DW_CFA_advance_loc4
+       .long   .Lpush_ebx-.Lpush_edi
+       .byte   14                              # DW_CFA_def_cfa_offset
+       .uleb128 16
+       .byte   0x83                            # DW_CFA_offset %ebx
+        .uleb128 4
+       .byte   4                               # DW_CFA_advance_loc4
+       .long   .Lsub_esp-.Lpush_ebx
+       .byte   14                              # DW_CFA_def_cfa_offset
+       .uleb128 28
+       .byte   4                               # DW_CFA_advance_loc4
+       .long   .Ladd_esp-.Lsub_esp
+       .byte   14                              # DW_CFA_def_cfa_offset
+       .uleb128 16
+       .byte   4                               # DW_CFA_advance_loc4
+       .long   .Lpop_ebx-.Ladd_esp
+       .byte   14                              # DW_CFA_def_cfa_offset
+       .uleb128 12
+       .byte   0xc3                            # DW_CFA_restore %ebx
+       .byte   4                               # DW_CFA_advance_loc4
+       .long   .Lpop_edi-.Lpop_ebx
+       .byte   14                              # DW_CFA_def_cfa_offset
+       .uleb128 8
+       .byte   0xc7                            # DW_CFA_restore %edi
+       .byte   4                               # DW_CFA_advance_loc4
+       .long   .Lpop_esi-.Lpop_edi
+       .byte   14                              # DW_CFA_def_cfa_offset
+       .uleb128 4
+       .byte   0xc6                            # DW_CFA_restore %esi
+       .byte   4                               # DW_CFA_advance_loc4
+       .long   .Lafter_ret-.Lpop_esi
+       .byte   14                              # DW_CFA_def_cfa_offset
+       .uleb128 28
+       .byte   0x86                            # DW_CFA_offset %esi
+        .uleb128 2
+       .byte   0x87                            # DW_CFA_offset %edi
+        .uleb128 3
+       .byte   0x83                            # DW_CFA_offset %ebx
+        .uleb128 4
+       .align  4
+.LENDFDE:
+
+
+#ifdef SHARED
+       .hidden DW.ref.__gcc_personality_v0
+       .weak   DW.ref.__gcc_personality_v0
+       .section .gnu.linkonce.d.DW.ref.__gcc_personality_v0,"aw",@progbits
+       .align  4
+       .type   DW.ref.__gcc_personality_v0, @object
+       .size   DW.ref.__gcc_personality_v0, 4
+DW.ref.__gcc_personality_v0:
+       .long   __gcc_personality_v0
+#endif
index b129627..bb4d644 100644 (file)
@@ -1,4 +1,4 @@
-/* Copyright (C) 2002, 2003, 2005 Free Software Foundation, Inc.
+/* Copyright (C) 2002, 2003, 2005, 2007 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
    Contributed by Ulrich Drepper <drepper@redhat.com>, 2002.
 
@@ -20,6 +20,7 @@
 #include <sysdep.h>
 #include <shlib-compat.h>
 #include <pthread-errnos.h>
+#include <structsem.h>
 
 #ifndef UP
 # define LOCK lock
 #define FUTEX_WAKE             1
 
 
+#if VALUE != 0
+# error "code needs to be rewritten for VALUE != 0"
+#endif
+
        .text
 
        .globl  __new_sem_wait
        .type   __new_sem_wait,@function
        .align  16
-       cfi_startproc
 __new_sem_wait:
-       /* First check for cancellation.  */
-       movl    %gs:CANCELHANDLING, %eax
-       andl    $0xfffffff9, %eax
-       cmpl    $8, %eax
-       je      5f
+.LSTARTCODE:
+       pushl   %ebx
+.Lpush_ebx:
+       pushl   %esi
+.Lpush_esi:
+       subl    $4, %esp
+.Lsub_esp:
+
+       movl    16(%esp), %ebx
+
+       movl    (%ebx), %eax
+2:     testl   %eax, %eax
+       je      1f
+
+       leal    -1(%eax), %edx
+       LOCK
+       cmpxchgl %edx, (%ebx)
+       jne     2b
+7:     xorl    %eax, %eax
+
+9:     movl    4(%esp), %esi
+       movl    8(%esp), %ebx
+       addl    $12, %esp
+.Ladd_esp:
+       ret
+
+.Lafter_ret:
+1:     LOCK
+       incl    NWAITERS(%ebx)
+
+.LcleanupSTART:
+6:     call    __pthread_enable_asynccancel
+       movl    %eax, (%esp)
+
+       xorl    %esi, %esi
+       movl    $SYS_futex, %eax
+       movl    %esi, %ecx
+       movl    %esi, %edx
+       ENTER_KERNEL
+       movl    %eax, %esi
+
+       movl    (%esp), %eax
+       call    __pthread_disable_asynccancel
+.LcleanupEND:
+
+       testl   %esi, %esi
+       je      3f
+       cmpl    $-EWOULDBLOCK, %esi
+       jne     4f
+
+3:
+       movl    (%ebx), %eax
+5:     testl   %eax, %eax
+       je      6b
+
+       leal    -1(%eax), %edx
+       LOCK
+       cmpxchgl %edx, (%ebx)
+       jne     5b
+
+       LOCK
+       decl    NWAITERS(%ebx)
+       jmp     7b
+
+4:     LOCK
+       decl    NWAITERS(%ebx)
+
+       negl    %esi
+#ifdef PIC
+       call    __i686.get_pc_thunk.bx
+#else
+       movl    $8f, %ebx
+8:
+#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    %esi, (%edx)
+# else
+       movl    errno@gotntpoff(%ebx), %edx
+       movl    %esi, %gs:(%edx)
+# endif
+#else
+       call    __errno_location@plt
+       movl    %esi, (%eax)
+#endif
+       orl     $-1, %eax
+
+       jmp     9b
+       .size   __new_sem_wait,.-__new_sem_wait
+       versioned_symbol(libpthread, __new_sem_wait, sem_wait, GLIBC_2_1)
+
+
+       .type   sem_wait_cleanup,@function
+sem_wait_cleanup:
+       LOCK
+       decl    NWAITERS(%ebx)
+       movl    %eax, (%esp)
+.LcallUR:
+       call    _Unwind_Resume@PLT
+       hlt
+.LENDCODE:
+       .size   sem_wait_cleanup,.-sem_wait_cleanup
+
+
+       .section .gcc_except_table,"a",@progbits
+.LexceptSTART:
+       .byte   0xff                            # @LPStart format (omit)
+       .byte   0xff                            # @TType format (omit)
+       .byte   0x01                            # call-site format
+                                               # DW_EH_PE_uleb128
+       .uleb128 .Lcstend-.Lcstbegin
+.Lcstbegin:
+       .uleb128 .LcleanupSTART-.LSTARTCODE
+       .uleb128 .LcleanupEND-.LcleanupSTART
+       .uleb128 sem_wait_cleanup-.LSTARTCODE
+       .uleb128  0
+       .uleb128 .LcallUR-.LSTARTCODE
+       .uleb128 .LENDCODE-.LcallUR
+       .uleb128 0
+       .uleb128  0
+.Lcstend:
+
+
+       .section .eh_frame,"a",@progbits
+.LSTARTFRAME:
+       .long   .LENDCIE-.LSTARTCIE             # Length of the CIE.
+.LSTARTCIE:
+       .long   0                               # CIE ID.
+       .byte   1                               # Version number.
+#ifdef SHARED
+       .string "zPLR"                          # NUL-terminated augmentation
+                                               # string.
+#else
+       .string "zPL"                           # NUL-terminated augmentation
+                                               # string.
+#endif
+       .uleb128 1                              # Code alignment factor.
+       .sleb128 -4                             # Data alignment factor.
+       .byte   8                               # Return address register
+                                               # column.
+#ifdef SHARED
+       .uleb128 7                              # Augmentation value length.
+       .byte   0x9b                            # Personality: DW_EH_PE_pcrel
+                                               # + DW_EH_PE_sdata4
+                                               # + DW_EH_PE_indirect
+       .long   DW.ref.__gcc_personality_v0-.
+       .byte   0x1b                            # LSDA Encoding: DW_EH_PE_pcrel
+                                               # + DW_EH_PE_sdata4.
+       .byte   0x1b                            # FDE Encoding: DW_EH_PE_pcrel
+                                               # + DW_EH_PE_sdata4.
+#else
+       .uleb128 6                              # Augmentation value length.
+       .byte   0x0                             # Personality: absolute
+       .long   __gcc_personality_v0
+       .byte   0x0                             # LSDA Encoding: absolute
+#endif
+       .byte 0x0c                              # DW_CFA_def_cfa
+       .uleb128 4
+       .uleb128 4
+       .byte   0x88                            # DW_CFA_offset, column 0x10
+       .uleb128 1
+       .align 4
+.LENDCIE:
+
+       .long   .LENDFDE-.LSTARTFDE             # Length of the FDE.
+.LSTARTFDE:
+       .long   .LSTARTFDE-.LSTARTFRAME         # CIE pointer.
+#ifdef SHARED
+       .long   .LSTARTCODE-.                   # PC-relative start address
+                                               # of the code.
+#else
+       .long   .LSTARTCODE                     # Start address of the code.
+#endif
+       .long   .LENDCODE-.LSTARTCODE           # Length of the code.
+       .uleb128 4                              # Augmentation size
+#ifdef SHARED
+       .long   .LexceptSTART-.
+#else
+       .long   .LexceptSTART
+#endif
 
+       .byte   4                               # DW_CFA_advance_loc4
+       .long   .Lpush_ebx-.LSTARTCODE
+       .byte   14                              # DW_CFA_def_cfa_offset
+       .uleb128 8
+       .byte   0x83                            # DW_CFA_offset %ebx
+        .uleb128 2
+       .byte   4                               # DW_CFA_advance_loc4
+       .long   .Lpush_esi-.Lpush_ebx
+       .byte   14                              # DW_CFA_def_cfa_offset
+       .uleb128 12
+       .byte   0x86                            # DW_CFA_offset %esi
+        .uleb128 3
+       .byte   4                               # DW_CFA_advance_loc4
+       .long   .Lsub_esp-.Lpush_esi
+       .byte   14                              # DW_CFA_def_cfa_offset
+       .uleb128 16
+       .byte   4                               # DW_CFA_advance_loc4
+       .long   .Ladd_esp-.Lsub_esp
+       .byte   14                              # DW_CFA_def_cfa_offset
+       .uleb128 4
+       .byte   0xc3                            # DW_CFA_restore %ebx
+       .byte   0xc6                            # DW_CFA_restore %esi
+       .byte   4                               # DW_CFA_advance_loc4
+       .long   .Lafter_ret-.Ladd_esp
+       .byte   14                              # DW_CFA_def_cfa_offset
+       .uleb128 16
+       .byte   0x83                            # DW_CFA_offset %ebx
+        .uleb128 2
+       .byte   0x86                            # DW_CFA_offset %esi
+        .uleb128 3
+       .align  4
+.LENDFDE:
+
+
+#ifdef SHARED
+       .hidden DW.ref.__gcc_personality_v0
+       .weak   DW.ref.__gcc_personality_v0
+       .section .gnu.linkonce.d.DW.ref.__gcc_personality_v0,"aw",@progbits
+       .align  4
+       .type   DW.ref.__gcc_personality_v0, @object
+       .size   DW.ref.__gcc_personality_v0, 4
+DW.ref.__gcc_personality_v0:
+       .long   __gcc_personality_v0
+#endif
+
+
+#if SHLIB_COMPAT(libpthread, GLIBC_2_0, GLIBC_2_1)
+       .section ".text.compat", "ax"
+       .global __old_sem_wait
+       .type   __old_sem_wait,@function
+       .align  16
+       cfi_startproc
+__old_sem_wait:
        pushl   %ebx
        cfi_adjust_cfa_offset(4)
        pushl   %esi
@@ -52,9 +287,9 @@ __new_sem_wait:
        cfi_adjust_cfa_offset(4)
 
        movl    16(%esp), %ebx
-       cfi_offset(3, -8)               /* %ebx */
+       cfi_offset(ebx, -8)
 
-       cfi_offset(6, -12)              /* %esi */
+       cfi_offset(esi, -12)
 3:     movl    (%ebx), %eax
 2:     testl   %eax, %eax
        je      1f
@@ -65,17 +300,17 @@ __new_sem_wait:
        jne     2b
        xorl    %eax, %eax
 
-       movl    4(%esp), %esi
-       cfi_restore(6)
+5:     movl    4(%esp), %esi
        movl    8(%esp), %ebx
-       cfi_restore(3)
        addl    $12, %esp
+       cfi_restore(ebx)
+       cfi_restore(esi)
        cfi_adjust_cfa_offset(-12)
        ret
 
        cfi_adjust_cfa_offset(12)
-       cfi_offset(3, -8)               /* %ebx */
-       cfi_offset(6, -12)              /* %esi */
+       cfi_offset(ebx, -8)
+       cfi_offset(esi, -12)
 1:     call    __pthread_enable_asynccancel
        movl    %eax, (%esp)
 
@@ -115,25 +350,8 @@ __new_sem_wait:
        movl    %esi, (%eax)
 #endif
        orl     $-1, %eax
-       movl    4(%esp), %esi
-       cfi_restore(6)
-       movl    8(%esp), %ebx
-       cfi_restore(3)
-       addl    $12, %esp
-       cfi_adjust_cfa_offset(-12)
-       ret
-
-5:     /* Canceled.  */
-       movl    $0xffffffff, %gs:RESULT
-       LOCK
-       orl     $0x10, %gs:CANCELHANDLING
-       movl    %gs:CLEANUP_JMP_BUF, %eax
-       jmp     HIDDEN_JUMPTARGET (__pthread_unwind)
+       jmp     5b
        cfi_endproc
-       .size   __new_sem_wait,.-__new_sem_wait
-       versioned_symbol(libpthread, __new_sem_wait, sem_wait, GLIBC_2_1)
-#if SHLIB_COMPAT(libpthread, GLIBC_2_0, GLIBC_2_1)
-       .global __old_sem_wait
-__old_sem_wait = __new_sem_wait
+       .size   __old_sem_wait,.-__old_sem_wait
        compat_symbol(libpthread, __old_sem_wait, sem_wait, GLIBC_2_0)
 #endif
index 1dec19e..eff932c 100644 (file)
@@ -1,4 +1,4 @@
-/* Copyright (C) 2002, 2003, 2004 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.
 
@@ -137,9 +137,16 @@ struct pthread_key_struct
 
 
 /* Semaphore variable structure.  */
-struct sem
+struct new_sem
 {
-  unsigned int count;
+  unsigned int value;
+  int private;
+  unsigned long int nwaiters;
+};
+
+struct old_sem
+{
+  unsigned int value;
 };
 
 
index 671b43f..f8bc695 100644 (file)
@@ -1,5 +1,5 @@
 /* sem_post -- post to a POSIX semaphore.  Generic futex-using version.
-   Copyright (C) 2003, 2004 Free Software Foundation, Inc.
+   Copyright (C) 2003, 2004, 2007 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
    Contributed by Jakub Jelinek <jakub@redhat.com>, 2003.
 
 int
 __new_sem_post (sem_t *sem)
 {
+  struct new_sem *isem = (struct new_sem *) sem;
+
+  int nr = atomic_increment_val (&isem->value);
+  atomic_full_barrier ();
+  if (isem->nwaiters > 0)
+    {
+      int err = lll_futex_wake (&isem->value, 1);
+      if (__builtin_expect (err, 0) < 0)
+       {
+         __set_errno (-err);
+         return -1;
+       }
+    }
+  return 0;
+}
+versioned_symbol (libpthread, __new_sem_post, sem_post, GLIBC_2_1);
+
+
+#if SHLIB_COMPAT (libpthread, GLIBC_2_0, GLIBC_2_1)
+int
+attribute_compat_text_section
+__old_sem_post (sem_t *sem)
+{
   int *futex = (int *) sem;
 
   int nr = atomic_increment_val (futex);
-  int err = lll_futex_wake (futex, nr);
+  int err = lll_futex_wake (futex, 1);
   if (__builtin_expect (err, 0) < 0)
     {
       __set_errno (-err);
@@ -40,8 +63,5 @@ __new_sem_post (sem_t *sem)
     }
   return 0;
 }
-versioned_symbol (libpthread, __new_sem_post, sem_post, GLIBC_2_1);
-#if SHLIB_COMPAT (libpthread, GLIBC_2_0, GLIBC_2_1)
-strong_alias (__new_sem_post, __old_sem_post)
 compat_symbol (libpthread, __old_sem_post, sem_post, GLIBC_2_0);
 #endif
index ef897c1..30f6a87 100644 (file)
@@ -1,5 +1,5 @@
 /* sem_timedwait -- wait on a semaphore.  Generic futex-using version.
-   Copyright (C) 2003 Free Software Foundation, Inc.
+   Copyright (C) 2003, 2007 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
    Contributed by Paul Mackerras <paulus@au.ibm.com>, 2003.
 
 #include <shlib-compat.h>
 
 
+extern void __sem_wait_cleanup (void *arg) attribute_hidden;
+
+
+void
+attribute_hidden
+__sem_wait_cleanup (void *arg)
+{
+  struct new_sem *isem = (struct new_sem *) arg;
+
+  atomic_decrement (&isem->nwaiters);
+}
+
+
 int
 sem_timedwait (sem_t *sem, const struct timespec *abstime)
 {
-  /* First check for cancellation.  */
-  CANCELLATION_P (THREAD_SELF);
-
-  int *futex = (int *) sem;
-  int val;
+  struct new_sem *isem = (struct new_sem *) sem;
   int err;
 
-  if (*futex > 0)
+  if (atomic_decrement_if_positive (&isem->value) > 0)
+    return 0;
+
+  if (abstime->tv_nsec < 0 || abstime->tv_nsec >= 1000000000)
     {
-      val = atomic_decrement_if_positive (futex);
-      if (val > 0)
-       return 0;
+      __set_errno (EINVAL);
+      return -1;
     }
 
-  err = -EINVAL;
-  if (abstime->tv_nsec < 0 || abstime->tv_nsec >= 1000000000)
-    goto error_return;
+  atomic_increment (&isem->nwaiters);
+
+  pthread_cleanup_push (__sem_wait_cleanup, isem);
 
-  do
+  while (1)
     {
       struct timeval tv;
       struct timespec rt;
@@ -70,7 +81,11 @@ sem_timedwait (sem_t *sem, const struct timespec *abstime)
       /* Already timed out?  */
       err = -ETIMEDOUT;
       if (sec < 0)
-       goto error_return;
+       {
+         __set_errno (ETIMEDOUT);
+         err = -1;
+         break;
+       }
 
       /* Do wait.  */
       rt.tv_sec = sec;
@@ -79,21 +94,28 @@ sem_timedwait (sem_t *sem, const struct timespec *abstime)
       /* Enable asynchronous cancellation.  Required by the standard.  */
       int oldtype = __pthread_enable_asynccancel ();
 
-      err = lll_futex_timed_wait (futex, 0, &rt);
+      err = lll_futex_timed_wait (&isem->value, 0, &rt);
 
       /* Disable asynchronous cancellation.  */
       __pthread_disable_asynccancel (oldtype);
 
       if (err != 0 && err != -EWOULDBLOCK)
-       goto error_return;
+       {
+         __set_errno (-err);
+         err = -1;
+         break;
+       }
 
-      val = atomic_decrement_if_positive (futex);
+      if (atomic_decrement_if_positive (&isem->value) > 0)
+       {
+         err = 0;
+         break;
+       }
     }
-  while (val <= 0);
 
-  return 0;
+  pthread_cleanup_pop (0);
+
+  atomic_decrement (&isem->nwaiters);
 
- error_return:
-  __set_errno (-err);
-  return -1;
+  return err;
 }
index d1aa975..e35b648 100644 (file)
 #include <shlib-compat.h>
 
 
+void
+attribute_hidden
+__sem_wait_cleanup (void *arg)
+{
+  struct new_sem *isem = (struct new_sem *) arg;
+
+  atomic_decrement (&isem->nwaiters);
+}
+
+
 int
 __new_sem_wait (sem_t *sem)
 {
+  struct new_sem *isem = (struct new_sem *) sem;
+  int err;
+
+  if (atomic_decrement_if_positive (&isem->value) > 0)
+    return 0;
+
+  atomic_increment (&isem->nwaiters);
+
+  pthread_cleanup_push (__sem_wait_cleanup, isem);
+
+  while (1)
+    {
+      /* Enable asynchronous cancellation.  Required by the standard.  */
+      int oldtype = __pthread_enable_asynccancel ();
+
+      err = lll_futex_wait (&isem->value, 0);
+
+      /* Disable asynchronous cancellation.  */
+      __pthread_disable_asynccancel (oldtype);
+
+      if (err != 0 && err != -EWOULDBLOCK)
+       {
+         __set_errno (-err);
+         err = -1;
+       }
+
+      if (atomic_decrement_if_positive (&isem->value) > 0)
+       {
+         err = 0;
+         break;
+       }
+    }
+
+  pthread_cleanup_pop (0);
+
+  atomic_decrement (&isem->nwaiters);
+
+  return err;
+}
+versioned_symbol (libpthread, __new_sem_wait, sem_wait, GLIBC_2_1);
+
+
+#if SHLIB_COMPAT (libpthread, GLIBC_2_0, GLIBC_2_1)
+int
+attribute_compat_text_section
+__old_sem_wait (sem_t *sem)
+{
   int *futex = (int *) sem;
   int err;
 
@@ -53,8 +110,5 @@ __new_sem_wait (sem_t *sem)
   return -1;
 }
 
-versioned_symbol (libpthread, __new_sem_wait, sem_wait, GLIBC_2_1);
-#if SHLIB_COMPAT (libpthread, GLIBC_2_0, GLIBC_2_1)
-strong_alias (__new_sem_wait, __old_sem_wait)
 compat_symbol (libpthread, __old_sem_wait, sem_wait, GLIBC_2_0);
 #endif
diff --git a/nptl/sysdeps/unix/sysv/linux/structsem.sym b/nptl/sysdeps/unix/sysv/linux/structsem.sym
new file mode 100644 (file)
index 0000000..4f32c68
--- /dev/null
@@ -0,0 +1,10 @@
+#include <stddef.h>
+#include <sched.h>
+#include <bits/pthreadtypes.h>
+#include "internaltypes.h"
+
+--
+
+VALUE          offsetof (struct new_sem, value)
+PRIVATE                offsetof (struct new_sem, private)
+NWAITERS       offsetof (struct new_sem, nwaiters)
index 7f608a5..1f5d0bb 100644 (file)
@@ -1,4 +1,4 @@
-/* Copyright (C) 2002, 2003, 2005 Free Software Foundation, Inc.
+/* Copyright (C) 2002, 2003, 2005, 2007 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
    Contributed by Ulrich Drepper <drepper@redhat.com>, 2002.
 
@@ -20,6 +20,7 @@
 #include <sysdep.h>
 #include <shlib-compat.h>
 #include <pthread-errnos.h>
+#include <structsem.h>
 
 #ifndef UP
 # define LOCK lock
        .type   sem_post,@function
        .align  16
 sem_post:
-       movl    $1, %edx
        LOCK
-       xaddl   %edx, (%rdi)
+#if VALUE == 0
+       addl    $1, (%rdi)
+#else
+       addl    $1, VALUE(%rdi)
+#endif
+
+       cmpq    $0, NWAITERS(%rdi)
+       je      2f
 
        movl    $SYS_futex, %eax
        movl    $FUTEX_WAKE, %esi
-       incl    %edx
+       movl    $1, %edx
        syscall
 
        testq   %rax, %rax
        js      1f
 
-       xorl    %eax, %eax
+2:     xorl    %eax, %eax
        retq
 
 1:
index 8c5c2a6..1bb74c0 100644 (file)
@@ -20,6 +20,7 @@
 #include <sysdep.h>
 #include <shlib-compat.h>
 #include <pthread-errnos.h>
+#include <structsem.h>
 
 #ifndef UP
 # define LOCK lock
@@ -28,6 +29,7 @@
 #endif
 
 #define SYS_futex              202
+#define FUTEX_WAIT             0
 
 /* For the calculation see asm/vsyscall.h.  */
 #define VSYSCALL_ADDR_vgettimeofday    0xffffffffff600000
        .globl  sem_timedwait
        .type   sem_timedwait,@function
        .align  16
-       cfi_startproc
 sem_timedwait:
+.LSTARTCODE:
+#if VALUE == 0
        movl    (%rdi), %eax
+#else
+       movl    VALUE(%rdi), %eax
+#endif
 2:     testl   %eax, %eax
        je      1f
 
        leaq    -1(%rax), %rdx
        LOCK
+#if VALUE == 0
        cmpxchgl %edx, (%rdi)
+#else
+       cmpxchgl %edx, VALUE(%rdi)
+#endif
        jne     2b
 
        xorl    %eax, %eax
@@ -54,25 +64,25 @@ sem_timedwait:
 
        /* Check whether the timeout value is valid.  */
 1:     pushq   %r12
-       cfi_adjust_cfa_offset(8)
+.Lpush_r12:
        pushq   %r13
-       cfi_adjust_cfa_offset(8)
+.Lpush_r13:
        pushq   %r14
-       cfi_adjust_cfa_offset(8)
+.Lpush_r14:
        subq    $24, %rsp
-       cfi_adjust_cfa_offset(24)
+.Lsubq:
 
        movq    %rdi, %r12
-       cfi_offset(12, -16)             /* %r12 */
        movq    %rsi, %r13
-       cfi_offset(13, -24)             /* %r13 */
 
        /* Check for invalid nanosecond field.  */
        cmpq    $1000000000, 8(%r13)
        movl    $EINVAL, %r14d
-       cfi_offset(14, -24)             /* %r14 */
        jae     6f
 
+       LOCK
+       addq    $1, NWAITERS(%r12)
+
 7:     xorl    %esi, %esi
        movq    %rsp, %rdi
        movq    $VSYSCALL_ADDR_vgettimeofday, %rax
@@ -96,12 +106,17 @@ sem_timedwait:
        movq    %rdi, (%rsp)    /* Store relative timeout.  */
        movq    %rsi, 8(%rsp)
 
+.LcleanupSTART:
        call    __pthread_enable_asynccancel
        movl    %eax, 16(%rsp)
 
        movq    %rsp, %r10
+#if VALUE == 0
        movq    %r12, %rdi
-       xorl    %esi, %esi
+#else
+       leaq    VALUE(%r12), %rdi
+#endif
+       movl    $FUTEX_WAIT, %esi
        movl    $SYS_futex, %eax
        xorl    %edx, %edx
        syscall
@@ -109,39 +124,47 @@ sem_timedwait:
 
        movl    16(%rsp), %edi
        call    __pthread_disable_asynccancel
+.LcleanupEND:
 
        testq   %r14, %r14
        je      9f
        cmpq    $-EWOULDBLOCK, %r14
        jne     3f
 
-9:     movl    (%r12), %eax
+9:
+#if VALUE == 0
+       movl    (%r12), %eax
+#else
+       movl    VALUE(%r12), %eax
+#endif
 8:     testl   %eax, %eax
        je      7b
 
        leaq    -1(%rax), %rcx
        LOCK
+#if VALUE == 0
        cmpxchgl %ecx, (%r12)
+#else
+       cmpxchgl %ecx, VALUE(%r12)
+#endif
        jne     8b
 
        xorl    %eax, %eax
-10:    addq    $24, %rsp
-       cfi_adjust_cfa_offset(-24)
+
+10:    LOCK
+       subq    $1, NWAITERS(%r12)
+
+       addq    $24, %rsp
+.Laddq:
        popq    %r14
-       cfi_adjust_cfa_offset(-8)
-       cfi_restore(14)
+.Lpop_r14:
        popq    %r13
-       cfi_adjust_cfa_offset(-8)
-       cfi_restore(13)
+.Lpop_r13:
        popq    %r12
-       cfi_adjust_cfa_offset(-8)
-       cfi_restore(12)
+.Lpop_r12:
        retq
 
-       cfi_adjust_cfa_offset(48)
-       cfi_offset(12, -16)             /* %r12 */
-       cfi_offset(13, -24)             /* %r13 */
-       cfi_offset(14, -32)             /* %r14 */
+.Lafter_retq:
 3:     negq    %r14
 6:
 #if USE___THREAD
@@ -154,5 +177,159 @@ sem_timedwait:
 
        orl     $-1, %eax
        jmp     10b
-       cfi_endproc
        .size   sem_timedwait,.-sem_timedwait
+
+
+       .type   sem_timedwait_cleanup,@function
+sem_timedwait_cleanup:
+       LOCK
+       subq    $1, NWAITERS(%r12)
+       movq    %rax, %rdi
+.LcallUR:
+       call    _Unwind_Resume@PLT
+       hlt
+.LENDCODE:
+       .size   sem_timedwait_cleanup,.-sem_timedwait_cleanup
+
+
+       .section .gcc_except_table,"a",@progbits
+.LexceptSTART:
+       .byte   0xff                            # @LPStart format (omit)
+       .byte   0xff                            # @TType format (omit)
+       .byte   0x01                            # call-site format
+                                               # DW_EH_PE_uleb128
+       .uleb128 .Lcstend-.Lcstbegin
+.Lcstbegin:
+       .uleb128 .LcleanupSTART-.LSTARTCODE
+       .uleb128 .LcleanupEND-.LcleanupSTART
+       .uleb128 sem_timedwait_cleanup-.LSTARTCODE
+       .uleb128  0
+       .uleb128 .LcallUR-.LSTARTCODE
+       .uleb128 .LENDCODE-.LcallUR
+       .uleb128 0
+       .uleb128  0
+.Lcstend:
+
+
+       .section .eh_frame,"a",@progbits
+.LSTARTFRAME:
+       .long   .LENDCIE-.LSTARTCIE             # Length of the CIE.
+.LSTARTCIE:
+       .long   0                               # CIE ID.
+       .byte   1                               # Version number.
+#ifdef SHARED
+       .string "zPLR"                          # NUL-terminated augmentation
+                                               # string.
+#else
+       .string "zPL"                           # NUL-terminated augmentation
+                                               # string.
+#endif
+       .uleb128 1                              # Code alignment factor.
+       .sleb128 -8                             # Data alignment factor.
+       .byte   16                              # Return address register
+                                               # column.
+#ifdef SHARED
+       .uleb128 7                              # Augmentation value length.
+       .byte   0x9b                            # Personality: DW_EH_PE_pcrel
+                                               # + DW_EH_PE_sdata4
+                                               # + DW_EH_PE_indirect
+       .long   DW.ref.__gcc_personality_v0-.
+       .byte   0x1b                            # LSDA Encoding: DW_EH_PE_pcrel
+                                               # + DW_EH_PE_sdata4.
+       .byte   0x1b                            # FDE Encoding: DW_EH_PE_pcrel
+                                               # + DW_EH_PE_sdata4.
+#else
+       .uleb128 10                             # Augmentation value length.
+       .byte   0x0                             # Personality: absolute
+       .quad   __gcc_personality_v0
+       .byte   0x0                             # LSDA Encoding: absolute
+#endif
+       .byte 0x0c                              # DW_CFA_def_cfa
+       .uleb128 7
+       .uleb128 8
+       .byte   0x90                            # DW_CFA_offset, column 0x10
+       .uleb128 1
+       .align 8
+.LENDCIE:
+
+       .long   .LENDFDE-.LSTARTFDE             # Length of the FDE.
+.LSTARTFDE:
+       .long   .LSTARTFDE-.LSTARTFRAME         # CIE pointer.
+#ifdef SHARED
+       .long   .LSTARTCODE-.                   # PC-relative start address
+                                               # of the code.
+       .long   .LENDCODE-.LSTARTCODE           # Length of the code.
+       .uleb128 4                              # Augmentation size
+       .long   .LexceptSTART-.
+#else
+       .quad   .LSTARTCODE                     # Start address of the code.
+       .quad   .LENDCODE-.LSTARTCODE           # Length of the code.
+       .uleb128 8                              # Augmentation size
+       .quad   .LexceptSTART
+#endif
+
+       .byte   4                               # DW_CFA_advance_loc4
+       .long   .Lpush_r12-.LSTARTCODE
+       .byte   14                              # DW_CFA_def_cfa_offset
+       .uleb128 16
+       .byte   0x8c                            # DW_CFA_offset %r12
+        .uleb128 2
+       .byte   4                               # DW_CFA_advance_loc4
+       .long   .Lpush_r13-.Lpush_r12
+       .byte   14                              # DW_CFA_def_cfa_offset
+       .uleb128 24
+       .byte   0x8d                            # DW_CFA_offset %r13
+        .uleb128 3
+       .byte   4                               # DW_CFA_advance_loc4
+       .long   .Lpush_r14-.Lpush_r13
+       .byte   14                              # DW_CFA_def_cfa_offset
+       .uleb128 32
+       .byte   0x8e                            # DW_CFA_offset %r14
+        .uleb128 4
+       .byte   4                               # DW_CFA_advance_loc4
+       .long   .Lsubq-.Lpush_r14
+       .byte   14                              # DW_CFA_def_cfa_offset
+       .uleb128 56
+       .byte   4                               # DW_CFA_advance_loc4
+       .long   .Laddq-.Lsubq
+       .byte   14                              # DW_CFA_def_cfa_offset
+       .uleb128 32
+       .byte   4                               # DW_CFA_advance_loc4
+       .long   .Lpop_r14-.Laddq
+       .byte   14                              # DW_CFA_def_cfa_offset
+       .uleb128 24
+       .byte   0xce                            # DW_CFA_restore %r14
+       .byte   4                               # DW_CFA_advance_loc4
+       .long   .Lpop_r13-.Lpop_r14
+       .byte   14                              # DW_CFA_def_cfa_offset
+       .uleb128 16
+       .byte   0xcd                            # DW_CFA_restore %r13
+       .byte   4                               # DW_CFA_advance_loc4
+       .long   .Lpop_r12-.Lpop_r13
+       .byte   14                              # DW_CFA_def_cfa_offset
+       .uleb128 8
+       .byte   0xcc                            # DW_CFA_restore %r12
+       .byte   4                               # DW_CFA_advance_loc4
+       .long   .Lafter_retq-.Lpop_r12
+       .byte   14                              # DW_CFA_def_cfa_offset
+       .uleb128 56
+       .byte   0x8c                            # DW_CFA_offset %r12
+        .uleb128 2
+       .byte   0x8d                            # DW_CFA_offset %r13
+        .uleb128 3
+       .byte   0x8e                            # DW_CFA_offset %r14
+        .uleb128 4
+       .align  8
+.LENDFDE:
+
+
+#ifdef SHARED
+       .hidden DW.ref.__gcc_personality_v0
+       .weak   DW.ref.__gcc_personality_v0
+       .section .gnu.linkonce.d.DW.ref.__gcc_personality_v0,"aw",@progbits
+       .align  8
+       .type   DW.ref.__gcc_personality_v0, @object
+       .size   DW.ref.__gcc_personality_v0, 8
+DW.ref.__gcc_personality_v0:
+       .quad   __gcc_personality_v0
+#endif
index 5bd78eb..e958d63 100644 (file)
@@ -20,6 +20,7 @@
 #include <sysdep.h>
 #include <shlib-compat.h>
 #include <pthread-errnos.h>
+#include <structsem.h>
 
 #ifndef UP
 # define LOCK lock
@@ -28,6 +29,7 @@
 #endif
 
 #define SYS_futex              202
+#define FUTEX_WAIT             0
 
 
        .text
        .globl  sem_wait
        .type   sem_wait,@function
        .align  16
-       cfi_startproc
 sem_wait:
+.LSTARTCODE:
        pushq   %r12
-       cfi_adjust_cfa_offset(8)
-       cfi_offset(12, -16)
+.Lpush_r12:
        pushq   %r13
-       cfi_adjust_cfa_offset(8)
+.Lpush_r13:
        movq    %rdi, %r13
-       cfi_offset(13, -24)
 
-3:     movl    (%r13), %eax
+#if VALUE == 0
+       movl    (%r13), %eax
+#else
+       movl    VALUE(%r13), %eax
+#endif
 2:     testl   %eax, %eax
        je      1f
 
-       leaq    -1(%rax), %rdx
+       leal    -1(%rax), %edx
        LOCK
+#if VALUE == 0
        cmpxchgl %edx, (%r13)
+#else
+       cmpxchgl %edx, VALUE(%r13)
+#endif
        jne     2b
-       xorl    %eax, %eax
 
-       popq    %r13
-       cfi_adjust_cfa_offset(-8)
-       cfi_restore(13)
+7:     xorl    %eax, %eax
+
+9:     popq    %r13
+.Lpop_r13:
        popq    %r12
-       cfi_adjust_cfa_offset(-8)
-       cfi_restore(12)
+.Lpop_r12:
 
        retq
 
-       cfi_adjust_cfa_offset(16)
-       cfi_offset(12, -16)
-       cfi_offset(13, -24)
-1:     call    __pthread_enable_asynccancel
+.Lafter_retq:
+1:     LOCK
+       addq    $1, NWAITERS(%r13)
+
+.LcleanupSTART:
+6:     call    __pthread_enable_asynccancel
        movl    %eax, %r8d
 
        xorq    %r10, %r10
        movl    $SYS_futex, %eax
        movq    %r13, %rdi
-       movq    %r10, %rsi
-       movq    %r10, %rdx
+       movl    $FUTEX_WAIT, %esi
+       xorl    %edx, %edx
        syscall
        movq    %rax, %r12
 
        movl    %r8d, %edi
        call    __pthread_disable_asynccancel
+.LcleanupEND:
 
        testq   %r12, %r12
-       je      3b
+       je      3f
        cmpq    $-EWOULDBLOCK, %r12
-       je      3b
-       negq    %r12
+       jne     4f
+
+3:
+#if VALUE == 0
+       movl    (%r13), %eax
+#else
+       movl    VALUE(%r13), %eax
+#endif
+5:     testl   %eax, %eax
+       je      6b
+
+       leal    -1(%rax), %edx
+       LOCK
+#if VALUE == 0
+       cmpxchgl %edx, (%r13)
+#else
+       cmpxchgl %edx, VALUE(%r13)
+#endif
+       jne     5b
+
+       LOCK
+       subq    $1, NWAITERS(%r13)
+       jmp     7b
+
+4:     negq    %r12
 #if USE___THREAD
        movq    errno@gottpoff(%rip), %rdx
        movl    %r12d, %fs:(%rdx)
@@ -95,13 +128,142 @@ sem_wait:
 #endif
        orl     $-1, %eax
 
-       popq    %r13
-       cfi_adjust_cfa_offset(-8)
-       cfi_restore(13)
-       popq    %r12
-       cfi_adjust_cfa_offset(-8)
-       cfi_restore(12)
+       LOCK
+       subq    $1, NWAITERS(%r13)
 
-       retq
-       cfi_endproc
+       jmp 9b
        .size   sem_wait,.-sem_wait
+
+
+       .type   sem_wait_cleanup,@function
+sem_wait_cleanup:
+       LOCK
+       subq    $1, NWAITERS(%r13)
+       movq    %rax, %rdi
+.LcallUR:
+       call    _Unwind_Resume@PLT
+       hlt
+.LENDCODE:
+       .size   sem_wait_cleanup,.-sem_wait_cleanup
+
+
+       .section .gcc_except_table,"a",@progbits
+.LexceptSTART:
+       .byte   0xff                            # @LPStart format (omit)
+       .byte   0xff                            # @TType format (omit)
+       .byte   0x01                            # call-site format
+                                               # DW_EH_PE_uleb128
+       .uleb128 .Lcstend-.Lcstbegin
+.Lcstbegin:
+       .uleb128 .LcleanupSTART-.LSTARTCODE
+       .uleb128 .LcleanupEND-.LcleanupSTART
+       .uleb128 sem_wait_cleanup-.LSTARTCODE
+       .uleb128  0
+       .uleb128 .LcallUR-.LSTARTCODE
+       .uleb128 .LENDCODE-.LcallUR
+       .uleb128 0
+       .uleb128  0
+.Lcstend:
+
+
+       .section .eh_frame,"a",@progbits
+.LSTARTFRAME:
+       .long   .LENDCIE-.LSTARTCIE             # Length of the CIE.
+.LSTARTCIE:
+       .long   0                               # CIE ID.
+       .byte   1                               # Version number.
+#ifdef SHARED
+       .string "zPLR"                          # NUL-terminated augmentation
+                                               # string.
+#else
+       .string "zPL"                           # NUL-terminated augmentation
+                                               # string.
+#endif
+       .uleb128 1                              # Code alignment factor.
+       .sleb128 -8                             # Data alignment factor.
+       .byte   16                              # Return address register
+                                               # column.
+#ifdef SHARED
+       .uleb128 7                              # Augmentation value length.
+       .byte   0x9b                            # Personality: DW_EH_PE_pcrel
+                                               # + DW_EH_PE_sdata4
+                                               # + DW_EH_PE_indirect
+       .long   DW.ref.__gcc_personality_v0-.
+       .byte   0x1b                            # LSDA Encoding: DW_EH_PE_pcrel
+                                               # + DW_EH_PE_sdata4.
+       .byte   0x1b                            # FDE Encoding: DW_EH_PE_pcrel
+                                               # + DW_EH_PE_sdata4.
+#else
+       .uleb128 10                             # Augmentation value length.
+       .byte   0x0                             # Personality: absolute
+       .quad   __gcc_personality_v0
+       .byte   0x0                             # LSDA Encoding: absolute
+#endif
+       .byte 0x0c                              # DW_CFA_def_cfa
+       .uleb128 7
+       .uleb128 8
+       .byte   0x90                            # DW_CFA_offset, column 0x10
+       .uleb128 1
+       .align 8
+.LENDCIE:
+
+       .long   .LENDFDE-.LSTARTFDE             # Length of the FDE.
+.LSTARTFDE:
+       .long   .LSTARTFDE-.LSTARTFRAME         # CIE pointer.
+#ifdef SHARED
+       .long   .LSTARTCODE-.                   # PC-relative start address
+                                               # of the code.
+       .long   .LENDCODE-.LSTARTCODE           # Length of the code.
+       .uleb128 4                              # Augmentation size
+       .long   .LexceptSTART-.
+#else
+       .quad   .LSTARTCODE                     # Start address of the code.
+       .quad   .LENDCODE-.LSTARTCODE           # Length of the code.
+       .uleb128 8                              # Augmentation size
+       .quad   .LexceptSTART
+#endif
+
+       .byte   4                               # DW_CFA_advance_loc4
+       .long   .Lpush_r12-.LSTARTCODE
+       .byte   14                              # DW_CFA_def_cfa_offset
+       .uleb128 16
+       .byte   0x8c                            # DW_CFA_offset %r12
+        .uleb128 2
+       .byte   4                               # DW_CFA_advance_loc4
+       .long   .Lpush_r13-.Lpush_r12
+       .byte   14                              # DW_CFA_def_cfa_offset
+       .uleb128 24
+       .byte   0x8d                            # DW_CFA_offset %r13
+        .uleb128 3
+       .byte   4                               # DW_CFA_advance_loc4
+       .long   .Lpop_r13-.Lpush_r13
+       .byte   14                              # DW_CFA_def_cfa_offset
+       .uleb128 16
+       .byte   0xcd                            # DW_CFA_restore %r13
+       .byte   4                               # DW_CFA_advance_loc4
+       .long   .Lpop_r12-.Lpop_r13
+       .byte   14                              # DW_CFA_def_cfa_offset
+       .uleb128 8
+       .byte   0xcc                            # DW_CFA_restore %r12
+       .byte   4                               # DW_CFA_advance_loc4
+       .long   .Lafter_retq-.Lpop_r12
+       .byte   14                              # DW_CFA_def_cfa_offset
+       .uleb128 24
+       .byte   0x8c                            # DW_CFA_offset %r12
+        .uleb128 2
+       .byte   0x8d                            # DW_CFA_offset %r13
+        .uleb128 3
+       .align  8
+.LENDFDE:
+
+
+#ifdef SHARED
+       .hidden DW.ref.__gcc_personality_v0
+       .weak   DW.ref.__gcc_personality_v0
+       .section .gnu.linkonce.d.DW.ref.__gcc_personality_v0,"aw",@progbits
+       .align  8
+       .type   DW.ref.__gcc_personality_v0, @object
+       .size   DW.ref.__gcc_personality_v0, 8
+DW.ref.__gcc_personality_v0:
+       .quad   __gcc_personality_v0
+#endif
index db8936f..17a1e29 100644 (file)
@@ -1,4 +1,4 @@
-/* Copyright (C) 2005 Free Software Foundation, Inc.
+/* Copyright (C) 2005, 2007 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
    Contributed by Ulrich Drepper <drepper@redhat.com>, 2005.
 
@@ -59,7 +59,8 @@ do_test (void)
   TEST_TYPE2 (pthread_rwlockattr_t, struct pthread_rwlockattr);
   TEST_TYPE2 (pthread_barrier_t, struct pthread_barrier);
   TEST_TYPE2 (pthread_barrierattr_t, struct pthread_barrierattr);
-  TEST_TYPE2 (sem_t, struct sem);
+  TEST_TYPE2 (sem_t, struct new_sem);
+  TEST_TYPE2 (sem_t, struct old_sem);
 
   return result;
 }