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