00db10
Torvald Riegel's semaphore reimplemenation to fix upstream swbz#12674.
00db10
00db10
commit 042e1521c794a945edc43b5bfa7e69ad70420524
00db10
Author: Carlos O'Donell <carlos@systemhalted.org>
00db10
Date:   Wed Jan 21 00:46:16 2015 -0500
00db10
00db10
    Fix semaphore destruction (bug 12674).
00db10
    
00db10
    This commit fixes semaphore destruction by either using 64b atomic
00db10
    operations (where available), or by using two separate fields when only
00db10
    32b atomic operations are available.  In the latter case, we keep a
00db10
    conservative estimate of whether there are any waiting threads in one
00db10
    bit of the field that counts the number of available tokens, thus
00db10
    allowing sem_post to atomically both add a token and determine whether
00db10
    it needs to call futex_wake.
00db10
    
00db10
    See:
00db10
    https://sourceware.org/ml/libc-alpha/2014-12/msg00155.html 
00db10
00db10
Notes:
00db10
* For x86_64 and i686, rather than movign to the generic lll_futex_wake
00db10
  we fix the existing versions to return the syscall result and to be
00db10
  usable as an R-value.
00db10
* We also backport fixes for swbz#18434, and swbz#18138.
00db10
* We ignore swbz#17870 because it applies only to x32.
00db10
00db10
Index: glibc-2.17-c758a686/nptl/DESIGN-sem.txt
00db10
===================================================================
00db10
--- glibc-2.17-c758a686.orig/nptl/DESIGN-sem.txt
00db10
+++ /dev/null
00db10
@@ -1,46 +0,0 @@
00db10
-Semaphores pseudocode
00db10
-==============================
00db10
-
00db10
-       int sem_wait(sem_t * sem);
00db10
-       int sem_trywait(sem_t * sem);
00db10
-       int sem_post(sem_t * sem);
00db10
-       int sem_getvalue(sem_t * sem, int * sval);
00db10
-
00db10
-struct sem_t {
00db10
-
00db10
-   unsigned int count;
00db10
-         - current semaphore count, also used as a futex
00db10
-}
00db10
-
00db10
-sem_wait(sem_t *sem)
00db10
-{
00db10
-  for (;;) {
00db10
-
00db10
-    if (atomic_decrement_if_positive(sem->count))
00db10
-      break;
00db10
-
00db10
-    futex_wait(&sem->count, 0)
00db10
-  }
00db10
-}
00db10
-
00db10
-sem_post(sem_t *sem)
00db10
-{
00db10
-  n = atomic_increment(sem->count);
00db10
-  // Pass the new value of sem->count
00db10
-  futex_wake(&sem->count, n + 1);
00db10
-}
00db10
-
00db10
-sem_trywait(sem_t *sem)
00db10
-{
00db10
-  if (atomic_decrement_if_positive(sem->count)) {
00db10
-    return 0;
00db10
-  } else {
00db10
-    return EAGAIN;
00db10
-  }
00db10
-}
00db10
-
00db10
-sem_getvalue(sem_t *sem, int *sval)
00db10
-{
00db10
-  *sval = sem->count;
00db10
-  read_barrier();
00db10
-}
00db10
Index: glibc-2.17-c758a686/nptl/Makefile
00db10
===================================================================
00db10
--- glibc-2.17-c758a686.orig/nptl/Makefile
00db10
+++ glibc-2.17-c758a686/nptl/Makefile
00db10
@@ -95,7 +95,7 @@ libpthread-routines = nptl-init vars eve
00db10
 		      sem_init sem_destroy \
00db10
 		      sem_open sem_close sem_unlink \
00db10
 		      sem_getvalue \
00db10
-		      sem_wait sem_trywait sem_timedwait sem_post \
00db10
+		      sem_wait sem_timedwait sem_post \
00db10
 		      cleanup cleanup_defer cleanup_compat \
00db10
 		      cleanup_defer_compat unwind \
00db10
 		      pt-longjmp pt-cleanup\
00db10
Index: glibc-2.17-c758a686/nptl/sem_getvalue.c
00db10
===================================================================
00db10
--- glibc-2.17-c758a686.orig/nptl/sem_getvalue.c
00db10
+++ glibc-2.17-c758a686/nptl/sem_getvalue.c
00db10
@@ -19,23 +19,37 @@
00db10
 #include <semaphore.h>
00db10
 #include <shlib-compat.h>
00db10
 #include "semaphoreP.h"
00db10
+#include <atomic.h>
00db10
 
00db10
 
00db10
 int
00db10
-__new_sem_getvalue (sem, sval)
00db10
-     sem_t *sem;
00db10
-     int *sval;
00db10
+__new_sem_getvalue (sem_t *sem, int *sval)
00db10
 {
00db10
   struct new_sem *isem = (struct new_sem *) sem;
00db10
 
00db10
   /* XXX Check for valid SEM parameter.  */
00db10
+  /* FIXME This uses relaxed MO, even though POSIX specifies that this function
00db10
+     should be linearizable.  However, its debatable whether linearizability
00db10
+     is the right requirement.  We need to follow up with POSIX and, if
00db10
+     necessary, use a stronger MO here and elsewhere (e.g., potentially
00db10
+     release MO in all places where we consume a token).  */
00db10
 
00db10
-  *sval = isem->value;
00db10
+#if __HAVE_64B_ATOMICS
00db10
+  *sval = atomic_load_relaxed (&isem->data) & SEM_VALUE_MASK;
00db10
+#else
00db10
+  *sval = atomic_load_relaxed (&isem->value) >> SEM_VALUE_SHIFT;
00db10
+#endif
00db10
 
00db10
   return 0;
00db10
 }
00db10
 versioned_symbol (libpthread, __new_sem_getvalue, sem_getvalue, GLIBC_2_1);
00db10
 #if SHLIB_COMPAT(libpthread, GLIBC_2_0, GLIBC_2_1)
00db10
-strong_alias (__new_sem_getvalue, __old_sem_getvalue)
00db10
+int
00db10
+__old_sem_getvalue (sem_t *sem, int *sval)
00db10
+{
00db10
+  struct old_sem *isem = (struct old_sem *) sem;
00db10
+  *sval = isem->value;
00db10
+  return 0;
00db10
+}
00db10
 compat_symbol (libpthread, __old_sem_getvalue, sem_getvalue, GLIBC_2_0);
00db10
 #endif
00db10
Index: glibc-2.17-c758a686/nptl/sem_init.c
00db10
===================================================================
00db10
--- glibc-2.17-c758a686.orig/nptl/sem_init.c
00db10
+++ glibc-2.17-c758a686/nptl/sem_init.c
00db10
@@ -18,17 +18,28 @@
00db10
 
00db10
 #include <errno.h>
00db10
 #include <semaphore.h>
00db10
-#include <lowlevellock.h>
00db10
 #include <shlib-compat.h>
00db10
 #include "semaphoreP.h"
00db10
 #include <kernel-features.h>
00db10
 
00db10
+/* Returns FUTEX_PRIVATE if pshared is zero and private futexes are supported;
00db10
+   returns FUTEX_SHARED otherwise.
00db10
+   TODO Remove when cleaning up the futex API throughout glibc.  */
00db10
+static __always_inline int
00db10
+futex_private_if_supported (int pshared)
00db10
+{
00db10
+  if (pshared != 0)
00db10
+    return LLL_SHARED;
00db10
+#ifdef __ASSUME_PRIVATE_FUTEX
00db10
+  return LLL_PRIVATE;
00db10
+#else
00db10
+  return THREAD_GETMEM (THREAD_SELF, header.private_futex)
00db10
+      ^ FUTEX_PRIVATE_FLAG;
00db10
+#endif
00db10
+}
00db10
 
00db10
 int
00db10
-__new_sem_init (sem, pshared, value)
00db10
-     sem_t *sem;
00db10
-     int pshared;
00db10
-     unsigned int value;
00db10
+__new_sem_init (sem_t *sem, int pshared, unsigned int value)
00db10
 {
00db10
   /* Parameter sanity check.  */
00db10
   if (__builtin_expect (value > SEM_VALUE_MAX, 0))
00db10
@@ -40,16 +51,15 @@ __new_sem_init (sem, pshared, value)
00db10
   /* Map to the internal type.  */
00db10
   struct new_sem *isem = (struct new_sem *) sem;
00db10
 
00db10
-  /* Use the values the user provided.  */
00db10
-  isem->value = value;
00db10
-#ifdef __ASSUME_PRIVATE_FUTEX
00db10
-  isem->private = pshared ? 0 : FUTEX_PRIVATE_FLAG;
00db10
+  /* Use the values the caller provided.  */
00db10
+#if __HAVE_64B_ATOMICS
00db10
+  isem->data = value;
00db10
 #else
00db10
-  isem->private = pshared ? 0 : THREAD_GETMEM (THREAD_SELF,
00db10
-					       header.private_futex);
00db10
+  isem->value = value << SEM_VALUE_SHIFT;
00db10
+  isem->nwaiters = 0;
00db10
 #endif
00db10
 
00db10
-  isem->nwaiters = 0;
00db10
+  isem->private = futex_private_if_supported (pshared);
00db10
 
00db10
   return 0;
00db10
 }
00db10
Index: glibc-2.17-c758a686/nptl/sem_open.c
00db10
===================================================================
00db10
--- glibc-2.17-c758a686.orig/nptl/sem_open.c
00db10
+++ glibc-2.17-c758a686/nptl/sem_open.c
00db10
@@ -307,9 +307,14 @@ sem_open (const char *name, int oflag, .
00db10
 	struct new_sem newsem;
00db10
       } sem;
00db10
 
00db10
-      sem.newsem.value = value;
00db10
-      sem.newsem.private = 0;
00db10
+#if __HAVE_64B_ATOMICS
00db10
+      sem.newsem.data = value;
00db10
+#else
00db10
+      sem.newsem.value = value << SEM_VALUE_SHIFT;
00db10
       sem.newsem.nwaiters = 0;
00db10
+#endif
00db10
+      /* This always is a shared semaphore.  */
00db10
+      sem.newsem.private = LLL_SHARED;
00db10
 
00db10
       /* Initialize the remaining bytes as well.  */
00db10
       memset ((char *) &sem.initsem + sizeof (struct new_sem), '\0',
00db10
Index: glibc-2.17-c758a686/nptl/tst-sem11.c
00db10
===================================================================
00db10
--- glibc-2.17-c758a686.orig/nptl/tst-sem11.c
00db10
+++ glibc-2.17-c758a686/nptl/tst-sem11.c
00db10
@@ -34,8 +34,11 @@ main (void)
00db10
       puts ("sem_init failed");
00db10
       return 1;
00db10
     }
00db10
-
00db10
+#if __HAVE_64B_ATOMICS
00db10
+  if ((u.ns.data >> SEM_NWAITERS_SHIFT) != 0)
00db10
+#else
00db10
   if (u.ns.nwaiters != 0)
00db10
+#endif
00db10
     {
00db10
       puts ("nwaiters not initialized");
00db10
       return 1;
00db10
@@ -68,7 +71,11 @@ main (void)
00db10
       goto again;
00db10
     }
00db10
 
00db10
+#if __HAVE_64B_ATOMICS
00db10
+  if ((u.ns.data >> SEM_NWAITERS_SHIFT) != 0)
00db10
+#else
00db10
   if (u.ns.nwaiters != 0)
00db10
+#endif
00db10
     {
00db10
       puts ("nwaiters not reset");
00db10
       return 1;
00db10
Index: glibc-2.17-c758a686/nptl/tst-sem13.c
00db10
===================================================================
00db10
--- glibc-2.17-c758a686.orig/nptl/tst-sem13.c
00db10
+++ glibc-2.17-c758a686/nptl/tst-sem13.c
00db10
@@ -33,9 +33,14 @@ do_test (void)
00db10
       perror ("sem_timedwait did not fail with EINVAL");
00db10
       return 1;
00db10
     }
00db10
-  if (u.ns.nwaiters != 0)
00db10
+#if __HAVE_64B_ATOMICS
00db10
+  unsigned int nwaiters = (u.ns.data >> SEM_NWAITERS_SHIFT);
00db10
+#else
00db10
+  unsigned int nwaiters = u.ns.nwaiters;
00db10
+#endif
00db10
+  if (nwaiters != 0)
00db10
     {
00db10
-      printf ("sem_timedwait modified nwaiters: %ld\n", u.ns.nwaiters);
00db10
+      printf ("sem_timedwait modified nwaiters: %d\n", nwaiters);
00db10
       return 1;
00db10
     }
00db10
 
00db10
@@ -52,9 +57,14 @@ do_test (void)
00db10
       perror ("2nd sem_timedwait did not fail with ETIMEDOUT");
00db10
       return 1;
00db10
     }
00db10
-  if (u.ns.nwaiters != 0)
00db10
+#if __HAVE_64B_ATOMICS
00db10
+  nwaiters = (u.ns.data >> SEM_NWAITERS_SHIFT);
00db10
+#else
00db10
+  nwaiters = u.ns.nwaiters;
00db10
+#endif
00db10
+  if (nwaiters != 0)
00db10
     {
00db10
-      printf ("2nd sem_timedwait modified nwaiters: %ld\n", u.ns.nwaiters);
00db10
+      printf ("2nd sem_timedwait modified nwaiters: %d\n", nwaiters);
00db10
       return 1;
00db10
     }
00db10
 
00db10
Index: glibc-2.17-c758a686/nptl/sysdeps/unix/sysv/linux/i386/i486/sem_post.S
00db10
===================================================================
00db10
--- glibc-2.17-c758a686.orig/nptl/sysdeps/unix/sysv/linux/i386/i486/sem_post.S
00db10
+++ /dev/null
00db10
@@ -1,151 +0,0 @@
00db10
-/* Copyright (C) 2002,2003,2005,2007,2008,2011-2012
00db10
-   Free Software Foundation, Inc.
00db10
-   This file is part of the GNU C Library.
00db10
-   Contributed by Ulrich Drepper <drepper@redhat.com>, 2002.
00db10
-
00db10
-   The GNU C Library is free software; you can redistribute it and/or
00db10
-   modify it under the terms of the GNU Lesser General Public
00db10
-   License as published by the Free Software Foundation; either
00db10
-   version 2.1 of the License, or (at your option) any later version.
00db10
-
00db10
-   The GNU C Library is distributed in the hope that it will be useful,
00db10
-   but WITHOUT ANY WARRANTY; without even the implied warranty of
00db10
-   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00db10
-   Lesser General Public License for more details.
00db10
-
00db10
-   You should have received a copy of the GNU Lesser General Public
00db10
-   License along with the GNU C Library; if not, see
00db10
-   <http://www.gnu.org/licenses/>.  */
00db10
-
00db10
-#include <sysdep.h>
00db10
-#include <shlib-compat.h>
00db10
-#include <pthread-errnos.h>
00db10
-#include <structsem.h>
00db10
-#include <lowlevellock.h>
00db10
-
00db10
-
00db10
-	.text
00db10
-
00db10
-	.globl	__new_sem_post
00db10
-	.type	__new_sem_post,@function
00db10
-	.align	16
00db10
-__new_sem_post:
00db10
-	cfi_startproc
00db10
-	pushl	%ebx
00db10
-	cfi_adjust_cfa_offset(4)
00db10
-	cfi_offset(%ebx, -8)
00db10
-
00db10
-	movl	8(%esp), %ebx
00db10
-
00db10
-#if VALUE == 0
00db10
-	movl	(%ebx), %eax
00db10
-#else
00db10
-	movl	VALUE(%ebx), %eax
00db10
-#endif
00db10
-0:	cmpl	$SEM_VALUE_MAX, %eax
00db10
-	je	3f
00db10
-	leal	1(%eax), %edx
00db10
-	LOCK
00db10
-#if VALUE == 0
00db10
-	cmpxchgl %edx, (%ebx)
00db10
-#else
00db10
-	cmpxchgl %edx, VALUE(%ebx)
00db10
-#endif
00db10
-	jnz	0b
00db10
-
00db10
-	cmpl	$0, NWAITERS(%ebx)
00db10
-	je	2f
00db10
-
00db10
-	movl	$FUTEX_WAKE, %ecx
00db10
-	orl	PRIVATE(%ebx), %ecx
00db10
-	movl	$1, %edx
00db10
-	movl	$SYS_futex, %eax
00db10
-	ENTER_KERNEL
00db10
-
00db10
-	testl	%eax, %eax
00db10
-	js	1f
00db10
-
00db10
-2:	xorl	%eax, %eax
00db10
-	popl	%ebx
00db10
-	cfi_adjust_cfa_offset(-4)
00db10
-	cfi_restore(%ebx)
00db10
-	ret
00db10
-
00db10
-	cfi_adjust_cfa_offset(4)
00db10
-	cfi_offset(%ebx, -8)
00db10
-1:
00db10
-#ifdef PIC
00db10
-	SETUP_PIC_REG(bx)
00db10
-#else
00db10
-	movl	$4f, %ebx
00db10
-4:
00db10
-#endif
00db10
-	addl	$_GLOBAL_OFFSET_TABLE_, %ebx
00db10
-#ifdef NO_TLS_DIRECT_SEG_REFS
00db10
-	movl	errno@gotntpoff(%ebx), %edx
00db10
-	addl	%gs:0, %edx
00db10
-	movl	$EINVAL, (%edx)
00db10
-#else
00db10
-	movl	errno@gotntpoff(%ebx), %edx
00db10
-	movl	$EINVAL, %gs:(%edx)
00db10
-#endif
00db10
-
00db10
-	orl	$-1, %eax
00db10
-	popl	%ebx
00db10
-	ret
00db10
-
00db10
-3:
00db10
-#ifdef PIC
00db10
-	SETUP_PIC_REG(bx)
00db10
-#else
00db10
-	movl	$5f, %ebx
00db10
-5:
00db10
-#endif
00db10
-	addl	$_GLOBAL_OFFSET_TABLE_, %ebx
00db10
-#ifdef NO_TLS_DIRECT_SEG_REFS
00db10
-	movl	errno@gotntpoff(%ebx), %edx
00db10
-	addl	%gs:0, %edx
00db10
-	movl	$EOVERFLOW, (%edx)
00db10
-#else
00db10
-	movl	errno@gotntpoff(%ebx), %edx
00db10
-	movl	$EOVERFLOW, %gs:(%edx)
00db10
-#endif
00db10
-
00db10
-	orl	$-1, %eax
00db10
-	popl	%ebx
00db10
-	cfi_adjust_cfa_offset(-4)
00db10
-	cfi_restore(%ebx)
00db10
-	ret
00db10
-	cfi_endproc
00db10
-	.size	__new_sem_post,.-__new_sem_post
00db10
-	versioned_symbol(libpthread, __new_sem_post, sem_post, GLIBC_2_1)
00db10
-#if SHLIB_COMPAT(libpthread, GLIBC_2_0, GLIBC_2_1)
00db10
-	.global	__old_sem_post
00db10
-	.type	__old_sem_post,@function
00db10
-__old_sem_post:
00db10
-	cfi_startproc
00db10
-	pushl	%ebx
00db10
-	cfi_adjust_cfa_offset(4)
00db10
-	cfi_offset(%ebx, -8)
00db10
-
00db10
-	movl	8(%esp), %ebx
00db10
-	LOCK
00db10
-	addl	$1, (%ebx)
00db10
-
00db10
-	movl	$SYS_futex, %eax
00db10
-	movl	$FUTEX_WAKE, %ecx
00db10
-	movl	$1, %edx
00db10
-	ENTER_KERNEL
00db10
-
00db10
-	testl	%eax, %eax
00db10
-	js	1b
00db10
-
00db10
-	xorl	%eax, %eax
00db10
-	popl	%ebx
00db10
-	cfi_adjust_cfa_offset(-4)
00db10
-	cfi_restore(%ebx)
00db10
-	ret
00db10
-	cfi_endproc
00db10
-	.size	__old_sem_post,.-__old_sem_post
00db10
-	compat_symbol(libpthread, __old_sem_post, sem_post, GLIBC_2_0)
00db10
-#endif
00db10
Index: glibc-2.17-c758a686/nptl/sysdeps/unix/sysv/linux/i386/i486/sem_timedwait.S
00db10
===================================================================
00db10
--- glibc-2.17-c758a686.orig/nptl/sysdeps/unix/sysv/linux/i386/i486/sem_timedwait.S
00db10
+++ /dev/null
00db10
@@ -1,327 +0,0 @@
00db10
-/* Copyright (C) 2002-2012 Free Software Foundation, Inc.
00db10
-   This file is part of the GNU C Library.
00db10
-   Contributed by Ulrich Drepper <drepper@redhat.com>, 2002.
00db10
-
00db10
-   The GNU C Library is free software; you can redistribute it and/or
00db10
-   modify it under the terms of the GNU Lesser General Public
00db10
-   License as published by the Free Software Foundation; either
00db10
-   version 2.1 of the License, or (at your option) any later version.
00db10
-
00db10
-   The GNU C Library is distributed in the hope that it will be useful,
00db10
-   but WITHOUT ANY WARRANTY; without even the implied warranty of
00db10
-   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00db10
-   Lesser General Public License for more details.
00db10
-
00db10
-   You should have received a copy of the GNU Lesser General Public
00db10
-   License along with the GNU C Library; if not, see
00db10
-   <http://www.gnu.org/licenses/>.  */
00db10
-
00db10
-#include <sysdep.h>
00db10
-#include <shlib-compat.h>
00db10
-#include <pthread-errnos.h>
00db10
-#include <structsem.h>
00db10
-#include <lowlevellock.h>
00db10
-
00db10
-
00db10
-#if VALUE != 0
00db10
-# error "code needs to be rewritten for VALUE != 0"
00db10
-#endif
00db10
-
00db10
-
00db10
-	.text
00db10
-
00db10
-	.globl	sem_timedwait
00db10
-	.type	sem_timedwait,@function
00db10
-	.align	16
00db10
-sem_timedwait:
00db10
-.LSTARTCODE:
00db10
-	movl	4(%esp), %ecx
00db10
-
00db10
-	movl	(%ecx), %eax
00db10
-2:	testl	%eax, %eax
00db10
-	je	1f
00db10
-
00db10
-	leal	-1(%eax), %edx
00db10
-	LOCK
00db10
-	cmpxchgl %edx, (%ecx)
00db10
-	jne	2b
00db10
-
00db10
-	xorl	%eax, %eax
00db10
-	ret
00db10
-
00db10
-	/* Check whether the timeout value is valid.  */
00db10
-1:	pushl	%esi
00db10
-.Lpush_esi:
00db10
-	pushl	%edi
00db10
-.Lpush_edi:
00db10
-	pushl	%ebx
00db10
-.Lpush_ebx:
00db10
-	subl	$12, %esp
00db10
-.Lsub_esp:
00db10
-
00db10
-	movl	32(%esp), %edi
00db10
-
00db10
-	/* Check for invalid nanosecond field.  */
00db10
-	cmpl	$1000000000, 4(%edi)
00db10
-	movl	$EINVAL, %esi
00db10
-	jae	.Lerrno_exit
00db10
-
00db10
-	LOCK
00db10
-	incl	NWAITERS(%ecx)
00db10
-
00db10
-7:	xorl	%ecx, %ecx
00db10
-	movl	%esp, %ebx
00db10
-	movl	%ecx, %edx
00db10
-	movl	$__NR_gettimeofday, %eax
00db10
-	ENTER_KERNEL
00db10
-
00db10
-	/* Compute relative timeout.  */
00db10
-	movl	4(%esp), %eax
00db10
-	movl	$1000, %edx
00db10
-	mul	%edx		/* Milli seconds to nano seconds.  */
00db10
-	movl	(%edi), %ecx
00db10
-	movl	4(%edi), %edx
00db10
-	subl	(%esp), %ecx
00db10
-	subl	%eax, %edx
00db10
-	jns	5f
00db10
-	addl	$1000000000, %edx
00db10
-	subl	$1, %ecx
00db10
-5:	testl	%ecx, %ecx
00db10
-	movl	$ETIMEDOUT, %esi
00db10
-	js	6f		/* Time is already up.  */
00db10
-
00db10
-	movl	%ecx, (%esp)	/* Store relative timeout.  */
00db10
-	movl	%edx, 4(%esp)
00db10
-
00db10
-.LcleanupSTART:
00db10
-	call	__pthread_enable_asynccancel
00db10
-	movl	%eax, 8(%esp)
00db10
-
00db10
-	movl	28(%esp), %ebx	/* Load semaphore address.  */
00db10
-#if FUTEX_WAIT == 0
00db10
-	movl	PRIVATE(%ebx), %ecx
00db10
-#else
00db10
-	movl	$FUTEX_WAIT, %ecx
00db10
-	orl	PRIVATE(%ebx), %ecx
00db10
-#endif
00db10
-	movl	%esp, %esi
00db10
-	xorl	%edx, %edx
00db10
-	movl	$SYS_futex, %eax
00db10
-	ENTER_KERNEL
00db10
-	movl	%eax, %esi
00db10
-
00db10
-	movl	8(%esp), %eax
00db10
-	call	__pthread_disable_asynccancel
00db10
-.LcleanupEND:
00db10
-
00db10
-	testl	%esi, %esi
00db10
-	je	9f
00db10
-	cmpl	$-EWOULDBLOCK, %esi
00db10
-	jne	3f
00db10
-
00db10
-9:	movl	(%ebx), %eax
00db10
-8:	testl	%eax, %eax
00db10
-	je	7b
00db10
-
00db10
-	leal	-1(%eax), %ecx
00db10
-	LOCK
00db10
-	cmpxchgl %ecx, (%ebx)
00db10
-	jne	8b
00db10
-
00db10
-	xorl	%eax, %eax
00db10
-
00db10
-	LOCK
00db10
-	decl	NWAITERS(%ebx)
00db10
-
00db10
-10:	addl	$12, %esp
00db10
-.Ladd_esp:
00db10
-	popl	%ebx
00db10
-.Lpop_ebx:
00db10
-	popl	%edi
00db10
-.Lpop_edi:
00db10
-	popl	%esi
00db10
-.Lpop_esi:
00db10
-	ret
00db10
-
00db10
-.Lafter_ret:
00db10
-3:	negl	%esi
00db10
-6:
00db10
-	movl	28(%esp), %ebx	/* Load semaphore address.  */
00db10
-	LOCK
00db10
-	decl	NWAITERS(%ebx)
00db10
-.Lerrno_exit:
00db10
-#ifdef PIC
00db10
-	SETUP_PIC_REG(bx)
00db10
-#else
00db10
-	movl	$4f, %ebx
00db10
-4:
00db10
-#endif
00db10
-	addl	$_GLOBAL_OFFSET_TABLE_, %ebx
00db10
-#ifdef NO_TLS_DIRECT_SEG_REFS
00db10
-	movl	errno@gotntpoff(%ebx), %edx
00db10
-	addl	%gs:0, %edx
00db10
-	movl	%esi, (%edx)
00db10
-#else
00db10
-	movl	errno@gotntpoff(%ebx), %edx
00db10
-	movl	%esi, %gs:(%edx)
00db10
-#endif
00db10
-
00db10
-	orl	$-1, %eax
00db10
-	jmp	10b
00db10
-	.size	sem_timedwait,.-sem_timedwait
00db10
-
00db10
-
00db10
-	.type	sem_wait_cleanup,@function
00db10
-sem_wait_cleanup:
00db10
-	LOCK
00db10
-	decl	NWAITERS(%ebx)
00db10
-	movl	%eax, (%esp)
00db10
-.LcallUR:
00db10
-	call	_Unwind_Resume@PLT
00db10
-	hlt
00db10
-.LENDCODE:
00db10
-	.size	sem_wait_cleanup,.-sem_wait_cleanup
00db10
-
00db10
-
00db10
-	.section .gcc_except_table,"a",@progbits
00db10
-.LexceptSTART:
00db10
-	.byte	0xff				# @LPStart format (omit)
00db10
-	.byte	0xff				# @TType format (omit)
00db10
-	.byte	0x01				# call-site format
00db10
-						# DW_EH_PE_uleb128
00db10
-	.uleb128 .Lcstend-.Lcstbegin
00db10
-.Lcstbegin:
00db10
-	.uleb128 .LcleanupSTART-.LSTARTCODE
00db10
-	.uleb128 .LcleanupEND-.LcleanupSTART
00db10
-	.uleb128 sem_wait_cleanup-.LSTARTCODE
00db10
-	.uleb128  0
00db10
-	.uleb128 .LcallUR-.LSTARTCODE
00db10
-	.uleb128 .LENDCODE-.LcallUR
00db10
-	.uleb128 0
00db10
-	.uleb128  0
00db10
-.Lcstend:
00db10
-
00db10
-
00db10
-	.section .eh_frame,"a",@progbits
00db10
-.LSTARTFRAME:
00db10
-	.long	.LENDCIE-.LSTARTCIE		# Length of the CIE.
00db10
-.LSTARTCIE:
00db10
-	.long	0				# CIE ID.
00db10
-	.byte	1				# Version number.
00db10
-#ifdef SHARED
00db10
-	.string	"zPLR"				# NUL-terminated augmentation
00db10
-						# string.
00db10
-#else
00db10
-	.string	"zPL"				# NUL-terminated augmentation
00db10
-						# string.
00db10
-#endif
00db10
-	.uleb128 1				# Code alignment factor.
00db10
-	.sleb128 -4				# Data alignment factor.
00db10
-	.byte	8				# Return address register
00db10
-						# column.
00db10
-#ifdef SHARED
00db10
-	.uleb128 7				# Augmentation value length.
00db10
-	.byte	0x9b				# Personality: DW_EH_PE_pcrel
00db10
-						# + DW_EH_PE_sdata4
00db10
-						# + DW_EH_PE_indirect
00db10
-	.long	DW.ref.__gcc_personality_v0-.
00db10
-	.byte	0x1b				# LSDA Encoding: DW_EH_PE_pcrel
00db10
-						# + DW_EH_PE_sdata4.
00db10
-	.byte	0x1b				# FDE Encoding: DW_EH_PE_pcrel
00db10
-						# + DW_EH_PE_sdata4.
00db10
-#else
00db10
-	.uleb128 6				# Augmentation value length.
00db10
-	.byte	0x0				# Personality: absolute
00db10
-	.long	__gcc_personality_v0
00db10
-	.byte	0x0				# LSDA Encoding: absolute
00db10
-#endif
00db10
-	.byte 0x0c				# DW_CFA_def_cfa
00db10
-	.uleb128 4
00db10
-	.uleb128 4
00db10
-	.byte	0x88				# DW_CFA_offset, column 0x10
00db10
-	.uleb128 1
00db10
-	.align 4
00db10
-.LENDCIE:
00db10
-
00db10
-	.long	.LENDFDE-.LSTARTFDE		# Length of the FDE.
00db10
-.LSTARTFDE:
00db10
-	.long	.LSTARTFDE-.LSTARTFRAME		# CIE pointer.
00db10
-#ifdef SHARED
00db10
-	.long	.LSTARTCODE-.			# PC-relative start address
00db10
-						# of the code.
00db10
-#else
00db10
-	.long	.LSTARTCODE			# Start address of the code.
00db10
-#endif
00db10
-	.long	.LENDCODE-.LSTARTCODE		# Length of the code.
00db10
-	.uleb128 4				# Augmentation size
00db10
-#ifdef SHARED
00db10
-	.long	.LexceptSTART-.
00db10
-#else
00db10
-	.long	.LexceptSTART
00db10
-#endif
00db10
-
00db10
-	.byte	4				# DW_CFA_advance_loc4
00db10
-	.long	.Lpush_esi-.LSTARTCODE
00db10
-	.byte	14				# DW_CFA_def_cfa_offset
00db10
-	.uleb128 8
00db10
-	.byte   0x86				# DW_CFA_offset %esi
00db10
-	.uleb128 2
00db10
-	.byte	4				# DW_CFA_advance_loc4
00db10
-	.long	.Lpush_edi-.Lpush_esi
00db10
-	.byte	14				# DW_CFA_def_cfa_offset
00db10
-	.uleb128 12
00db10
-	.byte   0x87				# DW_CFA_offset %edi
00db10
-	.uleb128 3
00db10
-	.byte	4				# DW_CFA_advance_loc4
00db10
-	.long	.Lpush_ebx-.Lpush_edi
00db10
-	.byte	14				# DW_CFA_def_cfa_offset
00db10
-	.uleb128 16
00db10
-	.byte   0x83				# DW_CFA_offset %ebx
00db10
-	.uleb128 4
00db10
-	.byte	4				# DW_CFA_advance_loc4
00db10
-	.long	.Lsub_esp-.Lpush_ebx
00db10
-	.byte	14				# DW_CFA_def_cfa_offset
00db10
-	.uleb128 28
00db10
-	.byte	4				# DW_CFA_advance_loc4
00db10
-	.long	.Ladd_esp-.Lsub_esp
00db10
-	.byte	14				# DW_CFA_def_cfa_offset
00db10
-	.uleb128 16
00db10
-	.byte	4				# DW_CFA_advance_loc4
00db10
-	.long	.Lpop_ebx-.Ladd_esp
00db10
-	.byte	14				# DW_CFA_def_cfa_offset
00db10
-	.uleb128 12
00db10
-	.byte	0xc3				# DW_CFA_restore %ebx
00db10
-	.byte	4				# DW_CFA_advance_loc4
00db10
-	.long	.Lpop_edi-.Lpop_ebx
00db10
-	.byte	14				# DW_CFA_def_cfa_offset
00db10
-	.uleb128 8
00db10
-	.byte	0xc7				# DW_CFA_restore %edi
00db10
-	.byte	4				# DW_CFA_advance_loc4
00db10
-	.long	.Lpop_esi-.Lpop_edi
00db10
-	.byte	14				# DW_CFA_def_cfa_offset
00db10
-	.uleb128 4
00db10
-	.byte	0xc6				# DW_CFA_restore %esi
00db10
-	.byte	4				# DW_CFA_advance_loc4
00db10
-	.long	.Lafter_ret-.Lpop_esi
00db10
-	.byte	14				# DW_CFA_def_cfa_offset
00db10
-	.uleb128 28
00db10
-	.byte   0x86				# DW_CFA_offset %esi
00db10
-	.uleb128 2
00db10
-	.byte   0x87				# DW_CFA_offset %edi
00db10
-	.uleb128 3
00db10
-	.byte   0x83				# DW_CFA_offset %ebx
00db10
-	.uleb128 4
00db10
-	.align	4
00db10
-.LENDFDE:
00db10
-
00db10
-
00db10
-#ifdef SHARED
00db10
-	.hidden	DW.ref.__gcc_personality_v0
00db10
-	.weak	DW.ref.__gcc_personality_v0
00db10
-	.section .gnu.linkonce.d.DW.ref.__gcc_personality_v0,"aw",@progbits
00db10
-	.align	4
00db10
-	.type	DW.ref.__gcc_personality_v0, @object
00db10
-	.size	DW.ref.__gcc_personality_v0, 4
00db10
-DW.ref.__gcc_personality_v0:
00db10
-	.long	__gcc_personality_v0
00db10
-#endif
00db10
Index: glibc-2.17-c758a686/nptl/sysdeps/unix/sysv/linux/i386/i486/sem_trywait.S
00db10
===================================================================
00db10
--- glibc-2.17-c758a686.orig/nptl/sysdeps/unix/sysv/linux/i386/i486/sem_trywait.S
00db10
+++ /dev/null
00db10
@@ -1,67 +0,0 @@
00db10
-/* Copyright (C) 2002-2003, 2005, 2007, 2011-2012 Free Software Foundation, Inc.
00db10
-   This file is part of the GNU C Library.
00db10
-   Contributed by Ulrich Drepper <drepper@redhat.com>, 2002.
00db10
-
00db10
-   The GNU C Library is free software; you can redistribute it and/or
00db10
-   modify it under the terms of the GNU Lesser General Public
00db10
-   License as published by the Free Software Foundation; either
00db10
-   version 2.1 of the License, or (at your option) any later version.
00db10
-
00db10
-   The GNU C Library is distributed in the hope that it will be useful,
00db10
-   but WITHOUT ANY WARRANTY; without even the implied warranty of
00db10
-   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00db10
-   Lesser General Public License for more details.
00db10
-
00db10
-   You should have received a copy of the GNU Lesser General Public
00db10
-   License along with the GNU C Library; if not, see
00db10
-   <http://www.gnu.org/licenses/>.  */
00db10
-
00db10
-#include <sysdep.h>
00db10
-#include <shlib-compat.h>
00db10
-#include <pthread-errnos.h>
00db10
-#include <lowlevellock.h>
00db10
-
00db10
-	.text
00db10
-
00db10
-	.globl	__new_sem_trywait
00db10
-	.type	__new_sem_trywait,@function
00db10
-	.align	16
00db10
-__new_sem_trywait:
00db10
-	movl	4(%esp), %ecx
00db10
-
00db10
-	movl	(%ecx), %eax
00db10
-2:	testl	%eax, %eax
00db10
-	jz	1f
00db10
-
00db10
-	leal	-1(%eax), %edx
00db10
-	LOCK
00db10
-	cmpxchgl %edx, (%ecx)
00db10
-	jne	2b
00db10
-	xorl	%eax, %eax
00db10
-	ret
00db10
-
00db10
-1:
00db10
-#ifdef PIC
00db10
-	SETUP_PIC_REG(cx)
00db10
-#else
00db10
-	movl	$3f, %ecx
00db10
-3:
00db10
-#endif
00db10
-	addl	$_GLOBAL_OFFSET_TABLE_, %ecx
00db10
-#ifdef NO_TLS_DIRECT_SEG_REFS
00db10
-	movl	errno@gotntpoff(%ecx), %edx
00db10
-	addl	%gs:0, %edx
00db10
-	movl	$EAGAIN, (%edx)
00db10
-#else
00db10
-	movl	errno@gotntpoff(%ecx), %edx
00db10
-	movl	$EAGAIN, %gs:(%edx)
00db10
-#endif
00db10
-	orl	$-1, %eax
00db10
-	ret
00db10
-	.size	__new_sem_trywait,.-__new_sem_trywait
00db10
-	versioned_symbol(libpthread, __new_sem_trywait, sem_trywait, GLIBC_2_1)
00db10
-#if SHLIB_COMPAT(libpthread, GLIBC_2_0, GLIBC_2_1)
00db10
-	.global	__old_sem_trywait
00db10
-__old_sem_trywait = __new_sem_trywait
00db10
-	compat_symbol(libpthread, __old_sem_trywait, sem_trywait, GLIBC_2_0)
00db10
-#endif
00db10
Index: glibc-2.17-c758a686/nptl/sysdeps/unix/sysv/linux/i386/i486/sem_wait.S
00db10
===================================================================
00db10
--- glibc-2.17-c758a686.orig/nptl/sysdeps/unix/sysv/linux/i386/i486/sem_wait.S
00db10
+++ /dev/null
00db10
@@ -1,343 +0,0 @@
00db10
-/* Copyright (C) 2002-2003, 2005, 2007, 2011-2012 Free Software Foundation, Inc.
00db10
-   This file is part of the GNU C Library.
00db10
-   Contributed by Ulrich Drepper <drepper@redhat.com>, 2002.
00db10
-
00db10
-   The GNU C Library is free software; you can redistribute it and/or
00db10
-   modify it under the terms of the GNU Lesser General Public
00db10
-   License as published by the Free Software Foundation; either
00db10
-   version 2.1 of the License, or (at your option) any later version.
00db10
-
00db10
-   The GNU C Library is distributed in the hope that it will be useful,
00db10
-   but WITHOUT ANY WARRANTY; without even the implied warranty of
00db10
-   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00db10
-   Lesser General Public License for more details.
00db10
-
00db10
-   You should have received a copy of the GNU Lesser General Public
00db10
-   License along with the GNU C Library; if not, see
00db10
-   <http://www.gnu.org/licenses/>.  */
00db10
-
00db10
-#include <sysdep.h>
00db10
-#include <shlib-compat.h>
00db10
-#include <pthread-errnos.h>
00db10
-#include <structsem.h>
00db10
-#include <lowlevellock.h>
00db10
-
00db10
-
00db10
-#if VALUE != 0
00db10
-# error "code needs to be rewritten for VALUE != 0"
00db10
-#endif
00db10
-
00db10
-	.text
00db10
-
00db10
-	.globl	__new_sem_wait
00db10
-	.type	__new_sem_wait,@function
00db10
-	.align	16
00db10
-__new_sem_wait:
00db10
-.LSTARTCODE:
00db10
-	pushl	%ebx
00db10
-.Lpush_ebx:
00db10
-	pushl	%esi
00db10
-.Lpush_esi:
00db10
-	subl	$4, %esp
00db10
-.Lsub_esp:
00db10
-
00db10
-	movl	16(%esp), %ebx
00db10
-
00db10
-	movl	(%ebx), %eax
00db10
-2:	testl	%eax, %eax
00db10
-	je	1f
00db10
-
00db10
-	leal	-1(%eax), %edx
00db10
-	LOCK
00db10
-	cmpxchgl %edx, (%ebx)
00db10
-	jne	2b
00db10
-7:	xorl	%eax, %eax
00db10
-
00db10
-9:	movl	4(%esp), %esi
00db10
-	movl	8(%esp), %ebx
00db10
-	addl	$12, %esp
00db10
-.Ladd_esp:
00db10
-	ret
00db10
-
00db10
-.Lafter_ret:
00db10
-1:	LOCK
00db10
-	incl	NWAITERS(%ebx)
00db10
-
00db10
-.LcleanupSTART:
00db10
-6:	call	__pthread_enable_asynccancel
00db10
-	movl	%eax, (%esp)
00db10
-
00db10
-#if FUTEX_WAIT == 0
00db10
-	movl	PRIVATE(%ebx), %ecx
00db10
-#else
00db10
-	movl	$FUTEX_WAIT, %ecx
00db10
-	orl	PRIVATE(%ebx), %ecx
00db10
-#endif
00db10
-	xorl	%esi, %esi
00db10
-	xorl	%edx, %edx
00db10
-	movl	$SYS_futex, %eax
00db10
-	ENTER_KERNEL
00db10
-	movl	%eax, %esi
00db10
-
00db10
-	movl	(%esp), %eax
00db10
-	call	__pthread_disable_asynccancel
00db10
-.LcleanupEND:
00db10
-
00db10
-	testl	%esi, %esi
00db10
-	je	3f
00db10
-	cmpl	$-EWOULDBLOCK, %esi
00db10
-	jne	4f
00db10
-
00db10
-3:
00db10
-	movl	(%ebx), %eax
00db10
-5:	testl	%eax, %eax
00db10
-	je	6b
00db10
-
00db10
-	leal	-1(%eax), %edx
00db10
-	LOCK
00db10
-	cmpxchgl %edx, (%ebx)
00db10
-	jne	5b
00db10
-
00db10
-	LOCK
00db10
-	decl	NWAITERS(%ebx)
00db10
-	jmp	7b
00db10
-
00db10
-4:	LOCK
00db10
-	decl	NWAITERS(%ebx)
00db10
-
00db10
-	negl	%esi
00db10
-#ifdef PIC
00db10
-	SETUP_PIC_REG(bx)
00db10
-#else
00db10
-	movl	$8f, %ebx
00db10
-8:
00db10
-#endif
00db10
-	addl	$_GLOBAL_OFFSET_TABLE_, %ebx
00db10
-#ifdef NO_TLS_DIRECT_SEG_REFS
00db10
-	movl	errno@gotntpoff(%ebx), %edx
00db10
-	addl	%gs:0, %edx
00db10
-	movl	%esi, (%edx)
00db10
-#else
00db10
-	movl	errno@gotntpoff(%ebx), %edx
00db10
-	movl	%esi, %gs:(%edx)
00db10
-#endif
00db10
-	orl	$-1, %eax
00db10
-
00db10
-	jmp	9b
00db10
-	.size	__new_sem_wait,.-__new_sem_wait
00db10
-	versioned_symbol(libpthread, __new_sem_wait, sem_wait, GLIBC_2_1)
00db10
-
00db10
-
00db10
-	.type	sem_wait_cleanup,@function
00db10
-sem_wait_cleanup:
00db10
-	LOCK
00db10
-	decl	NWAITERS(%ebx)
00db10
-	movl	%eax, (%esp)
00db10
-.LcallUR:
00db10
-	call	_Unwind_Resume@PLT
00db10
-	hlt
00db10
-.LENDCODE:
00db10
-	.size	sem_wait_cleanup,.-sem_wait_cleanup
00db10
-
00db10
-
00db10
-	.section .gcc_except_table,"a",@progbits
00db10
-.LexceptSTART:
00db10
-	.byte	0xff				# @LPStart format (omit)
00db10
-	.byte	0xff				# @TType format (omit)
00db10
-	.byte	0x01				# call-site format
00db10
-						# DW_EH_PE_uleb128
00db10
-	.uleb128 .Lcstend-.Lcstbegin
00db10
-.Lcstbegin:
00db10
-	.uleb128 .LcleanupSTART-.LSTARTCODE
00db10
-	.uleb128 .LcleanupEND-.LcleanupSTART
00db10
-	.uleb128 sem_wait_cleanup-.LSTARTCODE
00db10
-	.uleb128  0
00db10
-	.uleb128 .LcallUR-.LSTARTCODE
00db10
-	.uleb128 .LENDCODE-.LcallUR
00db10
-	.uleb128 0
00db10
-	.uleb128  0
00db10
-.Lcstend:
00db10
-
00db10
-
00db10
-	.section .eh_frame,"a",@progbits
00db10
-.LSTARTFRAME:
00db10
-	.long	.LENDCIE-.LSTARTCIE		# Length of the CIE.
00db10
-.LSTARTCIE:
00db10
-	.long	0				# CIE ID.
00db10
-	.byte	1				# Version number.
00db10
-#ifdef SHARED
00db10
-	.string	"zPLR"				# NUL-terminated augmentation
00db10
-						# string.
00db10
-#else
00db10
-	.string	"zPL"				# NUL-terminated augmentation
00db10
-						# string.
00db10
-#endif
00db10
-	.uleb128 1				# Code alignment factor.
00db10
-	.sleb128 -4				# Data alignment factor.
00db10
-	.byte	8				# Return address register
00db10
-						# column.
00db10
-#ifdef SHARED
00db10
-	.uleb128 7				# Augmentation value length.
00db10
-	.byte	0x9b				# Personality: DW_EH_PE_pcrel
00db10
-						# + DW_EH_PE_sdata4
00db10
-						# + DW_EH_PE_indirect
00db10
-	.long	DW.ref.__gcc_personality_v0-.
00db10
-	.byte	0x1b				# LSDA Encoding: DW_EH_PE_pcrel
00db10
-						# + DW_EH_PE_sdata4.
00db10
-	.byte	0x1b				# FDE Encoding: DW_EH_PE_pcrel
00db10
-						# + DW_EH_PE_sdata4.
00db10
-#else
00db10
-	.uleb128 6				# Augmentation value length.
00db10
-	.byte	0x0				# Personality: absolute
00db10
-	.long	__gcc_personality_v0
00db10
-	.byte	0x0				# LSDA Encoding: absolute
00db10
-#endif
00db10
-	.byte 0x0c				# DW_CFA_def_cfa
00db10
-	.uleb128 4
00db10
-	.uleb128 4
00db10
-	.byte	0x88				# DW_CFA_offset, column 0x10
00db10
-	.uleb128 1
00db10
-	.align 4
00db10
-.LENDCIE:
00db10
-
00db10
-	.long	.LENDFDE-.LSTARTFDE		# Length of the FDE.
00db10
-.LSTARTFDE:
00db10
-	.long	.LSTARTFDE-.LSTARTFRAME		# CIE pointer.
00db10
-#ifdef SHARED
00db10
-	.long	.LSTARTCODE-.			# PC-relative start address
00db10
-						# of the code.
00db10
-#else
00db10
-	.long	.LSTARTCODE			# Start address of the code.
00db10
-#endif
00db10
-	.long	.LENDCODE-.LSTARTCODE		# Length of the code.
00db10
-	.uleb128 4				# Augmentation size
00db10
-#ifdef SHARED
00db10
-	.long	.LexceptSTART-.
00db10
-#else
00db10
-	.long	.LexceptSTART
00db10
-#endif
00db10
-
00db10
-	.byte	4				# DW_CFA_advance_loc4
00db10
-	.long	.Lpush_ebx-.LSTARTCODE
00db10
-	.byte	14				# DW_CFA_def_cfa_offset
00db10
-	.uleb128 8
00db10
-	.byte   0x83				# DW_CFA_offset %ebx
00db10
-	.uleb128 2
00db10
-	.byte	4				# DW_CFA_advance_loc4
00db10
-	.long	.Lpush_esi-.Lpush_ebx
00db10
-	.byte	14				# DW_CFA_def_cfa_offset
00db10
-	.uleb128 12
00db10
-	.byte   0x86				# DW_CFA_offset %esi
00db10
-	.uleb128 3
00db10
-	.byte	4				# DW_CFA_advance_loc4
00db10
-	.long	.Lsub_esp-.Lpush_esi
00db10
-	.byte	14				# DW_CFA_def_cfa_offset
00db10
-	.uleb128 16
00db10
-	.byte	4				# DW_CFA_advance_loc4
00db10
-	.long	.Ladd_esp-.Lsub_esp
00db10
-	.byte	14				# DW_CFA_def_cfa_offset
00db10
-	.uleb128 4
00db10
-	.byte	0xc3				# DW_CFA_restore %ebx
00db10
-	.byte	0xc6				# DW_CFA_restore %esi
00db10
-	.byte	4				# DW_CFA_advance_loc4
00db10
-	.long	.Lafter_ret-.Ladd_esp
00db10
-	.byte	14				# DW_CFA_def_cfa_offset
00db10
-	.uleb128 16
00db10
-	.byte   0x83				# DW_CFA_offset %ebx
00db10
-	.uleb128 2
00db10
-	.byte   0x86				# DW_CFA_offset %esi
00db10
-	.uleb128 3
00db10
-	.align	4
00db10
-.LENDFDE:
00db10
-
00db10
-
00db10
-#ifdef SHARED
00db10
-	.hidden	DW.ref.__gcc_personality_v0
00db10
-	.weak	DW.ref.__gcc_personality_v0
00db10
-	.section .gnu.linkonce.d.DW.ref.__gcc_personality_v0,"aw",@progbits
00db10
-	.align	4
00db10
-	.type	DW.ref.__gcc_personality_v0, @object
00db10
-	.size	DW.ref.__gcc_personality_v0, 4
00db10
-DW.ref.__gcc_personality_v0:
00db10
-	.long	__gcc_personality_v0
00db10
-#endif
00db10
-
00db10
-
00db10
-#if SHLIB_COMPAT(libpthread, GLIBC_2_0, GLIBC_2_1)
00db10
-	.section ".text.compat", "ax"
00db10
-	.global	__old_sem_wait
00db10
-	.type	__old_sem_wait,@function
00db10
-	.align	16
00db10
-	cfi_startproc
00db10
-__old_sem_wait:
00db10
-	pushl	%ebx
00db10
-	cfi_adjust_cfa_offset(4)
00db10
-	pushl	%esi
00db10
-	cfi_adjust_cfa_offset(4)
00db10
-	subl	$4, %esp
00db10
-	cfi_adjust_cfa_offset(4)
00db10
-
00db10
-	movl	16(%esp), %ebx
00db10
-	cfi_offset(ebx, -8)
00db10
-
00db10
-	cfi_offset(esi, -12)
00db10
-3:	movl	(%ebx), %eax
00db10
-2:	testl	%eax, %eax
00db10
-	je	1f
00db10
-
00db10
-	leal	-1(%eax), %edx
00db10
-	LOCK
00db10
-	cmpxchgl %edx, (%ebx)
00db10
-	jne	2b
00db10
-	xorl	%eax, %eax
00db10
-
00db10
-5:	movl	4(%esp), %esi
00db10
-	movl	8(%esp), %ebx
00db10
-	addl	$12, %esp
00db10
-	cfi_restore(ebx)
00db10
-	cfi_restore(esi)
00db10
-	cfi_adjust_cfa_offset(-12)
00db10
-	ret
00db10
-
00db10
-	cfi_adjust_cfa_offset(12)
00db10
-	cfi_offset(ebx, -8)
00db10
-	cfi_offset(esi, -12)
00db10
-1:	call	__pthread_enable_asynccancel
00db10
-	movl	%eax, (%esp)
00db10
-
00db10
-	xorl	%esi, %esi
00db10
-	movl	$SYS_futex, %eax
00db10
-	movl	%esi, %ecx
00db10
-	movl	%esi, %edx
00db10
-	ENTER_KERNEL
00db10
-	movl	%eax, %esi
00db10
-
00db10
-	movl	(%esp), %eax
00db10
-	call	__pthread_disable_asynccancel
00db10
-
00db10
-	testl	%esi, %esi
00db10
-	je	3b
00db10
-	cmpl	$-EWOULDBLOCK, %esi
00db10
-	je	3b
00db10
-	negl	%esi
00db10
-#ifdef PIC
00db10
-	SETUP_PIC_REG(bx)
00db10
-#else
00db10
-	movl	$4f, %ebx
00db10
-4:
00db10
-#endif
00db10
-	addl	$_GLOBAL_OFFSET_TABLE_, %ebx
00db10
-#ifdef NO_TLS_DIRECT_SEG_REFS
00db10
-	movl	errno@gotntpoff(%ebx), %edx
00db10
-	addl	%gs:0, %edx
00db10
-	movl	%esi, (%edx)
00db10
-#else
00db10
-	movl	errno@gotntpoff(%ebx), %edx
00db10
-	movl	%esi, %gs:(%edx)
00db10
-#endif
00db10
-	orl	$-1, %eax
00db10
-	jmp	5b
00db10
-	cfi_endproc
00db10
-	.size	__old_sem_wait,.-__old_sem_wait
00db10
-	compat_symbol(libpthread, __old_sem_wait, sem_wait, GLIBC_2_0)
00db10
-#endif
00db10
Index: glibc-2.17-c758a686/nptl/sysdeps/unix/sysv/linux/i386/i586/sem_post.S
00db10
===================================================================
00db10
--- glibc-2.17-c758a686.orig/nptl/sysdeps/unix/sysv/linux/i386/i586/sem_post.S
00db10
+++ /dev/null
00db10
@@ -1,19 +0,0 @@
00db10
-/* Copyright (C) 2003 Free Software Foundation, Inc.
00db10
-   This file is part of the GNU C Library.
00db10
-   Contributed by Ulrich Drepper <drepper@redhat.com>, 2003.
00db10
-
00db10
-   The GNU C Library is free software; you can redistribute it and/or
00db10
-   modify it under the terms of the GNU Lesser General Public
00db10
-   License as published by the Free Software Foundation; either
00db10
-   version 2.1 of the License, or (at your option) any later version.
00db10
-
00db10
-   The GNU C Library is distributed in the hope that it will be useful,
00db10
-   but WITHOUT ANY WARRANTY; without even the implied warranty of
00db10
-   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00db10
-   Lesser General Public License for more details.
00db10
-
00db10
-   You should have received a copy of the GNU Lesser General Public
00db10
-   License along with the GNU C Library; if not, see
00db10
-   <http://www.gnu.org/licenses/>.  */
00db10
-
00db10
-#include "../i486/sem_post.S"
00db10
Index: glibc-2.17-c758a686/nptl/sysdeps/unix/sysv/linux/i386/i586/sem_timedwait.S
00db10
===================================================================
00db10
--- glibc-2.17-c758a686.orig/nptl/sysdeps/unix/sysv/linux/i386/i586/sem_timedwait.S
00db10
+++ /dev/null
00db10
@@ -1,19 +0,0 @@
00db10
-/* Copyright (C) 2003 Free Software Foundation, Inc.
00db10
-   This file is part of the GNU C Library.
00db10
-   Contributed by Ulrich Drepper <drepper@redhat.com>, 2003.
00db10
-
00db10
-   The GNU C Library is free software; you can redistribute it and/or
00db10
-   modify it under the terms of the GNU Lesser General Public
00db10
-   License as published by the Free Software Foundation; either
00db10
-   version 2.1 of the License, or (at your option) any later version.
00db10
-
00db10
-   The GNU C Library is distributed in the hope that it will be useful,
00db10
-   but WITHOUT ANY WARRANTY; without even the implied warranty of
00db10
-   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00db10
-   Lesser General Public License for more details.
00db10
-
00db10
-   You should have received a copy of the GNU Lesser General Public
00db10
-   License along with the GNU C Library; if not, see
00db10
-   <http://www.gnu.org/licenses/>.  */
00db10
-
00db10
-#include "../i486/sem_timedwait.S"
00db10
Index: glibc-2.17-c758a686/nptl/sysdeps/unix/sysv/linux/i386/i586/sem_trywait.S
00db10
===================================================================
00db10
--- glibc-2.17-c758a686.orig/nptl/sysdeps/unix/sysv/linux/i386/i586/sem_trywait.S
00db10
+++ /dev/null
00db10
@@ -1,19 +0,0 @@
00db10
-/* Copyright (C) 2003 Free Software Foundation, Inc.
00db10
-   This file is part of the GNU C Library.
00db10
-   Contributed by Ulrich Drepper <drepper@redhat.com>, 2003.
00db10
-
00db10
-   The GNU C Library is free software; you can redistribute it and/or
00db10
-   modify it under the terms of the GNU Lesser General Public
00db10
-   License as published by the Free Software Foundation; either
00db10
-   version 2.1 of the License, or (at your option) any later version.
00db10
-
00db10
-   The GNU C Library is distributed in the hope that it will be useful,
00db10
-   but WITHOUT ANY WARRANTY; without even the implied warranty of
00db10
-   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00db10
-   Lesser General Public License for more details.
00db10
-
00db10
-   You should have received a copy of the GNU Lesser General Public
00db10
-   License along with the GNU C Library; if not, see
00db10
-   <http://www.gnu.org/licenses/>.  */
00db10
-
00db10
-#include "../i486/sem_trywait.S"
00db10
Index: glibc-2.17-c758a686/nptl/sysdeps/unix/sysv/linux/i386/i586/sem_wait.S
00db10
===================================================================
00db10
--- glibc-2.17-c758a686.orig/nptl/sysdeps/unix/sysv/linux/i386/i586/sem_wait.S
00db10
+++ /dev/null
00db10
@@ -1,19 +0,0 @@
00db10
-/* Copyright (C) 2003 Free Software Foundation, Inc.
00db10
-   This file is part of the GNU C Library.
00db10
-   Contributed by Ulrich Drepper <drepper@redhat.com>, 2003.
00db10
-
00db10
-   The GNU C Library is free software; you can redistribute it and/or
00db10
-   modify it under the terms of the GNU Lesser General Public
00db10
-   License as published by the Free Software Foundation; either
00db10
-   version 2.1 of the License, or (at your option) any later version.
00db10
-
00db10
-   The GNU C Library is distributed in the hope that it will be useful,
00db10
-   but WITHOUT ANY WARRANTY; without even the implied warranty of
00db10
-   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00db10
-   Lesser General Public License for more details.
00db10
-
00db10
-   You should have received a copy of the GNU Lesser General Public
00db10
-   License along with the GNU C Library; if not, see
00db10
-   <http://www.gnu.org/licenses/>.  */
00db10
-
00db10
-#include "../i486/sem_wait.S"
00db10
Index: glibc-2.17-c758a686/nptl/sysdeps/unix/sysv/linux/i386/i686/sem_post.S
00db10
===================================================================
00db10
--- glibc-2.17-c758a686.orig/nptl/sysdeps/unix/sysv/linux/i386/i686/sem_post.S
00db10
+++ /dev/null
00db10
@@ -1,19 +0,0 @@
00db10
-/* Copyright (C) 2003 Free Software Foundation, Inc.
00db10
-   This file is part of the GNU C Library.
00db10
-   Contributed by Ulrich Drepper <drepper@redhat.com>, 2003.
00db10
-
00db10
-   The GNU C Library is free software; you can redistribute it and/or
00db10
-   modify it under the terms of the GNU Lesser General Public
00db10
-   License as published by the Free Software Foundation; either
00db10
-   version 2.1 of the License, or (at your option) any later version.
00db10
-
00db10
-   The GNU C Library is distributed in the hope that it will be useful,
00db10
-   but WITHOUT ANY WARRANTY; without even the implied warranty of
00db10
-   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00db10
-   Lesser General Public License for more details.
00db10
-
00db10
-   You should have received a copy of the GNU Lesser General Public
00db10
-   License along with the GNU C Library; if not, see
00db10
-   <http://www.gnu.org/licenses/>.  */
00db10
-
00db10
-#include "../i486/sem_post.S"
00db10
Index: glibc-2.17-c758a686/nptl/sysdeps/unix/sysv/linux/i386/i686/sem_timedwait.S
00db10
===================================================================
00db10
--- glibc-2.17-c758a686.orig/nptl/sysdeps/unix/sysv/linux/i386/i686/sem_timedwait.S
00db10
+++ /dev/null
00db10
@@ -1,19 +0,0 @@
00db10
-/* Copyright (C) 2003 Free Software Foundation, Inc.
00db10
-   This file is part of the GNU C Library.
00db10
-   Contributed by Ulrich Drepper <drepper@redhat.com>, 2003.
00db10
-
00db10
-   The GNU C Library is free software; you can redistribute it and/or
00db10
-   modify it under the terms of the GNU Lesser General Public
00db10
-   License as published by the Free Software Foundation; either
00db10
-   version 2.1 of the License, or (at your option) any later version.
00db10
-
00db10
-   The GNU C Library is distributed in the hope that it will be useful,
00db10
-   but WITHOUT ANY WARRANTY; without even the implied warranty of
00db10
-   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00db10
-   Lesser General Public License for more details.
00db10
-
00db10
-   You should have received a copy of the GNU Lesser General Public
00db10
-   License along with the GNU C Library; if not, see
00db10
-   <http://www.gnu.org/licenses/>.  */
00db10
-
00db10
-#include "../i486/sem_timedwait.S"
00db10
Index: glibc-2.17-c758a686/nptl/sysdeps/unix/sysv/linux/i386/i686/sem_trywait.S
00db10
===================================================================
00db10
--- glibc-2.17-c758a686.orig/nptl/sysdeps/unix/sysv/linux/i386/i686/sem_trywait.S
00db10
+++ /dev/null
00db10
@@ -1,19 +0,0 @@
00db10
-/* Copyright (C) 2003 Free Software Foundation, Inc.
00db10
-   This file is part of the GNU C Library.
00db10
-   Contributed by Ulrich Drepper <drepper@redhat.com>, 2003.
00db10
-
00db10
-   The GNU C Library is free software; you can redistribute it and/or
00db10
-   modify it under the terms of the GNU Lesser General Public
00db10
-   License as published by the Free Software Foundation; either
00db10
-   version 2.1 of the License, or (at your option) any later version.
00db10
-
00db10
-   The GNU C Library is distributed in the hope that it will be useful,
00db10
-   but WITHOUT ANY WARRANTY; without even the implied warranty of
00db10
-   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00db10
-   Lesser General Public License for more details.
00db10
-
00db10
-   You should have received a copy of the GNU Lesser General Public
00db10
-   License along with the GNU C Library; if not, see
00db10
-   <http://www.gnu.org/licenses/>.  */
00db10
-
00db10
-#include "../i486/sem_trywait.S"
00db10
Index: glibc-2.17-c758a686/nptl/sysdeps/unix/sysv/linux/i386/i686/sem_wait.S
00db10
===================================================================
00db10
--- glibc-2.17-c758a686.orig/nptl/sysdeps/unix/sysv/linux/i386/i686/sem_wait.S
00db10
+++ /dev/null
00db10
@@ -1,19 +0,0 @@
00db10
-/* Copyright (C) 2003 Free Software Foundation, Inc.
00db10
-   This file is part of the GNU C Library.
00db10
-   Contributed by Ulrich Drepper <drepper@redhat.com>, 2003.
00db10
-
00db10
-   The GNU C Library is free software; you can redistribute it and/or
00db10
-   modify it under the terms of the GNU Lesser General Public
00db10
-   License as published by the Free Software Foundation; either
00db10
-   version 2.1 of the License, or (at your option) any later version.
00db10
-
00db10
-   The GNU C Library is distributed in the hope that it will be useful,
00db10
-   but WITHOUT ANY WARRANTY; without even the implied warranty of
00db10
-   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00db10
-   Lesser General Public License for more details.
00db10
-
00db10
-   You should have received a copy of the GNU Lesser General Public
00db10
-   License along with the GNU C Library; if not, see
00db10
-   <http://www.gnu.org/licenses/>.  */
00db10
-
00db10
-#include "../i486/sem_wait.S"
00db10
Index: glibc-2.17-c758a686/nptl/sysdeps/unix/sysv/linux/internaltypes.h
00db10
===================================================================
00db10
--- glibc-2.17-c758a686.orig/nptl/sysdeps/unix/sysv/linux/internaltypes.h
00db10
+++ glibc-2.17-c758a686/nptl/sysdeps/unix/sysv/linux/internaltypes.h
00db10
@@ -20,6 +20,8 @@
00db10
 #define _INTERNALTYPES_H	1
00db10
 
00db10
 #include <stdint.h>
00db10
+#include <atomic.h>
00db10
+#include <endian.h>
00db10
 
00db10
 
00db10
 struct pthread_attr
00db10
@@ -141,9 +143,29 @@ struct pthread_key_struct
00db10
 /* Semaphore variable structure.  */
00db10
 struct new_sem
00db10
 {
00db10
+#if __HAVE_64B_ATOMICS
00db10
+  /* The data field holds both value (in the least-significant 32 bytes) and
00db10
+     nwaiters.  */
00db10
+# if __BYTE_ORDER == __LITTLE_ENDIAN
00db10
+#  define SEM_VALUE_OFFSET 0
00db10
+# elif __BYTE_ORDER == __BIG_ENDIAN
00db10
+#  define SEM_VALUE_OFFSET 1
00db10
+# else
00db10
+# error Unsupported byte order.
00db10
+# endif
00db10
+# define SEM_NWAITERS_SHIFT 32
00db10
+# define SEM_VALUE_MASK (~(unsigned int)0)
00db10
+  unsigned long int data;
00db10
+  int private;
00db10
+  int pad;
00db10
+#else
00db10
+# define SEM_VALUE_SHIFT 1
00db10
+# define SEM_NWAITERS_MASK ((unsigned int)1)
00db10
   unsigned int value;
00db10
   int private;
00db10
-  unsigned long int nwaiters;
00db10
+  int pad;
00db10
+  unsigned int nwaiters;
00db10
+#endif
00db10
 };
00db10
 
00db10
 struct old_sem
00db10
Index: glibc-2.17-c758a686/nptl/sysdeps/unix/sysv/linux/powerpc/sem_post.c
00db10
===================================================================
00db10
--- glibc-2.17-c758a686.orig/nptl/sysdeps/unix/sysv/linux/powerpc/sem_post.c
00db10
+++ /dev/null
00db10
@@ -1,71 +0,0 @@
00db10
-/* sem_post -- post to a POSIX semaphore.  Powerpc version.
00db10
-   Copyright (C) 2003-2012 Free Software Foundation, Inc.
00db10
-   This file is part of the GNU C Library.
00db10
-   Contributed by Paul Mackerras <paulus@au.ibm.com>, 2003.
00db10
-
00db10
-   The GNU C Library is free software; you can redistribute it and/or
00db10
-   modify it under the terms of the GNU Lesser General Public
00db10
-   License as published by the Free Software Foundation; either
00db10
-   version 2.1 of the License, or (at your option) any later version.
00db10
-
00db10
-   The GNU C Library is distributed in the hope that it will be useful,
00db10
-   but WITHOUT ANY WARRANTY; without even the implied warranty of
00db10
-   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.	 See the GNU
00db10
-   Lesser General Public License for more details.
00db10
-
00db10
-   You should have received a copy of the GNU Lesser General Public
00db10
-   License along with the GNU C Library; if not, see
00db10
-   <http://www.gnu.org/licenses/>.  */
00db10
-
00db10
-#include <errno.h>
00db10
-#include <sysdep.h>
00db10
-#include <lowlevellock.h>
00db10
-#include <internaltypes.h>
00db10
-#include <semaphore.h>
00db10
-
00db10
-#include <shlib-compat.h>
00db10
-
00db10
-int
00db10
-__new_sem_post (sem_t *sem)
00db10
-{
00db10
-  struct new_sem *isem = (struct new_sem *) sem;
00db10
-
00db10
-  __asm __volatile (__lll_rel_instr ::: "memory");
00db10
-  atomic_increment (&isem->value);
00db10
-  __asm __volatile (__lll_acq_instr ::: "memory");
00db10
-  if (isem->nwaiters > 0)
00db10
-    {
00db10
-      int err = lll_futex_wake (&isem->value, 1,
00db10
-				isem->private ^ FUTEX_PRIVATE_FLAG);
00db10
-      if (__builtin_expect (err, 0) < 0)
00db10
-	{
00db10
-	  __set_errno (-err);
00db10
-	  return -1;
00db10
-	}
00db10
-    }
00db10
-  return 0;
00db10
-}
00db10
-versioned_symbol (libpthread, __new_sem_post, sem_post, GLIBC_2_1);
00db10
-
00db10
-#if SHLIB_COMPAT (libpthread, GLIBC_2_0, GLIBC_2_1)
00db10
-
00db10
-int
00db10
-attribute_compat_text_section
00db10
-__old_sem_post (sem_t *sem)
00db10
-{
00db10
-  int *futex = (int *) sem;
00db10
-
00db10
-  __asm __volatile (__lll_rel_instr ::: "memory");
00db10
-  (void) atomic_increment_val (futex);
00db10
-  /* We always have to assume it is a shared semaphore.  */
00db10
-  int err = lll_futex_wake (futex, 1, LLL_SHARED);
00db10
-  if (__builtin_expect (err, 0) < 0)
00db10
-    {
00db10
-      __set_errno (-err);
00db10
-      return -1;
00db10
-    }
00db10
-  return 0;
00db10
-}
00db10
-
00db10
-compat_symbol (libpthread, __old_sem_post, sem_post, GLIBC_2_0);
00db10
-#endif
00db10
Index: glibc-2.17-c758a686/nptl/sysdeps/unix/sysv/linux/sem_post.c
00db10
===================================================================
00db10
--- glibc-2.17-c758a686.orig/nptl/sysdeps/unix/sysv/linux/sem_post.c
00db10
+++ glibc-2.17-c758a686/nptl/sysdeps/unix/sysv/linux/sem_post.c
00db10
@@ -25,34 +25,78 @@
00db10
 
00db10
 #include <shlib-compat.h>
00db10
 
00db10
+/* Wrapper for lll_futex_wake, with error checking.
00db10
+   TODO Remove when cleaning up the futex API throughout glibc.  */
00db10
+static __always_inline void
00db10
+futex_wake (unsigned int* futex, int processes_to_wake, int private)
00db10
+{
00db10
+  int res = lll_futex_wake (futex, processes_to_wake, private);
00db10
+  /* No error.  Ignore the number of woken processes.  */
00db10
+  if (res >= 0)
00db10
+    return;
00db10
+  switch (res)
00db10
+    {
00db10
+    case -EFAULT: /* Could have happened due to memory reuse.  */
00db10
+    case -EINVAL: /* Could be either due to incorrect alignment (a bug in
00db10
+		     glibc or in the application) or due to memory being
00db10
+		     reused for a PI futex.  We cannot distinguish between the
00db10
+		     two causes, and one of them is correct use, so we do not
00db10
+		     act in this case.  */
00db10
+      return;
00db10
+    case -ENOSYS: /* Must have been caused by a glibc bug.  */
00db10
+    /* No other errors are documented at this time.  */
00db10
+    default:
00db10
+      abort ();
00db10
+    }
00db10
+}
00db10
+
00db10
+
00db10
+/* See sem_wait for an explanation of the algorithm.  */
00db10
 int
00db10
 __new_sem_post (sem_t *sem)
00db10
 {
00db10
   struct new_sem *isem = (struct new_sem *) sem;
00db10
+  int private = isem->private;
00db10
 
00db10
-  __typeof (isem->value) cur;
00db10
+#if __HAVE_64B_ATOMICS
00db10
+  /* Add a token to the semaphore.  We use release MO to make sure that a
00db10
+     thread acquiring this token synchronizes with us and other threads that
00db10
+     added tokens before (the release sequence includes atomic RMW operations
00db10
+     by other threads).  */
00db10
+  /* TODO Use atomic_fetch_add to make it scale better than a CAS loop?  */
00db10
+  unsigned long int d = atomic_load_relaxed (&isem->data);
00db10
   do
00db10
     {
00db10
-      cur = isem->value;
00db10
-      if (isem->value == SEM_VALUE_MAX)
00db10
+      if ((d & SEM_VALUE_MASK) == SEM_VALUE_MAX)
00db10
 	{
00db10
 	  __set_errno (EOVERFLOW);
00db10
 	  return -1;
00db10
 	}
00db10
     }
00db10
-  while (atomic_compare_and_exchange_bool_rel (&isem->value, cur + 1, cur));
00db10
+  while (!atomic_compare_exchange_weak_release (&isem->data, &d, d + 1));
00db10
 
00db10
-  atomic_full_barrier ();
00db10
-  if (isem->nwaiters > 0)
00db10
+  /* If there is any potentially blocked waiter, wake one of them.  */
00db10
+  if ((d >> SEM_NWAITERS_SHIFT) > 0)
00db10
+    futex_wake (((unsigned int *) &isem->data) + SEM_VALUE_OFFSET, 1, private);
00db10
+#else
00db10
+  /* Add a token to the semaphore.  Similar to 64b version.  */
00db10
+  unsigned int v = atomic_load_relaxed (&isem->value);
00db10
+  do
00db10
     {
00db10
-      int err = lll_futex_wake (&isem->value, 1,
00db10
-				isem->private ^ FUTEX_PRIVATE_FLAG);
00db10
-      if (__builtin_expect (err, 0) < 0)
00db10
+      if ((v << SEM_VALUE_SHIFT) == SEM_VALUE_MAX)
00db10
 	{
00db10
-	  __set_errno (-err);
00db10
+	  __set_errno (EOVERFLOW);
00db10
 	  return -1;
00db10
 	}
00db10
     }
00db10
+  while (!atomic_compare_exchange_weak_release (&isem->value,
00db10
+      &v, v + (1 << SEM_VALUE_SHIFT)));
00db10
+
00db10
+  /* If there is any potentially blocked waiter, wake one of them.  */
00db10
+  if ((v & SEM_NWAITERS_MASK) != 0)
00db10
+    futex_wake (&isem->value, 1, private);
00db10
+#endif
00db10
+
00db10
   return 0;
00db10
 }
00db10
 versioned_symbol (libpthread, __new_sem_post, sem_post, GLIBC_2_1);
00db10
@@ -65,6 +109,9 @@ __old_sem_post (sem_t *sem)
00db10
 {
00db10
   int *futex = (int *) sem;
00db10
 
00db10
+  /* We must need to synchronize with consumers of this token, so the atomic
00db10
+     increment must have release MO semantics.  */
00db10
+  atomic_write_barrier ();
00db10
   (void) atomic_increment_val (futex);
00db10
   /* We always have to assume it is a shared semaphore.  */
00db10
   int err = lll_futex_wake (futex, 1, LLL_SHARED);
00db10
Index: glibc-2.17-c758a686/nptl/sysdeps/unix/sysv/linux/sem_timedwait.c
00db10
===================================================================
00db10
--- glibc-2.17-c758a686.orig/nptl/sysdeps/unix/sysv/linux/sem_timedwait.c
00db10
+++ glibc-2.17-c758a686/nptl/sysdeps/unix/sysv/linux/sem_timedwait.c
00db10
@@ -1,5 +1,5 @@
00db10
-/* sem_timedwait -- wait on a semaphore.  Generic futex-using version.
00db10
-   Copyright (C) 2003, 2007, 2012 Free Software Foundation, Inc.
00db10
+/* sem_timedwait -- wait on a semaphore with timeout.
00db10
+   Copyright (C) 2003-2015 Free Software Foundation, Inc.
00db10
    This file is part of the GNU C Library.
00db10
    Contributed by Paul Mackerras <paulus@au.ibm.com>, 2003.
00db10
 
00db10
@@ -17,42 +17,13 @@
00db10
    License along with the GNU C Library; if not, see
00db10
    <http://www.gnu.org/licenses/>.  */
00db10
 
00db10
-#include <errno.h>
00db10
-#include <sysdep.h>
00db10
-#include <lowlevellock.h>
00db10
-#include <internaltypes.h>
00db10
-#include <semaphore.h>
00db10
-
00db10
-#include <pthreadP.h>
00db10
-#include <shlib-compat.h>
00db10
-
00db10
-
00db10
-extern void __sem_wait_cleanup (void *arg) attribute_hidden;
00db10
-
00db10
-/* This is in a seperate function in order to make sure gcc
00db10
-   puts the call site into an exception region, and thus the
00db10
-   cleanups get properly run.  */
00db10
-static int
00db10
-__attribute__ ((noinline))
00db10
-do_futex_timed_wait (struct new_sem *isem, struct timespec *rt)
00db10
-{
00db10
-  int err, oldtype = __pthread_enable_asynccancel ();
00db10
-
00db10
-  err = lll_futex_timed_wait (&isem->value, 0, rt,
00db10
-			      isem->private ^ FUTEX_PRIVATE_FLAG);
00db10
-
00db10
-  __pthread_disable_asynccancel (oldtype);
00db10
-  return err;
00db10
-}
00db10
+#include "sem_waitcommon.c"
00db10
 
00db10
+/* This is in a separate file because because sem_timedwait is only provided
00db10
+   if __USE_XOPEN2K is defined.  */
00db10
 int
00db10
 sem_timedwait (sem_t *sem, const struct timespec *abstime)
00db10
 {
00db10
-  struct new_sem *isem = (struct new_sem *) sem;
00db10
-  int err;
00db10
-
00db10
-  if (atomic_decrement_if_positive (&isem->value) > 0)
00db10
-    return 0;
00db10
 
00db10
   if (abstime->tv_nsec < 0 || abstime->tv_nsec >= 1000000000)
00db10
     {
00db10
@@ -60,57 +31,8 @@ sem_timedwait (sem_t *sem, const struct
00db10
       return -1;
00db10
     }
00db10
 
00db10
-  atomic_increment (&isem->nwaiters);
00db10
-
00db10
-  pthread_cleanup_push (__sem_wait_cleanup, isem);
00db10
-
00db10
-  while (1)
00db10
-    {
00db10
-      struct timeval tv;
00db10
-      struct timespec rt;
00db10
-      int sec, nsec;
00db10
-
00db10
-      /* Get the current time.  */
00db10
-      __gettimeofday (&tv, NULL);
00db10
-
00db10
-      /* Compute relative timeout.  */
00db10
-      sec = abstime->tv_sec - tv.tv_sec;
00db10
-      nsec = abstime->tv_nsec - tv.tv_usec * 1000;
00db10
-      if (nsec < 0)
00db10
-	{
00db10
-	  nsec += 1000000000;
00db10
-	  --sec;
00db10
-	}
00db10
-
00db10
-      /* Already timed out?  */
00db10
-      if (sec < 0)
00db10
-	{
00db10
-	  __set_errno (ETIMEDOUT);
00db10
-	  err = -1;
00db10
-	  break;
00db10
-	}
00db10
-
00db10
-      /* Do wait.  */
00db10
-      rt.tv_sec = sec;
00db10
-      rt.tv_nsec = nsec;
00db10
-      err = do_futex_timed_wait(isem, &rt);
00db10
-      if (err != 0 && err != -EWOULDBLOCK)
00db10
-	{
00db10
-	  __set_errno (-err);
00db10
-	  err = -1;
00db10
-	  break;
00db10
-	}
00db10
-
00db10
-      if (atomic_decrement_if_positive (&isem->value) > 0)
00db10
-	{
00db10
-	  err = 0;
00db10
-	  break;
00db10
-	}
00db10
-    }
00db10
-
00db10
-  pthread_cleanup_pop (0);
00db10
-
00db10
-  atomic_decrement (&isem->nwaiters);
00db10
-
00db10
-  return err;
00db10
+  if (__new_sem_wait_fast ((struct new_sem *) sem, 0) == 0)
00db10
+    return 0;
00db10
+  else
00db10
+    return __new_sem_wait_slow((struct new_sem *) sem, abstime);
00db10
 }
00db10
Index: glibc-2.17-c758a686/nptl/sysdeps/unix/sysv/linux/sem_trywait.c
00db10
===================================================================
00db10
--- glibc-2.17-c758a686.orig/nptl/sysdeps/unix/sysv/linux/sem_trywait.c
00db10
+++ /dev/null
00db10
@@ -1,49 +0,0 @@
00db10
-/* sem_trywait -- wait on a semaphore.  Generic futex-using version.
00db10
-   Copyright (C) 2003 Free Software Foundation, Inc.
00db10
-   This file is part of the GNU C Library.
00db10
-   Contributed by Paul Mackerras <paulus@au.ibm.com>, 2003.
00db10
-
00db10
-   The GNU C Library is free software; you can redistribute it and/or
00db10
-   modify it under the terms of the GNU Lesser General Public
00db10
-   License as published by the Free Software Foundation; either
00db10
-   version 2.1 of the License, or (at your option) any later version.
00db10
-
00db10
-   The GNU C Library is distributed in the hope that it will be useful,
00db10
-   but WITHOUT ANY WARRANTY; without even the implied warranty of
00db10
-   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.	 See the GNU
00db10
-   Lesser General Public License for more details.
00db10
-
00db10
-   You should have received a copy of the GNU Lesser General Public
00db10
-   License along with the GNU C Library; if not, see
00db10
-   <http://www.gnu.org/licenses/>.  */
00db10
-
00db10
-#include <errno.h>
00db10
-#include <sysdep.h>
00db10
-#include <lowlevellock.h>
00db10
-#include <internaltypes.h>
00db10
-#include <semaphore.h>
00db10
-
00db10
-#include <shlib-compat.h>
00db10
-
00db10
-
00db10
-int
00db10
-__new_sem_trywait (sem_t *sem)
00db10
-{
00db10
-  int *futex = (int *) sem;
00db10
-  int val;
00db10
-
00db10
-  if (*futex > 0)
00db10
-    {
00db10
-      val = atomic_decrement_if_positive (futex);
00db10
-      if (val > 0)
00db10
-	return 0;
00db10
-    }
00db10
-
00db10
-  __set_errno (EAGAIN);
00db10
-  return -1;
00db10
-}
00db10
-versioned_symbol (libpthread, __new_sem_trywait, sem_trywait, GLIBC_2_1);
00db10
-#if SHLIB_COMPAT (libpthread, GLIBC_2_0, GLIBC_2_1)
00db10
-strong_alias (__new_sem_trywait, __old_sem_trywait)
00db10
-compat_symbol (libpthread, __old_sem_trywait, sem_trywait, GLIBC_2_0);
00db10
-#endif
00db10
Index: glibc-2.17-c758a686/nptl/sysdeps/unix/sysv/linux/sem_wait.c
00db10
===================================================================
00db10
--- glibc-2.17-c758a686.orig/nptl/sysdeps/unix/sysv/linux/sem_wait.c
00db10
+++ glibc-2.17-c758a686/nptl/sysdeps/unix/sysv/linux/sem_wait.c
00db10
@@ -17,79 +17,18 @@
00db10
    License along with the GNU C Library; if not, see
00db10
    <http://www.gnu.org/licenses/>.  */
00db10
 
00db10
-#include <errno.h>
00db10
-#include <sysdep.h>
00db10
-#include <lowlevellock.h>
00db10
-#include <internaltypes.h>
00db10
-#include <semaphore.h>
00db10
-
00db10
-#include <pthreadP.h>
00db10
-#include <shlib-compat.h>
00db10
-
00db10
-
00db10
-void
00db10
-attribute_hidden
00db10
-__sem_wait_cleanup (void *arg)
00db10
-{
00db10
-  struct new_sem *isem = (struct new_sem *) arg;
00db10
-
00db10
-  atomic_decrement (&isem->nwaiters);
00db10
-}
00db10
-
00db10
-/* This is in a seperate function in order to make sure gcc
00db10
-   puts the call site into an exception region, and thus the
00db10
-   cleanups get properly run.  */
00db10
-static int
00db10
-__attribute__ ((noinline))
00db10
-do_futex_wait (struct new_sem *isem)
00db10
-{
00db10
-  int err, oldtype = __pthread_enable_asynccancel ();
00db10
-
00db10
-  err = lll_futex_wait (&isem->value, 0, isem->private ^ FUTEX_PRIVATE_FLAG);
00db10
-
00db10
-  __pthread_disable_asynccancel (oldtype);
00db10
-  return err;
00db10
-}
00db10
+#include "sem_waitcommon.c"
00db10
 
00db10
 int
00db10
 __new_sem_wait (sem_t *sem)
00db10
 {
00db10
-  struct new_sem *isem = (struct new_sem *) sem;
00db10
-  int err;
00db10
-
00db10
-  if (atomic_decrement_if_positive (&isem->value) > 0)
00db10
+  if (__new_sem_wait_fast ((struct new_sem *) sem, 0) == 0)
00db10
     return 0;
00db10
-
00db10
-  atomic_increment (&isem->nwaiters);
00db10
-
00db10
-  pthread_cleanup_push (__sem_wait_cleanup, isem);
00db10
-
00db10
-  while (1)
00db10
-    {
00db10
-      err = do_futex_wait(isem);
00db10
-      if (err != 0 && err != -EWOULDBLOCK)
00db10
-	{
00db10
-	  __set_errno (-err);
00db10
-	  err = -1;
00db10
-	  break;
00db10
-	}
00db10
-
00db10
-      if (atomic_decrement_if_positive (&isem->value) > 0)
00db10
-	{
00db10
-	  err = 0;
00db10
-	  break;
00db10
-	}
00db10
-    }
00db10
-
00db10
-  pthread_cleanup_pop (0);
00db10
-
00db10
-  atomic_decrement (&isem->nwaiters);
00db10
-
00db10
-  return err;
00db10
+  else
00db10
+    return __new_sem_wait_slow((struct new_sem *) sem, NULL);
00db10
 }
00db10
 versioned_symbol (libpthread, __new_sem_wait, sem_wait, GLIBC_2_1);
00db10
 
00db10
-
00db10
 #if SHLIB_COMPAT (libpthread, GLIBC_2_0, GLIBC_2_1)
00db10
 int
00db10
 attribute_compat_text_section
00db10
@@ -120,3 +59,34 @@ __old_sem_wait (sem_t *sem)
00db10
 
00db10
 compat_symbol (libpthread, __old_sem_wait, sem_wait, GLIBC_2_0);
00db10
 #endif
00db10
+
00db10
+int
00db10
+__new_sem_trywait (sem_t *sem)
00db10
+{
00db10
+  /* We must not fail spuriously, so require a definitive result even if this
00db10
+     may lead to a long execution time.  */
00db10
+  if (__new_sem_wait_fast ((struct new_sem *) sem, 1) == 0)
00db10
+    return 0;
00db10
+  __set_errno (EAGAIN);
00db10
+  return -1;
00db10
+}
00db10
+versioned_symbol (libpthread, __new_sem_trywait, sem_trywait, GLIBC_2_1);
00db10
+#if SHLIB_COMPAT (libpthread, GLIBC_2_0, GLIBC_2_1)
00db10
+int
00db10
+__old_sem_trywait (sem_t *sem)
00db10
+{
00db10
+  int *futex = (int *) sem;
00db10
+  int val;
00db10
+
00db10
+  if (*futex > 0)
00db10
+    {
00db10
+      val = atomic_decrement_if_positive (futex);
00db10
+      if (val > 0)
00db10
+	return 0;
00db10
+    }
00db10
+
00db10
+  __set_errno (EAGAIN);
00db10
+  return -1;
00db10
+}
00db10
+compat_symbol (libpthread, __old_sem_trywait, sem_trywait, GLIBC_2_0);
00db10
+#endif
00db10
Index: glibc-2.17-c758a686/nptl/sysdeps/unix/sysv/linux/sem_waitcommon.c
00db10
===================================================================
00db10
--- /dev/null
00db10
+++ glibc-2.17-c758a686/nptl/sysdeps/unix/sysv/linux/sem_waitcommon.c
00db10
@@ -0,0 +1,467 @@
00db10
+/* sem_waitcommon -- wait on a semaphore, shared code.
00db10
+   Copyright (C) 2003-2015 Free Software Foundation, Inc.
00db10
+   This file is part of the GNU C Library.
00db10
+   Contributed by Paul Mackerras <paulus@au.ibm.com>, 2003.
00db10
+
00db10
+   The GNU C Library is free software; you can redistribute it and/or
00db10
+   modify it under the terms of the GNU Lesser General Public
00db10
+   License as published by the Free Software Foundation; either
00db10
+   version 2.1 of the License, or (at your option) any later version.
00db10
+
00db10
+   The GNU C Library is distributed in the hope that it will be useful,
00db10
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
00db10
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.	 See the GNU
00db10
+   Lesser General Public License for more details.
00db10
+
00db10
+   You should have received a copy of the GNU Lesser General Public
00db10
+   License along with the GNU C Library; if not, see
00db10
+   <http://www.gnu.org/licenses/>.  */
00db10
+
00db10
+#include <errno.h>
00db10
+#include <sysdep.h>
00db10
+#include <lowlevellock.h>
00db10
+#include <internaltypes.h>
00db10
+#include <semaphore.h>
00db10
+#include <sys/time.h>
00db10
+
00db10
+#include <pthreadP.h>
00db10
+#include <shlib-compat.h>
00db10
+#include <atomic.h>
00db10
+
00db10
+/* Wrapper for lll_futex_wait with absolute timeout and error checking.
00db10
+   TODO Remove when cleaning up the futex API throughout glibc.  */
00db10
+static __always_inline int
00db10
+futex_abstimed_wait (unsigned int* futex, unsigned int expected,
00db10
+		     const struct timespec* abstime, int private, bool cancel)
00db10
+{
00db10
+  int err, oldtype;
00db10
+  if (abstime == NULL)
00db10
+    {
00db10
+      if (cancel)
00db10
+	oldtype = __pthread_enable_asynccancel ();
00db10
+      err = lll_futex_wait (futex, expected, private);
00db10
+      if (cancel)
00db10
+	__pthread_disable_asynccancel (oldtype);
00db10
+    }
00db10
+  else
00db10
+    {
00db10
+      struct timeval tv;
00db10
+      struct timespec rt;
00db10
+      int sec, nsec;
00db10
+
00db10
+      /* Get the current time.  */
00db10
+      __gettimeofday (&tv, NULL);
00db10
+
00db10
+      /* Compute relative timeout.  */
00db10
+      sec = abstime->tv_sec - tv.tv_sec;
00db10
+      nsec = abstime->tv_nsec - tv.tv_usec * 1000;
00db10
+      if (nsec < 0)
00db10
+        {
00db10
+          nsec += 1000000000;
00db10
+          --sec;
00db10
+        }
00db10
+
00db10
+      /* Already timed out?  */
00db10
+      if (sec < 0)
00db10
+        return ETIMEDOUT;
00db10
+
00db10
+      /* Do wait.  */
00db10
+      rt.tv_sec = sec;
00db10
+      rt.tv_nsec = nsec;
00db10
+      if (cancel)
00db10
+	oldtype = __pthread_enable_asynccancel ();
00db10
+      err = lll_futex_timed_wait (futex, expected, &rt, private);
00db10
+      if (cancel)
00db10
+	__pthread_disable_asynccancel (oldtype);
00db10
+    }
00db10
+  switch (err)
00db10
+    {
00db10
+    case 0:
00db10
+    case -EAGAIN:
00db10
+    case -EINTR:
00db10
+    case -ETIMEDOUT:
00db10
+      return -err;
00db10
+
00db10
+    case -EFAULT: /* Must have been caused by a glibc or application bug.  */
00db10
+    case -EINVAL: /* Either due to wrong alignment or due to the timeout not
00db10
+		     being normalized.  Must have been caused by a glibc or
00db10
+		     application bug.  */
00db10
+    case -ENOSYS: /* Must have been caused by a glibc bug.  */
00db10
+    /* No other errors are documented at this time.  */
00db10
+    default:
00db10
+      abort ();
00db10
+    }
00db10
+}
00db10
+
00db10
+/* Wrapper for lll_futex_wake, with error checking.
00db10
+   TODO Remove when cleaning up the futex API throughout glibc.  */
00db10
+static __always_inline void
00db10
+futex_wake (unsigned int* futex, int processes_to_wake, int private)
00db10
+{
00db10
+  int res = lll_futex_wake (futex, processes_to_wake, private);
00db10
+  /* No error.  Ignore the number of woken processes.  */
00db10
+  if (res >= 0)
00db10
+    return;
00db10
+  switch (res)
00db10
+    {
00db10
+    case -EFAULT: /* Could have happened due to memory reuse.  */
00db10
+    case -EINVAL: /* Could be either due to incorrect alignment (a bug in
00db10
+		     glibc or in the application) or due to memory being
00db10
+		     reused for a PI futex.  We cannot distinguish between the
00db10
+		     two causes, and one of them is correct use, so we do not
00db10
+		     act in this case.  */
00db10
+      return;
00db10
+    case -ENOSYS: /* Must have been caused by a glibc bug.  */
00db10
+    /* No other errors are documented at this time.  */
00db10
+    default:
00db10
+      abort ();
00db10
+    }
00db10
+}
00db10
+
00db10
+
00db10
+/* The semaphore provides two main operations: sem_post adds a token to the
00db10
+   semaphore; sem_wait grabs a token from the semaphore, potentially waiting
00db10
+   until there is a token available.  A sem_wait needs to synchronize with
00db10
+   the sem_post that provided the token, so that whatever lead to the sem_post
00db10
+   happens before the code after sem_wait.
00db10
+
00db10
+   Conceptually, available tokens can simply be counted; let's call that the
00db10
+   value of the semaphore.  However, we also want to know whether there might
00db10
+   be a sem_wait that is blocked on the value because it was zero (using a
00db10
+   futex with the value being the futex variable); if there is no blocked
00db10
+   sem_wait, sem_post does not need to execute a futex_wake call.  Therefore,
00db10
+   we also need to count the number of potentially blocked sem_wait calls
00db10
+   (which we call nwaiters).
00db10
+
00db10
+   What makes this tricky is that POSIX requires that a semaphore can be
00db10
+   destroyed as soon as the last remaining sem_wait has returned, and no
00db10
+   other sem_wait or sem_post calls are executing concurrently.  However, the
00db10
+   sem_post call whose token was consumed by the last sem_wait is considered
00db10
+   to have finished once it provided the token to the sem_wait.
00db10
+   Thus, sem_post must not access the semaphore struct anymore after it has
00db10
+   made a token available; IOW, it needs to be able to atomically provide
00db10
+   a token and check whether any blocked sem_wait calls might exist.
00db10
+
00db10
+   This is straightforward to do if the architecture provides 64b atomics
00db10
+   because we can just put both the value and nwaiters into one variable that
00db10
+   we access atomically: This is the data field, the value is in the
00db10
+   least-significant 32 bits, and nwaiters in the other bits.  When sem_post
00db10
+   makes a value available, it can atomically check nwaiters.
00db10
+
00db10
+   If we have only 32b atomics available, we cannot put both nwaiters and
00db10
+   value into one 32b value because then we might have too few bits for both
00db10
+   of those counters.  Therefore, we need to use two distinct fields.
00db10
+
00db10
+   To allow sem_post to atomically make a token available and check for
00db10
+   blocked sem_wait calls, we use one bit in value to indicate whether
00db10
+   nwaiters is nonzero.  That allows sem_post to use basically the same
00db10
+   algorithm as with 64b atomics, but requires sem_wait to update the bit; it
00db10
+   can't do this atomically with another access to nwaiters, but it can compute
00db10
+   a conservative value for the bit because it's benign if the bit is set
00db10
+   even if nwaiters is zero (all we get is an unnecessary futex wake call by
00db10
+   sem_post).
00db10
+   Specifically, sem_wait will unset the bit speculatively if it believes that
00db10
+   there is no other concurrently executing sem_wait.  If it misspeculated,
00db10
+   it will have to clean up by waking any other sem_wait call (i.e., what
00db10
+   sem_post would do otherwise).  This does not conflict with the destruction
00db10
+   requirement because the semaphore must not be destructed while any sem_wait
00db10
+   is still executing.  */
00db10
+
00db10
+/* Set this to true if you assume that, in contrast to current Linux futex
00db10
+   documentation, lll_futex_wake can return -EINTR only if interrupted by a
00db10
+   signal, not spuriously due to some other reason.
00db10
+   TODO Discuss EINTR conditions with the Linux kernel community.  For
00db10
+   now, we set this to true to not change behavior of semaphores compared
00db10
+   to previous glibc builds.  */
00db10
+static const int sem_assume_only_signals_cause_futex_EINTR = 1;
00db10
+
00db10
+#if !__HAVE_64B_ATOMICS
00db10
+static void
00db10
+__sem_wait_32_finish (struct new_sem *sem);
00db10
+#endif
00db10
+
00db10
+static void
00db10
+__sem_wait_cleanup (void *arg)
00db10
+{
00db10
+  struct new_sem *sem = (struct new_sem *) arg;
00db10
+
00db10
+#if __HAVE_64B_ATOMICS
00db10
+  /* Stop being registered as a waiter.  See below for MO.  */
00db10
+  atomic_fetch_add_relaxed (&sem->data, -(1UL << SEM_NWAITERS_SHIFT));
00db10
+#else
00db10
+  __sem_wait_32_finish (sem);
00db10
+#endif
00db10
+}
00db10
+
00db10
+/* Wait until at least one token is available, possibly with a timeout.
00db10
+   This is in a separate function in order to make sure gcc
00db10
+   puts the call site into an exception region, and thus the
00db10
+   cleanups get properly run.  TODO still necessary?  Other futex_wait
00db10
+   users don't seem to need it.  */
00db10
+static int
00db10
+__attribute__ ((noinline))
00db10
+do_futex_wait (struct new_sem *sem, const struct timespec *abstime)
00db10
+{
00db10
+  int err;
00db10
+
00db10
+#if __HAVE_64B_ATOMICS
00db10
+  err = futex_abstimed_wait ((unsigned int *) &sem->data + SEM_VALUE_OFFSET, 0,
00db10
+			     abstime, sem->private, true);
00db10
+#else
00db10
+  err = futex_abstimed_wait (&sem->value, SEM_NWAITERS_MASK, abstime,
00db10
+			     sem->private, true);
00db10
+#endif
00db10
+
00db10
+  return err;
00db10
+}
00db10
+
00db10
+/* Fast path: Try to grab a token without blocking.  */
00db10
+static int
00db10
+__new_sem_wait_fast (struct new_sem *sem, int definitive_result)
00db10
+{
00db10
+  /* We need acquire MO if we actually grab a token, so that this
00db10
+     synchronizes with all token providers (i.e., the RMW operation we read
00db10
+     from or all those before it in modification order; also see sem_post).
00db10
+     We do not need to guarantee any ordering if we observed that there is
00db10
+     no token (POSIX leaves it unspecified whether functions that fail
00db10
+     synchronize memory); thus, relaxed MO is sufficient for the initial load
00db10
+     and the failure path of the CAS.  If the weak CAS fails and we need a
00db10
+     definitive result, retry.  */
00db10
+#if __HAVE_64B_ATOMICS
00db10
+  unsigned long d = atomic_load_relaxed (&sem->data);
00db10
+  do
00db10
+    {
00db10
+      if ((d & SEM_VALUE_MASK) == 0)
00db10
+	break;
00db10
+      if (atomic_compare_exchange_weak_acquire (&sem->data, &d, d - 1))
00db10
+	return 0;
00db10
+    }
00db10
+  while (definitive_result);
00db10
+  return -1;
00db10
+#else
00db10
+  unsigned int v = atomic_load_relaxed (&sem->value);
00db10
+  do
00db10
+    {
00db10
+      if ((v >> SEM_VALUE_SHIFT) == 0)
00db10
+	break;
00db10
+      if (atomic_compare_exchange_weak_acquire (&sem->value,
00db10
+	  &v, v - (1 << SEM_VALUE_SHIFT)))
00db10
+	return 0;
00db10
+    }
00db10
+  while (definitive_result);
00db10
+  return -1;
00db10
+#endif
00db10
+}
00db10
+
00db10
+/* Slow path that blocks.  */
00db10
+static int
00db10
+__attribute__ ((noinline))
00db10
+__new_sem_wait_slow (struct new_sem *sem, const struct timespec *abstime)
00db10
+{
00db10
+  int err = 0;
00db10
+
00db10
+#if __HAVE_64B_ATOMICS
00db10
+  /* Add a waiter.  Relaxed MO is sufficient because we can rely on the
00db10
+     ordering provided by the RMW operations we use.  */
00db10
+  unsigned long d = atomic_fetch_add_relaxed (&sem->data,
00db10
+      1UL << SEM_NWAITERS_SHIFT);
00db10
+
00db10
+  pthread_cleanup_push (__sem_wait_cleanup, sem);
00db10
+
00db10
+  /* Wait for a token to be available.  Retry until we can grab one.  */
00db10
+  for (;;)
00db10
+    {
00db10
+      /* If there is no token available, sleep until there is.  */
00db10
+      if ((d & SEM_VALUE_MASK) == 0)
00db10
+	{
00db10
+	  err = do_futex_wait (sem, abstime);
00db10
+	  /* A futex return value of 0 or EAGAIN is due to a real or spurious
00db10
+	     wake-up, or due to a change in the number of tokens.  We retry in
00db10
+	     these cases.
00db10
+	     If we timed out, forward this to the caller.
00db10
+	     EINTR could be either due to being interrupted by a signal, or
00db10
+	     due to a spurious wake-up.  Thus, we cannot distinguish between
00db10
+	     both, and are not allowed to return EINTR to the caller but have
00db10
+	     to retry; this is because we may not have been interrupted by a
00db10
+	     signal.  However, if we assume that only signals cause a futex
00db10
+	     return of EINTR, we forward EINTR to the caller.
00db10
+
00db10
+	     Retrying on EINTR is technically always allowed because to
00db10
+	     reliably interrupt sem_wait with a signal, the signal handler
00db10
+	     must call sem_post (which is AS-Safe).  In executions where the
00db10
+	     signal handler does not do that, the implementation can correctly
00db10
+	     claim that sem_wait hadn't actually started to execute yet, and
00db10
+	     thus the signal never actually interrupted sem_wait.  We make no
00db10
+	     timing guarantees, so the program can never observe that sem_wait
00db10
+	     actually did start to execute.  Thus, in a correct program, we
00db10
+	     can expect a signal that wanted to interrupt the sem_wait to have
00db10
+	     provided a token, and can just try to grab this token if
00db10
+	     futex_wait returns EINTR.  */
00db10
+	  if (err == ETIMEDOUT ||
00db10
+	      (err == EINTR && sem_assume_only_signals_cause_futex_EINTR))
00db10
+	    {
00db10
+	      __set_errno (err);
00db10
+	      err = -1;
00db10
+	      /* Stop being registered as a waiter.  */
00db10
+	      atomic_fetch_add_relaxed (&sem->data,
00db10
+		  -(1UL << SEM_NWAITERS_SHIFT));
00db10
+	      break;
00db10
+	    }
00db10
+	  /* Relaxed MO is sufficient; see below.  */
00db10
+	  d = atomic_load_relaxed (&sem->data);
00db10
+	}
00db10
+      else
00db10
+	{
00db10
+	  /* Try to grab both a token and stop being a waiter.  We need
00db10
+	     acquire MO so this synchronizes with all token providers (i.e.,
00db10
+	     the RMW operation we read from or all those before it in
00db10
+	     modification order; also see sem_post).  On the failure path,
00db10
+	     relaxed MO is sufficient because we only eventually need the
00db10
+	     up-to-date value; the futex_wait or the CAS perform the real
00db10
+	     work.  */
00db10
+	  if (atomic_compare_exchange_weak_acquire (&sem->data,
00db10
+	      &d, d - 1 - (1UL << SEM_NWAITERS_SHIFT)))
00db10
+	    {
00db10
+	      err = 0;
00db10
+	      break;
00db10
+	    }
00db10
+	}
00db10
+    }
00db10
+
00db10
+  pthread_cleanup_pop (0);
00db10
+#else
00db10
+  /* The main difference to the 64b-atomics implementation is that we need to
00db10
+     access value and nwaiters in separate steps, and that the nwaiters bit
00db10
+     in the value can temporarily not be set even if nwaiters is nonzero.
00db10
+     We work around incorrectly unsetting the nwaiters bit by letting sem_wait
00db10
+     set the bit again and waking the number of waiters that could grab a
00db10
+     token.  There are two additional properties we need to ensure:
00db10
+     (1) We make sure that whenever unsetting the bit, we see the increment of
00db10
+     nwaiters by the other thread that set the bit.  IOW, we will notice if
00db10
+     we make a mistake.
00db10
+     (2) When setting the nwaiters bit, we make sure that we see the unsetting
00db10
+     of the bit by another waiter that happened before us.  This avoids having
00db10
+     to blindly set the bit whenever we need to block on it.  We set/unset
00db10
+     the bit while having incremented nwaiters (i.e., are a registered
00db10
+     waiter), and the problematic case only happens when one waiter indeed
00db10
+     followed another (i.e., nwaiters was never larger than 1); thus, this
00db10
+     works similarly as with a critical section using nwaiters (see the MOs
00db10
+     and related comments below).
00db10
+
00db10
+     An alternative approach would be to unset the bit after decrementing
00db10
+     nwaiters; however, that would result in needing Dekker-like
00db10
+     synchronization and thus full memory barriers.  We also would not be able
00db10
+     to prevent misspeculation, so this alternative scheme does not seem
00db10
+     beneficial.  */
00db10
+  unsigned int v;
00db10
+
00db10
+  /* Add a waiter.  We need acquire MO so this synchronizes with the release
00db10
+     MO we use when decrementing nwaiters below; it ensures that if another
00db10
+     waiter unset the bit before us, we see that and set it again.  Also see
00db10
+     property (2) above.  */
00db10
+  atomic_fetch_add_acquire (&sem->nwaiters, 1);
00db10
+
00db10
+  pthread_cleanup_push (__sem_wait_cleanup, sem);
00db10
+
00db10
+  /* Wait for a token to be available.  Retry until we can grab one.  */
00db10
+  /* We do not need any ordering wrt. to this load's reads-from, so relaxed
00db10
+     MO is sufficient.  The acquire MO above ensures that in the problematic
00db10
+     case, we do see the unsetting of the bit by another waiter.  */
00db10
+  v = atomic_load_relaxed (&sem->value);
00db10
+  do
00db10
+    {
00db10
+      do
00db10
+	{
00db10
+	  /* We are about to block, so make sure that the nwaiters bit is
00db10
+	     set.  We need release MO on the CAS to ensure that when another
00db10
+	     waiter unsets the nwaiters bit, it will also observe that we
00db10
+	     incremented nwaiters in the meantime (also see the unsetting of
00db10
+	     the bit below).  Relaxed MO on CAS failure is sufficient (see
00db10
+	     above).  */
00db10
+	  do
00db10
+	    {
00db10
+	      if ((v & SEM_NWAITERS_MASK) != 0)
00db10
+		break;
00db10
+	    }
00db10
+	  while (!atomic_compare_exchange_weak_release (&sem->value,
00db10
+	      &v, v | SEM_NWAITERS_MASK));
00db10
+	  /* If there is no token, wait.  */
00db10
+	  if ((v >> SEM_VALUE_SHIFT) == 0)
00db10
+	    {
00db10
+	      /* See __HAVE_64B_ATOMICS variant.  */
00db10
+	      err = do_futex_wait(sem, abstime);
00db10
+	      if (err == ETIMEDOUT ||
00db10
+		  (err == EINTR && sem_assume_only_signals_cause_futex_EINTR))
00db10
+		{
00db10
+		  __set_errno (err);
00db10
+		  err = -1;
00db10
+		  goto error;
00db10
+		}
00db10
+	      err = 0;
00db10
+	      /* We blocked, so there might be a token now.  Relaxed MO is
00db10
+		 sufficient (see above).  */
00db10
+	      v = atomic_load_relaxed (&sem->value);
00db10
+	    }
00db10
+	}
00db10
+      /* If there is no token, we must not try to grab one.  */
00db10
+      while ((v >> SEM_VALUE_SHIFT) == 0);
00db10
+    }
00db10
+  /* Try to grab a token.  We need acquire MO so this synchronizes with
00db10
+     all token providers (i.e., the RMW operation we read from or all those
00db10
+     before it in modification order; also see sem_post).  */
00db10
+  while (!atomic_compare_exchange_weak_acquire (&sem->value,
00db10
+      &v, v - (1 << SEM_VALUE_SHIFT)));
00db10
+
00db10
+error:
00db10
+  pthread_cleanup_pop (0);
00db10
+
00db10
+  __sem_wait_32_finish (sem);
00db10
+#endif
00db10
+
00db10
+  return err;
00db10
+}
00db10
+
00db10
+/* Stop being a registered waiter (non-64b-atomics code only).  */
00db10
+#if !__HAVE_64B_ATOMICS
00db10
+static void
00db10
+__sem_wait_32_finish (struct new_sem *sem)
00db10
+{
00db10
+  /* The nwaiters bit is still set, try to unset it now if this seems
00db10
+     necessary.  We do this before decrementing nwaiters so that the unsetting
00db10
+     is visible to other waiters entering after us.  Relaxed MO is sufficient
00db10
+     because we are just speculating here; a stronger MO would not prevent
00db10
+     misspeculation.  */
00db10
+  unsigned int wguess = atomic_load_relaxed (&sem->nwaiters);
00db10
+  if (wguess == 1)
00db10
+    /* We might be the last waiter, so unset.  This needs acquire MO so that
00db10
+       it syncronizes with the release MO when setting the bit above; if we
00db10
+       overwrite someone else that set the bit, we'll read in the following
00db10
+       decrement of nwaiters at least from that release sequence, so we'll
00db10
+       see if the other waiter is still active or if another writer entered
00db10
+       in the meantime (i.e., using the check below).  */
00db10
+    atomic_fetch_and_acquire (&sem->value, ~SEM_NWAITERS_MASK);
00db10
+
00db10
+  /* Now stop being a waiter, and see whether our guess was correct.
00db10
+     This needs release MO so that it synchronizes with the acquire MO when
00db10
+     a waiter increments nwaiters; this makes sure that newer writers see that
00db10
+     we reset the waiters_present bit.  */
00db10
+  unsigned int wfinal = atomic_fetch_add_release (&sem->nwaiters, -1);
00db10
+  if (wfinal > 1 && wguess == 1)
00db10
+    {
00db10
+      /* We guessed wrong, and so need to clean up after the mistake and
00db10
+         unblock any waiters that could have not been woken.  There is no
00db10
+         additional ordering that we need to set up, so relaxed MO is
00db10
+         sufficient.  */
00db10
+      unsigned int v = atomic_fetch_or_relaxed (&sem->value,
00db10
+						SEM_NWAITERS_MASK);
00db10
+      /* If there are available tokens, then wake as many waiters.  If there
00db10
+         aren't any, then there is no need to wake anyone because there is
00db10
+         none to grab for another waiter.  If tokens become available
00db10
+         subsequently, then the respective sem_post calls will do the wake-up
00db10
+         due to us having set the nwaiters bit again.  */
00db10
+      v >>= SEM_VALUE_SHIFT;
00db10
+      if (v > 0)
00db10
+	futex_wake (&sem->value, v, sem->private);
00db10
+    }
00db10
+}
00db10
+#endif
00db10
Index: glibc-2.17-c758a686/nptl/sysdeps/unix/sysv/linux/structsem.sym
00db10
===================================================================
00db10
--- glibc-2.17-c758a686.orig/nptl/sysdeps/unix/sysv/linux/structsem.sym
00db10
+++ /dev/null
00db10
@@ -1,12 +0,0 @@
00db10
-#include <limits.h>
00db10
-#include <stddef.h>
00db10
-#include <sched.h>
00db10
-#include <bits/pthreadtypes.h>
00db10
-#include "internaltypes.h"
00db10
-
00db10
---
00db10
-
00db10
-VALUE		offsetof (struct new_sem, value)
00db10
-PRIVATE		offsetof (struct new_sem, private)
00db10
-NWAITERS	offsetof (struct new_sem, nwaiters)
00db10
-SEM_VALUE_MAX	SEM_VALUE_MAX
00db10
Index: glibc-2.17-c758a686/nptl/sysdeps/unix/sysv/linux/x86_64/sem_post.S
00db10
===================================================================
00db10
--- glibc-2.17-c758a686.orig/nptl/sysdeps/unix/sysv/linux/x86_64/sem_post.S
00db10
+++ /dev/null
00db10
@@ -1,75 +0,0 @@
00db10
-/* Copyright (C) 2002,2003,2005,2007,2008,2011 Free Software Foundation, Inc.
00db10
-   This file is part of the GNU C Library.
00db10
-   Contributed by Ulrich Drepper <drepper@redhat.com>, 2002.
00db10
-
00db10
-   The GNU C Library is free software; you can redistribute it and/or
00db10
-   modify it under the terms of the GNU Lesser General Public
00db10
-   License as published by the Free Software Foundation; either
00db10
-   version 2.1 of the License, or (at your option) any later version.
00db10
-
00db10
-   The GNU C Library is distributed in the hope that it will be useful,
00db10
-   but WITHOUT ANY WARRANTY; without even the implied warranty of
00db10
-   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00db10
-   Lesser General Public License for more details.
00db10
-
00db10
-   You should have received a copy of the GNU Lesser General Public
00db10
-   License along with the GNU C Library; if not, see
00db10
-   <http://www.gnu.org/licenses/>.  */
00db10
-
00db10
-#include <sysdep.h>
00db10
-#include <lowlevellock.h>
00db10
-#include <shlib-compat.h>
00db10
-#include <pthread-errnos.h>
00db10
-#include <structsem.h>
00db10
-
00db10
-
00db10
-	.text
00db10
-
00db10
-	.globl	sem_post
00db10
-	.type	sem_post,@function
00db10
-	.align	16
00db10
-sem_post:
00db10
-#if VALUE == 0
00db10
-	movl	(%rdi), %eax
00db10
-#else
00db10
-	movl	VALUE(%rdi), %eax
00db10
-#endif
00db10
-0:	cmpl	$SEM_VALUE_MAX, %eax
00db10
-	je	3f
00db10
-	leal	1(%rax), %esi
00db10
-	LOCK
00db10
-#if VALUE == 0
00db10
-	cmpxchgl %esi, (%rdi)
00db10
-#else
00db10
-	cmpxchgl %esi, VALUE(%rdi)
00db10
-#endif
00db10
-	jnz	0b
00db10
-
00db10
-	LP_OP(cmp) $0, NWAITERS(%rdi)
00db10
-	je	2f
00db10
-
00db10
-	movl	$SYS_futex, %eax
00db10
-	movl	$FUTEX_WAKE, %esi
00db10
-	orl	PRIVATE(%rdi), %esi
00db10
-	movl	$1, %edx
00db10
-	syscall
00db10
-
00db10
-	testq	%rax, %rax
00db10
-	js	1f
00db10
-
00db10
-2:	xorl	%eax, %eax
00db10
-	retq
00db10
-
00db10
-1:
00db10
-	movl	$EINVAL, %eax
00db10
-	jmp	4f
00db10
-
00db10
-3:
00db10
-	movl	$EOVERFLOW, %eax
00db10
-
00db10
-4:
00db10
-	movq	errno@gottpoff(%rip), %rdx
00db10
-	movl	%eax, %fs:(%rdx)
00db10
-	orl	$-1, %eax
00db10
-	retq
00db10
-	.size	sem_post,.-sem_post
00db10
Index: glibc-2.17-c758a686/nptl/sysdeps/unix/sysv/linux/x86_64/sem_timedwait.S
00db10
===================================================================
00db10
--- glibc-2.17-c758a686.orig/nptl/sysdeps/unix/sysv/linux/x86_64/sem_timedwait.S
00db10
+++ /dev/null
00db10
@@ -1,380 +0,0 @@
00db10
-/* Copyright (C) 2002,2003,2005,2007,2009,2010,2011 Free Software Foundation, Inc.
00db10
-   This file is part of the GNU C Library.
00db10
-   Contributed by Ulrich Drepper <drepper@redhat.com>, 2002.
00db10
-
00db10
-   The GNU C Library is free software; you can redistribute it and/or
00db10
-   modify it under the terms of the GNU Lesser General Public
00db10
-   License as published by the Free Software Foundation; either
00db10
-   version 2.1 of the License, or (at your option) any later version.
00db10
-
00db10
-   The GNU C Library is distributed in the hope that it will be useful,
00db10
-   but WITHOUT ANY WARRANTY; without even the implied warranty of
00db10
-   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00db10
-   Lesser General Public License for more details.
00db10
-
00db10
-   You should have received a copy of the GNU Lesser General Public
00db10
-   License along with the GNU C Library; if not, see
00db10
-   <http://www.gnu.org/licenses/>.  */
00db10
-
00db10
-#include <sysdep.h>
00db10
-#include <kernel-features.h>
00db10
-#include <lowlevellock.h>
00db10
-#include <shlib-compat.h>
00db10
-#include <pthread-errnos.h>
00db10
-#include <structsem.h>
00db10
-
00db10
-	.text
00db10
-
00db10
-	.globl	sem_timedwait
00db10
-	.type	sem_timedwait,@function
00db10
-	.align	16
00db10
-sem_timedwait:
00db10
-.LSTARTCODE:
00db10
-	cfi_startproc
00db10
-#ifdef SHARED
00db10
-	cfi_personality(DW_EH_PE_pcrel | DW_EH_PE_sdata4 | DW_EH_PE_indirect,
00db10
-			DW.ref.__gcc_personality_v0)
00db10
-	cfi_lsda(DW_EH_PE_pcrel | DW_EH_PE_sdata4, .LexceptSTART)
00db10
-#else
00db10
-	cfi_personality(DW_EH_PE_udata4, __gcc_personality_v0)
00db10
-	cfi_lsda(DW_EH_PE_udata4, .LexceptSTART)
00db10
-#endif
00db10
-#if VALUE == 0
00db10
-	movl	(%rdi), %eax
00db10
-#else
00db10
-	movl	VALUE(%rdi), %eax
00db10
-#endif
00db10
-2:	testl	%eax, %eax
00db10
-	je	1f
00db10
-
00db10
-	leaq	-1(%rax), %rdx
00db10
-	LOCK
00db10
-#if VALUE == 0
00db10
-	cmpxchgl %edx, (%rdi)
00db10
-#else
00db10
-	cmpxchgl %edx, VALUE(%rdi)
00db10
-#endif
00db10
-	jne	2b
00db10
-
00db10
-	xorl	%eax, %eax
00db10
-	retq
00db10
-
00db10
-	/* Check whether the timeout value is valid.  */
00db10
-1:	cmpq	$1000000000, 8(%rsi)
00db10
-	jae	6f
00db10
-
00db10
-#ifndef __ASSUME_FUTEX_CLOCK_REALTIME
00db10
-#  ifdef PIC
00db10
-	cmpl	$0, __have_futex_clock_realtime(%rip)
00db10
-#  else
00db10
-	cmpl	$0, __have_futex_clock_realtime
00db10
-#  endif
00db10
-	je	.Lreltmo
00db10
-#endif
00db10
-
00db10
-	cmpq	$0, (%rsi)
00db10
-	js	16f
00db10
-
00db10
-	/* This push is only needed to store the sem_t pointer for the
00db10
-	   exception handler.  */
00db10
-	pushq	%rdi
00db10
-	cfi_adjust_cfa_offset(8)
00db10
-
00db10
-	movq	%rsi, %r10
00db10
-
00db10
-	LOCK
00db10
-	LP_OP(add) $1, NWAITERS(%rdi)
00db10
-
00db10
-.LcleanupSTART:
00db10
-13:	call	__pthread_enable_asynccancel
00db10
-	movl	%eax, %r8d
00db10
-
00db10
-#if VALUE != 0
00db10
-	leaq	VALUE(%rdi), %rdi
00db10
-#endif
00db10
-	movl	$0xffffffff, %r9d
00db10
-	movl	$FUTEX_WAIT_BITSET|FUTEX_CLOCK_REALTIME, %esi
00db10
-	orl	PRIVATE(%rdi), %esi
00db10
-	movl	$SYS_futex, %eax
00db10
-	xorl	%edx, %edx
00db10
-	syscall
00db10
-	movq	%rax, %r9
00db10
-#if VALUE != 0
00db10
-	leaq	-VALUE(%rdi), %rdi
00db10
-#endif
00db10
-
00db10
-	xchgq	%r8, %rdi
00db10
-	call	__pthread_disable_asynccancel
00db10
-.LcleanupEND:
00db10
-	movq	%r8, %rdi
00db10
-
00db10
-	testq	%r9, %r9
00db10
-	je	11f
00db10
-	cmpq	$-EWOULDBLOCK, %r9
00db10
-	jne	3f
00db10
-
00db10
-11:
00db10
-#if VALUE == 0
00db10
-	movl	(%rdi), %eax
00db10
-#else
00db10
-	movl	VALUE(%rdi), %eax
00db10
-#endif
00db10
-14:	testl	%eax, %eax
00db10
-	je	13b
00db10
-
00db10
-	leaq	-1(%rax), %rcx
00db10
-	LOCK
00db10
-#if VALUE == 0
00db10
-	cmpxchgl %ecx, (%rdi)
00db10
-#else
00db10
-	cmpxchgl %ecx, VALUE(%rdi)
00db10
-#endif
00db10
-	jne	14b
00db10
-
00db10
-	xorl	%eax, %eax
00db10
-
00db10
-15:	LOCK
00db10
-	LP_OP(sub) $1, NWAITERS(%rdi)
00db10
-
00db10
-	leaq	8(%rsp), %rsp
00db10
-	cfi_adjust_cfa_offset(-8)
00db10
-	retq
00db10
-
00db10
-	cfi_adjust_cfa_offset(8)
00db10
-3:	negq	%r9
00db10
-	movq	errno@gottpoff(%rip), %rdx
00db10
-	movl	%r9d, %fs:(%rdx)
00db10
-
00db10
-	orl	$-1, %eax
00db10
-	jmp	15b
00db10
-
00db10
-	cfi_adjust_cfa_offset(-8)
00db10
-6:
00db10
-	movq	errno@gottpoff(%rip), %rdx
00db10
-	movl	$EINVAL, %fs:(%rdx)
00db10
-
00db10
-	orl	$-1, %eax
00db10
-
00db10
-	retq
00db10
-
00db10
-16:
00db10
-	movq	errno@gottpoff(%rip), %rdx
00db10
-	movl	$ETIMEDOUT, %fs:(%rdx)
00db10
-
00db10
-	orl	$-1, %eax
00db10
-
00db10
-	retq
00db10
-
00db10
-#ifndef __ASSUME_FUTEX_CLOCK_REALTIME
00db10
-.Lreltmo:
00db10
-	pushq	%r12
00db10
-	cfi_adjust_cfa_offset(8)
00db10
-	cfi_rel_offset(%r12, 0)
00db10
-	pushq	%r13
00db10
-	cfi_adjust_cfa_offset(8)
00db10
-	cfi_rel_offset(%r13, 0)
00db10
-	pushq	%r14
00db10
-	cfi_adjust_cfa_offset(8)
00db10
-	cfi_rel_offset(%r14, 0)
00db10
-
00db10
-#ifdef __ASSUME_FUTEX_CLOCK_REALTIME
00db10
-# define STACKFRAME 8
00db10
-#else
00db10
-# define STACKFRAME 24
00db10
-#endif
00db10
-	subq	$STACKFRAME, %rsp
00db10
-	cfi_adjust_cfa_offset(STACKFRAME)
00db10
-
00db10
-	movq	%rdi, %r12
00db10
-	movq	%rsi, %r13
00db10
-
00db10
-	LOCK
00db10
-	LP_OP(add) $1, NWAITERS(%r12)
00db10
-
00db10
-7:	xorl	%esi, %esi
00db10
-	movq	%rsp,%rdi
00db10
-	/* This call works because we directly jump to a system call entry
00db10
-	   which preserves all the registers.  */
00db10
-	call	JUMPTARGET(__gettimeofday)
00db10
-
00db10
-	/* Compute relative timeout.  */
00db10
-	movq	8(%rsp), %rax
00db10
-	movl	$1000, %edi
00db10
-	mul	%rdi		/* Milli seconds to nano seconds.  */
00db10
-	movq	(%r13), %rdi
00db10
-	movq	8(%r13), %rsi
00db10
-	subq	(%rsp), %rdi
00db10
-	subq	%rax, %rsi
00db10
-	jns	5f
00db10
-	addq	$1000000000, %rsi
00db10
-	decq	%rdi
00db10
-5:	testq	%rdi, %rdi
00db10
-	movl	$ETIMEDOUT, %r14d
00db10
-	js	36f		/* Time is already up.  */
00db10
-
00db10
-	movq	%rdi, (%rsp)	/* Store relative timeout.  */
00db10
-	movq	%rsi, 8(%rsp)
00db10
-
00db10
-.LcleanupSTART2:
00db10
-	call	__pthread_enable_asynccancel
00db10
-	movl	%eax, 16(%rsp)
00db10
-
00db10
-	movq	%rsp, %r10
00db10
-# if VALUE == 0
00db10
-	movq	%r12, %rdi
00db10
-# else
00db10
-	leaq	VALUE(%r12), %rdi
00db10
-# endif
00db10
-# if FUTEX_WAIT == 0
00db10
-	movl	PRIVATE(%rdi), %esi
00db10
-# else
00db10
-	movl	$FUTEX_WAIT, %esi
00db10
-	orl	PRIVATE(%rdi), %esi
00db10
-# endif
00db10
-	movl	$SYS_futex, %eax
00db10
-	xorl	%edx, %edx
00db10
-	syscall
00db10
-	movq	%rax, %r14
00db10
-
00db10
-	movl	16(%rsp), %edi
00db10
-	call	__pthread_disable_asynccancel
00db10
-.LcleanupEND2:
00db10
-
00db10
-	testq	%r14, %r14
00db10
-	je	9f
00db10
-	cmpq	$-EWOULDBLOCK, %r14
00db10
-	jne	33f
00db10
-
00db10
-9:
00db10
-# if VALUE == 0
00db10
-	movl	(%r12), %eax
00db10
-# else
00db10
-	movl	VALUE(%r12), %eax
00db10
-# endif
00db10
-8:	testl	%eax, %eax
00db10
-	je	7b
00db10
-
00db10
-	leaq	-1(%rax), %rcx
00db10
-	LOCK
00db10
-# if VALUE == 0
00db10
-	cmpxchgl %ecx, (%r12)
00db10
-# else
00db10
-	cmpxchgl %ecx, VALUE(%r12)
00db10
-# endif
00db10
-	jne	8b
00db10
-
00db10
-	xorl	%eax, %eax
00db10
-
00db10
-45:	LOCK
00db10
-	LP_OP(sub) $1, NWAITERS(%r12)
00db10
-
00db10
-	addq	$STACKFRAME, %rsp
00db10
-	cfi_adjust_cfa_offset(-STACKFRAME)
00db10
-	popq	%r14
00db10
-	cfi_adjust_cfa_offset(-8)
00db10
-	cfi_restore(%r14)
00db10
-	popq	%r13
00db10
-	cfi_adjust_cfa_offset(-8)
00db10
-	cfi_restore(%r13)
00db10
-	popq	%r12
00db10
-	cfi_adjust_cfa_offset(-8)
00db10
-	cfi_restore(%r12)
00db10
-	retq
00db10
-
00db10
-	cfi_adjust_cfa_offset(STACKFRAME + 3 * 8)
00db10
-	cfi_rel_offset(%r12, STACKFRAME + 2 * 8)
00db10
-	cfi_rel_offset(%r13, STACKFRAME + 1 * 8)
00db10
-	cfi_rel_offset(%r14, STACKFRAME)
00db10
-33:	negq	%r14
00db10
-36:
00db10
-	movq	errno@gottpoff(%rip), %rdx
00db10
-	movl	%r14d, %fs:(%rdx)
00db10
-
00db10
-	orl	$-1, %eax
00db10
-	jmp	45b
00db10
-#endif
00db10
-	cfi_endproc
00db10
-	.size	sem_timedwait,.-sem_timedwait
00db10
-
00db10
-
00db10
-	.type	sem_timedwait_cleanup,@function
00db10
-sem_timedwait_cleanup:
00db10
-	cfi_startproc
00db10
-	cfi_adjust_cfa_offset(8)
00db10
-
00db10
-	movq	(%rsp), %rdi
00db10
-	LOCK
00db10
-	LP_OP(sub) $1, NWAITERS(%rdi)
00db10
-	movq	%rax, %rdi
00db10
-.LcallUR:
00db10
-	call	_Unwind_Resume@PLT
00db10
-	hlt
00db10
-.LENDCODE:
00db10
-	cfi_endproc
00db10
-	.size	sem_timedwait_cleanup,.-sem_timedwait_cleanup
00db10
-
00db10
-
00db10
-#ifndef __ASSUME_FUTEX_CLOCK_REALTIME
00db10
-	.type	sem_timedwait_cleanup2,@function
00db10
-sem_timedwait_cleanup2:
00db10
-	cfi_startproc
00db10
-	cfi_adjust_cfa_offset(STACKFRAME + 3 * 8)
00db10
-	cfi_rel_offset(%r12, STACKFRAME + 2 * 8)
00db10
-	cfi_rel_offset(%r13, STACKFRAME + 1 * 8)
00db10
-	cfi_rel_offset(%r14, STACKFRAME)
00db10
-
00db10
-	LOCK
00db10
-	LP_OP(sub) $1, NWAITERS(%r12)
00db10
-	movq	%rax, %rdi
00db10
-	movq	STACKFRAME(%rsp), %r14
00db10
-	movq	STACKFRAME+8(%rsp), %r13
00db10
-	movq	STACKFRAME+16(%rsp), %r12
00db10
-.LcallUR2:
00db10
-	call	_Unwind_Resume@PLT
00db10
-	hlt
00db10
-.LENDCODE2:
00db10
-	cfi_endproc
00db10
-	.size	sem_timedwait_cleanup2,.-sem_timedwait_cleanup2
00db10
-#endif
00db10
-
00db10
-
00db10
-	.section .gcc_except_table,"a",@progbits
00db10
-.LexceptSTART:
00db10
-	.byte	DW_EH_PE_omit			# @LPStart format
00db10
-	.byte	DW_EH_PE_omit			# @TType format
00db10
-	.byte	DW_EH_PE_uleb128		# call-site format
00db10
-	.uleb128 .Lcstend-.Lcstbegin
00db10
-.Lcstbegin:
00db10
-	.uleb128 .LcleanupSTART-.LSTARTCODE
00db10
-	.uleb128 .LcleanupEND-.LcleanupSTART
00db10
-	.uleb128 sem_timedwait_cleanup-.LSTARTCODE
00db10
-	.uleb128  0
00db10
-#ifndef __ASSUME_FUTEX_CLOCK_REALTIME
00db10
-	.uleb128 .LcleanupSTART2-.LSTARTCODE
00db10
-	.uleb128 .LcleanupEND2-.LcleanupSTART2
00db10
-	.uleb128 sem_timedwait_cleanup2-.LSTARTCODE
00db10
-	.uleb128  0
00db10
-#endif
00db10
-	.uleb128 .LcallUR-.LSTARTCODE
00db10
-	.uleb128 .LENDCODE-.LcallUR
00db10
-	.uleb128 0
00db10
-	.uleb128  0
00db10
-#ifndef __ASSUME_FUTEX_CLOCK_REALTIME
00db10
-	.uleb128 .LcallUR2-.LSTARTCODE
00db10
-	.uleb128 .LENDCODE2-.LcallUR2
00db10
-	.uleb128 0
00db10
-	.uleb128  0
00db10
-#endif
00db10
-.Lcstend:
00db10
-
00db10
-
00db10
-#ifdef SHARED
00db10
-	.hidden	DW.ref.__gcc_personality_v0
00db10
-	.weak	DW.ref.__gcc_personality_v0
00db10
-	.section .gnu.linkonce.d.DW.ref.__gcc_personality_v0,"aw",@progbits
00db10
-	.align	LP_SIZE
00db10
-	.type	DW.ref.__gcc_personality_v0, @object
00db10
-	.size	DW.ref.__gcc_personality_v0, LP_SIZE
00db10
-DW.ref.__gcc_personality_v0:
00db10
-	ASM_ADDR __gcc_personality_v0
00db10
-#endif
00db10
Index: glibc-2.17-c758a686/nptl/sysdeps/unix/sysv/linux/x86_64/sem_trywait.S
00db10
===================================================================
00db10
--- glibc-2.17-c758a686.orig/nptl/sysdeps/unix/sysv/linux/x86_64/sem_trywait.S
00db10
+++ /dev/null
00db10
@@ -1,47 +0,0 @@
00db10
-/* Copyright (C) 2002, 2003, 2005, 2007, 2011 Free Software Foundation, Inc.
00db10
-   This file is part of the GNU C Library.
00db10
-   Contributed by Ulrich Drepper <drepper@redhat.com>, 2002.
00db10
-
00db10
-   The GNU C Library is free software; you can redistribute it and/or
00db10
-   modify it under the terms of the GNU Lesser General Public
00db10
-   License as published by the Free Software Foundation; either
00db10
-   version 2.1 of the License, or (at your option) any later version.
00db10
-
00db10
-   The GNU C Library is distributed in the hope that it will be useful,
00db10
-   but WITHOUT ANY WARRANTY; without even the implied warranty of
00db10
-   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00db10
-   Lesser General Public License for more details.
00db10
-
00db10
-   You should have received a copy of the GNU Lesser General Public
00db10
-   License along with the GNU C Library; if not, see
00db10
-   <http://www.gnu.org/licenses/>.  */
00db10
-
00db10
-#include <sysdep.h>
00db10
-#include <lowlevellock.h>
00db10
-#include <shlib-compat.h>
00db10
-#include <pthread-errnos.h>
00db10
-
00db10
-	.text
00db10
-
00db10
-	.globl	sem_trywait
00db10
-	.type	sem_trywait,@function
00db10
-	.align	16
00db10
-sem_trywait:
00db10
-	movl	(%rdi), %eax
00db10
-2:	testl	%eax, %eax
00db10
-	jz	1f
00db10
-
00db10
-	leal	-1(%rax), %edx
00db10
-	LOCK
00db10
-	cmpxchgl %edx, (%rdi)
00db10
-	jne	2b
00db10
-
00db10
-	xorl	%eax, %eax
00db10
-	retq
00db10
-
00db10
-1:
00db10
-	movq	errno@gottpoff(%rip), %rdx
00db10
-	movl	$EAGAIN, %fs:(%rdx)
00db10
-	orl	$-1, %eax
00db10
-	retq
00db10
-	.size	sem_trywait,.-sem_trywait
00db10
Index: glibc-2.17-c758a686/nptl/sysdeps/unix/sysv/linux/x86_64/sem_wait.S
00db10
===================================================================
00db10
--- glibc-2.17-c758a686.orig/nptl/sysdeps/unix/sysv/linux/x86_64/sem_wait.S
00db10
+++ /dev/null
00db10
@@ -1,176 +0,0 @@
00db10
-/* Copyright (C) 2002, 2003, 2005, 2007, 2009, 2011 Free Software Foundation, Inc.
00db10
-   This file is part of the GNU C Library.
00db10
-   Contributed by Ulrich Drepper <drepper@redhat.com>, 2002.
00db10
-
00db10
-   The GNU C Library is free software; you can redistribute it and/or
00db10
-   modify it under the terms of the GNU Lesser General Public
00db10
-   License as published by the Free Software Foundation; either
00db10
-   version 2.1 of the License, or (at your option) any later version.
00db10
-
00db10
-   The GNU C Library is distributed in the hope that it will be useful,
00db10
-   but WITHOUT ANY WARRANTY; without even the implied warranty of
00db10
-   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00db10
-   Lesser General Public License for more details.
00db10
-
00db10
-   You should have received a copy of the GNU Lesser General Public
00db10
-   License along with the GNU C Library; if not, see
00db10
-   <http://www.gnu.org/licenses/>.  */
00db10
-
00db10
-#include <sysdep.h>
00db10
-#include <lowlevellock.h>
00db10
-#include <shlib-compat.h>
00db10
-#include <pthread-errnos.h>
00db10
-#include <structsem.h>
00db10
-
00db10
-
00db10
-	.text
00db10
-
00db10
-	.globl	sem_wait
00db10
-	.type	sem_wait,@function
00db10
-	.align	16
00db10
-sem_wait:
00db10
-.LSTARTCODE:
00db10
-	cfi_startproc
00db10
-#ifdef SHARED
00db10
-	cfi_personality(DW_EH_PE_pcrel | DW_EH_PE_sdata4 | DW_EH_PE_indirect,
00db10
-			DW.ref.__gcc_personality_v0)
00db10
-	cfi_lsda(DW_EH_PE_pcrel | DW_EH_PE_sdata4, .LexceptSTART)
00db10
-#else
00db10
-	cfi_personality(DW_EH_PE_udata4, __gcc_personality_v0)
00db10
-	cfi_lsda(DW_EH_PE_udata4, .LexceptSTART)
00db10
-#endif
00db10
-
00db10
-#if VALUE == 0
00db10
-	movl	(%rdi), %eax
00db10
-#else
00db10
-	movl	VALUE(%rdi), %eax
00db10
-#endif
00db10
-2:	testl	%eax, %eax
00db10
-	je	1f
00db10
-
00db10
-	leal	-1(%rax), %edx
00db10
-	LOCK
00db10
-#if VALUE == 0
00db10
-	cmpxchgl %edx, (%rdi)
00db10
-#else
00db10
-	cmpxchgl %edx, VALUE(%rdi)
00db10
-#endif
00db10
-	jne	2b
00db10
-
00db10
-	xorl	%eax, %eax
00db10
-	retq
00db10
-
00db10
-	/* This push is only needed to store the sem_t pointer for the
00db10
-	   exception handler.  */
00db10
-1:	pushq	%rdi
00db10
-	cfi_adjust_cfa_offset(8)
00db10
-
00db10
-	LOCK
00db10
-	LP_OP(add) $1, NWAITERS(%rdi)
00db10
-
00db10
-.LcleanupSTART:
00db10
-6:	call	__pthread_enable_asynccancel
00db10
-	movl	%eax, %r8d
00db10
-
00db10
-	xorq	%r10, %r10
00db10
-	movl	$SYS_futex, %eax
00db10
-#if FUTEX_WAIT == 0
00db10
-	movl	PRIVATE(%rdi), %esi
00db10
-#else
00db10
-	movl	$FUTEX_WAIT, %esi
00db10
-	orl	PRIVATE(%rdi), %esi
00db10
-#endif
00db10
-	xorl	%edx, %edx
00db10
-	syscall
00db10
-	movq	%rax, %rcx
00db10
-
00db10
-	xchgq	%r8, %rdi
00db10
-	call	__pthread_disable_asynccancel
00db10
-.LcleanupEND:
00db10
-	movq	%r8, %rdi
00db10
-
00db10
-	testq	%rcx, %rcx
00db10
-	je	3f
00db10
-	cmpq	$-EWOULDBLOCK, %rcx
00db10
-	jne	4f
00db10
-
00db10
-3:
00db10
-#if VALUE == 0
00db10
-	movl	(%rdi), %eax
00db10
-#else
00db10
-	movl	VALUE(%rdi), %eax
00db10
-#endif
00db10
-5:	testl	%eax, %eax
00db10
-	je	6b
00db10
-
00db10
-	leal	-1(%rax), %edx
00db10
-	LOCK
00db10
-#if VALUE == 0
00db10
-	cmpxchgl %edx, (%rdi)
00db10
-#else
00db10
-	cmpxchgl %edx, VALUE(%rdi)
00db10
-#endif
00db10
-	jne	5b
00db10
-
00db10
-	xorl	%eax, %eax
00db10
-
00db10
-9:	LOCK
00db10
-	LP_OP(sub) $1, NWAITERS(%rdi)
00db10
-
00db10
-	leaq	8(%rsp), %rsp
00db10
-	cfi_adjust_cfa_offset(-8)
00db10
-
00db10
-	retq
00db10
-
00db10
-	cfi_adjust_cfa_offset(8)
00db10
-4:	negq	%rcx
00db10
-	movq	errno@gottpoff(%rip), %rdx
00db10
-	movl	%ecx, %fs:(%rdx)
00db10
-	orl	$-1, %eax
00db10
-
00db10
-	jmp 9b
00db10
-	.size	sem_wait,.-sem_wait
00db10
-
00db10
-
00db10
-	.type	sem_wait_cleanup,@function
00db10
-sem_wait_cleanup:
00db10
-	movq	(%rsp), %rdi
00db10
-	LOCK
00db10
-	LP_OP(sub) $1, NWAITERS(%rdi)
00db10
-	movq	%rax, %rdi
00db10
-.LcallUR:
00db10
-	call	_Unwind_Resume@PLT
00db10
-	hlt
00db10
-.LENDCODE:
00db10
-	cfi_endproc
00db10
-	.size	sem_wait_cleanup,.-sem_wait_cleanup
00db10
-
00db10
-
00db10
-	.section .gcc_except_table,"a",@progbits
00db10
-.LexceptSTART:
00db10
-	.byte	DW_EH_PE_omit			# @LPStart format
00db10
-	.byte	DW_EH_PE_omit			# @TType format
00db10
-	.byte	DW_EH_PE_uleb128		# call-site format
00db10
-	.uleb128 .Lcstend-.Lcstbegin
00db10
-.Lcstbegin:
00db10
-	.uleb128 .LcleanupSTART-.LSTARTCODE
00db10
-	.uleb128 .LcleanupEND-.LcleanupSTART
00db10
-	.uleb128 sem_wait_cleanup-.LSTARTCODE
00db10
-	.uleb128  0
00db10
-	.uleb128 .LcallUR-.LSTARTCODE
00db10
-	.uleb128 .LENDCODE-.LcallUR
00db10
-	.uleb128 0
00db10
-	.uleb128  0
00db10
-.Lcstend:
00db10
-
00db10
-
00db10
-#ifdef SHARED
00db10
-	.hidden	DW.ref.__gcc_personality_v0
00db10
-	.weak	DW.ref.__gcc_personality_v0
00db10
-	.section .gnu.linkonce.d.DW.ref.__gcc_personality_v0,"aw",@progbits
00db10
-	.align	LP_SIZE
00db10
-	.type	DW.ref.__gcc_personality_v0, @object
00db10
-	.size	DW.ref.__gcc_personality_v0, LP_SIZE
00db10
-DW.ref.__gcc_personality_v0:
00db10
-	ASM_ADDR __gcc_personality_v0
00db10
-#endif
00db10
Index: glibc-2.17-c758a686/ports/sysdeps/unix/sysv/linux/alpha/nptl/sem_post.c
00db10
===================================================================
00db10
--- glibc-2.17-c758a686.orig/ports/sysdeps/unix/sysv/linux/alpha/nptl/sem_post.c
00db10
+++ /dev/null
00db10
@@ -1,5 +0,0 @@
00db10
-/* ??? This is an ass-backwards way to do this.  We should simply define
00db10
-   the acquire/release semantics of atomic_exchange_and_add.  And even if
00db10
-   we don't do this, we should be using atomic_full_barrier or otherwise.  */
00db10
-#define __lll_rel_instr  "mb"
00db10
-#include <nptl/sysdeps/unix/sysv/linux/sem_post.c>
00db10
Index: glibc-2.17-c758a686/nptl/sysdeps/unix/sysv/linux/sh/sem_post.S
00db10
===================================================================
00db10
--- glibc-2.17-c758a686.orig/nptl/sysdeps/unix/sysv/linux/sh/sem_post.S
00db10
+++ /dev/null
00db10
@@ -1,111 +0,0 @@
00db10
-/* Copyright (C) 2003-2012 Free Software Foundation, Inc.
00db10
-   This file is part of the GNU C Library.
00db10
-
00db10
-   The GNU C Library is free software; you can redistribute it and/or
00db10
-   modify it under the terms of the GNU Lesser General Public
00db10
-   License as published by the Free Software Foundation; either
00db10
-   version 2.1 of the License, or (at your option) any later version.
00db10
-
00db10
-   The GNU C Library is distributed in the hope that it will be useful,
00db10
-   but WITHOUT ANY WARRANTY; without even the implied warranty of
00db10
-   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00db10
-   Lesser General Public License for more details.
00db10
-
00db10
-   You should have received a copy of the GNU Lesser General Public
00db10
-   License along with the GNU C Library; if not, see
00db10
-   <http://www.gnu.org/licenses/>.  */
00db10
-
00db10
-#include <sysdep.h>
00db10
-#include <shlib-compat.h>
00db10
-#include <pthread-errnos.h>
00db10
-#include <structsem.h>
00db10
-#include <lowlevellock.h>
00db10
-#include "lowlevel-atomic.h"
00db10
-
00db10
-
00db10
-	.text
00db10
-
00db10
-	.globl	__new_sem_post
00db10
-	.type	__new_sem_post,@function
00db10
-	.align	5
00db10
-	cfi_startproc
00db10
-__new_sem_post:
00db10
-	mov.l	@(VALUE,r4), r2
00db10
-0:
00db10
-	mov.l	.Lmax, r1
00db10
-	cmp/eq	r1, r2
00db10
-	bt/s	3f
00db10
-	 mov	r2, r3
00db10
-	mov	r3, r5
00db10
-	add	#1, r5
00db10
-	CMPXCHG (r3, @(VALUE,r4), r5, r2)
00db10
-	bf	0b
00db10
-	mov.l	@(NWAITERS,r4), r2
00db10
-	tst	r2, r2
00db10
-	bt	2f
00db10
-	mov	#FUTEX_WAKE, r5
00db10
-	mov.l	@(PRIVATE,r4), r1
00db10
-	or	r1, r5
00db10
-	mov	#1, r6
00db10
-	mov	#0, r7
00db10
-	mov	#SYS_futex, r3
00db10
-	extu.b	r3, r3
00db10
-	trapa	#0x14
00db10
-	SYSCALL_INST_PAD
00db10
-
00db10
-	cmp/pz	r0
00db10
-	bf	1f
00db10
-2:
00db10
-	rts
00db10
-	 mov	#0, r0
00db10
-
00db10
-1:
00db10
-	bra	4f
00db10
-	 mov	#EINVAL, r2
00db10
-
00db10
-3:
00db10
-	mov	#EOVERFLOW, r2
00db10
-4:
00db10
-	mov.l	r12, @-r15
00db10
-	cfi_adjust_cfa_offset (4)
00db10
-	cfi_rel_offset (r12, 0)
00db10
-	mov.l	r8, @-r15
00db10
-	cfi_adjust_cfa_offset (4)
00db10
-	cfi_rel_offset (r8, 0)
00db10
-	sts.l	pr, @-r15
00db10
-	cfi_adjust_cfa_offset (4)
00db10
-	cfi_rel_offset (pr, 0)
00db10
-	mova	.Lgot3, r0
00db10
-	mov.l	.Lgot3, r12
00db10
-	add	r0, r12
00db10
-
00db10
-	mov.l	.Lerrno3, r0
00db10
-	stc	gbr, r1
00db10
-	mov.l	@(r0, r12), r0
00db10
-	bra	.Lexit
00db10
-	 add	r1, r0
00db10
-	.align	2
00db10
-.Lerrno3:
00db10
-	.long	errno@GOTTPOFF
00db10
-.Lexit:
00db10
-	mov.l	r2, @r0
00db10
-	lds.l	@r15+, pr
00db10
-	cfi_adjust_cfa_offset (-4)
00db10
-	cfi_restore (pr)
00db10
-	mov.l	@r15+, r8
00db10
-	cfi_adjust_cfa_offset (-4)
00db10
-	cfi_restore (r8)
00db10
-	mov.l	@r15+, r12
00db10
-	cfi_adjust_cfa_offset (-4)
00db10
-	cfi_restore (r12)
00db10
-	rts
00db10
-	 mov	#-1, r0
00db10
-	cfi_endproc
00db10
-
00db10
-	.align	2
00db10
-.Lmax:
00db10
-	.long	SEM_VALUE_MAX
00db10
-.Lgot3:
00db10
-	.long	_GLOBAL_OFFSET_TABLE_
00db10
-	.size	__new_sem_post,.-__new_sem_post
00db10
-	versioned_symbol(libpthread, __new_sem_post, sem_post, GLIBC_2_1)
00db10
Index: glibc-2.17-c758a686/nptl/sysdeps/unix/sysv/linux/sh/sem_timedwait.S
00db10
===================================================================
00db10
--- glibc-2.17-c758a686.orig/nptl/sysdeps/unix/sysv/linux/sh/sem_timedwait.S
00db10
+++ /dev/null
00db10
@@ -1,281 +0,0 @@
00db10
-/* Copyright (C) 2003-2012 Free Software Foundation, Inc.
00db10
-   This file is part of the GNU C Library.
00db10
-
00db10
-   The GNU C Library is free software; you can redistribute it and/or
00db10
-   modify it under the terms of the GNU Lesser General Public
00db10
-   License as published by the Free Software Foundation; either
00db10
-   version 2.1 of the License, or (at your option) any later version.
00db10
-
00db10
-   The GNU C Library is distributed in the hope that it will be useful,
00db10
-   but WITHOUT ANY WARRANTY; without even the implied warranty of
00db10
-   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00db10
-   Lesser General Public License for more details.
00db10
-
00db10
-   You should have received a copy of the GNU Lesser General Public
00db10
-   License along with the GNU C Library; if not, see
00db10
-   <http://www.gnu.org/licenses/>.  */
00db10
-
00db10
-#include <sysdep.h>
00db10
-#include <shlib-compat.h>
00db10
-#include <pthread-errnos.h>
00db10
-#include <tcb-offsets.h>
00db10
-#include <structsem.h>
00db10
-#include <lowlevellock.h>
00db10
-#include "lowlevel-atomic.h"
00db10
-
00db10
-
00db10
-#if VALUE != 0
00db10
-# error "code needs to be rewritten for VALUE != 0"
00db10
-#endif
00db10
-
00db10
-	.text
00db10
-
00db10
-	.globl	sem_timedwait
00db10
-	.type	sem_timedwait,@function
00db10
-	.align	5
00db10
-	cfi_startproc
00db10
-sem_timedwait:
00db10
-.LSTARTCODE:
00db10
-#ifdef SHARED
00db10
-	cfi_personality(DW_EH_PE_pcrel | DW_EH_PE_sdata4 | DW_EH_PE_indirect,
00db10
-			DW.ref.__gcc_personality_v0)
00db10
-	cfi_lsda(DW_EH_PE_pcrel | DW_EH_PE_sdata4, .LexceptSTART)
00db10
-#else
00db10
-	cfi_personality(DW_EH_PE_absptr, __gcc_personality_v0)
00db10
-	cfi_lsda(DW_EH_PE_absptr, .LexceptSTART)
00db10
-#endif
00db10
-	mov.l	@r4, r0
00db10
-2:
00db10
-	tst	r0, r0
00db10
-	bt	1f
00db10
-	mov	r0, r3
00db10
-	mov	r0, r6
00db10
-	add	#-1, r3
00db10
-	CMPXCHG (r6, @r4, r3, r2)
00db10
-	bf/s	2b
00db10
-	 mov	r2, r0
00db10
-	rts
00db10
-	 mov	#0, r0
00db10
-
00db10
-1:
00db10
-	/* Check whether the timeout value is valid.  */
00db10
-	mov.l	r8, @-r15
00db10
-	cfi_adjust_cfa_offset (4)
00db10
-	cfi_rel_offset (r8, 0)
00db10
-	mov.l	r9, @-r15
00db10
-	cfi_adjust_cfa_offset (4)
00db10
-	cfi_rel_offset (r9, 0)
00db10
-	mov.l	r10, @-r15
00db10
-	cfi_adjust_cfa_offset (4)
00db10
-	cfi_rel_offset (r10, 0)
00db10
-	mov.l	r12, @-r15
00db10
-	cfi_adjust_cfa_offset (4)
00db10
-	cfi_rel_offset (r12, 0)
00db10
-	sts.l	pr, @-r15
00db10
-	cfi_adjust_cfa_offset (4)
00db10
-	cfi_rel_offset (pr, 0)
00db10
-	add	#-8, r15
00db10
-	cfi_adjust_cfa_offset (8)
00db10
-
00db10
-	mov	r4, r8
00db10
-	mov	r5, r9
00db10
-
00db10
-	/* Check for invalid nanosecond field.  */
00db10
-	mov.l	@(4,r9), r0
00db10
-	mov.l	.L1g, r1
00db10
-	cmp/hs	r1, r0
00db10
-	bt/s	.Lerrno_exit
00db10
-	 mov	#EINVAL, r10
00db10
-	INC (@(NWAITERS,r8),r2)
00db10
-
00db10
-7:
00db10
-	/* Compute relative timeout.  */
00db10
-	mov	r15, r4
00db10
-	mov	#0, r5
00db10
-	mov	#__NR_gettimeofday, r3
00db10
-	trapa	#0x12
00db10
-	SYSCALL_INST_PAD
00db10
-
00db10
-	mov.l	@(4,r15), r0
00db10
-	mov.w	.L1k, r1
00db10
-	dmulu.l	r0, r1		/* Milli seconds to nano seconds.  */
00db10
-	mov.l	@r9, r2
00db10
-	mov.l	@(4,r9), r3
00db10
-	mov.l	@r15, r0
00db10
-	sts	macl, r1
00db10
-	sub	r0, r2
00db10
-	clrt
00db10
-	subc	r1, r3
00db10
-	bf	5f
00db10
-	mov.l	.L1g, r1
00db10
-	add	r1, r3
00db10
-	add	#-1, r2
00db10
-5:
00db10
-	cmp/pz	r2
00db10
-	bf/s	6f		/* Time is already up.  */
00db10
-	 mov	#ETIMEDOUT, r0
00db10
-
00db10
-	/* Store relative timeout.  */
00db10
-	mov.l	r2, @r15
00db10
-	mov.l	r3, @(4,r15)
00db10
-
00db10
-.LcleanupSTART:
00db10
-	mov.l	.Lenable0, r1
00db10
-	bsrf	r1
00db10
-	 nop
00db10
-.Lenable0b:
00db10
-	mov	r0, r10
00db10
-
00db10
-	mov	r8, r4
00db10
-#if FUTEX_WAIT == 0
00db10
-	mov.l	@(PRIVATE,r8), r5
00db10
-#else
00db10
-	mov.l	@(PRIVATE,r8), r5
00db10
-	mov	#FUTEX_WAIT, r0
00db10
-	or	r0, r5
00db10
-#endif
00db10
-	mov	#0, r6
00db10
-	mov	r15, r7
00db10
-	mov	#SYS_futex, r3
00db10
-	extu.b	r3, r3
00db10
-	trapa	#0x14
00db10
-	SYSCALL_INST_PAD
00db10
-
00db10
-	mov.l	.Ldisable0, r1
00db10
-	mov	r10, r4
00db10
-	bsrf	r1
00db10
-	 mov	r0, r10
00db10
-.Ldisable0b:
00db10
-	mov	r10, r0
00db10
-.LcleanupEND:
00db10
-
00db10
-	tst	r0, r0
00db10
-	bt	9f
00db10
-	cmp/eq	#-EWOULDBLOCK, r0
00db10
-	bf	3f
00db10
-9:
00db10
-	mov.l	@r8, r0
00db10
-8:
00db10
-	tst	r0, r0
00db10
-	bt	7b
00db10
-
00db10
-	mov	r0, r3
00db10
-	mov	r0, r4
00db10
-	add	#-1, r3
00db10
-	CMPXCHG (r4, @r8, r3, r2)
00db10
-	bf/s	8b
00db10
-	 mov	r2, r0
00db10
-
00db10
-	DEC (@(NWAITERS,r8), r2)
00db10
-	mov	#0, r0
00db10
-
00db10
-10:
00db10
-	cfi_remember_state
00db10
-	add	#8, r15
00db10
-	cfi_adjust_cfa_offset (-8)
00db10
-	lds.l	@r15+, pr
00db10
-	cfi_adjust_cfa_offset (-4)
00db10
-	cfi_restore (pr)
00db10
-	mov.l	@r15+, r12
00db10
-	cfi_adjust_cfa_offset (-4)
00db10
-	cfi_restore (r12)
00db10
-	mov.l	@r15+, r10
00db10
-	cfi_adjust_cfa_offset (-4)
00db10
-	cfi_restore (r10)
00db10
-	mov.l	@r15+, r9
00db10
-	cfi_adjust_cfa_offset (-4)
00db10
-	cfi_restore (r9)
00db10
-	mov.l	@r15+, r8
00db10
-	cfi_adjust_cfa_offset (-4)
00db10
-	cfi_restore (r8)
00db10
-	rts
00db10
-	 nop
00db10
-	cfi_restore_state
00db10
-
00db10
-3:
00db10
-	neg	r0, r0
00db10
-6:
00db10
-	mov	r0, r10
00db10
-	DEC (@(NWAITERS,r8), r2)
00db10
-.Lerrno_exit:
00db10
-	mova	.Lgot2, r0
00db10
-	mov.l	.Lgot2, r12
00db10
-	add	r0, r12
00db10
-
00db10
-	mov.l	.Lerrno2, r0
00db10
-	stc	gbr, r1
00db10
-	mov.l	@(r0, r12), r0
00db10
-	bra	.Lexit
00db10
-	 add	r1, r0
00db10
-	.align	2
00db10
-.Lerrno2:
00db10
-	.long	errno@GOTTPOFF
00db10
-.Lexit:
00db10
-	mov.l	r10, @r0
00db10
-	bra	10b
00db10
-	 mov	#-1, r0
00db10
-
00db10
-.L1k:
00db10
-	.word	1000
00db10
-	.align	2
00db10
-.L1g:
00db10
-	.long	1000000000
00db10
-.Lgot2:
00db10
-	.long	_GLOBAL_OFFSET_TABLE_
00db10
-.Lenable0:
00db10
-	.long	__pthread_enable_asynccancel-.Lenable0b
00db10
-.Ldisable0:
00db10
-	.long	__pthread_disable_asynccancel-.Ldisable0b
00db10
-	.size	sem_timedwait,.-sem_timedwait
00db10
-
00db10
-	.type	sem_wait_cleanup,@function
00db10
-sem_wait_cleanup:
00db10
-	DEC (@(NWAITERS,r8), r2)
00db10
-.LcallUR:
00db10
-	mov.l	.Lresume, r1
00db10
-#ifdef PIC
00db10
-	add	r12, r1
00db10
-#endif
00db10
-	jsr	@r1
00db10
-	 nop
00db10
-	sleep
00db10
-
00db10
-	.align	2
00db10
-.Lresume:
00db10
-#ifdef PIC
00db10
-	.long	_Unwind_Resume@GOTOFF
00db10
-#else
00db10
-	.long	_Unwind_Resume
00db10
-#endif
00db10
-.LENDCODE:
00db10
-	cfi_endproc
00db10
-	.size	sem_wait_cleanup,.-sem_wait_cleanup
00db10
-
00db10
-
00db10
-	.section .gcc_except_table,"a",@progbits
00db10
-.LexceptSTART:
00db10
-	.byte	DW_EH_PE_omit			! @LPStart format (omit)
00db10
-	.byte	DW_EH_PE_omit			! @TType format (omit)
00db10
-	.byte	DW_EH_PE_uleb128		! call-site format
00db10
-	.uleb128 .Lcstend-.Lcstbegin
00db10
-.Lcstbegin:
00db10
-	.uleb128 .LcleanupSTART-.LSTARTCODE
00db10
-	.uleb128 .LcleanupEND-.LcleanupSTART
00db10
-	.uleb128 sem_wait_cleanup-.LSTARTCODE
00db10
-	.uleb128  0
00db10
-	.uleb128 .LcallUR-.LSTARTCODE
00db10
-	.uleb128 .LENDCODE-.LcallUR
00db10
-	.uleb128 0
00db10
-	.uleb128  0
00db10
-.Lcstend:
00db10
-
00db10
-#ifdef SHARED
00db10
-	.hidden	DW.ref.__gcc_personality_v0
00db10
-	.weak	DW.ref.__gcc_personality_v0
00db10
-	.section .gnu.linkonce.d.DW.ref.__gcc_personality_v0,"aw",@progbits
00db10
-	.align	4
00db10
-	.type	DW.ref.__gcc_personality_v0, @object
00db10
-	.size	DW.ref.__gcc_personality_v0, 4
00db10
-DW.ref.__gcc_personality_v0:
00db10
-	.long	__gcc_personality_v0
00db10
-#endif
00db10
Index: glibc-2.17-c758a686/nptl/sysdeps/unix/sysv/linux/sh/sem_trywait.S
00db10
===================================================================
00db10
--- glibc-2.17-c758a686.orig/nptl/sysdeps/unix/sysv/linux/sh/sem_trywait.S
00db10
+++ /dev/null
00db10
@@ -1,102 +0,0 @@
00db10
-/* Copyright (C) 2003-2012 Free Software Foundation, Inc.
00db10
-   This file is part of the GNU C Library.
00db10
-
00db10
-   The GNU C Library is free software; you can redistribute it and/or
00db10
-   modify it under the terms of the GNU Lesser General Public
00db10
-   License as published by the Free Software Foundation; either
00db10
-   version 2.1 of the License, or (at your option) any later version.
00db10
-
00db10
-   The GNU C Library is distributed in the hope that it will be useful,
00db10
-   but WITHOUT ANY WARRANTY; without even the implied warranty of
00db10
-   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00db10
-   Lesser General Public License for more details.
00db10
-
00db10
-   You should have received a copy of the GNU Lesser General Public
00db10
-   License along with the GNU C Library; if not, see
00db10
-   <http://www.gnu.org/licenses/>.  */
00db10
-
00db10
-#include <sysdep.h>
00db10
-#include <shlib-compat.h>
00db10
-#include <pthread-errnos.h>
00db10
-#include <lowlevellock.h>
00db10
-#include "lowlevel-atomic.h"
00db10
-
00db10
-
00db10
-	.text
00db10
-
00db10
-	.globl	__new_sem_trywait
00db10
-	.type	__new_sem_trywait,@function
00db10
-	.align	5
00db10
-	cfi_startproc
00db10
-__new_sem_trywait:
00db10
-	mov.l	r12, @-r15
00db10
-	cfi_adjust_cfa_offset (4)
00db10
-	cfi_rel_offset (r12, 0)
00db10
-	mov.l	r8, @-r15
00db10
-	cfi_adjust_cfa_offset (4)
00db10
-	cfi_rel_offset (r8, 0)
00db10
-	sts.l	pr, @-r15
00db10
-	cfi_adjust_cfa_offset (4)
00db10
-	cfi_rel_offset (pr, 0)
00db10
-	mov	r4, r8
00db10
-	mov.l	@r8, r0
00db10
-2:
00db10
-	tst	r0, r0
00db10
-	bt	1f
00db10
-
00db10
-	mov	r0, r3
00db10
-	mov	r0, r4
00db10
-	add	#-1, r3
00db10
-	CMPXCHG (r4, @r8, r3, r2)
00db10
-	bf/s	2b
00db10
-	 mov	r2, r0
00db10
-
00db10
-	cfi_remember_state
00db10
-	lds.l	@r15+, pr
00db10
-	cfi_adjust_cfa_offset (-4)
00db10
-	cfi_restore (pr)
00db10
-	mov.l	@r15+, r8
00db10
-	cfi_adjust_cfa_offset (-4)
00db10
-	cfi_restore (r8)
00db10
-	mov.l	@r15+, r12
00db10
-	cfi_adjust_cfa_offset (-4)
00db10
-	cfi_restore (r12)
00db10
-	rts
00db10
-	 mov	#0, r0
00db10
-	cfi_restore_state
00db10
-
00db10
-1:
00db10
-	mov	#EAGAIN, r8
00db10
-	mova	.Lgot1, r0
00db10
-	mov.l	.Lgot1, r12
00db10
-	add	r0, r12
00db10
-
00db10
-	mov.l	.Lerrno1, r0
00db10
-	stc	gbr, r1
00db10
-	mov.l	@(r0, r12), r0
00db10
-	bra	.Lexit
00db10
-	 add	r1, r0
00db10
-	.align	2
00db10
-.Lerrno1:
00db10
-	.long	errno@GOTTPOFF
00db10
-.Lexit:
00db10
-	mov.l	r8, @r0
00db10
-	lds.l	@r15+, pr
00db10
-	cfi_adjust_cfa_offset (-4)
00db10
-	cfi_restore (pr)
00db10
-	mov.l	@r15+, r8
00db10
-	cfi_adjust_cfa_offset (-4)
00db10
-	cfi_restore (r8)
00db10
-	mov.l	@r15+, r12
00db10
-	cfi_adjust_cfa_offset (-4)
00db10
-	cfi_restore (r12)
00db10
-	rts
00db10
-	 mov	#-1, r0
00db10
-
00db10
-	cfi_endproc
00db10
-
00db10
-	.align	2
00db10
-.Lgot1:
00db10
-	.long	_GLOBAL_OFFSET_TABLE_
00db10
-	.size	__new_sem_trywait,.-__new_sem_trywait
00db10
-	versioned_symbol(libpthread, __new_sem_trywait, sem_trywait, GLIBC_2_1)
00db10
Index: glibc-2.17-c758a686/nptl/sysdeps/unix/sysv/linux/sh/sem_wait.S
00db10
===================================================================
00db10
--- glibc-2.17-c758a686.orig/nptl/sysdeps/unix/sysv/linux/sh/sem_wait.S
00db10
+++ /dev/null
00db10
@@ -1,229 +0,0 @@
00db10
-/* Copyright (C) 2003-2012 Free Software Foundation, Inc.
00db10
-   This file is part of the GNU C Library.
00db10
-
00db10
-   The GNU C Library is free software; you can redistribute it and/or
00db10
-   modify it under the terms of the GNU Lesser General Public
00db10
-   License as published by the Free Software Foundation; either
00db10
-   version 2.1 of the License, or (at your option) any later version.
00db10
-
00db10
-   The GNU C Library is distributed in the hope that it will be useful,
00db10
-   but WITHOUT ANY WARRANTY; without even the implied warranty of
00db10
-   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00db10
-   Lesser General Public License for more details.
00db10
-
00db10
-   You should have received a copy of the GNU Lesser General Public
00db10
-   License along with the GNU C Library; if not, see
00db10
-   <http://www.gnu.org/licenses/>.  */
00db10
-
00db10
-#include <sysdep.h>
00db10
-#include <shlib-compat.h>
00db10
-#include <pthread-errnos.h>
00db10
-#include <tcb-offsets.h>
00db10
-#include <structsem.h>
00db10
-#include <lowlevellock.h>
00db10
-#include "lowlevel-atomic.h"
00db10
-
00db10
-
00db10
-#if VALUE != 0
00db10
-# error "code needs to be rewritten for VALUE != 0"
00db10
-#endif
00db10
-
00db10
-	.text
00db10
-
00db10
-	.globl	__new_sem_wait
00db10
-	.type	__new_sem_wait,@function
00db10
-	.align	5
00db10
-	cfi_startproc
00db10
-__new_sem_wait:
00db10
-.LSTARTCODE:
00db10
-#ifdef SHARED
00db10
-	cfi_personality(DW_EH_PE_pcrel | DW_EH_PE_sdata4 | DW_EH_PE_indirect,
00db10
-			DW.ref.__gcc_personality_v0)
00db10
-	cfi_lsda(DW_EH_PE_pcrel | DW_EH_PE_sdata4, .LexceptSTART)
00db10
-#else
00db10
-	cfi_personality(DW_EH_PE_absptr, __gcc_personality_v0)
00db10
-	cfi_lsda(DW_EH_PE_absptr, .LexceptSTART)
00db10
-#endif
00db10
-	mov.l	r8, @-r15
00db10
-	cfi_adjust_cfa_offset (4)
00db10
-	cfi_rel_offset (r8, 0)
00db10
-	mov.l	r10, @-r15
00db10
-	cfi_adjust_cfa_offset (4)
00db10
-	cfi_rel_offset (r10, 0)
00db10
-	mov.l	r12, @-r15
00db10
-	cfi_adjust_cfa_offset (4)
00db10
-	cfi_rel_offset (r12, 0)
00db10
-	sts.l	pr, @-r15
00db10
-	cfi_adjust_cfa_offset (4)
00db10
-	cfi_rel_offset (pr, 0)
00db10
-
00db10
-	mov	r4, r8
00db10
-	mov.l	@r8, r0
00db10
-2:
00db10
-	tst	r0, r0
00db10
-	bt	1f
00db10
-	mov	r0, r3
00db10
-	mov	r0, r4
00db10
-	add	#-1, r3
00db10
-	CMPXCHG (r4, @r8, r3, r2)
00db10
-	bf/s	2b
00db10
-	 mov	r2, r0
00db10
-7:
00db10
-	mov	#0, r0
00db10
-9:
00db10
-	cfi_remember_state
00db10
-	lds.l	@r15+, pr
00db10
-	cfi_adjust_cfa_offset (-4)
00db10
-	cfi_restore (pr)
00db10
-	mov.l	@r15+, r12
00db10
-	cfi_adjust_cfa_offset (-4)
00db10
-	cfi_restore (r12)
00db10
-	mov.l	@r15+, r10
00db10
-	cfi_adjust_cfa_offset (-4)
00db10
-	cfi_restore (r10)
00db10
-	rts
00db10
-	 mov.l	@r15+, r8
00db10
-	/* Omit CFI for restore in delay slot.  */
00db10
-	cfi_restore_state
00db10
-
00db10
-.Lafter_ret:
00db10
-1:
00db10
-	INC (@(NWAITERS,r8),r2)
00db10
-
00db10
-.LcleanupSTART:
00db10
-6:
00db10
-	mov.l	.Lenable0, r1
00db10
-	bsrf	r1
00db10
-	 nop
00db10
-.Lenable0b:
00db10
-	mov	r0, r10
00db10
-
00db10
-	mov	r8, r4
00db10
-#if FUTEX_WAIT == 0
00db10
-	mov.l	@(PRIVATE,r8), r5
00db10
-#else
00db10
-	mov.l	@(PRIVATE,r8), r5
00db10
-	mov	#FUTEX_WAIT, r0
00db10
-	or	r0, r5
00db10
-#endif
00db10
-	mov	#0, r6
00db10
-	mov	#0, r7
00db10
-	mov	#SYS_futex, r3
00db10
-	extu.b	r3, r3
00db10
-	trapa	#0x14
00db10
-	SYSCALL_INST_PAD
00db10
-
00db10
-	mov.l	.Ldisable0, r1
00db10
-	mov	r10, r4
00db10
-	bsrf	r1
00db10
-	 mov	r0, r10
00db10
-.Ldisable0b:
00db10
-	mov	r10, r0
00db10
-.LcleanupEND:
00db10
-
00db10
-	tst	r0, r0
00db10
-	bt	3f
00db10
-	cmp/eq	#-EWOULDBLOCK, r0
00db10
-	bf	4f
00db10
-
00db10
-3:
00db10
-	mov.l	@r8, r0
00db10
-5:
00db10
-	tst	r0, r0
00db10
-	bt	6b
00db10
-
00db10
-	mov	r0, r3
00db10
-	mov	r0, r4
00db10
-	add	#-1, r3
00db10
-	CMPXCHG (r4, @r8, r3, r2)
00db10
-	bf/s	5b
00db10
-	 mov	r2, r0
00db10
-
00db10
-	DEC (@(NWAITERS,r8), r2)
00db10
-	bra	7b
00db10
-	 nop
00db10
-
00db10
-4:
00db10
-	neg	r0, r0
00db10
-	mov	r0, r4
00db10
-	DEC (@(NWAITERS,r8), r2)
00db10
-	mov	r4, r8
00db10
-	mova	.Lgot0, r0
00db10
-	mov.l	.Lgot0, r12
00db10
-	add	r0, r12
00db10
-
00db10
-	mov.l	.Lerrno0, r0
00db10
-	stc	gbr, r1
00db10
-	mov.l	@(r0, r12), r0
00db10
-	bra	.Lexit
00db10
-	 add	r1, r0
00db10
-	.align	2
00db10
-.Lerrno0:
00db10
-	.long	errno@GOTTPOFF
00db10
-.Lexit:
00db10
-	mov.l	r8, @r0
00db10
-	bra	9b
00db10
-	 mov	#-1, r0
00db10
-
00db10
-	.align	2
00db10
-.Lgot0:
00db10
-	.long	_GLOBAL_OFFSET_TABLE_
00db10
-.Lenable0:
00db10
-	.long	__pthread_enable_asynccancel-.Lenable0b
00db10
-.Ldisable0:
00db10
-	.long	__pthread_disable_asynccancel-.Ldisable0b
00db10
-	.size	__new_sem_wait,.-__new_sem_wait
00db10
-	versioned_symbol(libpthread, __new_sem_wait, sem_wait, GLIBC_2_1)
00db10
-
00db10
-
00db10
-	.type	sem_wait_cleanup,@function
00db10
-sem_wait_cleanup:
00db10
-	DEC (@(NWAITERS,r8), r2)
00db10
-.LcallUR:
00db10
-	mov.l	.Lresume, r1
00db10
-#ifdef PIC
00db10
-	add	r12, r1
00db10
-#endif
00db10
-	jsr	@r1
00db10
-	 nop
00db10
-	sleep
00db10
-
00db10
-	.align	2
00db10
-.Lresume:
00db10
-#ifdef PIC
00db10
-	.long	_Unwind_Resume@GOTOFF
00db10
-#else
00db10
-	.long	_Unwind_Resume
00db10
-#endif
00db10
-.LENDCODE:
00db10
-	cfi_endproc
00db10
-	.size	sem_wait_cleanup,.-sem_wait_cleanup
00db10
-
00db10
-
00db10
-	.section .gcc_except_table,"a",@progbits
00db10
-.LexceptSTART:
00db10
-	.byte	DW_EH_PE_omit			! @LPStart format (omit)
00db10
-	.byte	DW_EH_PE_omit			! @TType format (omit)
00db10
-	.byte	DW_EH_PE_uleb128		! call-site format
00db10
-	.uleb128 .Lcstend-.Lcstbegin
00db10
-.Lcstbegin:
00db10
-	.uleb128 .LcleanupSTART-.LSTARTCODE
00db10
-	.uleb128 .LcleanupEND-.LcleanupSTART
00db10
-	.uleb128 sem_wait_cleanup-.LSTARTCODE
00db10
-	.uleb128  0
00db10
-	.uleb128 .LcallUR-.LSTARTCODE
00db10
-	.uleb128 .LENDCODE-.LcallUR
00db10
-	.uleb128 0
00db10
-	.uleb128  0
00db10
-.Lcstend:
00db10
-
00db10
-#ifdef SHARED
00db10
-	.hidden	DW.ref.__gcc_personality_v0
00db10
-	.weak	DW.ref.__gcc_personality_v0
00db10
-	.section .gnu.linkonce.d.DW.ref.__gcc_personality_v0,"aw",@progbits
00db10
-	.align	4
00db10
-	.type	DW.ref.__gcc_personality_v0, @object
00db10
-	.size	DW.ref.__gcc_personality_v0, 4
00db10
-DW.ref.__gcc_personality_v0:
00db10
-	.long	__gcc_personality_v0
00db10
-#endif
00db10
Index: glibc-2.17-c758a686/nptl/sysdeps/unix/sysv/linux/Makefile
00db10
===================================================================
00db10
--- glibc-2.17-c758a686.orig/nptl/sysdeps/unix/sysv/linux/Makefile
00db10
+++ glibc-2.17-c758a686/nptl/sysdeps/unix/sysv/linux/Makefile
00db10
@@ -24,8 +24,7 @@ libpthread-sysdep_routines += pt-fork pt
00db10
 
00db10
 gen-as-const-headers += lowlevelcond.sym lowlevelrwlock.sym \
00db10
 			lowlevelbarrier.sym unwindbuf.sym \
00db10
-			lowlevelrobustlock.sym pthread-pi-defines.sym \
00db10
-			structsem.sym
00db10
+			lowlevelrobustlock.sym pthread-pi-defines.sym
00db10
 endif
00db10
 
00db10
 ifeq ($(subdir),posix)
00db10
Index: glibc-2.17-c758a686/nptl/sysdeps/unix/sysv/linux/x86_64/lowlevellock.h
00db10
===================================================================
00db10
--- glibc-2.17-c758a686.orig/nptl/sysdeps/unix/sysv/linux/x86_64/lowlevellock.h
00db10
+++ glibc-2.17-c758a686/nptl/sysdeps/unix/sysv/linux/x86_64/lowlevellock.h
00db10
@@ -225,17 +225,18 @@ LLL_STUB_UNWIND_INFO_END
00db10
 
00db10
 
00db10
 #define lll_futex_wake(futex, nr, private) \
00db10
-  do {									      \
00db10
-    int __ignore;							      \
00db10
+  ({									      \
00db10
+    int __status;							      \
00db10
     register __typeof (nr) _nr __asm ("edx") = (nr);			      \
00db10
     LIBC_PROBE (lll_futex_wake, 3, futex, nr, private);                       \
00db10
     __asm __volatile ("syscall"						      \
00db10
-		      : "=a" (__ignore)					      \
00db10
+		      : "=a" (__status)					      \
00db10
 		      : "0" (SYS_futex), "D" (futex),			      \
00db10
 			"S" (__lll_private_flag (FUTEX_WAKE, private)),	      \
00db10
 			"d" (_nr)					      \
00db10
 		      : "memory", "cc", "r10", "r11", "cx");		      \
00db10
-  } while (0)
00db10
+    __status;								      \
00db10
+  })
00db10
 
00db10
 
00db10
 /* NB: in the lll_trylock macro we simply return the value in %eax
00db10
Index: glibc-2.17-c758a686/nptl/sysdeps/unix/sysv/linux/i386/lowlevellock.h
00db10
===================================================================
00db10
--- glibc-2.17-c758a686.orig/nptl/sysdeps/unix/sysv/linux/i386/lowlevellock.h
00db10
+++ glibc-2.17-c758a686/nptl/sysdeps/unix/sysv/linux/i386/lowlevellock.h
00db10
@@ -224,20 +224,21 @@ LLL_STUB_UNWIND_INFO_END
00db10
 
00db10
 
00db10
 #define lll_futex_wake(futex, nr, private) \
00db10
-  do {									      \
00db10
-    int __ignore;							      \
00db10
+  ({									      \
00db10
+    int __status;							      \
00db10
     register __typeof (nr) _nr asm ("edx") = (nr);			      \
00db10
     LIBC_PROBE (lll_futex_wake, 3, futex, nr, private);                       \
00db10
     __asm __volatile (LLL_EBX_LOAD					      \
00db10
 		      LLL_ENTER_KERNEL					      \
00db10
 		      LLL_EBX_LOAD					      \
00db10
-		      : "=a" (__ignore)					      \
00db10
+		      : "=a" (__status)					      \
00db10
 		      : "0" (SYS_futex), LLL_EBX_REG (futex),		      \
00db10
 			"c" (__lll_private_flag (FUTEX_WAKE, private)),	      \
00db10
 			"d" (_nr),					      \
00db10
 			"i" (0) /* phony, to align next arg's number */,      \
00db10
 			"i" (offsetof (tcbhead_t, sysinfo)));		      \
00db10
-  } while (0)
00db10
+    __status;								      \
00db10
+  })
00db10
 
00db10
 
00db10
 /* NB: in the lll_trylock macro we simply return the value in %eax