summaryrefslogtreecommitdiff
path: root/nptl/sysdeps/unix/sysv/linux/x86_64
diff options
context:
space:
mode:
Diffstat (limited to 'nptl/sysdeps/unix/sysv/linux/x86_64')
-rw-r--r--nptl/sysdeps/unix/sysv/linux/x86_64/bits/pthreadtypes.h11
-rw-r--r--nptl/sysdeps/unix/sysv/linux/x86_64/libc-lowlevellock.S23
-rw-r--r--nptl/sysdeps/unix/sysv/linux/x86_64/lowlevellock.S55
-rw-r--r--nptl/sysdeps/unix/sysv/linux/x86_64/lowlevellock.h63
-rw-r--r--nptl/sysdeps/unix/sysv/linux/x86_64/pthread_barrier_wait.S6
-rw-r--r--nptl/sysdeps/unix/sysv/linux/x86_64/pthread_cond_timedwait.S10
-rw-r--r--nptl/sysdeps/unix/sysv/linux/x86_64/pthread_cond_wait.S12
-rw-r--r--nptl/sysdeps/unix/sysv/linux/x86_64/pthread_once.S30
-rw-r--r--nptl/sysdeps/unix/sysv/linux/x86_64/pthread_rwlock_rdlock.S18
-rw-r--r--nptl/sysdeps/unix/sysv/linux/x86_64/pthread_rwlock_timedrdlock.S15
-rw-r--r--nptl/sysdeps/unix/sysv/linux/x86_64/pthread_rwlock_timedwrlock.S15
-rw-r--r--nptl/sysdeps/unix/sysv/linux/x86_64/pthread_rwlock_unlock.S18
-rw-r--r--nptl/sysdeps/unix/sysv/linux/x86_64/pthread_rwlock_wrlock.S18
-rw-r--r--nptl/sysdeps/unix/sysv/linux/x86_64/sem_post.S18
-rw-r--r--nptl/sysdeps/unix/sysv/linux/x86_64/sem_timedwait.S228
-rw-r--r--nptl/sysdeps/unix/sysv/linux/x86_64/sem_trywait.S4
-rw-r--r--nptl/sysdeps/unix/sysv/linux/x86_64/sem_wait.S227
17 files changed, 610 insertions, 161 deletions
diff --git a/nptl/sysdeps/unix/sysv/linux/x86_64/bits/pthreadtypes.h b/nptl/sysdeps/unix/sysv/linux/x86_64/bits/pthreadtypes.h
index 693387a266..7a09c81194 100644
--- a/nptl/sysdeps/unix/sysv/linux/x86_64/bits/pthreadtypes.h
+++ b/nptl/sysdeps/unix/sysv/linux/x86_64/bits/pthreadtypes.h
@@ -1,4 +1,4 @@
-/* Copyright (C) 2002, 2003, 2004, 2005, 2006 Free Software Foundation, Inc.
+/* Copyright (C) 2002,2003,2004,2005,2006,2007 Free Software Foundation, Inc.
This file is part of the GNU C Library.
Contributed by Ulrich Drepper <drepper@redhat.com>, 2002.
@@ -159,9 +159,9 @@ typedef union
unsigned int __nr_readers_queued;
unsigned int __nr_writers_queued;
int __writer;
- int __pad1;
+ int __shared;
+ unsigned long int __pad1;
unsigned long int __pad2;
- unsigned long int __pad3;
/* FLAGS must stay at this position in the structure to maintain
binary compatibility. */
unsigned int __flags;
@@ -177,7 +177,10 @@ typedef union
unsigned int __nr_writers_queued;
/* FLAGS must stay at this position in the structure to maintain
binary compatibility. */
- unsigned int __flags;
+ unsigned char __flags;
+ unsigned char __shared;
+ unsigned char __pad1;
+ unsigned char __pad2;
int __writer;
} __data;
# endif
diff --git a/nptl/sysdeps/unix/sysv/linux/x86_64/libc-lowlevellock.S b/nptl/sysdeps/unix/sysv/linux/x86_64/libc-lowlevellock.S
index 3621efa4fc..3265eee0ed 100644
--- a/nptl/sysdeps/unix/sysv/linux/x86_64/libc-lowlevellock.S
+++ b/nptl/sysdeps/unix/sysv/linux/x86_64/libc-lowlevellock.S
@@ -1,4 +1,4 @@
-/* Copyright (C) 2002, 2003 Free Software Foundation, Inc.
+/* Copyright (C) 2002, 2003, 2007 Free Software Foundation, Inc.
This file is part of the GNU C Library.
Contributed by Ulrich Drepper <drepper@redhat.com>, 2002.
@@ -17,14 +17,19 @@
Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
02111-1307 USA. */
-/* In libc.so we do not unconditionally use the lock prefix. Only if
- the application is using threads. */
-#ifndef UP
-# define LOCK \
- cmpl $0, __libc_multiple_threads(%rip); \
- je 0f; \
- lock; \
-0:
+#include <kernel-features.h>
+
+/* All locks in libc are private. Use the kernel feature if possible. */
+#define FUTEX_PRIVATE_FLAG 128
+#ifdef __ASSUME_PRIVATE_FUTEX
+# define FUTEX_WAIT (0 | FUTEX_PRIVATE_FLAG)
+# define FUTEX_WAKE (1 | FUTEX_PRIVATE_FLAG)
+#else
+# define LOAD_FUTEX_WAIT(reg) \
+ movl %fs:PRIVATE_FUTEX, reg
+# define LOAD_FUTEX_WAKE(reg) \
+ movl %fs:PRIVATE_FUTEX, reg ; \
+ orl $FUTEX_WAKE, reg
#endif
#include "lowlevellock.S"
diff --git a/nptl/sysdeps/unix/sysv/linux/x86_64/lowlevellock.S b/nptl/sysdeps/unix/sysv/linux/x86_64/lowlevellock.S
index 6724ded762..502f1d442f 100644
--- a/nptl/sysdeps/unix/sysv/linux/x86_64/lowlevellock.S
+++ b/nptl/sysdeps/unix/sysv/linux/x86_64/lowlevellock.S
@@ -31,8 +31,23 @@
#endif
#define SYS_futex 202
-#define FUTEX_WAIT 0
-#define FUTEX_WAKE 1
+#ifndef FUTEX_WAIT
+# define FUTEX_WAIT 0
+# define FUTEX_WAKE 1
+#endif
+
+#ifndef LOAD_FUTEX_WAIT
+# if FUTEX_WAIT == 0
+# define LOAD_FUTEX_WAIT(reg) \
+ xorl reg, reg
+# else
+# define LOAD_FUTEX_WAIT(reg) \
+ movl $FUTEX_WAIT, reg
+# endif
+# define LOAD_FUTEX_WAKE(reg) \
+ movl $FUTEX_WAKE, reg
+#endif
+
/* For the calculation see asm/vsyscall.h. */
#define VSYSCALL_ADDR_vgettimeofday 0xffffffffff600000
@@ -52,11 +67,7 @@ __lll_mutex_lock_wait:
cfi_offset(%rdx, -24)
xorq %r10, %r10 /* No timeout. */
movl $2, %edx
-#if FUTEX_WAIT == 0
- xorl %esi, %esi
-#else
- movl $FUTEX_WAIT, %esi
-#endif
+ LOAD_FUTEX_WAIT (%esi)
cmpl %edx, %eax /* NB: %edx == 2 */
jne 2f
@@ -151,11 +162,7 @@ __lll_mutex_timedlock_wait:
je 8f
movq %rsp, %r10
-#if FUTEX_WAIT == 0
- xorl %esi, %esi
-#else
- movl $FUTEX_WAIT, %esi
-#endif
+ LOAD_FUTEX_WAIT (%esi)
movq %r12, %rdi
movl $SYS_futex, %eax
syscall
@@ -213,26 +220,6 @@ __lll_mutex_timedlock_wait:
#endif
-#ifdef NOT_IN_libc
- .globl lll_unlock_wake_cb
- .type lll_unlock_wake_cb,@function
- .hidden lll_unlock_wake_cb
- .align 16
-lll_unlock_wake_cb:
- pushq %rsi
- pushq %rdx
-
- LOCK
- addl $1, (%rdi)
- jng 1f
-
- popq %rdx
- popq %rsi
- retq
- .size lll_unlock_wake_cb,.-lll_unlock_wake_cb
-#endif
-
-
.globl __lll_mutex_unlock_wake
.type __lll_mutex_unlock_wake,@function
.hidden __lll_mutex_unlock_wake
@@ -247,7 +234,7 @@ __lll_mutex_unlock_wake:
cfi_offset(%rdx, -24)
movl $0, (%rdi)
- movl $FUTEX_WAKE, %esi
+ LOAD_FUTEX_WAKE (%esi)
movl $1, %edx /* Wake one thread. */
movl $SYS_futex, %eax
syscall
@@ -311,6 +298,8 @@ __lll_timedwait_tid:
jz 4f
movq %rsp, %r10
+ /* XXX The kernel so far uses global futex for the wakeup at
+ all times. */
#if FUTEX_WAIT == 0
xorl %esi, %esi
#else
diff --git a/nptl/sysdeps/unix/sysv/linux/x86_64/lowlevellock.h b/nptl/sysdeps/unix/sysv/linux/x86_64/lowlevellock.h
index bb988f3b2b..7ec7deff17 100644
--- a/nptl/sysdeps/unix/sysv/linux/x86_64/lowlevellock.h
+++ b/nptl/sysdeps/unix/sysv/linux/x86_64/lowlevellock.h
@@ -23,6 +23,8 @@
#include <time.h>
#include <sys/param.h>
#include <bits/pthreadtypes.h>
+#include <kernel-features.h>
+#include <tcb-offsets.h>
#ifndef LOCK_INSTR
# ifdef UP
@@ -39,8 +41,41 @@
#define FUTEX_LOCK_PI 6
#define FUTEX_UNLOCK_PI 7
#define FUTEX_TRYLOCK_PI 8
+#define FUTEX_PRIVATE_FLAG 128
+/* Values for 'private' parameter of locking macros. Yes, the
+ definition seems to be backwards. But it is not. The bit will be
+ reversed before passing to the system call. */
+#define LLL_PRIVATE 0
+#define LLL_SHARED FUTEX_PRIVATE_FLAG
+
+#if !defined NOT_IN_libc || defined IS_IN_rtld
+/* In libc.so or ld.so all futexes are private. */
+# ifdef __ASSUME_PRIVATE_FUTEX
+# define __lll_private_flag(fl, private) \
+ ((fl) | FUTEX_PRIVATE_FLAG)
+# else
+# define __lll_private_flag(fl, private) \
+ ((fl) | THREAD_GETMEM (THREAD_SELF, header.private_futex))
+# endif
+#else
+# ifdef __ASSUME_PRIVATE_FUTEX
+# define __lll_private_flag(fl, private) \
+ (((fl) | FUTEX_PRIVATE_FLAG) ^ (private))
+# else
+# define __lll_private_flag(fl, private) \
+ (__builtin_constant_p (private) \
+ ? ((private) == 0 \
+ ? ((fl) | THREAD_GETMEM (THREAD_SELF, header.private_futex)) \
+ : (fl)) \
+ : ({ unsigned int __fl = ((private) ^ FUTEX_PRIVATE_FLAG); \
+ asm ("andl %%fs:%P1, %0" : "+r" (__fl) \
+ : "i" (offsetof (struct pthread, header.private_futex))); \
+ __fl | (fl); }))
+# endif
+#endif
+
/* Initializer for compatibility lock. */
#define LLL_MUTEX_LOCK_INITIALIZER (0)
#define LLL_MUTEX_LOCK_INITIALIZER_LOCKED (1)
@@ -148,46 +183,39 @@ LLL_STUB_UNWIND_INFO_START \
LLL_STUB_UNWIND_INFO_END
-#define lll_futex_wait(futex, val) \
- ({ \
- int __status; \
- register __typeof (val) _val __asm ("edx") = (val); \
- __asm __volatile ("xorq %%r10, %%r10\n\t" \
- "syscall" \
- : "=a" (__status) \
- : "0" (SYS_futex), "D" (futex), "S" (FUTEX_WAIT), \
- "d" (_val) \
- : "memory", "cc", "r10", "r11", "cx"); \
- __status; \
- })
+#define lll_futex_wait(futex, val, private) \
+ lll_futex_timed_wait(futex, val, NULL, private)
-#define lll_futex_timed_wait(futex, val, timeout) \
+#define lll_futex_timed_wait(futex, val, timeout, private) \
({ \
register const struct timespec *__to __asm ("r10") = timeout; \
int __status; \
register __typeof (val) _val __asm ("edx") = (val); \
__asm __volatile ("syscall" \
: "=a" (__status) \
- : "0" (SYS_futex), "D" (futex), "S" (FUTEX_WAIT), \
+ : "0" (SYS_futex), "D" (futex), \
+ "S" (__lll_private_flag (FUTEX_WAIT, private)), \
"d" (_val), "r" (__to) \
: "memory", "cc", "r11", "cx"); \
__status; \
})
-#define lll_futex_wake(futex, nr) \
+#define lll_futex_wake(futex, nr, private) \
do { \
int __ignore; \
register __typeof (nr) _nr __asm ("edx") = (nr); \
__asm __volatile ("syscall" \
: "=a" (__ignore) \
- : "0" (SYS_futex), "D" (futex), "S" (FUTEX_WAKE), \
+ : "0" (SYS_futex), "D" (futex), \
+ "S" (__lll_private_flag (FUTEX_WAKE, private)), \
"d" (_nr) \
: "memory", "cc", "r10", "r11", "cx"); \
} while (0)
+
/* Does not preserve %eax and %ecx. */
extern int __lll_mutex_lock_wait (int *__futex, int __val) attribute_hidden;
/* Does not preserver %eax, %ecx, and %edx. */
@@ -454,9 +482,6 @@ typedef int lll_lock_t;
#define LLL_LOCK_INITIALIZER_LOCKED (1)
-extern int lll_unlock_wake_cb (int *__futex) attribute_hidden;
-
-
/* The states of a lock are:
0 - untaken
1 - taken by one user
diff --git a/nptl/sysdeps/unix/sysv/linux/x86_64/pthread_barrier_wait.S b/nptl/sysdeps/unix/sysv/linux/x86_64/pthread_barrier_wait.S
index fa8125dd87..63771b3840 100644
--- a/nptl/sysdeps/unix/sysv/linux/x86_64/pthread_barrier_wait.S
+++ b/nptl/sysdeps/unix/sysv/linux/x86_64/pthread_barrier_wait.S
@@ -1,4 +1,4 @@
-/* Copyright (C) 2002, 2003, 2004, 2005 Free Software Foundation, Inc.
+/* Copyright (C) 2002, 2003, 2004, 2005, 2007 Free Software Foundation, Inc.
This file is part of the GNU C Library.
Contributed by Ulrich Drepper <drepper@redhat.com>, 2002.
@@ -65,9 +65,10 @@ pthread_barrier_wait:
if the CURR_EVENT memory has meanwhile been changed. */
7:
#if FUTEX_WAIT == 0
- xorl %esi, %esi
+ movl PRIVATE(%rdi), %esi
#else
movl $FUTEX_WAIT, %esi
+ orl PRIVATE(%rdi), %esi
#endif
xorq %r10, %r10
8: movl $SYS_futex, %eax
@@ -116,6 +117,7 @@ pthread_barrier_wait:
so 0x7fffffff is the highest value. */
movl $0x7fffffff, %edx
movl $FUTEX_WAKE, %esi
+ orl PRIVATE(%rdi), %esi
movl $SYS_futex, %eax
syscall
diff --git a/nptl/sysdeps/unix/sysv/linux/x86_64/pthread_cond_timedwait.S b/nptl/sysdeps/unix/sysv/linux/x86_64/pthread_cond_timedwait.S
index ad3ae1e76e..2afd601b8c 100644
--- a/nptl/sysdeps/unix/sysv/linux/x86_64/pthread_cond_timedwait.S
+++ b/nptl/sysdeps/unix/sysv/linux/x86_64/pthread_cond_timedwait.S
@@ -1,4 +1,4 @@
-/* Copyright (C) 2002, 2003, 2004, 2005 Free Software Foundation, Inc.
+/* Copyright (C) 2002, 2003, 2004, 2005, 2007 Free Software Foundation, Inc.
This file is part of the GNU C Library.
Contributed by Ulrich Drepper <drepper@redhat.com>, 2002.
@@ -111,7 +111,7 @@ __pthread_cond_timedwait:
movq 8(%rsp), %rdi
incq total_seq(%rdi)
incl cond_futex(%rdi)
- addl $(1 << clock_bits), cond_nwaiters(%rdi)
+ addl $(1 << nwaiters_shift), cond_nwaiters(%rdi)
/* Install cancellation handler. */
#ifdef PIC
@@ -137,7 +137,7 @@ __pthread_cond_timedwait:
structure stores the number minus 1. */
movq 8(%rsp), %rdi
movl cond_nwaiters(%rdi), %edi
- andl $((1 << clock_bits) - 1), %edi
+ andl $((1 << nwaiters_shift) - 1), %edi
/* Only clocks 0 and 1 are allowed so far. Both are handled in the
kernel. */
leaq 24(%rsp), %rsi
@@ -250,13 +250,13 @@ __pthread_cond_timedwait:
9: xorq %r14, %r14
14: incq woken_seq(%rdi)
-24: subl $(1 << clock_bits), cond_nwaiters(%rdi)
+24: subl $(1 << nwaiters_shift), cond_nwaiters(%rdi)
/* Wake up a thread which wants to destroy the condvar object. */
cmpq $0xffffffffffffffff, total_seq(%rdi)
jne 25f
movl cond_nwaiters(%rdi), %eax
- andl $~((1 << clock_bits) - 1), %eax
+ andl $~((1 << nwaiters_shift) - 1), %eax
jne 25f
addq $cond_nwaiters, %rdi
diff --git a/nptl/sysdeps/unix/sysv/linux/x86_64/pthread_cond_wait.S b/nptl/sysdeps/unix/sysv/linux/x86_64/pthread_cond_wait.S
index 969e80da2a..aaad22e020 100644
--- a/nptl/sysdeps/unix/sysv/linux/x86_64/pthread_cond_wait.S
+++ b/nptl/sysdeps/unix/sysv/linux/x86_64/pthread_cond_wait.S
@@ -1,4 +1,4 @@
-/* Copyright (C) 2002, 2003, 2004, 2005, 2006 Free Software Foundation, Inc.
+/* Copyright (C) 2002,2003,2004,2005,2006,2007 Free Software Foundation, Inc.
This file is part of the GNU C Library.
Contributed by Ulrich Drepper <drepper@redhat.com>, 2002.
@@ -77,14 +77,14 @@ __condvar_cleanup:
incl cond_futex(%rdi)
6: incq woken_seq(%rdi)
-3: subl $(1 << clock_bits), cond_nwaiters(%rdi)
+3: subl $(1 << nwaiters_shift), cond_nwaiters(%rdi)
/* Wake up a thread which wants to destroy the condvar object. */
xorq %r12, %r12
cmpq $0xffffffffffffffff, total_seq(%rdi)
jne 4f
movl cond_nwaiters(%rdi), %eax
- andl $~((1 << clock_bits) - 1), %eax
+ andl $~((1 << nwaiters_shift) - 1), %eax
jne 4f
addq $cond_nwaiters, %rdi
@@ -185,7 +185,7 @@ __pthread_cond_wait:
movq 8(%rsp), %rdi
incq total_seq(%rdi)
incl cond_futex(%rdi)
- addl $(1 << clock_bits), cond_nwaiters(%rdi)
+ addl $(1 << nwaiters_shift), cond_nwaiters(%rdi)
/* Install cancellation handler. */
#ifdef PIC
@@ -262,13 +262,13 @@ __pthread_cond_wait:
incq woken_seq(%rdi)
/* Unlock */
-16: subl $(1 << clock_bits), cond_nwaiters(%rdi)
+16: subl $(1 << nwaiters_shift), cond_nwaiters(%rdi)
/* Wake up a thread which wants to destroy the condvar object. */
cmpq $0xffffffffffffffff, total_seq(%rdi)
jne 17f
movl cond_nwaiters(%rdi), %eax
- andl $~((1 << clock_bits) - 1), %eax
+ andl $~((1 << nwaiters_shift) - 1), %eax
jne 17f
addq $cond_nwaiters, %rdi
diff --git a/nptl/sysdeps/unix/sysv/linux/x86_64/pthread_once.S b/nptl/sysdeps/unix/sysv/linux/x86_64/pthread_once.S
index 9db5516913..7740c599d1 100644
--- a/nptl/sysdeps/unix/sysv/linux/x86_64/pthread_once.S
+++ b/nptl/sysdeps/unix/sysv/linux/x86_64/pthread_once.S
@@ -1,4 +1,4 @@
-/* Copyright (C) 2002, 2003, 2005 Free Software Foundation, Inc.
+/* Copyright (C) 2002, 2003, 2005, 2007 Free Software Foundation, Inc.
This file is part of the GNU C Library.
Contributed by Ulrich Drepper <drepper@redhat.com>, 2002.
@@ -17,14 +17,19 @@
Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
02111-1307 USA. */
+#include <kernel-features.h>
+#include <tcb-offsets.h>
+
#ifndef UP
# define LOCK lock
#else
# define LOCK
#endif
-#define SYS_futex 202
-#define FUTEX_WAKE 1
+#define SYS_futex 202
+#define FUTEX_WAIT 0
+#define FUTEX_WAKE 1
+#define FUTEX_PRIVATE_FLAG 128
.comm __fork_generation, 4, 4
@@ -74,10 +79,15 @@ __pthread_once:
jnz 3f /* Different for generation -> run initializer. */
/* Somebody else got here first. Wait. */
-#if FUTEX_WAIT == 0
- xorl %esi, %esi
+#ifdef __ASSUME_PRIVATE_FUTEX
+ movl $FUTEX_WAIT|FUTEX_PRIVATE_FLAG, %esi
#else
+# if FUTEX_WAIT == 0
+ movl %fs:PRIVATE_FUTEX, %esi
+# else
movl $FUTEX_WAIT, %esi
+ orl %fs:PRIVATE_FUTEX, %esi
+# endif
#endif
movl $SYS_futex, %eax
syscall
@@ -106,7 +116,12 @@ __pthread_once:
/* Wake up all other threads. */
movl $0x7fffffff, %edx
+#ifdef __ASSUME_PRIVATE_FUTEX
+ movl $FUTEX_WAKE|FUTEX_PRIVATE_FLAG, %esi
+#else
movl $FUTEX_WAKE, %esi
+ orl %fs:PRIVATE_FUTEX, %esi
+#endif
movl $SYS_futex, %eax
syscall
@@ -133,7 +148,12 @@ clear_once_control:
movl $0, (%rdi)
movl $0x7fffffff, %edx
+#ifdef __ASSUME_PRIVATE_FUTEX
+ movl $FUTEX_WAKE|FUTEX_PRIVATE_FLAG, %esi
+#else
movl $FUTEX_WAKE, %esi
+ orl %fs:PRIVATE_FUTEX, %esi
+#endif
movl $SYS_futex, %eax
syscall
diff --git a/nptl/sysdeps/unix/sysv/linux/x86_64/pthread_rwlock_rdlock.S b/nptl/sysdeps/unix/sysv/linux/x86_64/pthread_rwlock_rdlock.S
index 5e9d8fb1d6..e8d257502f 100644
--- a/nptl/sysdeps/unix/sysv/linux/x86_64/pthread_rwlock_rdlock.S
+++ b/nptl/sysdeps/unix/sysv/linux/x86_64/pthread_rwlock_rdlock.S
@@ -1,4 +1,4 @@
-/* Copyright (C) 2002, 2003, 2005 Free Software Foundation, Inc.
+/* Copyright (C) 2002, 2003, 2005, 2007 Free Software Foundation, Inc.
This file is part of the GNU C Library.
Contributed by Ulrich Drepper <drepper@redhat.com>, 2002.
@@ -20,11 +20,13 @@
#include <sysdep.h>
#include <lowlevelrwlock.h>
#include <pthread-errnos.h>
+#include <kernel-features.h>
#define SYS_futex 202
#define FUTEX_WAIT 0
#define FUTEX_WAKE 1
+#define FUTEX_PRIVATE_FLAG 128
#ifndef UP
# define LOCK lock
@@ -73,12 +75,20 @@ __pthread_rwlock_rdlock:
#endif
jne 10f
-11: addq $READERS_WAKEUP, %rdi
-#if FUTEX_WAIT == 0
- xorl %esi, %esi
+11:
+#ifdef __ASSUME_PRIVATE_FUTEX
+ movl $FUTEX_PRIVATE_FLAG|FUTEX_WAIT, %esi
+ xorl PSHARED(%rdi), %esi
#else
+# if FUTEX_WAIT == 0
+ movl PSHARED(%rdi), %esi
+# else
movl $FUTEX_WAIT, %esi
+ orl PSHARED(%rdi), %esi
+# endif
+ xorl %fs:PRIVATE_FUTEX, %esi
#endif
+ addq $READERS_WAKEUP, %rdi
movl $SYS_futex, %eax
syscall
diff --git a/nptl/sysdeps/unix/sysv/linux/x86_64/pthread_rwlock_timedrdlock.S b/nptl/sysdeps/unix/sysv/linux/x86_64/pthread_rwlock_timedrdlock.S
index b44660418a..f703eeb29f 100644
--- a/nptl/sysdeps/unix/sysv/linux/x86_64/pthread_rwlock_timedrdlock.S
+++ b/nptl/sysdeps/unix/sysv/linux/x86_64/pthread_rwlock_timedrdlock.S
@@ -1,4 +1,4 @@
-/* Copyright (C) 2002, 2003, 2004, 2005 Free Software Foundation, Inc.
+/* Copyright (C) 2002, 2003, 2004, 2005, 2007 Free Software Foundation, Inc.
This file is part of the GNU C Library.
Contributed by Ulrich Drepper <drepper@redhat.com>, 2002.
@@ -20,11 +20,13 @@
#include <sysdep.h>
#include <lowlevelrwlock.h>
#include <pthread-errnos.h>
+#include <kernel-features.h>
#define SYS_futex 202
#define FUTEX_WAIT 0
#define FUTEX_WAKE 1
+#define FUTEX_PRIVATE_FLAG 128
/* For the calculation see asm/vsyscall.h. */
#define VSYSCALL_ADDR_vgettimeofday 0xffffffffff600000
@@ -112,10 +114,17 @@ pthread_rwlock_timedrdlock:
movq %rcx, (%rsp) /* Store relative timeout. */
movq %rdi, 8(%rsp)
-#if FUTEX_WAIT == 0
- xorl %esi, %esi
+#ifdef __ASSUME_PRIVATE_FUTEX
+ movl $FUTEX_PRIVATE_FLAG|FUTEX_WAIT, %esi
+ xorl PSHARED(%r12), %esi
#else
+# if FUTEX_WAIT == 0
+ movl PSHARED(%r12), %esi
+# else
movl $FUTEX_WAIT, %esi
+ orl PSHARED(%r12), %esi
+# endif
+ xorl %fs:PRIVATE_FUTEX, %esi
#endif
movq %rsp, %r10
movl %r14d, %edx
diff --git a/nptl/sysdeps/unix/sysv/linux/x86_64/pthread_rwlock_timedwrlock.S b/nptl/sysdeps/unix/sysv/linux/x86_64/pthread_rwlock_timedwrlock.S
index 525e5b6b93..fc3bf3d69e 100644
--- a/nptl/sysdeps/unix/sysv/linux/x86_64/pthread_rwlock_timedwrlock.S
+++ b/nptl/sysdeps/unix/sysv/linux/x86_64/pthread_rwlock_timedwrlock.S
@@ -1,4 +1,4 @@
-/* Copyright (C) 2002, 2003, 2005 Free Software Foundation, Inc.
+/* Copyright (C) 2002, 2003, 2005, 2007 Free Software Foundation, Inc.
This file is part of the GNU C Library.
Contributed by Ulrich Drepper <drepper@redhat.com>, 2002.
@@ -20,11 +20,13 @@
#include <sysdep.h>
#include <lowlevelrwlock.h>
#include <pthread-errnos.h>
+#include <kernel-features.h>
#define SYS_futex 202
#define FUTEX_WAIT 0
#define FUTEX_WAKE 1
+#define FUTEX_PRIVATE_FLAG 128
/* For the calculation see asm/vsyscall.h. */
#define VSYSCALL_ADDR_vgettimeofday 0xffffffffff600000
@@ -108,10 +110,17 @@ pthread_rwlock_timedwrlock:
movq %rcx, (%rsp) /* Store relative timeout. */
movq %rdi, 8(%rsp)
-#if FUTEX_WAIT == 0
- xorl %esi, %esi
+#ifdef __ASSUME_PRIVATE_FUTEX
+ movl $FUTEX_PRIVATE_FLAG|FUTEX_WAIT, %esi
+ xorl PSHARED(%r12), %esi
#else
+# if FUTEX_WAIT == 0
+ movl PSHARED(%r12), %esi
+# else
movl $FUTEX_WAIT, %esi
+ orl PSHARED(%r12), %esi
+# endif
+ xorl %fs:PRIVATE_FUTEX, %esi
#endif
movq %rsp, %r10
movl %r14d, %edx
diff --git a/nptl/sysdeps/unix/sysv/linux/x86_64/pthread_rwlock_unlock.S b/nptl/sysdeps/unix/sysv/linux/x86_64/pthread_rwlock_unlock.S
index 3a6b9f0bad..c4597f60f7 100644
--- a/nptl/sysdeps/unix/sysv/linux/x86_64/pthread_rwlock_unlock.S
+++ b/nptl/sysdeps/unix/sysv/linux/x86_64/pthread_rwlock_unlock.S
@@ -1,4 +1,4 @@
-/* Copyright (C) 2002, 2003, 2005 Free Software Foundation, Inc.
+/* Copyright (C) 2002, 2003, 2005, 2007 Free Software Foundation, Inc.
This file is part of the GNU C Library.
Contributed by Ulrich Drepper <drepper@redhat.com>, 2002.
@@ -19,11 +19,13 @@
#include <sysdep.h>
#include <lowlevelrwlock.h>
+#include <kernel-features.h>
#define SYS_futex 202
#define FUTEX_WAIT 0
#define FUTEX_WAKE 1
+#define FUTEX_PRIVATE_FLAG 128
#ifndef UP
# define LOCK lock
@@ -56,9 +58,8 @@ __pthread_rwlock_unlock:
5: movl $0, WRITER(%rdi)
- movl $1, %esi
+ movl $1, %edx
leaq WRITERS_WAKEUP(%rdi), %r10
- movq %rsi, %rdx
cmpl $0, WRITERS_QUEUED(%rdi)
jne 0f
@@ -78,7 +79,16 @@ __pthread_rwlock_unlock:
#endif
jne 7f
-8: movl $SYS_futex, %eax
+8:
+#ifdef __ASSUME_PRIVATE_FUTEX
+ movl $FUTEX_PRIVATE_FLAG|FUTEX_WAKE, %esi
+ xorl PSHARED(%rdi), %esi
+#else
+ movl $FUTEX_WAKE, %esi
+ orl PSHARED(%rdi), %esi
+ xorl %fs:PRIVATE_FUTEX, %esi
+#endif
+ movl $SYS_futex, %eax
movq %r10, %rdi
syscall
diff --git a/nptl/sysdeps/unix/sysv/linux/x86_64/pthread_rwlock_wrlock.S b/nptl/sysdeps/unix/sysv/linux/x86_64/pthread_rwlock_wrlock.S
index 0e82f890aa..7f65726849 100644
--- a/nptl/sysdeps/unix/sysv/linux/x86_64/pthread_rwlock_wrlock.S
+++ b/nptl/sysdeps/unix/sysv/linux/x86_64/pthread_rwlock_wrlock.S
@@ -1,4 +1,4 @@
-/* Copyright (C) 2002, 2003, 2005 Free Software Foundation, Inc.
+/* Copyright (C) 2002, 2003, 2005, 2007 Free Software Foundation, Inc.
This file is part of the GNU C Library.
Contributed by Ulrich Drepper <drepper@redhat.com>, 2002.
@@ -20,11 +20,13 @@
#include <sysdep.h>
#include <lowlevelrwlock.h>
#include <pthread-errnos.h>
+#include <kernel-features.h>
#define SYS_futex 202
#define FUTEX_WAIT 0
#define FUTEX_WAKE 1
+#define FUTEX_PRIVATE_FLAG 128
#ifndef UP
# define LOCK lock
@@ -71,12 +73,20 @@ __pthread_rwlock_wrlock:
#endif
jne 10f
-11: addq $WRITERS_WAKEUP, %rdi
-#if FUTEX_WAIT == 0
- xorl %esi, %esi
+11:
+#ifdef __ASSUME_PRIVATE_FUTEX
+ movl $FUTEX_PRIVATE_FLAG|FUTEX_WAIT, %esi
+ xorl PSHARED(%rdi), %esi
#else
+# if FUTEX_WAIT == 0
+ movl PSHARED(%rdi), %esi
+# else
movl $FUTEX_WAIT, %esi
+ orl PSHARED(%rdi), %esi
+# endif
+ xorl %fs:PRIVATE_FUTEX, %esi
#endif
+ addq $WRITERS_WAKEUP, %rdi
movl $SYS_futex, %eax
syscall
diff --git a/nptl/sysdeps/unix/sysv/linux/x86_64/sem_post.S b/nptl/sysdeps/unix/sysv/linux/x86_64/sem_post.S
index 7f608a5974..4919c11fd2 100644
--- a/nptl/sysdeps/unix/sysv/linux/x86_64/sem_post.S
+++ b/nptl/sysdeps/unix/sysv/linux/x86_64/sem_post.S
@@ -1,4 +1,4 @@
-/* Copyright (C) 2002, 2003, 2005 Free Software Foundation, Inc.
+/* Copyright (C) 2002, 2003, 2005, 2007 Free Software Foundation, Inc.
This file is part of the GNU C Library.
Contributed by Ulrich Drepper <drepper@redhat.com>, 2002.
@@ -20,6 +20,7 @@
#include <sysdep.h>
#include <shlib-compat.h>
#include <pthread-errnos.h>
+#include <structsem.h>
#ifndef UP
# define LOCK lock
@@ -37,19 +38,26 @@
.type sem_post,@function
.align 16
sem_post:
- movl $1, %edx
LOCK
- xaddl %edx, (%rdi)
+#if VALUE == 0
+ addl $1, (%rdi)
+#else
+ addl $1, VALUE(%rdi)
+#endif
+
+ cmpq $0, NWAITERS(%rdi)
+ je 2f
movl $SYS_futex, %eax
movl $FUTEX_WAKE, %esi
- incl %edx
+ orl PRIVATE(%rdi), %esi
+ movl $1, %edx
syscall
testq %rax, %rax
js 1f
- xorl %eax, %eax
+2: xorl %eax, %eax
retq
1:
diff --git a/nptl/sysdeps/unix/sysv/linux/x86_64/sem_timedwait.S b/nptl/sysdeps/unix/sysv/linux/x86_64/sem_timedwait.S
index 8c5c2a6974..4068a1b6b8 100644
--- a/nptl/sysdeps/unix/sysv/linux/x86_64/sem_timedwait.S
+++ b/nptl/sysdeps/unix/sysv/linux/x86_64/sem_timedwait.S
@@ -20,6 +20,7 @@
#include <sysdep.h>
#include <shlib-compat.h>
#include <pthread-errnos.h>
+#include <structsem.h>
#ifndef UP
# define LOCK lock
@@ -28,6 +29,7 @@
#endif
#define SYS_futex 202
+#define FUTEX_WAIT 0
/* For the calculation see asm/vsyscall.h. */
#define VSYSCALL_ADDR_vgettimeofday 0xffffffffff600000
@@ -38,15 +40,23 @@
.globl sem_timedwait
.type sem_timedwait,@function
.align 16
- cfi_startproc
sem_timedwait:
+.LSTARTCODE:
+#if VALUE == 0
movl (%rdi), %eax
+#else
+ movl VALUE(%rdi), %eax
+#endif
2: testl %eax, %eax
je 1f
leaq -1(%rax), %rdx
LOCK
+#if VALUE == 0
cmpxchgl %edx, (%rdi)
+#else
+ cmpxchgl %edx, VALUE(%rdi)
+#endif
jne 2b
xorl %eax, %eax
@@ -54,25 +64,25 @@ sem_timedwait:
/* Check whether the timeout value is valid. */
1: pushq %r12
- cfi_adjust_cfa_offset(8)
+.Lpush_r12:
pushq %r13
- cfi_adjust_cfa_offset(8)
+.Lpush_r13:
pushq %r14
- cfi_adjust_cfa_offset(8)
+.Lpush_r14:
subq $24, %rsp
- cfi_adjust_cfa_offset(24)
+.Lsubq:
movq %rdi, %r12
- cfi_offset(12, -16) /* %r12 */
movq %rsi, %r13
- cfi_offset(13, -24) /* %r13 */
/* Check for invalid nanosecond field. */
cmpq $1000000000, 8(%r13)
movl $EINVAL, %r14d
- cfi_offset(14, -24) /* %r14 */
jae 6f
+ LOCK
+ addq $1, NWAITERS(%r12)
+
7: xorl %esi, %esi
movq %rsp, %rdi
movq $VSYSCALL_ADDR_vgettimeofday, %rax
@@ -96,12 +106,22 @@ sem_timedwait:
movq %rdi, (%rsp) /* Store relative timeout. */
movq %rsi, 8(%rsp)
+.LcleanupSTART:
call __pthread_enable_asynccancel
movl %eax, 16(%rsp)
movq %rsp, %r10
+#if VALUE == 0
movq %r12, %rdi
- xorl %esi, %esi
+#else
+ leaq VALUE(%r12), %rdi
+#endif
+#if FUTEX_WAIT == 0
+ movl PRIVATE(%rdi), %esi
+#else
+ movl $FUTEX_WAIT, %esi
+ orl PRIVATE(%rdi), %esi
+#endif
movl $SYS_futex, %eax
xorl %edx, %edx
syscall
@@ -109,39 +129,47 @@ sem_timedwait:
movl 16(%rsp), %edi
call __pthread_disable_asynccancel
+.LcleanupEND:
testq %r14, %r14
je 9f
cmpq $-EWOULDBLOCK, %r14
jne 3f
-9: movl (%r12), %eax
+9:
+#if VALUE == 0
+ movl (%r12), %eax
+#else
+ movl VALUE(%r12), %eax
+#endif
8: testl %eax, %eax
je 7b
leaq -1(%rax), %rcx
LOCK
+#if VALUE == 0
cmpxchgl %ecx, (%r12)
+#else
+ cmpxchgl %ecx, VALUE(%r12)
+#endif
jne 8b
xorl %eax, %eax
-10: addq $24, %rsp
- cfi_adjust_cfa_offset(-24)
+
+10: LOCK
+ subq $1, NWAITERS(%r12)
+
+ addq $24, %rsp
+.Laddq:
popq %r14
- cfi_adjust_cfa_offset(-8)
- cfi_restore(14)
+.Lpop_r14:
popq %r13
- cfi_adjust_cfa_offset(-8)
- cfi_restore(13)
+.Lpop_r13:
popq %r12
- cfi_adjust_cfa_offset(-8)
- cfi_restore(12)
+.Lpop_r12:
retq
- cfi_adjust_cfa_offset(48)
- cfi_offset(12, -16) /* %r12 */
- cfi_offset(13, -24) /* %r13 */
- cfi_offset(14, -32) /* %r14 */
+.Lafter_retq:
3: negq %r14
6:
#if USE___THREAD
@@ -154,5 +182,159 @@ sem_timedwait:
orl $-1, %eax
jmp 10b
- cfi_endproc
.size sem_timedwait,.-sem_timedwait
+
+
+ .type sem_timedwait_cleanup,@function
+sem_timedwait_cleanup:
+ LOCK
+ subq $1, NWAITERS(%r12)
+ movq %rax, %rdi
+.LcallUR:
+ call _Unwind_Resume@PLT
+ hlt
+.LENDCODE:
+ .size sem_timedwait_cleanup,.-sem_timedwait_cleanup
+
+
+ .section .gcc_except_table,"a",@progbits
+.LexceptSTART:
+ .byte 0xff # @LPStart format (omit)
+ .byte 0xff # @TType format (omit)
+ .byte 0x01 # call-site format
+ # DW_EH_PE_uleb128
+ .uleb128 .Lcstend-.Lcstbegin
+.Lcstbegin:
+ .uleb128 .LcleanupSTART-.LSTARTCODE
+ .uleb128 .LcleanupEND-.LcleanupSTART
+ .uleb128 sem_timedwait_cleanup-.LSTARTCODE
+ .uleb128 0
+ .uleb128 .LcallUR-.LSTARTCODE
+ .uleb128 .LENDCODE-.LcallUR
+ .uleb128 0
+ .uleb128 0
+.Lcstend:
+
+
+ .section .eh_frame,"a",@progbits
+.LSTARTFRAME:
+ .long .LENDCIE-.LSTARTCIE # Length of the CIE.
+.LSTARTCIE:
+ .long 0 # CIE ID.
+ .byte 1 # Version number.
+#ifdef SHARED
+ .string "zPLR" # NUL-terminated augmentation
+ # string.
+#else
+ .string "zPL" # NUL-terminated augmentation
+ # string.
+#endif
+ .uleb128 1 # Code alignment factor.
+ .sleb128 -8 # Data alignment factor.
+ .byte 16 # Return address register
+ # column.
+#ifdef SHARED
+ .uleb128 7 # Augmentation value length.
+ .byte 0x9b # Personality: DW_EH_PE_pcrel
+ # + DW_EH_PE_sdata4
+ # + DW_EH_PE_indirect
+ .long DW.ref.__gcc_personality_v0-.
+ .byte 0x1b # LSDA Encoding: DW_EH_PE_pcrel
+ # + DW_EH_PE_sdata4.
+ .byte 0x1b # FDE Encoding: DW_EH_PE_pcrel
+ # + DW_EH_PE_sdata4.
+#else
+ .uleb128 10 # Augmentation value length.
+ .byte 0x0 # Personality: absolute
+ .quad __gcc_personality_v0
+ .byte 0x0 # LSDA Encoding: absolute
+#endif
+ .byte 0x0c # DW_CFA_def_cfa
+ .uleb128 7
+ .uleb128 8
+ .byte 0x90 # DW_CFA_offset, column 0x10
+ .uleb128 1
+ .align 8
+.LENDCIE:
+
+ .long .LENDFDE-.LSTARTFDE # Length of the FDE.
+.LSTARTFDE:
+ .long .LSTARTFDE-.LSTARTFRAME # CIE pointer.
+#ifdef SHARED
+ .long .LSTARTCODE-. # PC-relative start address
+ # of the code.
+ .long .LENDCODE-.LSTARTCODE # Length of the code.
+ .uleb128 4 # Augmentation size
+ .long .LexceptSTART-.
+#else
+ .quad .LSTARTCODE # Start address of the code.
+ .quad .LENDCODE-.LSTARTCODE # Length of the code.
+ .uleb128 8 # Augmentation size
+ .quad .LexceptSTART
+#endif
+
+ .byte 4 # DW_CFA_advance_loc4
+ .long .Lpush_r12-.LSTARTCODE
+ .byte 14 # DW_CFA_def_cfa_offset
+ .uleb128 16
+ .byte 0x8c # DW_CFA_offset %r12
+ .uleb128 2
+ .byte 4 # DW_CFA_advance_loc4
+ .long .Lpush_r13-.Lpush_r12
+ .byte 14 # DW_CFA_def_cfa_offset
+ .uleb128 24
+ .byte 0x8d # DW_CFA_offset %r13
+ .uleb128 3
+ .byte 4 # DW_CFA_advance_loc4
+ .long .Lpush_r14-.Lpush_r13
+ .byte 14 # DW_CFA_def_cfa_offset
+ .uleb128 32
+ .byte 0x8e # DW_CFA_offset %r14
+ .uleb128 4
+ .byte 4 # DW_CFA_advance_loc4
+ .long .Lsubq-.Lpush_r14
+ .byte 14 # DW_CFA_def_cfa_offset
+ .uleb128 56
+ .byte 4 # DW_CFA_advance_loc4
+ .long .Laddq-.Lsubq
+ .byte 14 # DW_CFA_def_cfa_offset
+ .uleb128 32
+ .byte 4 # DW_CFA_advance_loc4
+ .long .Lpop_r14-.Laddq
+ .byte 14 # DW_CFA_def_cfa_offset
+ .uleb128 24
+ .byte 0xce # DW_CFA_restore %r14
+ .byte 4 # DW_CFA_advance_loc4
+ .long .Lpop_r13-.Lpop_r14
+ .byte 14 # DW_CFA_def_cfa_offset
+ .uleb128 16
+ .byte 0xcd # DW_CFA_restore %r13
+ .byte 4 # DW_CFA_advance_loc4
+ .long .Lpop_r12-.Lpop_r13
+ .byte 14 # DW_CFA_def_cfa_offset
+ .uleb128 8
+ .byte 0xcc # DW_CFA_restore %r12
+ .byte 4 # DW_CFA_advance_loc4
+ .long .Lafter_retq-.Lpop_r12
+ .byte 14 # DW_CFA_def_cfa_offset
+ .uleb128 56
+ .byte 0x8c # DW_CFA_offset %r12
+ .uleb128 2
+ .byte 0x8d # DW_CFA_offset %r13
+ .uleb128 3
+ .byte 0x8e # DW_CFA_offset %r14
+ .uleb128 4
+ .align 8
+.LENDFDE:
+
+
+#ifdef SHARED
+ .hidden DW.ref.__gcc_personality_v0
+ .weak DW.ref.__gcc_personality_v0
+ .section .gnu.linkonce.d.DW.ref.__gcc_personality_v0,"aw",@progbits
+ .align 8
+ .type DW.ref.__gcc_personality_v0, @object
+ .size DW.ref.__gcc_personality_v0, 8
+DW.ref.__gcc_personality_v0:
+ .quad __gcc_personality_v0
+#endif
diff --git a/nptl/sysdeps/unix/sysv/linux/x86_64/sem_trywait.S b/nptl/sysdeps/unix/sysv/linux/x86_64/sem_trywait.S
index 6b77dfc0d8..643090f065 100644
--- a/nptl/sysdeps/unix/sysv/linux/x86_64/sem_trywait.S
+++ b/nptl/sysdeps/unix/sysv/linux/x86_64/sem_trywait.S
@@ -1,4 +1,4 @@
-/* Copyright (C) 2002, 2003, 2005 Free Software Foundation, Inc.
+/* Copyright (C) 2002, 2003, 2005, 2007 Free Software Foundation, Inc.
This file is part of the GNU C Library.
Contributed by Ulrich Drepper <drepper@redhat.com>, 2002.
@@ -37,7 +37,7 @@ sem_trywait:
2: testl %eax, %eax
jz 1f
- leaq -1(%rax), %rdx
+ leal -1(%rax), %edx
LOCK
cmpxchgl %edx, (%rdi)
jne 2b
diff --git a/nptl/sysdeps/unix/sysv/linux/x86_64/sem_wait.S b/nptl/sysdeps/unix/sysv/linux/x86_64/sem_wait.S
index 5bd78eb944..e099ede029 100644
--- a/nptl/sysdeps/unix/sysv/linux/x86_64/sem_wait.S
+++ b/nptl/sysdeps/unix/sysv/linux/x86_64/sem_wait.S
@@ -20,6 +20,7 @@
#include <sysdep.h>
#include <shlib-compat.h>
#include <pthread-errnos.h>
+#include <structsem.h>
#ifndef UP
# define LOCK lock
@@ -28,6 +29,7 @@
#endif
#define SYS_futex 202
+#define FUTEX_WAIT 0
.text
@@ -35,57 +37,93 @@
.globl sem_wait
.type sem_wait,@function
.align 16
- cfi_startproc
sem_wait:
+.LSTARTCODE:
pushq %r12
- cfi_adjust_cfa_offset(8)
- cfi_offset(12, -16)
+.Lpush_r12:
pushq %r13
- cfi_adjust_cfa_offset(8)
+.Lpush_r13:
movq %rdi, %r13
- cfi_offset(13, -24)
-3: movl (%r13), %eax
+#if VALUE == 0
+ movl (%r13), %eax
+#else
+ movl VALUE(%r13), %eax
+#endif
2: testl %eax, %eax
je 1f
- leaq -1(%rax), %rdx
+ leal -1(%rax), %edx
LOCK
+#if VALUE == 0
cmpxchgl %edx, (%r13)
+#else
+ cmpxchgl %edx, VALUE(%r13)
+#endif
jne 2b
- xorl %eax, %eax
- popq %r13
- cfi_adjust_cfa_offset(-8)
- cfi_restore(13)
+7: xorl %eax, %eax
+
+9: popq %r13
+.Lpop_r13:
popq %r12
- cfi_adjust_cfa_offset(-8)
- cfi_restore(12)
+.Lpop_r12:
retq
- cfi_adjust_cfa_offset(16)
- cfi_offset(12, -16)
- cfi_offset(13, -24)
-1: call __pthread_enable_asynccancel
+.Lafter_retq:
+1: LOCK
+ addq $1, NWAITERS(%r13)
+
+.LcleanupSTART:
+6: call __pthread_enable_asynccancel
movl %eax, %r8d
xorq %r10, %r10
movl $SYS_futex, %eax
movq %r13, %rdi
- movq %r10, %rsi
- movq %r10, %rdx
+#if FUTEX_WAIT == 0
+ movl PRIVATE(%rdi), %esi
+#else
+ movl $FUTEX_WAIT, %esi
+ orl PRIVATE(%rdi), %esi
+#endif
+ xorl %edx, %edx
syscall
movq %rax, %r12
movl %r8d, %edi
call __pthread_disable_asynccancel
+.LcleanupEND:
testq %r12, %r12
- je 3b
+ je 3f
cmpq $-EWOULDBLOCK, %r12
- je 3b
- negq %r12
+ jne 4f
+
+3:
+#if VALUE == 0
+ movl (%r13), %eax
+#else
+ movl VALUE(%r13), %eax
+#endif
+5: testl %eax, %eax
+ je 6b
+
+ leal -1(%rax), %edx
+ LOCK
+#if VALUE == 0
+ cmpxchgl %edx, (%r13)
+#else
+ cmpxchgl %edx, VALUE(%r13)
+#endif
+ jne 5b
+
+ LOCK
+ subq $1, NWAITERS(%r13)
+ jmp 7b
+
+4: negq %r12
#if USE___THREAD
movq errno@gottpoff(%rip), %rdx
movl %r12d, %fs:(%rdx)
@@ -95,13 +133,142 @@ sem_wait:
#endif
orl $-1, %eax
- popq %r13
- cfi_adjust_cfa_offset(-8)
- cfi_restore(13)
- popq %r12
- cfi_adjust_cfa_offset(-8)
- cfi_restore(12)
+ LOCK
+ subq $1, NWAITERS(%r13)
- retq
- cfi_endproc
+ jmp 9b
.size sem_wait,.-sem_wait
+
+
+ .type sem_wait_cleanup,@function
+sem_wait_cleanup:
+ LOCK
+ subq $1, NWAITERS(%r13)
+ movq %rax, %rdi
+.LcallUR:
+ call _Unwind_Resume@PLT
+ hlt
+.LENDCODE:
+ .size sem_wait_cleanup,.-sem_wait_cleanup
+
+
+ .section .gcc_except_table,"a",@progbits
+.LexceptSTART:
+ .byte 0xff # @LPStart format (omit)
+ .byte 0xff # @TType format (omit)
+ .byte 0x01 # call-site format
+ # DW_EH_PE_uleb128
+ .uleb128 .Lcstend-.Lcstbegin
+.Lcstbegin:
+ .uleb128 .LcleanupSTART-.LSTARTCODE
+ .uleb128 .LcleanupEND-.LcleanupSTART
+ .uleb128 sem_wait_cleanup-.LSTARTCODE
+ .uleb128 0
+ .uleb128 .LcallUR-.LSTARTCODE
+ .uleb128 .LENDCODE-.LcallUR
+ .uleb128 0
+ .uleb128 0
+.Lcstend:
+
+
+ .section .eh_frame,"a",@progbits
+.LSTARTFRAME:
+ .long .LENDCIE-.LSTARTCIE # Length of the CIE.
+.LSTARTCIE:
+ .long 0 # CIE ID.
+ .byte 1 # Version number.
+#ifdef SHARED
+ .string "zPLR" # NUL-terminated augmentation
+ # string.
+#else
+ .string "zPL" # NUL-terminated augmentation
+ # string.
+#endif
+ .uleb128 1 # Code alignment factor.
+ .sleb128 -8 # Data alignment factor.
+ .byte 16 # Return address register
+ # column.
+#ifdef SHARED
+ .uleb128 7 # Augmentation value length.
+ .byte 0x9b # Personality: DW_EH_PE_pcrel
+ # + DW_EH_PE_sdata4
+ # + DW_EH_PE_indirect
+ .long DW.ref.__gcc_personality_v0-.
+ .byte 0x1b # LSDA Encoding: DW_EH_PE_pcrel
+ # + DW_EH_PE_sdata4.
+ .byte 0x1b # FDE Encoding: DW_EH_PE_pcrel
+ # + DW_EH_PE_sdata4.
+#else
+ .uleb128 10 # Augmentation value length.
+ .byte 0x0 # Personality: absolute
+ .quad __gcc_personality_v0
+ .byte 0x0 # LSDA Encoding: absolute
+#endif
+ .byte 0x0c # DW_CFA_def_cfa
+ .uleb128 7
+ .uleb128 8
+ .byte 0x90 # DW_CFA_offset, column 0x10
+ .uleb128 1
+ .align 8
+.LENDCIE:
+
+ .long .LENDFDE-.LSTARTFDE # Length of the FDE.
+.LSTARTFDE:
+ .long .LSTARTFDE-.LSTARTFRAME # CIE pointer.
+#ifdef SHARED
+ .long .LSTARTCODE-. # PC-relative start address
+ # of the code.
+ .long .LENDCODE-.LSTARTCODE # Length of the code.
+ .uleb128 4 # Augmentation size
+ .long .LexceptSTART-.
+#else
+ .quad .LSTARTCODE # Start address of the code.
+ .quad .LENDCODE-.LSTARTCODE # Length of the code.
+ .uleb128 8 # Augmentation size
+ .quad .LexceptSTART
+#endif
+
+ .byte 4 # DW_CFA_advance_loc4
+ .long .Lpush_r12-.LSTARTCODE
+ .byte 14 # DW_CFA_def_cfa_offset
+ .uleb128 16
+ .byte 0x8c # DW_CFA_offset %r12
+ .uleb128 2
+ .byte 4 # DW_CFA_advance_loc4
+ .long .Lpush_r13-.Lpush_r12
+ .byte 14 # DW_CFA_def_cfa_offset
+ .uleb128 24
+ .byte 0x8d # DW_CFA_offset %r13
+ .uleb128 3
+ .byte 4 # DW_CFA_advance_loc4
+ .long .Lpop_r13-.Lpush_r13
+ .byte 14 # DW_CFA_def_cfa_offset
+ .uleb128 16
+ .byte 0xcd # DW_CFA_restore %r13
+ .byte 4 # DW_CFA_advance_loc4
+ .long .Lpop_r12-.Lpop_r13
+ .byte 14 # DW_CFA_def_cfa_offset
+ .uleb128 8
+ .byte 0xcc # DW_CFA_restore %r12
+ .byte 4 # DW_CFA_advance_loc4
+ .long .Lafter_retq-.Lpop_r12
+ .byte 14 # DW_CFA_def_cfa_offset
+ .uleb128 24
+ .byte 0x8c # DW_CFA_offset %r12
+ .uleb128 2
+ .byte 0x8d # DW_CFA_offset %r13
+ .uleb128 3
+ .align 8
+.LENDFDE:
+
+
+#ifdef SHARED
+ .hidden DW.ref.__gcc_personality_v0
+ .weak DW.ref.__gcc_personality_v0
+ .section .gnu.linkonce.d.DW.ref.__gcc_personality_v0,"aw",@progbits
+ .align 8
+ .type DW.ref.__gcc_personality_v0, @object
+ .size DW.ref.__gcc_personality_v0, 8
+DW.ref.__gcc_personality_v0:
+ .quad __gcc_personality_v0
+#endif