[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[commits] r2290 - in /fsf/trunk/libc: ./ io/bits/ nptl/ nptl/sysdeps/unix/sysv/linux/ nptl/sysdeps/unix/sysv/linux/i386/i486/ nptl/sys...



Author: eglibc
Date: Sat May 26 00:02:20 2007
New Revision: 2290

Log:
Import glibc-mainline for 2007-05-26

Added:
    fsf/trunk/libc/nptl/sysdeps/unix/sysv/linux/structsem.sym
    fsf/trunk/libc/nptl/tst-sem10.c
    fsf/trunk/libc/nptl/tst-sem11.c
    fsf/trunk/libc/nptl/tst-sem12.c
Modified:
    fsf/trunk/libc/ChangeLog
    fsf/trunk/libc/io/bits/fcntl2.h
    fsf/trunk/libc/nptl/ChangeLog
    fsf/trunk/libc/nptl/Makefile
    fsf/trunk/libc/nptl/sem_getvalue.c
    fsf/trunk/libc/nptl/sem_init.c
    fsf/trunk/libc/nptl/sem_open.c
    fsf/trunk/libc/nptl/semaphoreP.h
    fsf/trunk/libc/nptl/sysdeps/unix/sysv/linux/Makefile
    fsf/trunk/libc/nptl/sysdeps/unix/sysv/linux/i386/i486/sem_post.S
    fsf/trunk/libc/nptl/sysdeps/unix/sysv/linux/i386/i486/sem_timedwait.S
    fsf/trunk/libc/nptl/sysdeps/unix/sysv/linux/i386/i486/sem_wait.S
    fsf/trunk/libc/nptl/sysdeps/unix/sysv/linux/internaltypes.h
    fsf/trunk/libc/nptl/sysdeps/unix/sysv/linux/sem_post.c
    fsf/trunk/libc/nptl/sysdeps/unix/sysv/linux/sem_timedwait.c
    fsf/trunk/libc/nptl/sysdeps/unix/sysv/linux/sem_wait.c
    fsf/trunk/libc/nptl/sysdeps/unix/sysv/linux/x86_64/sem_post.S
    fsf/trunk/libc/nptl/sysdeps/unix/sysv/linux/x86_64/sem_timedwait.S
    fsf/trunk/libc/nptl/sysdeps/unix/sysv/linux/x86_64/sem_wait.S
    fsf/trunk/libc/nptl/tst-typesizes.c

Modified: fsf/trunk/libc/ChangeLog
==============================================================================
--- fsf/trunk/libc/ChangeLog (original)
+++ fsf/trunk/libc/ChangeLog Sat May 26 00:02:20 2007
@@ -1,3 +1,20 @@
+2007-05-25  Jakub Jelinek  <jakub@xxxxxxxxxx>
+
+	* io/bits/fcntl2.h (__open_2): Add nonnull attribute.
+	(open): Fix comment typos.  Don't call __open_2 if flags
+	is a compile time constant without O_CREAT.
+	(__open64_2): Add nonnull attribute.
+	(open64): Fix comment typos.  Don't call __open64_2 if flags
+	is a compile time constant without O_CREAT.
+	(__openat_2): Add nonnull attribute, fix nonnull attribute
+	on redirect.
+	(openat): Fix comment typos.  Don't call __openat_2 if flags
+	is a compile time constant without O_CREAT.
+	(__openat64_2): Add nonnull attribute, fix nonnull attribute
+	on redirect.
+	(openat64): Fix comment typos.  Don't call __openat64_2 if flags
+	is a compile time constant without O_CREAT.
+
 2007-05-24  Ulrich Drepper  <drepper@xxxxxxxxxx>
 
 	* Makerules (sysd-rules): Define PTW for ptw-* files.

Modified: fsf/trunk/libc/io/bits/fcntl2.h
==============================================================================
--- fsf/trunk/libc/io/bits/fcntl2.h (original)
+++ fsf/trunk/libc/io/bits/fcntl2.h Sat May 26 00:02:20 2007
@@ -24,7 +24,7 @@
 /* Check that calls to open and openat with O_CREAT set have an
    appropriate third/fourth parameter.  */
 #ifndef __USE_FILE_OFFSET64
-extern int __open_2 (__const char *__path, int __oflag);
+extern int __open_2 (__const char *__path, int __oflag) __nonnull ((1));
 #else
 extern int __REDIRECT (__open_2, (__const char *__file, int __oflag),
 		       __open64_2) __nonnull ((1));
@@ -33,22 +33,27 @@
 #define open(fname, flags, ...) \
   ({ int ___r;								      \
      /* If the compiler complains about an invalid type, excess elements, etc \
-	in the initialization this means a paraleter of the wrong type has    \
+	in the initialization this means a parameter of the wrong type has    \
 	been passed to open. */						      \
      int ___arr[] = { __VA_ARGS__ };					      \
      if (__builtin_constant_p (flags) && ((flags) & O_CREAT) != 0)	      \
        {								      \
-	 /* If the compile complains about the size of this array type the    \
-	    the mode parameter is missing since O_CREAT has been used.  */    \
+	 /* If the compiler complains about the size of this array type the   \
+	    mode parameter is missing since O_CREAT has been used.  */	      \
 	 typedef int __open_missing_mode[((flags) & O_CREAT) != 0	      \
 					 ? ((long int) sizeof (___arr)	      \
 					    - (long int) sizeof (int)) : 1];  \
        }								      \
      if (sizeof (___arr) == 0)						      \
-       ___r = __open_2 (fname, flags);					      \
+       {								      \
+	 if (__builtin_constant_p (flags) && ((flags) & O_CREAT) == 0)	      \
+	   ___r = open (fname, flags);					      \
+	 else     							      \
+	   ___r = __open_2 (fname, flags);				      \
+       }								      \
      else								      \
        {								      \
-	 /* If the compile complains about the size of this array type too    \
+	 /* If the compiler complains about the size of this array type too   \
 	    many parameters have been passed to open.  */		      \
 	 typedef int __open_too_many_args[-(sizeof (___arr) > sizeof (int))]; \
 	 ___r = open (fname, flags, ___arr[0]);				      \
@@ -58,27 +63,32 @@
 
 
 #ifdef __USE_LARGEFILE64
-extern int __open64_2 (__const char *__path, int __oflag);
+extern int __open64_2 (__const char *__path, int __oflag) __nonnull ((1));
 
 # define open64(fname, flags, ...) \
   ({ int ___r;								      \
      /* If the compiler complains about an invalid type, excess elements, etc \
-	in the initialization this means a paraleter of the wrong type has    \
+	in the initialization this means a parameter of the wrong type has    \
 	been passed to open64. */					      \
      int ___arr[] = { __VA_ARGS__ };					      \
      if (__builtin_constant_p (flags) && ((flags) & O_CREAT) != 0)	      \
        {								      \
-	 /* If the compile complains about the size of this array type the    \
-	    the mode parameter is missing since O_CREAT has been used.  */    \
+	 /* If the compiler complains about the size of this array type the   \
+	    mode parameter is missing since O_CREAT has been used.  */	      \
 	 typedef int __open_missing_mode[((flags) & O_CREAT) != 0	      \
 					 ? ((long int) sizeof (___arr)	      \
 					    - (long int) sizeof (int)) : 1];  \
        }								      \
      if (sizeof (___arr) == 0)						      \
-       ___r = __open64_2 (fname, flags);				      \
+       {								      \
+	 if (__builtin_constant_p (flags) && ((flags) & O_CREAT) == 0)	      \
+	   ___r = open64 (fname, flags);				      \
+	 else     							      \
+	   ___r = __open64_2 (fname, flags);				      \
+       }								      \
      else								      \
        {								      \
-	 /* If the compile complains about the size of this array type too    \
+	 /* If the compiler complains about the size of this array type too   \
 	    many parameters have been passed to open64.  */		      \
 	 typedef int __open_too_many_args[-(sizeof (___arr) > sizeof (int))]; \
 	 ___r = open64 (fname, flags, ___arr[0]);			      \
@@ -89,32 +99,38 @@
 
 #ifdef __USE_ATFILE
 # ifndef __USE_FILE_OFFSET64
-extern int __openat_2 (int __fd, __const char *__path, int __oflag);
+extern int __openat_2 (int __fd, __const char *__path, int __oflag)
+     __nonnull ((2));
 # else
 extern int __REDIRECT (__openat_2, (int __fd, __const char *__file,
 				    int __oflag), __openat64_2)
-     __nonnull ((1));
+     __nonnull ((2));
 # endif
 
 # define openat(fd, fname, flags, ...) \
   ({ int ___r;								      \
      /* If the compiler complains about an invalid type, excess elements, etc \
-	in the initialization this means a paraleter of the wrong type has    \
+	in the initialization this means a parameter of the wrong type has    \
 	been passed to openat. */					      \
      int ___arr[] = { __VA_ARGS__ };					      \
      if (__builtin_constant_p (flags) && ((flags) & O_CREAT) != 0)	      \
        {								      \
-	 /* If the compile complains about the size of this array type the    \
-	    the mode parameter is missing since O_CREAT has been used.  */    \
+	 /* If the compiler complains about the size of this array type the   \
+	    mode parameter is missing since O_CREAT has been used.  */	      \
 	 typedef int __open_missing_mode[((flags) & O_CREAT) != 0	      \
 					 ? ((long int) sizeof (___arr)	      \
 					    - (long int) sizeof (int)) : 1];  \
        }								      \
      if (sizeof (___arr) == 0)						      \
-       ___r = __openat_2 (fd, fname, flags);				      \
+       {								      \
+	 if (__builtin_constant_p (flags) && ((flags) & O_CREAT) == 0)	      \
+	   ___r = openat (fd, fname, flags);				      \
+	 else     							      \
+	   ___r = __openat_2 (fd, fname, flags);			      \
+       }								      \
      else								      \
        {								      \
-	 /* If the compile complains about the size of this array type too    \
+	 /* If the compiler complains about the size of this array type too   \
 	    many parameters have been passed to openat.  */		      \
 	 typedef int __open_too_many_args[-(sizeof (___arr) > sizeof (int))]; \
 	 ___r = openat (fd, fname, flags, ___arr[0]);			      \
@@ -124,28 +140,34 @@
 
 
 # ifdef __USE_LARGEFILE64
-extern int __openat64_2 (int __fd, __const char *__path, int __oflag);
+extern int __openat64_2 (int __fd, __const char *__path, int __oflag)
+     __nonnull ((2));
 
 #  define openat64(fd, fname, flags, ...) \
   ({ int ___r;								      \
      /* If the compiler complains about an invalid type, excess elements, etc \
-	in the initialization this means a paraleter of the wrong type has    \
+	in the initialization this means a parameter of the wrong type has    \
 	been passed to openat64. */					      \
      int ___arr[] = { __VA_ARGS__ };					      \
      if (__builtin_constant_p (flags) && ((flags) & O_CREAT) != 0)	      \
        {								      \
-	 /* If the compile complains about the size of this array type the    \
-	    the mode parameter is missing since O_CREAT has been used.  */    \
+	 /* If the compiler complains about the size of this array type the   \
+	    mode parameter is missing since O_CREAT has been used.  */	      \
 	 typedef int __open_missing_mode[((flags) & O_CREAT) != 0	      \
 					 ? ((long int) sizeof (___arr)	      \
 					    - (long int) sizeof (int)) : 1];  \
        }								      \
      if (sizeof (___arr) == 0)						      \
-       ___r = __openat64_2 (fd, fname, flags);				      \
+       {								      \
+	 if (__builtin_constant_p (flags) && ((flags) & O_CREAT) == 0)	      \
+	   ___r = openat64 (fd, fname, flags);				      \
+	 else     							      \
+	   ___r = __openat64_2 (fd, fname, flags);			      \
+       }								      \
      else								      \
        {								      \
-	 /* If the compile complains about the size of this array type too    \
-	    many parameters have been passed to openat.  */		      \
+	 /* If the compiler complains about the size of this array type too   \
+	    many parameters have been passed to openat64.  */		      \
 	 typedef int __open_too_many_args[-(sizeof (___arr) > sizeof (int))]; \
 	 ___r = openat64 (fd, fname, flags, ___arr[0]);			      \
        }								      \

Modified: fsf/trunk/libc/nptl/ChangeLog
==============================================================================
--- fsf/trunk/libc/nptl/ChangeLog (original)
+++ fsf/trunk/libc/nptl/ChangeLog Sat May 26 00:02:20 2007
@@ -1,4 +1,49 @@
-2007-04-24  Jakub Jelinek  <jakub@xxxxxxxxxx>
+2007-05-25  Ulrich Drepper  <drepper@xxxxxxxxxx>
+
+	* sysdeps/unix/sysv/linux/i386/i486/sem_post.S: Add private futex
+	support.
+	* sysdeps/unix/sysv/linux/i386/i486/sem_timedwait.S: Likewise.
+	* sysdeps/unix/sysv/linux/i386/i486/sem_wait.S: Likewise.
+	* sysdeps/unix/sysv/linux/x86_64/sem_post.S: Likewise.
+	* sysdeps/unix/sysv/linux/x86_64/sem_timedwait.S: Likewise.
+	* sysdeps/unix/sysv/linux/x86_64/sem_wait.S: Likewise.
+
+	* 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@xxxxxxxxxx>
+	    Jakub Jelinek  <jakub@xxxxxxxxxx>
+
+	* sysdeps/unix/sysv/linux/i386/i486/sem_timedwait.S (sem_timedwait):
+	Move __pthread_enable_asynccancel right before futex syscall.
+	* sysdeps/unix/sysv/linux/x86_64/sem_timedwait.S (sem_timedwait):
+	Likewise.
+
+2007-05-24  Jakub Jelinek  <jakub@xxxxxxxxxx>
 
 	* sysdeps/i386/tls.h (THREAD_SET_PRIVATE_FUTEX,
 	THREAD_COPY_PRIVATE_FUTEX): Define.

Modified: fsf/trunk/libc/nptl/Makefile
==============================================================================
--- fsf/trunk/libc/nptl/Makefile (original)
+++ fsf/trunk/libc/nptl/Makefile Sat May 26 00:02:20 2007
@@ -218,7 +218,7 @@
 	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 \

Modified: fsf/trunk/libc/nptl/sem_getvalue.c
==============================================================================
--- fsf/trunk/libc/nptl/sem_getvalue.c (original)
+++ fsf/trunk/libc/nptl/sem_getvalue.c Sat May 26 00:02:20 2007
@@ -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@xxxxxxxxxx>, 2002.
 
@@ -27,11 +27,11 @@
      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;
 }

Modified: fsf/trunk/libc/nptl/sem_init.c
==============================================================================
--- fsf/trunk/libc/nptl/sem_init.c (original)
+++ fsf/trunk/libc/nptl/sem_init.c Sat May 26 00:02:20 2007
@@ -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@xxxxxxxxxx>, 2002.
 
@@ -22,6 +22,7 @@
 #include <lowlevellock.h>
 #include <shlib-compat.h>
 #include "semaphoreP.h"
+#include <kernel-features.h>
 
 
 int
@@ -38,18 +39,50 @@
     }
 
   /* 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

Modified: fsf/trunk/libc/nptl/sem_open.c
==============================================================================
--- fsf/trunk/libc/nptl/sem_open.c (original)
+++ fsf/trunk/libc/nptl/sem_open.c Sat May 26 00:02:20 2007
@@ -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@xxxxxxxxxx>, 2002.
 
@@ -304,12 +304,14 @@
       /* 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);

Modified: fsf/trunk/libc/nptl/semaphoreP.h
==============================================================================
--- fsf/trunk/libc/nptl/semaphoreP.h (original)
+++ fsf/trunk/libc/nptl/semaphoreP.h Sat May 26 00:02:20 2007
@@ -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@xxxxxxxxxx>, 2002.
 
@@ -60,8 +60,10 @@
 
 /* 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);

Modified: fsf/trunk/libc/nptl/sysdeps/unix/sysv/linux/Makefile
==============================================================================
--- fsf/trunk/libc/nptl/sysdeps/unix/sysv/linux/Makefile (original)
+++ fsf/trunk/libc/nptl/sysdeps/unix/sysv/linux/Makefile Sat May 26 00:02:20 2007
@@ -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@xxxxxxxxxx>, 2002.
 
@@ -25,7 +25,8 @@
 
 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)

Modified: fsf/trunk/libc/nptl/sysdeps/unix/sysv/linux/i386/i486/sem_post.S
==============================================================================
--- fsf/trunk/libc/nptl/sysdeps/unix/sysv/linux/i386/i486/sem_post.S (original)
+++ fsf/trunk/libc/nptl/sysdeps/unix/sysv/linux/i386/i486/sem_post.S Sat May 26 00:02:20 2007
@@ -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@xxxxxxxxxx>, 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,27 @@
 	pushl	%ebx
 
 	movl	8(%esp), %ebx
+
+	LOCK
+#if VALUE == 0
+	addl	$1, (%ebx)
+#else
+	addl	$1, VALUE(%ebx)
+#endif
+
+	cmpl	$0, NWAITERS(%ebx)
+	je	2f
+
+	movl	$FUTEX_WAKE, %ecx
+	orl	PRIVATE(%ebx), %ecx
 	movl	$1, %edx
-	LOCK
-	xaddl	%edx, (%ebx)
-
 	movl	$SYS_futex, %eax
-	movl	$FUTEX_WAKE, %ecx
-	addl	$1, %edx
 	ENTER_KERNEL
 
 	testl	%eax, %eax
 	js	1f
 
-	xorl	%eax, %eax
+2:	xorl	%eax, %eax
 	popl	%ebx
 	ret
 

Modified: fsf/trunk/libc/nptl/sysdeps/unix/sysv/linux/i386/i486/sem_timedwait.S
==============================================================================
--- fsf/trunk/libc/nptl/sysdeps/unix/sysv/linux/i386/i486/sem_timedwait.S (original)
+++ fsf/trunk/libc/nptl/sysdeps/unix/sysv/linux/i386/i486/sem_timedwait.S Sat May 26 00:02:20 2007
@@ -1,4 +1,4 @@
-/* Copyright (C) 2002, 2003, 2004, 2005 Free Software Foundation, Inc.
+/* Copyright (C) 2002, 2003, 2004, 2005, 2007 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
    Contributed by Ulrich Drepper <drepper@xxxxxxxxxx>, 2002.
 
@@ -20,6 +20,7 @@
 #include <sysdep.h>
 #include <shlib-compat.h>
 #include <pthread-errnos.h>
+#include <structsem.h>
 
 #ifndef UP
 # define LOCK lock
@@ -29,7 +30,12 @@
 
 #define SYS_gettimeofday	__NR_gettimeofday
 #define SYS_futex		240
-#define FUTEX_WAKE		1
+#define FUTEX_WAIT		0
+
+
+#if VALUE != 0
+# error "code needs to be rewritten for VALUE != 0"
+#endif
 
 
 	.text
@@ -37,14 +43,8 @@
 	.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,28 +61,25 @@
 
 	/* 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 */
-7:	call	__pthread_enable_asynccancel
-	movl	%eax, 8(%esp)
-
-	xorl	%ecx, %ecx
+	LOCK
+	incl	NWAITERS(%ecx)
+
+7:	xorl	%ecx, %ecx
 	movl	%esp, %ebx
 	movl	%ecx, %edx
 	movl	$SYS_gettimeofday, %eax
@@ -105,16 +102,27 @@
 
 	movl	%ecx, (%esp)	/* Store relative timeout.  */
 	movl	%edx, 4(%esp)
-	movl	28(%esp), %ebx
-	xorl	%ecx, %ecx
+
+.LcleanupSTART:
+	call	__pthread_enable_asynccancel
+	movl	%eax, 8(%esp)
+
+	movl	28(%esp), %ebx	/* Load semaphore address.  */
+#if FUTEX_WAIT == 0
+	movl	PRIVATE(%ebx), %ecx
+#else
+	movl	$FUTEX_WAIT, %ecx
+	orl	PRIVATE(%ebx), %ecx
+#endif
 	movl	%esp, %esi
+	xorl	%edx, %edx
 	movl	$SYS_futex, %eax
-	xorl	%edx, %edx
 	ENTER_KERNEL
 	movl	%eax, %esi
 
 	movl	8(%esp), %eax
 	call	__pthread_disable_asynccancel
+.LcleanupEND:
 
 	testl	%esi, %esi
 	je	9f
@@ -130,24 +138,22 @@
 	cmpxchgl %ecx, (%ebx)
 	jne	8b
 
+	xorl	%eax, %eax
+
+10:	LOCK
+	decl	NWAITERS(%ebx)
+
 	addl	$12, %esp
-	cfi_adjust_cfa_offset(-12)
-	xorl	%eax, %eax
+.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
@@ -171,25 +177,163 @@
 	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
-
-10:	/* Canceled.  */
-	movl	$0xffffffff, %gs:RESULT
+	jmp	10b
+	.size	sem_timedwait,.-sem_timedwait
+
+
+	.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

Modified: fsf/trunk/libc/nptl/sysdeps/unix/sysv/linux/i386/i486/sem_wait.S
==============================================================================
--- fsf/trunk/libc/nptl/sysdeps/unix/sysv/linux/i386/i486/sem_wait.S (original)
+++ fsf/trunk/libc/nptl/sysdeps/unix/sysv/linux/i386/i486/sem_wait.S Sat May 26 00:02:20 2007
@@ -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@xxxxxxxxxx>, 2002.
 
@@ -20,6 +20,7 @@
 #include <sysdep.h>
 #include <shlib-compat.h>
 #include <pthread-errnos.h>
+#include <structsem.h>
 
 #ifndef UP
 # define LOCK lock
@@ -28,34 +29,30 @@
 #endif
 
 #define SYS_futex		240
-#define FUTEX_WAKE		1
-
+#define FUTEX_WAIT		0
+
+
+#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
-	cfi_adjust_cfa_offset(4)
+.Lpush_ebx:
 	pushl	%esi
-	cfi_adjust_cfa_offset(4)
+.Lpush_esi:
 	subl	$4, %esp
-	cfi_adjust_cfa_offset(4)
+.Lsub_esp:
 
 	movl	16(%esp), %ebx
-	cfi_offset(3, -8)		/* %ebx */
-
-	cfi_offset(6, -12)		/* %esi */
-3:	movl	(%ebx), %eax
+
+	movl	(%ebx), %eax
 2:	testl	%eax, %eax
 	je	1f
 
@@ -63,42 +60,66 @@
 	LOCK
 	cmpxchgl %edx, (%ebx)
 	jne	2b
-	xorl	%eax, %eax
-
-	movl	4(%esp), %esi
-	cfi_restore(6)
+7:	xorl	%eax, %eax
+
+9:	movl	4(%esp), %esi
 	movl	8(%esp), %ebx
-	cfi_restore(3)
 	addl	$12, %esp
-	cfi_adjust_cfa_offset(-12)
+.Ladd_esp:
 	ret
 
-	cfi_adjust_cfa_offset(12)
-	cfi_offset(3, -8)		/* %ebx */
-	cfi_offset(6, -12)		/* %esi */
-1:	call	__pthread_enable_asynccancel
+.Lafter_ret:
+1:	LOCK
+	incl	NWAITERS(%ebx)
+
+.LcleanupSTART:
+6:	call	__pthread_enable_asynccancel
 	movl	%eax, (%esp)
 
+#if FUTEX_WAIT == 0
+	movl	PRIVATE(%ebx), %ecx
+#else
+	movl	$FUTEX_WAIT, %ecx
+	orl	PRIVATE(%ebx), %ecx
+#endif
 	xorl	%esi, %esi
+	xorl	%edx, %edx
 	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	3b
+	je	3f
 	cmpl	$-EWOULDBLOCK, %esi
-	je	3b
+	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	$4f, %ebx
-4:
+	movl	$8f, %ebx
+8:
 #endif
 	addl	$_GLOBAL_OFFSET_TABLE_, %ebx
 #if USE___THREAD
@@ -115,25 +136,227 @@
 	movl	%esi, (%eax)
 #endif
 	orl	$-1, %eax
-	movl	4(%esp), %esi
-	cfi_restore(6)
+
+	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
+	cfi_adjust_cfa_offset(4)
+	subl	$4, %esp
+	cfi_adjust_cfa_offset(4)
+
+	movl	16(%esp), %ebx
+	cfi_offset(ebx, -8)
+
+	cfi_offset(esi, -12)
+3:	movl	(%ebx), %eax
+2:	testl	%eax, %eax
+	je	1f
+
+	leal	-1(%eax), %edx
+	LOCK
+	cmpxchgl %edx, (%ebx)
+	jne	2b
+	xorl	%eax, %eax
+
+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
 
-5:	/* Canceled.  */
-	movl	$0xffffffff, %gs:RESULT
-	LOCK
-	orl	$0x10, %gs:CANCELHANDLING
-	movl	%gs:CLEANUP_JMP_BUF, %eax
-	jmp	HIDDEN_JUMPTARGET (__pthread_unwind)
+	cfi_adjust_cfa_offset(12)
+	cfi_offset(ebx, -8)
+	cfi_offset(esi, -12)
+1:	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
+
+	testl	%esi, %esi
+	je	3b
+	cmpl	$-EWOULDBLOCK, %esi
+	je	3b
+	negl	%esi
+#ifdef PIC
+	call	__i686.get_pc_thunk.bx
+#else
+	movl	$4f, %ebx
+4:
+#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	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

Modified: fsf/trunk/libc/nptl/sysdeps/unix/sysv/linux/internaltypes.h
==============================================================================
--- fsf/trunk/libc/nptl/sysdeps/unix/sysv/linux/internaltypes.h (original)
+++ fsf/trunk/libc/nptl/sysdeps/unix/sysv/linux/internaltypes.h Sat May 26 00:02:20 2007
@@ -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@xxxxxxxxxx>, 2002.
 
@@ -137,9 +137,16 @@
 
 
 /* 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;
 };
 
 

Modified: fsf/trunk/libc/nptl/sysdeps/unix/sysv/linux/sem_post.c
==============================================================================
--- fsf/trunk/libc/nptl/sysdeps/unix/sysv/linux/sem_post.c (original)
+++ fsf/trunk/libc/nptl/sysdeps/unix/sysv/linux/sem_post.c Sat May 26 00:02:20 2007
@@ -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@xxxxxxxxxx>, 2003.
 
@@ -29,10 +29,33 @@
 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 @@
     }
   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

Modified: fsf/trunk/libc/nptl/sysdeps/unix/sysv/linux/sem_timedwait.c
==============================================================================
--- fsf/trunk/libc/nptl/sysdeps/unix/sysv/linux/sem_timedwait.c (original)
+++ fsf/trunk/libc/nptl/sysdeps/unix/sysv/linux/sem_timedwait.c Sat May 26 00:02:20 2007
@@ -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@xxxxxxxxxx>, 2003.
 
@@ -28,28 +28,39 @@
 #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);
 
-  do
+  pthread_cleanup_push (__sem_wait_cleanup, isem);
+
+  while (1)
     {
       struct timeval tv;
       struct timespec rt;
@@ -70,7 +81,11 @@
       /* 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 @@
       /* 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);
 
- error_return:
-  __set_errno (-err);
-  return -1;
+  atomic_decrement (&isem->nwaiters);
+
+  return err;
 }

Modified: fsf/trunk/libc/nptl/sysdeps/unix/sysv/linux/sem_wait.c
==============================================================================
--- fsf/trunk/libc/nptl/sysdeps/unix/sysv/linux/sem_wait.c (original)
+++ fsf/trunk/libc/nptl/sysdeps/unix/sysv/linux/sem_wait.c Sat May 26 00:02:20 2007
@@ -28,8 +28,65 @@
 #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 @@
   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

Added: fsf/trunk/libc/nptl/sysdeps/unix/sysv/linux/structsem.sym
==============================================================================
--- fsf/trunk/libc/nptl/sysdeps/unix/sysv/linux/structsem.sym (added)
+++ fsf/trunk/libc/nptl/sysdeps/unix/sysv/linux/structsem.sym Sat May 26 00:02:20 2007
@@ -1,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)

Modified: fsf/trunk/libc/nptl/sysdeps/unix/sysv/linux/x86_64/sem_post.S
==============================================================================
--- fsf/trunk/libc/nptl/sysdeps/unix/sysv/linux/x86_64/sem_post.S (original)
+++ fsf/trunk/libc/nptl/sysdeps/unix/sysv/linux/x86_64/sem_post.S Sat May 26 00:02:20 2007
@@ -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@xxxxxxxxxx>, 2002.
 
@@ -20,6 +20,7 @@
 #include <sysdep.h>
 #include <shlib-compat.h>
 #include <pthread-errnos.h>
+#include <structsem.h>
 
 #ifndef UP
 # define LOCK lock
@@ -37,19 +38,26 @@
 	.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
+	orl	PRIVATE(%rdi), %esi
+	movl	$1, %edx
 	syscall
 
 	testq	%rax, %rax
 	js	1f
 
-	xorl	%eax, %eax
+2:	xorl	%eax, %eax
 	retq
 
 1:

Modified: fsf/trunk/libc/nptl/sysdeps/unix/sysv/linux/x86_64/sem_timedwait.S
==============================================================================
--- fsf/trunk/libc/nptl/sysdeps/unix/sysv/linux/x86_64/sem_timedwait.S (original)
+++ fsf/trunk/libc/nptl/sysdeps/unix/sysv/linux/x86_64/sem_timedwait.S Sat May 26 00:02:20 2007
@@ -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
@@ -38,15 +40,23 @@
 	.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,29 +64,26 @@
 
 	/* 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
 
-7:	call	__pthread_enable_asynccancel
-	movl	%eax, 16(%rsp)
-
-	xorl	%esi, %esi
+	LOCK
+	addq	$1, NWAITERS(%r12)
+
+7:	xorl	%esi, %esi
 	movq	%rsp, %rdi
 	movq	$VSYSCALL_ADDR_vgettimeofday, %rax
 	callq	*%rax
@@ -99,9 +106,22 @@
 	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
+#if FUTEX_WAIT == 0
+	movl	PRIVATE(%rdi), %esi
+#else
+	movl	$FUTEX_WAIT, %esi
+	orl	PRIVATE(%rdi), %esi
+#endif
 	movl	$SYS_futex, %eax
 	xorl	%edx, %edx
 	syscall
@@ -109,39 +129,47 @@
 
 	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 +182,159 @@
 
 	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

Modified: fsf/trunk/libc/nptl/sysdeps/unix/sysv/linux/x86_64/sem_wait.S
==============================================================================
--- fsf/trunk/libc/nptl/sysdeps/unix/sysv/linux/x86_64/sem_wait.S (original)
+++ fsf/trunk/libc/nptl/sysdeps/unix/sysv/linux/x86_64/sem_wait.S Sat May 26 00:02:20 2007
@@ -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
@@ -35,57 +37,93 @@
 	.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
-	LOCK
+	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
+#if FUTEX_WAIT == 0
+	movl	PRIVATE(%rdi), %esi
+#else
+	movl	$FUTEX_WAIT, %esi
+	orl	PRIVATE(%rdi), %esi
+#endif
+	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 +133,142 @@
 #endif
 	orl	$-1, %eax
 
-	popq	%r13
-	cfi_adjust_cfa_offset(-8)
-	cfi_restore(13)
-	popq	%r12
-	cfi_adjust_cfa_offset(-8)
-	cfi_restore(12)
-
-	retq
-	cfi_endproc
+	LOCK
+	subq	$1, NWAITERS(%r13)
+
+	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

Added: fsf/trunk/libc/nptl/tst-sem10.c
==============================================================================
--- fsf/trunk/libc/nptl/tst-sem10.c (added)
+++ fsf/trunk/libc/nptl/tst-sem10.c Sat May 26 00:02:20 2007
@@ -1,0 +1,88 @@
+/* Copyright (C) 2007 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+   Contributed by Jakub Jelinek <jakub@xxxxxxxxxx>, 2007.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, write to the Free
+   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+   02111-1307 USA.  */
+
+#include <errno.h>
+#include <pthread.h>
+#include <semaphore.h>
+#include <stdio.h>
+#include <time.h>
+#include <unistd.h>
+#include <sys/time.h>
+
+
+static int
+do_test (void)
+{
+  sem_t s;
+  if (sem_init (&s, 0, 0) == -1)
+    {
+      puts ("sem_init failed");
+      return 1;
+    }
+
+  struct timeval tv;
+  if (gettimeofday (&tv, NULL) != 0)
+    {
+      puts ("gettimeofday failed");
+      return 1;
+    }
+
+  struct timespec ts;
+  TIMEVAL_TO_TIMESPEC (&tv, &ts);
+
+  /* Set ts to yesterday.  */
+  ts.tv_sec -= 86400;
+
+  int type_before;
+  if (pthread_setcanceltype (PTHREAD_CANCEL_DEFERRED, &type_before) != 0)
+    {
+      puts ("first pthread_setcanceltype failed");
+      return 1;
+    }
+
+  errno = 0;
+  if (TEMP_FAILURE_RETRY (sem_timedwait (&s, &ts)) != -1)
+    {
+      puts ("sem_timedwait succeeded");
+      return 1;
+    }
+  if (errno != ETIMEDOUT)
+    {
+      printf ("sem_timedwait return errno = %d instead of ETIMEDOUT\n",
+	      errno);
+      return 1;
+    }
+
+  int type_after;
+  if (pthread_setcanceltype (PTHREAD_CANCEL_DEFERRED, &type_after) != 0)
+    {
+      puts ("second pthread_setcanceltype failed");
+      return 1;
+    }
+  if (type_after != PTHREAD_CANCEL_DEFERRED)
+    {
+      puts ("sem_timedwait changed cancellation type");
+      return 1;
+    }
+
+  return 0;
+}
+
+#define TEST_FUNCTION do_test ()
+#include "../test-skeleton.c"

Added: fsf/trunk/libc/nptl/tst-sem11.c
==============================================================================
--- fsf/trunk/libc/nptl/tst-sem11.c (added)
+++ fsf/trunk/libc/nptl/tst-sem11.c Sat May 26 00:02:20 2007
@@ -1,0 +1,76 @@
+#include <semaphore.h>
+#include <stdio.h>
+#include <unistd.h>
+#include <pthread.h>
+#include <internaltypes.h>
+
+#ifndef SEM_WAIT
+# define SEM_WAIT(s) sem_wait (s)
+#endif
+
+static void *
+tf (void *arg)
+{
+#ifdef PREPARE
+  PREPARE
+#endif
+  SEM_WAIT (arg);
+  return NULL;
+}
+
+int
+main (void)
+{
+  int tries = 5;
+  pthread_t th;
+  sem_t s;
+ again:
+  if (sem_init (&s, 0, 0) != 0)
+    {
+      puts ("sem_init failed");
+      return 1;
+    }
+
+  struct new_sem *is = (struct new_sem *) &s;
+
+  if (is->nwaiters != 0)
+    {
+      puts ("nwaiters not initialized");
+      return 1;
+    }
+
+  if (pthread_create (&th, NULL, tf, &s) != 0)
+    {
+      puts ("pthread_create failed");
+      return 1;
+    }
+
+  sleep (1);
+
+  if (pthread_cancel (th) != 0)
+    {
+      puts ("pthread_cancel failed");
+      return 1;
+    }
+
+  void *r;
+  if (pthread_join (th, &r) != 0)
+    {
+      puts ("pthread_join failed");
+      return 1;
+    }
+  if (r != PTHREAD_CANCELED && --tries > 0)
+    {
+      /* Maybe we get the scheduling right the next time.  */
+      sem_destroy (&s);
+      goto again;
+    }
+
+  if (is->nwaiters != 0)
+    {
+      puts ("nwaiters not reset");
+      return 1;
+    }
+
+  return 0;
+}

Added: fsf/trunk/libc/nptl/tst-sem12.c
==============================================================================
--- fsf/trunk/libc/nptl/tst-sem12.c (added)
+++ fsf/trunk/libc/nptl/tst-sem12.c Sat May 26 00:02:20 2007
@@ -1,0 +1,14 @@
+#include <time.h>
+#include <sys/time.h>
+
+
+#define PREPARE \
+  struct timespec ts; \
+  struct timeval tv; \
+  gettimeofday (&tv, NULL); \
+  TIMEVAL_TO_TIMESPEC (&tv, &ts); \
+  ts.tv_sec += 60;
+
+#define SEM_WAIT(s) sem_timedwait (s, &ts)
+
+#include "tst-sem11.c"

Modified: fsf/trunk/libc/nptl/tst-typesizes.c
==============================================================================
--- fsf/trunk/libc/nptl/tst-typesizes.c (original)
+++ fsf/trunk/libc/nptl/tst-typesizes.c Sat May 26 00:02:20 2007
@@ -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@xxxxxxxxxx>, 2005.
 
@@ -59,7 +59,8 @@
   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;
 }