summaryrefslogtreecommitdiff
path: root/libpthread/nptl/sysdeps/unix/sysv/linux/sh
diff options
context:
space:
mode:
authorAustin Foxley <austinf@cetoncorp.com>2010-02-16 12:27:18 -0800
committerAustin Foxley <austinf@cetoncorp.com>2010-02-16 12:27:18 -0800
commita032a6587011cbdac8c2f7e11f15dc4e592bbb55 (patch)
treeb8d8dfc6abf0168e098223c2134a3e4bd7640942 /libpthread/nptl/sysdeps/unix/sysv/linux/sh
parent70f1d42b13a741f603472f405299e5d2938aa728 (diff)
mass sync with glibc nptl
Signed-off-by: Austin Foxley <austinf@cetoncorp.com>
Diffstat (limited to 'libpthread/nptl/sysdeps/unix/sysv/linux/sh')
-rw-r--r--libpthread/nptl/sysdeps/unix/sysv/linux/sh/Makefile.arch5
-rw-r--r--libpthread/nptl/sysdeps/unix/sysv/linux/sh/bits/pthreadtypes.h19
-rw-r--r--libpthread/nptl/sysdeps/unix/sysv/linux/sh/bits/semaphore.h3
-rw-r--r--libpthread/nptl/sysdeps/unix/sysv/linux/sh/fork.c1
-rw-r--r--libpthread/nptl/sysdeps/unix/sysv/linux/sh/libc-lowlevellock.S2
-rw-r--r--libpthread/nptl/sysdeps/unix/sysv/linux/sh/lowlevel-atomic.h12
-rw-r--r--libpthread/nptl/sysdeps/unix/sysv/linux/sh/lowlevellock.S421
-rw-r--r--libpthread/nptl/sysdeps/unix/sysv/linux/sh/lowlevellock.h311
-rw-r--r--libpthread/nptl/sysdeps/unix/sysv/linux/sh/lowlevelrobustlock.S264
-rw-r--r--libpthread/nptl/sysdeps/unix/sysv/linux/sh/not-cancel.h83
-rw-r--r--libpthread/nptl/sysdeps/unix/sysv/linux/sh/pt-initfini.c21
-rw-r--r--libpthread/nptl/sysdeps/unix/sysv/linux/sh/pthread_barrier_wait.S49
-rw-r--r--libpthread/nptl/sysdeps/unix/sysv/linux/sh/pthread_cond_broadcast.S99
-rw-r--r--libpthread/nptl/sysdeps/unix/sysv/linux/sh/pthread_cond_signal.S119
-rw-r--r--libpthread/nptl/sysdeps/unix/sysv/linux/sh/pthread_cond_timedwait.S184
-rw-r--r--libpthread/nptl/sysdeps/unix/sysv/linux/sh/pthread_cond_wait.S220
-rw-r--r--libpthread/nptl/sysdeps/unix/sysv/linux/sh/pthread_once.S68
-rw-r--r--libpthread/nptl/sysdeps/unix/sysv/linux/sh/pthread_rwlock_rdlock.S62
-rw-r--r--libpthread/nptl/sysdeps/unix/sysv/linux/sh/pthread_rwlock_timedrdlock.S70
-rw-r--r--libpthread/nptl/sysdeps/unix/sysv/linux/sh/pthread_rwlock_timedwrlock.S67
-rw-r--r--libpthread/nptl/sysdeps/unix/sysv/linux/sh/pthread_rwlock_unlock.S48
-rw-r--r--libpthread/nptl/sysdeps/unix/sysv/linux/sh/pthread_rwlock_wrlock.S58
-rw-r--r--libpthread/nptl/sysdeps/unix/sysv/linux/sh/sem_post.S50
-rw-r--r--libpthread/nptl/sysdeps/unix/sysv/linux/sh/sem_timedwait.S266
-rw-r--r--libpthread/nptl/sysdeps/unix/sysv/linux/sh/sem_trywait.S9
-rw-r--r--libpthread/nptl/sysdeps/unix/sysv/linux/sh/sem_wait.S265
-rw-r--r--libpthread/nptl/sysdeps/unix/sysv/linux/sh/sysdep-cancel.h128
-rw-r--r--libpthread/nptl/sysdeps/unix/sysv/linux/sh/vfork.S2
28 files changed, 2092 insertions, 814 deletions
diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/sh/Makefile.arch b/libpthread/nptl/sysdeps/unix/sysv/linux/sh/Makefile.arch
index 9bd7569c9..940bd62f8 100644
--- a/libpthread/nptl/sysdeps/unix/sysv/linux/sh/Makefile.arch
+++ b/libpthread/nptl/sysdeps/unix/sysv/linux/sh/Makefile.arch
@@ -7,8 +7,8 @@
libpthread_SSRC = pt-vfork.S pthread_once.S pthread_rwlock_wrlock.S \
pthread_rwlock_rdlock.S pthread_rwlock_unlock.S \
- lowlevellock.S pthread_barrier_wait.S pthread_cond_broadcast.S \
- pthread_cond_signal.S \
+ lowlevellock.S lowlevelrobustlock.S pthread_barrier_wait.S \
+ pthread_cond_broadcast.S pthread_cond_signal.S \
pthread_rwlock_timedwrlock.S pthread_rwlock_timedrdlock.S \
sem_post.S sem_timedwait.S sem_trywait.S sem_wait.S
@@ -43,6 +43,7 @@ ASFLAGS-sem_wait.S = -D_LIBC_REENTRANT -DUSE___THREAD
ASFLAGS-libc-lowlevellock.S = -D_LIBC_REENTRANT -DUSE___THREAD
ASFLAGS-lowlevellock.S = -DNOT_IN_libc=1 -DIS_IN_libpthread=1 -D_LIBC_REENTRANT -DUSE___THREAD
+ASFLAGS-lowlevelrobustlock.S = -DNOT_IN_libc=1 -DIS_IN_libpthread=1 -D_LIBC_REENTRANT -DUSE___THREAD
ASFLAGS-clone.S = -D_LIBC_REENTRANT
ASFLAGS-vfork.S = -D_LIBC_REENTRANT
diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/sh/bits/pthreadtypes.h b/libpthread/nptl/sysdeps/unix/sysv/linux/sh/bits/pthreadtypes.h
index 969686dd5..badcda570 100644
--- a/libpthread/nptl/sysdeps/unix/sysv/linux/sh/bits/pthreadtypes.h
+++ b/libpthread/nptl/sysdeps/unix/sysv/linux/sh/bits/pthreadtypes.h
@@ -1,4 +1,5 @@
-/* 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.
@@ -20,6 +21,8 @@
#ifndef _BITS_PTHREADTYPES_H
#define _BITS_PTHREADTYPES_H 1
+#include <endian.h>
+
#define __SIZEOF_PTHREAD_ATTR_T 36
#define __SIZEOF_PTHREAD_MUTEX_T 24
#define __SIZEOF_PTHREAD_MUTEXATTR_T 4
@@ -127,9 +130,21 @@ typedef union
unsigned int __writer_wakeup;
unsigned int __nr_readers_queued;
unsigned int __nr_writers_queued;
+#if __BYTE_ORDER == __BIG_ENDIAN
+ unsigned char __pad1;
+ unsigned char __pad2;
+ unsigned char __shared;
+ /* FLAGS must stay at this position in the structure to maintain
+ binary compatibility. */
+ unsigned char __flags;
+#else
/* 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;
+#endif
pthread_t __writer;
} __data;
char __size[__SIZEOF_PTHREAD_RWLOCK_T];
diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/sh/bits/semaphore.h b/libpthread/nptl/sysdeps/unix/sysv/linux/sh/bits/semaphore.h
index e6c5d845c..934493c30 100644
--- a/libpthread/nptl/sysdeps/unix/sysv/linux/sh/bits/semaphore.h
+++ b/libpthread/nptl/sysdeps/unix/sysv/linux/sh/bits/semaphore.h
@@ -28,9 +28,6 @@
/* Value returned if `sem_open' failed. */
#define SEM_FAILED ((sem_t *) 0)
-/* Maximum value the semaphore can have. */
-#define SEM_VALUE_MAX (2147483647)
-
typedef union
{
diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/sh/fork.c b/libpthread/nptl/sysdeps/unix/sysv/linux/sh/fork.c
index dcedd2625..6868b9bcd 100644
--- a/libpthread/nptl/sysdeps/unix/sysv/linux/sh/fork.c
+++ b/libpthread/nptl/sysdeps/unix/sysv/linux/sh/fork.c
@@ -18,7 +18,6 @@
#include <sched.h>
#include <signal.h>
-#include <stdio.h>
#include <sysdep.h>
#include <tls.h>
diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/sh/libc-lowlevellock.S b/libpthread/nptl/sysdeps/unix/sysv/linux/sh/libc-lowlevellock.S
index 94a24b46e..feb82110c 100644
--- a/libpthread/nptl/sysdeps/unix/sysv/linux/sh/libc-lowlevellock.S
+++ b/libpthread/nptl/sysdeps/unix/sysv/linux/sh/libc-lowlevellock.S
@@ -1,4 +1,4 @@
-/* Copyright (C) 2003 Free Software Foundation, Inc.
+/* Copyright (C) 2003, 2007 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/sh/lowlevel-atomic.h b/libpthread/nptl/sysdeps/unix/sysv/linux/sh/lowlevel-atomic.h
index 062ce2871..c7028360f 100644
--- a/libpthread/nptl/sysdeps/unix/sysv/linux/sh/lowlevel-atomic.h
+++ b/libpthread/nptl/sysdeps/unix/sysv/linux/sh/lowlevel-atomic.h
@@ -1,4 +1,4 @@
-/* Copyright (C) 2003, 2004 Free Software Foundation, Inc.
+/* Copyright (C) 2003, 2004, 2008 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
@@ -44,16 +44,16 @@
mov.l reg, mem; \
99: mov r1, r15
-#define XADD(reg, mem, new, old) \
+#define XADD(reg, mem, old, tmp) \
.align 2; \
mova 99f, r0; \
nop; \
mov r15, r1; \
- mov _IMM4, r15; \
+ mov _IMM8, r15; \
98: mov.l mem, old; \
- mov old, new; \
- add reg, new; \
- mov.l new, mem; \
+ mov reg, tmp; \
+ add old, tmp; \
+ mov.l tmp, mem; \
99: mov r1, r15
#define XCHG(reg, mem, old) \
diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/sh/lowlevellock.S b/libpthread/nptl/sysdeps/unix/sysv/linux/sh/lowlevellock.S
index a5c916bb7..6d4036496 100644
--- a/libpthread/nptl/sysdeps/unix/sysv/linux/sh/lowlevellock.S
+++ b/libpthread/nptl/sysdeps/unix/sysv/linux/sh/lowlevellock.S
@@ -1,4 +1,5 @@
-/* Copyright (C) 2003, 2004 Free Software Foundation, Inc.
+/* Copyright (C) 2003, 2004, 2005, 2007, 2008, 2009
+ Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
@@ -18,73 +19,320 @@
#include <sysdep.h>
#include <pthread-errnos.h>
+#include <bits/kernel-features.h>
+#include <lowlevellock.h>
#include "lowlevel-atomic.h"
.text
-#define SYS_gettimeofday __NR_gettimeofday
-
-#define FUTEX_WAIT 0
-#define FUTEX_WAKE 1
-
+#ifdef __ASSUME_PRIVATE_FUTEX
+# define LOAD_PRIVATE_FUTEX_WAIT(reg,tmp,tmp2) \
+ mov #(FUTEX_WAIT | FUTEX_PRIVATE_FLAG), reg; \
+ extu.b reg, reg
+# define LOAD_PRIVATE_FUTEX_WAKE(reg,tmp,tmp2) \
+ mov #(FUTEX_WAKE | FUTEX_PRIVATE_FLAG), reg; \
+ extu.b reg, reg
+# define LOAD_FUTEX_WAIT(reg,tmp,tmp2) \
+ mov #(FUTEX_WAIT | FUTEX_PRIVATE_FLAG), tmp; \
+ extu.b tmp, tmp; \
+ xor tmp, reg
+# define LOAD_FUTEX_WAIT_ABS(reg,tmp,tmp2) \
+ mov #(FUTEX_WAIT_BITSET | FUTEX_PRIVATE_FLAG), tmp; \
+ extu.b tmp, tmp; \
+ mov #(FUTEX_CLOCK_REALTIME >> 8), tmp2; \
+ swap.b tmp2, tmp2; \
+ or tmp2, tmp; \
+ xor tmp, reg
+# define LOAD_FUTEX_WAKE(reg,tmp,tmp2) \
+ mov #(FUTEX_WAKE | FUTEX_PRIVATE_FLAG), tmp; \
+ extu.b tmp, tmp; \
+ xor tmp, reg
+#else
+# if FUTEX_WAIT == 0
+# define LOAD_PRIVATE_FUTEX_WAIT(reg,tmp,tmp2) \
+ stc gbr, tmp ; \
+ mov.w 99f, reg ; \
+ add reg, tmp ; \
+ bra 98f ; \
+ mov.l @tmp, reg ; \
+99: .word PRIVATE_FUTEX - TLS_PRE_TCB_SIZE ; \
+98:
+# else
+# define LOAD_PRIVATE_FUTEX_WAIT(reg,tmp,tmp2) \
+ stc gbr, tmp ; \
+ mov.w 99f, reg ; \
+ add reg, tmp ; \
+ mov.l @tmp, reg ; \
+ bra 98f ; \
+ mov #FUTEX_WAIT, tmp ; \
+99: .word PRIVATE_FUTEX - TLS_PRE_TCB_SIZE ; \
+98: or tmp, reg
+# endif
+# define LOAD_PRIVATE_FUTEX_WAKE(reg,tmp,tmp2) \
+ stc gbr, tmp ; \
+ mov.w 99f, reg ; \
+ add reg, tmp ; \
+ mov.l @tmp, reg ; \
+ bra 98f ; \
+ mov #FUTEX_WAKE, tmp ; \
+99: .word PRIVATE_FUTEX - TLS_PRE_TCB_SIZE ; \
+98: or tmp, reg
+# if FUTEX_WAIT == 0
+# define LOAD_FUTEX_WAIT(reg,tmp,tmp2) \
+ stc gbr, tmp ; \
+ mov.w 99f, tmp2 ; \
+ add tmp2, tmp ; \
+ mov.l @tmp, tmp2 ; \
+ bra 98f ; \
+ mov #FUTEX_PRIVATE_FLAG, tmp ; \
+99: .word PRIVATE_FUTEX - TLS_PRE_TCB_SIZE ; \
+98: extu.b tmp, tmp ; \
+ xor tmp, reg ; \
+ and tmp2, reg
+# else
+# define LOAD_FUTEX_WAIT(reg,tmp,tmp2) \
+ stc gbr, tmp ; \
+ mov.w 99f, tmp2 ; \
+ add tmp2, tmp ; \
+ mov.l @tmp, tmp2 ; \
+ bra 98f ; \
+ mov #FUTEX_PRIVATE_FLAG, tmp ; \
+99: .word PRIVATE_FUTEX - TLS_PRE_TCB_SIZE ; \
+98: extu.b tmp, tmp ; \
+ xor tmp, reg ; \
+ and tmp2, reg ; \
+ mov #FUTEX_WAIT, tmp ; \
+ or tmp, reg
+# endif
+# define LOAD_FUTEX_WAIT_ABS(reg,tmp,tmp2) \
+ stc gbr, tmp ; \
+ mov.w 99f, tmp2 ; \
+ add tmp2, tmp ; \
+ mov.l @tmp, tmp2 ; \
+ bra 98f ; \
+ mov #FUTEX_PRIVATE_FLAG, tmp ; \
+99: .word PRIVATE_FUTEX - TLS_PRE_TCB_SIZE ; \
+98: extu.b tmp, tmp ; \
+ xor tmp, reg ; \
+ and tmp2, reg ; \
+ mov #FUTEX_WAIT_BITSET, tmp ; \
+ mov #(FUTEX_CLOCK_REALTIME >> 8), tmp2; \
+ swap.b tmp2, tmp2; \
+ or tmp2, tmp; \
+ or tmp, reg
+# define LOAD_FUTEX_WAKE(reg,tmp,tmp2) \
+ stc gbr, tmp ; \
+ mov.w 99f, tmp2 ; \
+ add tmp2, tmp ; \
+ mov.l @tmp, tmp2 ; \
+ bra 98f ; \
+ mov #FUTEX_PRIVATE_FLAG, tmp ; \
+99: .word PRIVATE_FUTEX - TLS_PRE_TCB_SIZE ; \
+98: extu.b tmp, tmp ; \
+ xor tmp, reg ; \
+ and tmp2, reg ; \
+ mov #FUTEX_WAKE, tmp ; \
+ or tmp, reg
+#endif
- .globl __lll_mutex_lock_wait
- .type __lll_mutex_lock_wait,@function
- .hidden __lll_mutex_lock_wait
+ .globl __lll_lock_wait_private
+ .type __lll_lock_wait_private,@function
+ .hidden __lll_lock_wait_private
.align 5
- /* void __lll_mutex_lock_wait (int val, int *__futex) */
-__lll_mutex_lock_wait:
- mov #2, r6
- cmp/eq r4, r6
- mov r5, r4
+ cfi_startproc
+__lll_lock_wait_private:
+ mov.l r8, @-r15
+ cfi_adjust_cfa_offset(4)
+ cfi_rel_offset (r8, 0)
+ mov r4, r6
+ mov r5, r8
mov #0, r7 /* No timeout. */
- mov #FUTEX_WAIT, r5
+ LOAD_PRIVATE_FUTEX_WAIT (r5, r0, r1)
+ mov #2, r4
+ cmp/eq r4, r6
bf 2f
1:
+ mov r8, r4
mov #SYS_futex, r3
extu.b r3, r3
trapa #0x14
SYSCALL_INST_PAD
2:
- XCHG (r6, @r4, r2)
+ mov #2, r6
+ XCHG (r6, @r8, r2)
tst r2, r2
bf 1b
+ mov.l @r15+, r8
rts
- nop
- .size __lll_mutex_lock_wait,.-__lll_mutex_lock_wait
-
+ mov r2, r0
+ cfi_endproc
+ .size __lll_lock_wait_private,.-__lll_lock_wait_private
#ifdef NOT_IN_libc
- .globl __lll_mutex_timedlock_wait
- .type __lll_mutex_timedlock_wait,@function
- .hidden __lll_mutex_timedlock_wait
+ .globl __lll_lock_wait
+ .type __lll_lock_wait,@function
+ .hidden __lll_lock_wait
.align 5
- /* int __lll_mutex_timedlock_wait (int val, int *__futex,
- const struct timespec *abstime) */
-__lll_mutex_timedlock_wait:
+ cfi_startproc
+__lll_lock_wait:
+ mov.l r9, @-r15
+ cfi_adjust_cfa_offset(4)
+ cfi_rel_offset (r9, 0)
+ mov.l r8, @-r15
+ cfi_adjust_cfa_offset(4)
+ cfi_rel_offset (r8, 0)
+ mov r6, r9
+ mov r4, r6
+ mov r5, r8
+ mov #0, r7 /* No timeout. */
+ mov r9, r5
+ LOAD_FUTEX_WAIT (r5, r0, r1)
+
+ mov #2, r4
+ cmp/eq r4, r6
+ bf 2f
+
+1:
+ mov r8, r4
+ mov #SYS_futex, r3
+ extu.b r3, r3
+ trapa #0x14
+ SYSCALL_INST_PAD
+
+2:
+ mov #2, r6
+ XCHG (r6, @r8, r2)
+ tst r2, r2
+ bf 1b
+
+ mov.l @r15+, r8
+ mov.l @r15+, r9
+ ret
+ mov r2, r0
+ cfi_endproc
+ .size __lll_lock_wait,.-__lll_lock_wait
+
+ /* r5 (r8): futex
+ r7 (r11): flags
+ r6 (r9): timeout
+ r4 (r10): futex value
+ */
+ .globl __lll_timedlock_wait
+ .type __lll_timedlock_wait,@function
+ .hidden __lll_timedlock_wait
+ .align 5
+ cfi_startproc
+__lll_timedlock_wait:
+ mov.l r12, @-r15
+ cfi_adjust_cfa_offset(4)
+ cfi_rel_offset (r12, 0)
+
+# ifndef __ASSUME_FUTEX_CLOCK_REALTIME
+ mov.l .Lhave, r1
+# ifdef PIC
+ mova .Lgot, r0
+ mov.l .Lgot, r12
+ add r0, r12
+ add r12, r1
+# endif
+ mov.l @r1, r0
+ tst r0, r0
+ bt .Lreltmo
+# endif
+
+ mov r4, r2
+ mov r5, r4
+ mov r7, r5
+ mov r6, r7
+ LOAD_FUTEX_WAIT_ABS (r5, r0, r1)
+
+ mov #2, r6
+ cmp/eq r6, r2
+ bf/s 2f
+ mov r6, r2
+
+1:
+ mov #2, r6
+ mov #-1, r1
+ mov #SYS_futex, r3
+ extu.b r3, r3
+ trapa #0x16
+ SYSCALL_INST_PAD
+ mov r0, r6
+
+2:
+ XCHG (r2, @r4, r3) /* NB: lock is implied */
+
+ tst r3, r3
+ bt/s 3f
+ mov r6, r0
+
+ cmp/eq #-ETIMEDOUT, r0
+ bt 4f
+ cmp/eq #-EINVAL, r0
+ bf 1b
+4:
+ neg r0, r3
+3:
+ mov r3, r0
+ rts
+ mov.l @r15+, r12
+
+ .align 2
+# ifdef PIC
+.Lgot:
+ .long _GLOBAL_OFFSET_TABLE_
+.Lhave:
+ .long __have_futex_clock_realtime@GOTOFF
+# else
+.Lhave:
+ .long __have_futex_clock_realtime
+# endif
+
+# ifndef __ASSUME_FUTEX_CLOCK_REALTIME
+.Lreltmo:
/* Check for a valid timeout value. */
mov.l @(4,r6), r1
mov.l .L1g, r0
cmp/hs r0, r1
bt 3f
+ mov.l r11, @-r15
+ cfi_adjust_cfa_offset(4)
+ cfi_rel_offset (r11, 0)
+ mov.l r10, @-r15
+ cfi_adjust_cfa_offset(4)
+ cfi_rel_offset (r10, 0)
mov.l r9, @-r15
+ cfi_adjust_cfa_offset(4)
+ cfi_rel_offset (r9, 0)
mov.l r8, @-r15
+ cfi_adjust_cfa_offset(4)
+ cfi_rel_offset (r8, 0)
+ mov r7, r11
+ mov r4, r10
mov r6, r9
mov r5, r8
/* Stack frame for the timespec and timeval structs. */
add #-8, r15
+ cfi_adjust_cfa_offset(8)
+
+ mov #2, r2
+ XCHG (r2, @r8, r3)
+
+ tst r3, r3
+ bt 6f
1:
/* Get current time. */
mov r15, r4
mov #0, r5
- mov #SYS_gettimeofday, r3
+ mov #__NR_gettimeofday, r3
trapa #0x12
SYSCALL_INST_PAD
@@ -105,56 +353,49 @@ __lll_mutex_timedlock_wait:
add #-1, r2
4:
cmp/pz r2
- bf 5f /* Time is already up. */
+ bf 2f /* Time is already up. */
mov.l r2, @r15 /* Store relative timeout. */
mov.l r3, @(4,r15)
- mov #1, r3
- mov #2, r6
- CMPXCHG (r3, @r8, r6, r2)
- tst r2, r2
- bt 8f
-
mov r8, r4
- mov #FUTEX_WAIT, r5
+ mov r11, r5
+ LOAD_FUTEX_WAIT (r5, r0, r1)
+ mov r10, r6
mov r15, r7
mov #SYS_futex, r3
extu.b r3, r3
trapa #0x14
SYSCALL_INST_PAD
- mov r0, r4
+ mov r0, r5
-8:
- mov #0, r3
- CMPXCHG (r3, @r8, r6, r2)
- bf/s 7f
- mov #0, r0
+ mov #2, r2
+ XCHG (r2, @r8, r3)
+
+ tst r3, r3
+ bt/s 6f
+ mov #-ETIMEDOUT, r1
+ cmp/eq r5, r1
+ bf 1b
+
+2: mov #ETIMEDOUT, r3
6:
+ mov r3, r0
add #8, r15
mov.l @r15+, r8
- rts
mov.l @r15+, r9
-7:
- /* Check whether the time expired. */
- mov #-ETIMEDOUT, r1
- cmp/eq r5, r1
- bt 5f
+ mov.l @r15+, r10
+ mov.l @r15+, r11
+ rts
+ mov.l @r15+, r12
- /* Make sure the current holder knows we are going to sleep. */
- XCHG (r2, @r8, r3)
- tst r3, r3
- bt/s 6b
- mov #0, r0
- bra 1b
- nop
3:
+ mov.l @r15+, r12
rts
- mov #EINVAL, r0
-5:
- bra 6b
- mov #ETIMEDOUT, r0
+ mov #EINVAL, r0
+# endif
+ cfi_endproc
.L1k:
.word 1000
@@ -162,21 +403,16 @@ __lll_mutex_timedlock_wait:
.L1g:
.long 1000000000
- .size __lll_mutex_timedlock_wait,.-__lll_mutex_timedlock_wait
+ .size __lll_timedlock_wait,.-__lll_timedlock_wait
#endif
-
-#ifdef NOT_IN_libc
- .globl lll_unlock_wake_cb
- .type lll_unlock_wake_cb,@function
- .hidden lll_unlock_wake_cb
+ .globl __lll_unlock_wake_private
+ .type __lll_unlock_wake_private,@function
+ .hidden __lll_unlock_wake_private
.align 5
-lll_unlock_wake_cb:
- DEC (@r4, r2)
- tst r2, r2
- bt 1f
-
- mov #FUTEX_WAKE, r5
+ cfi_startproc
+__lll_unlock_wake_private:
+ LOAD_PRIVATE_FUTEX_WAKE (r5, r0, r1)
mov #1, r6 /* Wake one thread. */
mov #0, r7
mov.l r7, @r4 /* Stores 0. */
@@ -184,21 +420,19 @@ lll_unlock_wake_cb:
extu.b r3, r3
trapa #0x14
SYSCALL_INST_PAD
-
-1:
rts
- nop
- .size lll_unlock_wake_cb,.-lll_unlock_wake_cb
-#endif
-
+ nop
+ cfi_endproc
+ .size __lll_unlock_wake_private,.-__lll_unlock_wake_private
- .globl __lll_mutex_unlock_wake
- .type __lll_mutex_unlock_wake,@function
- .hidden __lll_mutex_unlock_wake
+#ifdef NOT_IN_libc
+ .globl __lll_unlock_wake
+ .type __lll_unlock_wake,@function
+ .hidden __lll_unlock_wake
.align 5
- /* void __lll_mutex_unlock_wake(int *__futex) */
-__lll_mutex_unlock_wake:
- mov #FUTEX_WAKE, r5
+ cfi_startproc
+__lll_unlock_wake:
+ LOAD_FUTEX_WAKE (r5, r0, r1)
mov #1, r6 /* Wake one thread. */
mov #0, r7
mov.l r7, @r4 /* Stores 0. */
@@ -207,29 +441,34 @@ __lll_mutex_unlock_wake:
trapa #0x14
SYSCALL_INST_PAD
rts
- nop
- .size __lll_mutex_unlock_wake,.-__lll_mutex_unlock_wake
-
+ nop
+ cfi_endproc
+ .size __lll_unlock_wake,.-__lll_unlock_wake
-#ifdef NOT_IN_libc
.globl __lll_timedwait_tid
.type __lll_timedwait_tid,@function
.hidden __lll_timedwait_tid
.align 5
+ cfi_startproc
__lll_timedwait_tid:
mov.l r9, @-r15
+ cfi_adjust_cfa_offset(4)
+ cfi_rel_offset (r9, 0)
mov.l r8, @-r15
+ cfi_adjust_cfa_offset(4)
+ cfi_rel_offset (r8, 0)
mov r4, r8
mov r5, r9
/* Stack frame for the timespec and timeval structs. */
add #-8, r15
+ cfi_adjust_cfa_offset(8)
2:
/* Get current time. */
mov r15, r4
mov #0, r5
- mov #SYS_gettimeofday, r3
+ mov #__NR_gettimeofday, r3
trapa #0x12
SYSCALL_INST_PAD
@@ -260,7 +499,10 @@ __lll_timedwait_tid:
bt 4f
mov r8, r4
- mov #FUTEX_WAIT, r5
+ /* XXX The kernel so far uses global futex for the wakeup at
+ all times. */
+ mov #0, r5
+ extu.b r5, r5
mov r2, r6
mov r15, r7
mov #SYS_futex, r3
@@ -277,7 +519,7 @@ __lll_timedwait_tid:
add #8, r15
mov.l @r15+, r8
rts
- mov.l @r15+, r9
+ mov.l @r15+, r9
1:
/* Check whether the time expired. */
mov #-ETIMEDOUT, r1
@@ -285,7 +527,8 @@ __lll_timedwait_tid:
bf 2b
6:
bra 3b
- mov #ETIMEDOUT, r0
+ mov #ETIMEDOUT, r0
+ cfi_endproc
.L1k2:
.word 1000
diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/sh/lowlevellock.h b/libpthread/nptl/sysdeps/unix/sysv/linux/sh/lowlevellock.h
index 45339f5e0..d7fada991 100644
--- a/libpthread/nptl/sysdeps/unix/sysv/linux/sh/lowlevellock.h
+++ b/libpthread/nptl/sysdeps/unix/sysv/linux/sh/lowlevellock.h
@@ -1,4 +1,5 @@
-/* Copyright (C) 2003, 2004 Free Software Foundation, Inc.
+/* Copyright (C) 2003, 2004, 2006, 2007, 2008, 2009
+ Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
@@ -19,28 +20,107 @@
#ifndef _LOWLEVELLOCK_H
#define _LOWLEVELLOCK_H 1
-#include <syscall.h>
+#ifndef __ASSEMBLER__
#include <time.h>
#include <sys/param.h>
#include <bits/pthreadtypes.h>
+#include <bits/kernel-features.h>
+#endif
+#define SYS_futex 240
#define FUTEX_WAIT 0
#define FUTEX_WAKE 1
+#define FUTEX_CMP_REQUEUE 4
+#define FUTEX_WAKE_OP 5
+#define FUTEX_LOCK_PI 6
+#define FUTEX_UNLOCK_PI 7
+#define FUTEX_TRYLOCK_PI 8
+#define FUTEX_WAIT_BITSET 9
+#define FUTEX_WAKE_BITSET 10
+#define FUTEX_PRIVATE_FLAG 128
+#define FUTEX_CLOCK_REALTIME 256
+
+#define FUTEX_BITSET_MATCH_ANY 0xffffffff
+
+#define FUTEX_OP_CLEAR_WAKE_IF_GT_ONE ((4 << 24) | 1)
+
+/* 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)) \
+ : ((fl) | (((private) ^ FUTEX_PRIVATE_FLAG) \
+ & THREAD_GETMEM (THREAD_SELF, header.private_futex))))
+# endif
+#endif
+#ifndef __ASSEMBLER__
/* Initializer for compatibility lock. */
-#define LLL_MUTEX_LOCK_INITIALIZER (0)
-#define LLL_MUTEX_LOCK_INITIALIZER_LOCKED (1)
-#define LLL_MUTEX_LOCK_INITIALIZER_WAITERS (2)
-
-extern int __lll_mutex_lock_wait (int val, int *__futex) attribute_hidden;
-extern int __lll_mutex_timedlock_wait (int val, int *__futex,
- const struct timespec *abstime)
- attribute_hidden;
-extern int __lll_mutex_unlock_wake (int *__futex) attribute_hidden;
-
+#define LLL_LOCK_INITIALIZER (0)
+#define LLL_LOCK_INITIALIZER_LOCKED (1)
+#define LLL_LOCK_INITIALIZER_WAITERS (2)
+
+extern int __lll_lock_wait_private (int val, int *__futex)
+ attribute_hidden;
+extern int __lll_lock_wait (int val, int *__futex, int private)
+ attribute_hidden;
+extern int __lll_timedlock_wait (int val, int *__futex,
+ const struct timespec *abstime, int private)
+ attribute_hidden;
+extern int __lll_robust_lock_wait (int val, int *__futex, int private)
+ attribute_hidden;
+extern int __lll_robust_timedlock_wait (int val, int *__futex,
+ const struct timespec *abstime,
+ int private)
+ attribute_hidden;
+extern int __lll_unlock_wake_private (int *__futex) attribute_hidden;
+extern int __lll_unlock_wake (int *__futex, int private) attribute_hidden;
+
+#define lll_trylock(futex) \
+ ({ unsigned char __result; \
+ __asm __volatile ("\
+ .align 2\n\
+ mova 1f,r0\n\
+ nop\n\
+ mov r15,r1\n\
+ mov #-8,r15\n\
+ 0: mov.l @%1,r2\n\
+ cmp/eq r2,%3\n\
+ bf 1f\n\
+ mov.l %2,@%1\n\
+ 1: mov r1,r15\n\
+ mov #-1,%0\n\
+ negc %0,%0"\
+ : "=r" (__result) \
+ : "r" (&(futex)), \
+ "r" (LLL_LOCK_INITIALIZER_LOCKED), \
+ "r" (LLL_LOCK_INITIALIZER) \
+ : "r0", "r1", "r2", "t", "memory"); \
+ __result; })
-#define lll_mutex_trylock(futex) \
+#define lll_robust_trylock(futex, id) \
({ unsigned char __result; \
__asm __volatile ("\
.align 2\n\
@@ -57,12 +137,12 @@ extern int __lll_mutex_unlock_wake (int *__futex) attribute_hidden;
negc %0,%0"\
: "=r" (__result) \
: "r" (&(futex)), \
- "r" (LLL_MUTEX_LOCK_INITIALIZER_LOCKED), \
- "r" (LLL_MUTEX_LOCK_INITIALIZER) \
+ "r" (id), \
+ "r" (LLL_LOCK_INITIALIZER) \
: "r0", "r1", "r2", "t", "memory"); \
__result; })
-#define lll_mutex_cond_trylock(futex) \
+#define lll_cond_trylock(futex) \
({ unsigned char __result; \
__asm __volatile ("\
.align 2\n\
@@ -79,12 +159,12 @@ extern int __lll_mutex_unlock_wake (int *__futex) attribute_hidden;
negc %0,%0"\
: "=r" (__result) \
: "r" (&(futex)), \
- "r" (LLL_MUTEX_LOCK_INITIALIZER_WAITERS), \
- "r" (LLL_MUTEX_LOCK_INITIALIZER) \
+ "r" (LLL_LOCK_INITIALIZER_WAITERS), \
+ "r" (LLL_LOCK_INITIALIZER) \
: "r0", "r1", "r2", "t", "memory"); \
__result; })
-#define lll_mutex_lock(futex) \
+#define lll_lock(futex, private) \
(void) ({ int __result, *__futex = &(futex); \
__asm __volatile ("\
.align 2\n\
@@ -100,11 +180,37 @@ extern int __lll_mutex_unlock_wake (int *__futex) attribute_hidden;
: "=&r" (__result) : "r" (1), "r" (__futex) \
: "r0", "r1", "t", "memory"); \
if (__result) \
- __lll_mutex_lock_wait (__result, __futex); })
+ { \
+ if (__builtin_constant_p (private) \
+ && (private) == LLL_PRIVATE) \
+ __lll_lock_wait_private (__result, __futex); \
+ else \
+ __lll_lock_wait (__result, __futex, (private)); \
+ } \
+ })
+
+#define lll_robust_lock(futex, id, private) \
+ ({ int __result, *__futex = &(futex); \
+ __asm __volatile ("\
+ .align 2\n\
+ mova 1f,r0\n\
+ nop\n\
+ mov r15,r1\n\
+ mov #-8,r15\n\
+ 0: mov.l @%2,%0\n\
+ tst %0,%0\n\
+ bf 1f\n\
+ mov.l %1,@%2\n\
+ 1: mov r1,r15"\
+ : "=&r" (__result) : "r" (id), "r" (__futex) \
+ : "r0", "r1", "t", "memory"); \
+ if (__result) \
+ __result = __lll_robust_lock_wait (__result, __futex, private); \
+ __result; })
/* Special version of lll_mutex_lock which causes the unlock function to
always wakeup waiters. */
-#define lll_mutex_cond_lock(futex) \
+#define lll_cond_lock(futex, private) \
(void) ({ int __result, *__futex = &(futex); \
__asm __volatile ("\
.align 2\n\
@@ -120,9 +226,28 @@ extern int __lll_mutex_unlock_wake (int *__futex) attribute_hidden;
: "=&r" (__result) : "r" (2), "r" (__futex) \
: "r0", "r1", "t", "memory"); \
if (__result) \
- __lll_mutex_lock_wait (__result, __futex); })
+ __lll_lock_wait (__result, __futex, private); })
-#define lll_mutex_timedlock(futex, timeout) \
+#define lll_robust_cond_lock(futex, id, private) \
+ ({ int __result, *__futex = &(futex); \
+ __asm __volatile ("\
+ .align 2\n\
+ mova 1f,r0\n\
+ nop\n\
+ mov r15,r1\n\
+ mov #-8,r15\n\
+ 0: mov.l @%2,%0\n\
+ tst %0,%0\n\
+ bf 1f\n\
+ mov.l %1,@%2\n\
+ 1: mov r1,r15"\
+ : "=&r" (__result) : "r" (id | FUTEX_WAITERS), "r" (__futex) \
+ : "r0", "r1", "t", "memory"); \
+ if (__result) \
+ __result = __lll_robust_lock_wait (__result, __futex, private); \
+ __result; })
+
+#define lll_timedlock(futex, timeout, private) \
({ int __result, *__futex = &(futex); \
__asm __volatile ("\
.align 2\n\
@@ -138,10 +263,30 @@ extern int __lll_mutex_unlock_wake (int *__futex) attribute_hidden;
: "=&r" (__result) : "r" (1), "r" (__futex) \
: "r0", "r1", "t", "memory"); \
if (__result) \
- __result = __lll_mutex_timedlock_wait (__result, __futex, timeout); \
+ __result = __lll_timedlock_wait (__result, __futex, timeout, private); \
__result; })
-#define lll_mutex_unlock(futex) \
+#define lll_robust_timedlock(futex, timeout, id, private) \
+ ({ int __result, *__futex = &(futex); \
+ __asm __volatile ("\
+ .align 2\n\
+ mova 1f,r0\n\
+ nop\n\
+ mov r15,r1\n\
+ mov #-8,r15\n\
+ 0: mov.l @%2,%0\n\
+ tst %0,%0\n\
+ bf 1f\n\
+ mov.l %1,@%2\n\
+ 1: mov r1,r15"\
+ : "=&r" (__result) : "r" (id), "r" (__futex) \
+ : "r0", "r1", "t", "memory"); \
+ if (__result) \
+ __result = __lll_robust_timedlock_wait (__result, __futex, \
+ timeout, private); \
+ __result; })
+
+#define lll_unlock(futex, private) \
(void) ({ int __result, *__futex = &(futex); \
__asm __volatile ("\
.align 2\n\
@@ -155,22 +300,45 @@ extern int __lll_mutex_unlock_wake (int *__futex) attribute_hidden;
: "=&r" (__result) : "r" (__futex) \
: "r0", "r1", "memory"); \
if (__result) \
- __lll_mutex_unlock_wake (__futex); })
-
-#define lll_mutex_islocked(futex) \
- (futex != 0)
-
-
-/* We have a separate internal lock implementation which is not tied
- to binary compatibility. */
-
-/* Type for lock object. */
-typedef int lll_lock_t;
-
-/* Initializers for lock. */
-#define LLL_LOCK_INITIALIZER (0)
-#define LLL_LOCK_INITIALIZER_LOCKED (1)
+ { \
+ if (__builtin_constant_p (private) \
+ && (private) == LLL_PRIVATE) \
+ __lll_unlock_wake_private (__futex); \
+ else \
+ __lll_unlock_wake (__futex, (private)); \
+ } \
+ })
+
+#define lll_robust_unlock(futex, private) \
+ (void) ({ int __result, *__futex = &(futex); \
+ __asm __volatile ("\
+ .align 2\n\
+ mova 1f,r0\n\
+ mov r15,r1\n\
+ mov #-6,r15\n\
+ 0: mov.l @%1,%0\n\
+ and %2,%0\n\
+ mov.l %0,@%1\n\
+ 1: mov r1,r15"\
+ : "=&r" (__result) : "r" (__futex), "r" (FUTEX_WAITERS) \
+ : "r0", "r1", "memory"); \
+ if (__result) \
+ __lll_unlock_wake (__futex, private); })
+#define lll_robust_dead(futex, private) \
+ (void) ({ int __ignore, *__futex = &(futex); \
+ __asm __volatile ("\
+ .align 2\n\
+ mova 1f,r0\n\
+ mov r15,r1\n\
+ mov #-6,r15\n\
+ 0: mov.l @%1,%0\n\
+ or %2,%0\n\
+ mov.l %0,@%1\n\
+ 1: mov r1,r15"\
+ : "=&r" (__ignore) : "r" (__futex), "r" (FUTEX_OWNER_DIED) \
+ : "r0", "r1", "memory"); \
+ lll_futex_wake (__futex, 1, private); })
# ifdef NEED_SYSCALL_INST_PAD
# define SYSCALL_WITH_INST_PAD "\
@@ -180,27 +348,17 @@ typedef int lll_lock_t;
trapa #0x14"
# endif
-#define lll_futex_wait(futex, val) \
- do { \
- int __ignore; \
- register unsigned long __r3 __asm ("r3") = SYS_futex; \
- register unsigned long __r4 __asm ("r4") = (unsigned long) (futex); \
- register unsigned long __r5 __asm ("r5") = FUTEX_WAIT; \
- register unsigned long __r6 __asm ("r6") = (unsigned long) (val); \
- register unsigned long __r7 __asm ("r7") = 0; \
- __asm __volatile (SYSCALL_WITH_INST_PAD \
- : "=z" (__ignore) \
- : "r" (__r3), "r" (__r4), "r" (__r5), \
- "r" (__r6), "r" (__r7) \
- : "memory", "t"); \
- } while (0)
+#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) \
({ \
int __status; \
register unsigned long __r3 __asm ("r3") = SYS_futex; \
register unsigned long __r4 __asm ("r4") = (unsigned long) (futex); \
- register unsigned long __r5 __asm ("r5") = FUTEX_WAIT; \
+ register unsigned long __r5 __asm ("r5") \
+ = __lll_private_flag (FUTEX_WAIT, private); \
register unsigned long __r6 __asm ("r6") = (unsigned long) (val); \
register unsigned long __r7 __asm ("r7") = (timeout); \
__asm __volatile (SYSCALL_WITH_INST_PAD \
@@ -212,12 +370,13 @@ typedef int lll_lock_t;
})
-#define lll_futex_wake(futex, nr) \
+#define lll_futex_wake(futex, nr, private) \
do { \
int __ignore; \
register unsigned long __r3 __asm ("r3") = SYS_futex; \
register unsigned long __r4 __asm ("r4") = (unsigned long) (futex); \
- register unsigned long __r5 __asm ("r5") = FUTEX_WAKE; \
+ register unsigned long __r5 __asm ("r5") \
+ = __lll_private_flag (FUTEX_WAKE, private); \
register unsigned long __r6 __asm ("r6") = (unsigned long) (nr); \
register unsigned long __r7 __asm ("r7") = 0; \
__asm __volatile (SYSCALL_WITH_INST_PAD \
@@ -228,33 +387,19 @@ typedef int lll_lock_t;
} while (0)
-extern int lll_unlock_wake_cb (int *__futex) attribute_hidden;
-
-
-/* The states of a lock are:
- 0 - untaken
- 1 - taken by one user
- 2 - taken by more users */
-
-#define lll_trylock(futex) lll_mutex_trylock (futex)
-#define lll_lock(futex) lll_mutex_lock (futex)
-#define lll_unlock(futex) lll_mutex_unlock (futex)
-
#define lll_islocked(futex) \
(futex != LLL_LOCK_INITIALIZER)
-
/* The kernel notifies a process with uses CLONE_CLEARTID via futex
wakeup when the clone terminates. The memory location contains the
thread ID while the clone is running and is reset to zero
afterwards. */
-extern int __lll_wait_tid (int *tid) attribute_hidden;
#define lll_wait_tid(tid) \
do { \
__typeof (tid) *__tid = &(tid); \
while (*__tid != 0) \
- lll_futex_wait (__tid, *__tid); \
+ lll_futex_wait (__tid, *__tid, LLL_SHARED); \
} while (0)
extern int __lll_timedwait_tid (int *tid, const struct timespec *abstime)
@@ -271,24 +416,6 @@ extern int __lll_timedwait_tid (int *tid, const struct timespec *abstime)
} \
__result; })
-
-/* Conditional variable handling. */
-
-extern void __lll_cond_wait (pthread_cond_t *cond) attribute_hidden;
-extern int __lll_cond_timedwait (pthread_cond_t *cond,
- const struct timespec *abstime)
- attribute_hidden;
-extern void __lll_cond_wake (pthread_cond_t *cond) attribute_hidden;
-extern void __lll_cond_broadcast (pthread_cond_t *cond) attribute_hidden;
-
-
-#define lll_cond_wait(cond) \
- __lll_cond_wait (cond)
-#define lll_cond_timedwait(cond, abstime) \
- __lll_cond_timedwait (cond, abstime)
-#define lll_cond_wake(cond) \
- __lll_cond_wake (cond)
-#define lll_cond_broadcast(cond) \
- __lll_cond_broadcast (cond)
+#endif /* !__ASSEMBLER__ */
#endif /* lowlevellock.h */
diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/sh/lowlevelrobustlock.S b/libpthread/nptl/sysdeps/unix/sysv/linux/sh/lowlevelrobustlock.S
new file mode 100644
index 000000000..dab1ae4ab
--- /dev/null
+++ b/libpthread/nptl/sysdeps/unix/sysv/linux/sh/lowlevelrobustlock.S
@@ -0,0 +1,264 @@
+/* Copyright (C) 2003, 2004, 2005, 2006, 2007
+ Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <sysdep.h>
+#include <pthread-errnos.h>
+#include <lowlevellock.h>
+#include <lowlevelrobustlock.h>
+#include <bits/kernel-features.h>
+#include "lowlevel-atomic.h"
+
+ .text
+
+#define FUTEX_WAITERS 0x80000000
+#define FUTEX_OWNER_DIED 0x40000000
+
+#ifdef __ASSUME_PRIVATE_FUTEX
+# define LOAD_FUTEX_WAIT(reg,tmp,tmp2) \
+ mov #(FUTEX_WAIT | FUTEX_PRIVATE_FLAG), tmp; \
+ extu.b tmp, tmp; \
+ xor tmp, reg
+#else
+# if FUTEX_WAIT == 0
+# define LOAD_FUTEX_WAIT(reg,tmp,tmp2) \
+ stc gbr, tmp ; \
+ mov.w 99f, tmp2 ; \
+ add tmp2, tmp ; \
+ mov.l @tmp, tmp2 ; \
+ bra 98f ; \
+ mov #FUTEX_PRIVATE_FLAG, tmp ; \
+99: .word PRIVATE_FUTEX - TLS_PRE_TCB_SIZE ; \
+98: extu.b tmp, tmp ; \
+ xor tmp, reg ; \
+ and tmp2, reg
+# else
+# define LOAD_FUTEX_WAIT(reg,tmp,tmp2) \
+ stc gbr, tmp ; \
+ mov.w 99f, tmp2 ; \
+ add tmp2, tmp ; \
+ mov.l @tmp, tmp2 ; \
+ bra 98f ; \
+ mov #FUTEX_PRIVATE_FLAG, tmp ; \
+99: .word PRIVATE_FUTEX - TLS_PRE_TCB_SIZE ; \
+98: extu.b tmp, tmp ; \
+ xor tmp, reg ; \
+ and tmp2, reg ; \
+ mov #FUTEX_WAIT, tmp ; \
+ or tmp, reg
+# endif
+#endif
+
+ .globl __lll_robust_lock_wait
+ .type __lll_robust_lock_wait,@function
+ .hidden __lll_robust_lock_wait
+ .align 5
+ cfi_startproc
+__lll_robust_lock_wait:
+ mov.l r8, @-r15
+ cfi_adjust_cfa_offset(4)
+ cfi_rel_offset (r8, 0)
+ mov r5, r8
+ mov #0, r7 /* No timeout. */
+ mov r6, r5
+ LOAD_FUTEX_WAIT (r5, r0, r1)
+
+4:
+ mov r4, r6
+ mov.l .L_FUTEX_WAITERS, r0
+ or r0, r6
+ shlr r0 /* r0 = FUTEX_OWNER_DIED */
+ tst r0, r4
+ bf/s 3f
+ cmp/eq r4, r6
+ bt 1f
+
+ CMPXCHG (r4, @r8, r6, r2)
+ bf 2f
+
+1:
+ mov r8, r4
+ mov #SYS_futex, r3
+ extu.b r3, r3
+ trapa #0x14
+ SYSCALL_INST_PAD
+
+ mov.l @r8, r2
+
+2:
+ tst r2, r2
+ bf/s 4b
+ mov r2, r4
+
+ stc gbr, r1
+ mov.w .Ltidoff, r2
+ add r2, r1
+ mov.l @r1, r6
+ mov #0, r3
+ CMPXCHG (r3, @r8, r6, r4)
+ bf 4b
+ mov #0, r4
+
+3:
+ mov.l @r15+, r8
+ ret
+ mov r4, r0
+ cfi_endproc
+ .align 2
+.L_FUTEX_WAITERS:
+ .long FUTEX_WAITERS
+.Ltidoff:
+ .word TID - TLS_PRE_TCB_SIZE
+ .size __lll_robust_lock_wait,.-__lll_robust_lock_wait
+
+
+ .globl __lll_robust_timedlock_wait
+ .type __lll_robust_timedlock_wait,@function
+ .hidden __lll_robust_timedlock_wait
+ .align 5
+ cfi_startproc
+__lll_robust_timedlock_wait:
+ /* Check for a valid timeout value. */
+ mov.l @(4,r6), r1
+ mov.l .L1g, r0
+ cmp/hs r0, r1
+ bt 3f
+
+ mov.l r11, @-r15
+ cfi_adjust_cfa_offset(4)
+ cfi_rel_offset (r11, 0)
+ mov.l r10, @-r15
+ cfi_adjust_cfa_offset(4)
+ cfi_rel_offset (r10, 0)
+ mov.l r9, @-r15
+ cfi_adjust_cfa_offset(4)
+ cfi_rel_offset (r9, 0)
+ mov.l r8, @-r15
+ cfi_adjust_cfa_offset(4)
+ cfi_rel_offset (r8, 0)
+ mov r7, r11
+ mov r4, r10
+ mov r6, r9
+ mov r5, r8
+
+ /* Stack frame for the timespec and timeval structs. */
+ add #-8, r15
+ cfi_adjust_cfa_offset(8)
+
+1:
+ /* Get current time. */
+ mov r15, r4
+ mov #0, r5
+ mov #__NR_gettimeofday, r3
+ trapa #0x12
+ SYSCALL_INST_PAD
+
+ /* Compute relative timeout. */
+ mov.l @(4,r15), r0
+ mov.w .L1k, r1
+ dmulu.l r0, r1 /* Micro seconds to nano seconds. */
+ mov.l @r9, r2
+ mov.l @(4,r9), r3
+ mov.l @r15, r0
+ sts macl, r1
+ sub r0, r2
+ clrt
+ subc r1, r3
+ bf 4f
+ mov.l .L1g, r1
+ add r1, r3
+ add #-1, r2
+4:
+ cmp/pz r2
+ bf 8f /* Time is already up. */
+
+ mov.l r2, @r15 /* Store relative timeout. */
+ mov.l r3, @(4,r15)
+
+ mov r10, r6
+ mov.l .L_FUTEX_WAITERS2, r0
+ or r0, r6
+ shlr r0 /* r0 = FUTEX_OWNER_DIED */
+ tst r0, r4
+ bf/s 6f
+ cmp/eq r4, r6
+ bt 2f
+
+ CMPXCHG (r4, @r8, r6, r2)
+ bf/s 5f
+ mov #0, r5
+
+2:
+ mov r8, r4
+ mov r11, r5
+ LOAD_FUTEX_WAIT (r5, r0, r1)
+ mov r10, r6
+ mov r15, r7
+ mov #SYS_futex, r3
+ extu.b r3, r3
+ trapa #0x14
+ SYSCALL_INST_PAD
+ mov r0, r5
+
+ mov.l @r8, r2
+
+5:
+ tst r2, r2
+ bf/s 7f
+ mov r2, r10
+
+ stc gbr, r1
+ mov.w .Ltidoff2, r2
+ add r2, r1
+ mov.l @r1, r4
+ mov #0, r3
+ CMPXCHG (r3, @r8, r4, r10)
+ bf 7f
+ mov #0, r0
+
+6:
+ add #8, r15
+ mov.l @r15+, r8
+ mov.l @r15+, r9
+ mov.l @r15+, r10
+ rts
+ mov.l @r15+, r11
+
+7:
+ /* Check whether the time expired. */
+ mov #-ETIMEDOUT, r1
+ cmp/eq r5, r1
+ bf 1b
+
+8:
+ bra 6b
+ mov #ETIMEDOUT, r0
+3:
+ rts
+ mov #EINVAL, r0
+ cfi_endproc
+ .align 2
+.L_FUTEX_WAITERS2:
+ .long FUTEX_WAITERS
+.L1g:
+ .long 1000000000
+.Ltidoff2:
+ .word TID - TLS_PRE_TCB_SIZE
+.L1k:
+ .word 1000
+ .size __lll_robust_timedlock_wait,.-__lll_robust_timedlock_wait
diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/sh/not-cancel.h b/libpthread/nptl/sysdeps/unix/sysv/linux/sh/not-cancel.h
index eb83653d3..acf1a617e 100644
--- a/libpthread/nptl/sysdeps/unix/sysv/linux/sh/not-cancel.h
+++ b/libpthread/nptl/sysdeps/unix/sysv/linux/sh/not-cancel.h
@@ -1,82 +1 @@
-/* Uncancelable versions of cancelable interfaces. Linux/NPTL version.
- Copyright (C) 2003 Free Software Foundation, Inc.
- This file is part of the GNU C Library.
- Contributed by Ulrich Drepper <drepper@redhat.com>, 2003.
-
- The GNU C Library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Lesser General Public
- License as published by the Free Software Foundation; either
- version 2.1 of the License, or (at your option) any later version.
-
- The GNU C Library is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Lesser General Public License for more details.
-
- You should have received a copy of the GNU Lesser General Public
- License along with the GNU C Library; if not, write to the Free
- Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
- 02111-1307 USA. */
-
-#include <sysdep.h>
-
-#if !defined NOT_IN_libc || defined IS_IN_libpthread || defined IS_IN_librt
-extern int __open_nocancel (const char *, int, ...) attribute_hidden;
-extern int __close_nocancel (int) attribute_hidden;
-extern int __read_nocancel (int, void *, size_t) attribute_hidden;
-extern int __write_nocancel (int, const void *, size_t) attribute_hidden;
-extern pid_t __waitpid_nocancel (pid_t, int *, int) attribute_hidden;
-
-libc_hidden_proto(__open_nocancel)
-libc_hidden_proto(__close_nocancel)
-libc_hidden_proto(__read_nocancel)
-libc_hidden_proto(__write_nocancel)
-libc_hidden_proto(__waitpid_nocancel)
-
-#else
-#define __open_nocancel(name, ...) __open (name, __VA_ARGS__)
-#define __close_nocancel(fd) __close (fd)
-#define __read_nocancel(fd, buf, len) __read (fd, buf, len)
-#define __write_nocancel(fd, buf, len) __write (fd, buf, len)
-#define __waitpid_nocancel(pid, stat_loc, options) \
- __waitpid (pid, stat_loc, options)
-#endif
-
-/* Uncancelable open. */
-#define open_not_cancel(name, flags, mode) \
- __open_nocancel (name, flags, mode)
-#define open_not_cancel_2(name, flags) \
- __open_nocancel (name, flags)
-
-/* Uncancelable close. */
-#define close_not_cancel(fd) \
- __close_nocancel (fd)
-#define close_not_cancel_no_status(fd) \
- (void) ({ INTERNAL_SYSCALL_DECL (err); \
- INTERNAL_SYSCALL (close, err, 1, (fd)); })
-
-/* Uncancelable read. */
-#define read_not_cancel(fd, buf, n) \
- __read_nocancel (fd, buf, n)
-
-/* Uncancelable write. */
-#define write_not_cancel(fd, buf, n) \
- __write_nocancel (fd, buf, n)
-
-/* Uncancelable writev. */
-#define writev_not_cancel_no_status(fd, iov, n) \
- (void) ({ INTERNAL_SYSCALL_DECL (err); \
- INTERNAL_SYSCALL (writev, err, 3, (fd), (iov), (n)); })
-
-/* Uncancelable fcntl. */
-#define fcntl_not_cancel(fd, cmd, val) \
- __fcntl_nocancel (fd, cmd, val)
-
-/* Uncancelable waitpid. */
-#ifdef __NR_waitpid
-# define waitpid_not_cancel(pid, stat_loc, options) \
- __waitpid_nocancel (pid, stat_loc, options)
-#else
-# define waitpid_not_cancel(pid, stat_loc, options) \
- INLINE_SYSCALL (wait4, 4, pid, stat_loc, options, NULL)
-#endif
+#include "../i386/not-cancel.h"
diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/sh/pt-initfini.c b/libpthread/nptl/sysdeps/unix/sysv/linux/sh/pt-initfini.c
index 5391d5cc8..82c97c352 100644
--- a/libpthread/nptl/sysdeps/unix/sysv/linux/sh/pt-initfini.c
+++ b/libpthread/nptl/sysdeps/unix/sysv/linux/sh/pt-initfini.c
@@ -1,5 +1,5 @@
-/* Special .init and .fini section support for SH. NPTL version.
- Copyright (C) 2003 Free Software Foundation, Inc.
+/* Special .init and .fini section support for SH. NPTL version.
+ Copyright (C) 2003, 2009 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it
@@ -62,19 +62,12 @@ _init:\n\
mov.l .L24,r1\n\
add r0,r1\n\
jsr @r1\n\
- nop\n\
- mova .L23,r0\n\
- mov.l .L23,r1\n\
- add r0,r1\n\
- jsr @r1\n\
mov r15,r14\n\
bra 1f\n\
nop\n\
.align 2\n\
.L22:\n\
.long _GLOBAL_OFFSET_TABLE_\n\
-.L23:\n\
- .long __gmon_start__@PLT\n\
.L24:\n\
.long __pthread_initialize_minimal_internal@PLT\n\
1:\n\
@@ -91,16 +84,6 @@ _init:\n\
rts \n\
mov.l @r15+,r12\n\
END_INIT\n\
- .section .text\n\
- .align 5\n\
- .weak __gmon_start__\n\
- .type __gmon_start__,@function\n\
-__gmon_start__:\n\
- mov.l r14,@-r15\n\
- mov r15,r14\n\
- mov r14,r15\n\
- rts \n\
- mov.l @r15+,r14\n\
\n\
/*@_init_EPILOG_ENDS*/\n\
\n\
diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/sh/pthread_barrier_wait.S b/libpthread/nptl/sysdeps/unix/sysv/linux/sh/pthread_barrier_wait.S
index 608c7364c..4a6059aef 100644
--- a/libpthread/nptl/sysdeps/unix/sysv/linux/sh/pthread_barrier_wait.S
+++ b/libpthread/nptl/sysdeps/unix/sysv/linux/sh/pthread_barrier_wait.S
@@ -1,4 +1,4 @@
-/* Copyright (C) 2003, 2004 Free Software Foundation, Inc.
+/* Copyright (C) 2003, 2004, 2007, 2008 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
@@ -17,13 +17,10 @@
02111-1307 USA. */
#include <sysdep.h>
+#include <lowlevellock.h>
#include <lowlevelbarrier.h>
#include "lowlevel-atomic.h"
-#define FUTEX_WAIT 0
-#define FUTEX_WAKE 1
-
-
.text
.globl pthread_barrier_wait
@@ -64,7 +61,13 @@ pthread_barrier_wait:
#if CURR_EVENT != 0
add #CURR_EVENT, r4
#endif
+#if FUTEX_WAIT == 0
+ mov.l @(PRIVATE,r8), r5
+#else
mov #FUTEX_WAIT, r5
+ mov.l @(PRIVATE,r8), r0
+ or r0, r5
+#endif
mov #0, r7
8:
mov #SYS_futex, r3
@@ -81,8 +84,10 @@ pthread_barrier_wait:
/* Increment LEFT. If this brings the count back to the
initial count unlock the object. */
- INC (@(LEFT,r8), r2)
+ mov #1, r3
mov.l @(INIT_COUNT,r8), r4
+ XADD (r3, @(LEFT,r8), r2, r5)
+ add #-1, r4
cmp/eq r2, r4
bf 10f
@@ -115,6 +120,8 @@ pthread_barrier_wait:
#endif
mov #0, r7
mov #FUTEX_WAKE, r5
+ mov.l @(PRIVATE,r8), r0
+ or r0, r5
mov #SYS_futex, r3
extu.b r3, r3
trapa #0x14
@@ -122,8 +129,10 @@ pthread_barrier_wait:
/* Increment LEFT. If this brings the count back to the
initial count unlock the object. */
- INC (@(LEFT,r8), r2)
+ mov #1, r3
mov.l @(INIT_COUNT,r8), r4
+ XADD (r3, @(LEFT,r8), r2, r5)
+ add #-1, r4
cmp/eq r2, r4
bf 5f
@@ -139,6 +148,10 @@ pthread_barrier_wait:
mov.l @r15+, r9
1:
+ mov.l @(PRIVATE,r8), r6
+ mov #LLL_SHARED, r0
+ extu.b r0, r0
+ xor r0, r6
mov r2, r4
mov r8, r5
mov.l .Lwait0, r1
@@ -149,6 +162,10 @@ pthread_barrier_wait:
nop
4:
+ mov.l @(PRIVATE,r8), r5
+ mov #LLL_SHARED, r0
+ extu.b r0, r0
+ xor r0, r5
mov r8, r4
mov.l .Lwake0, r1
bsrf r1
@@ -159,6 +176,10 @@ pthread_barrier_wait:
6:
mov r6, r9
+ mov.l @(PRIVATE,r8), r5
+ mov #LLL_SHARED, r0
+ extu.b r0, r0
+ xor r0, r5
mov r8, r4
mov.l .Lwake1, r1
bsrf r1
@@ -167,8 +188,12 @@ pthread_barrier_wait:
bra 7b
mov r9, r6
-9:
+9:
mov r6, r9
+ mov.l @(PRIVATE,r8), r5
+ mov #LLL_SHARED, r0
+ extu.b r0, r0
+ xor r0, r5
mov r8, r4
mov.l .Lwake2, r1
bsrf r1
@@ -181,11 +206,11 @@ pthread_barrier_wait:
.Lall:
.long 0x7fffffff
.Lwait0:
- .long __lll_mutex_lock_wait-.Lwait0b
+ .long __lll_lock_wait-.Lwait0b
.Lwake0:
- .long __lll_mutex_unlock_wake-.Lwake0b
+ .long __lll_unlock_wake-.Lwake0b
.Lwake1:
- .long __lll_mutex_unlock_wake-.Lwake1b
+ .long __lll_unlock_wake-.Lwake1b
.Lwake2:
- .long __lll_mutex_unlock_wake-.Lwake2b
+ .long __lll_unlock_wake-.Lwake2b
.size pthread_barrier_wait,.-pthread_barrier_wait
diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/sh/pthread_cond_broadcast.S b/libpthread/nptl/sysdeps/unix/sysv/linux/sh/pthread_cond_broadcast.S
index 36eccf1e6..382512490 100644
--- a/libpthread/nptl/sysdeps/unix/sysv/linux/sh/pthread_cond_broadcast.S
+++ b/libpthread/nptl/sysdeps/unix/sysv/linux/sh/pthread_cond_broadcast.S
@@ -1,4 +1,4 @@
-/* Copyright (C) 2003, 2004 Free Software Foundation, Inc.
+/* Copyright (C) 2003, 2004, 2006, 2007 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
@@ -17,17 +17,13 @@
02111-1307 USA. */
#include <sysdep.h>
+#include <lowlevellock.h>
#include <lowlevelcond.h>
#include <bits/kernel-features.h>
+#include <pthread-pi-defines.h>
+#include <pthread-errnos.h>
#include "lowlevel-atomic.h"
-#define FUTEX_WAIT 0
-#define FUTEX_WAKE 1
-#define FUTEX_REQUEUE 3
-#define FUTEX_CMP_REQUEUE 4
-
-#define EINVAL 22
-
.text
/* int pthread_cond_broadcast (pthread_cond_t *cond) */
@@ -96,8 +92,24 @@ __pthread_cond_broadcast:
bt/s 9f
add #cond_futex, r4
+ /* XXX: The kernel only supports FUTEX_CMP_REQUEUE to the same
+ type of futex (private resp. shared). */
+ mov.l @(MUTEX_KIND,r9), r0
+ tst #(PI_BIT|PS_BIT), r0
+ bf 9f
+
/* Wake up all threads. */
- mov #FUTEX_CMP_REQUEUE, r5
+#ifdef __ASSUME_PRIVATE_FUTEX
+ mov #(FUTEX_CMP_REQUEUE|FUTEX_PRIVATE_FLAG), r5
+ extu.b r5, r5
+#else
+ stc gbr, r1
+ mov.w .Lpfoff, r2
+ add r2, r1
+ mov.l @r1, r5
+ mov #FUTEX_CMP_REQUEUE, r0
+ or r0, r5
+#endif
mov #1, r6
mov #-1, r7
shlr r7 /* r7 = 0x7fffffff */
@@ -154,10 +166,17 @@ __pthread_cond_broadcast:
#if cond_lock != 0
add #cond_lock, r5
#endif
- mov.l .Lmwait5, r1
+ mov.l @(dep_mutex,r8), r0
+ cmp/eq #-1, r0
+ bf/s 99f
+ mov #LLL_PRIVATE, r6
+ mov #LLL_SHARED, r6
+99:
+ extu.b r6, r6
+ mov.l .Lwait5, r1
bsrf r1
mov r2, r4
-.Lmwait5b:
+.Lwait5b:
bra 2b
nop
@@ -167,10 +186,16 @@ __pthread_cond_broadcast:
#if cond_lock != 0
add #cond_lock, r4
#endif
- mov.l .Lmwake5, r1
+ mov.l @(dep_mutex,r8), r0
+ cmp/eq #-1, r0
+ bf/s 99f
+ mov #LLL_PRIVATE, r5
+ mov #LLL_SHARED, r5
+99:
+ mov.l .Lwake5, r1
bsrf r1
- nop
-.Lmwake5b:
+ extu.b r5, r5
+.Lwake5b:
bra 6b
nop
@@ -180,15 +205,36 @@ __pthread_cond_broadcast:
#if cond_lock != 0
add #cond_lock, r4
#endif
- mov.l .Lmwake6, r1
+ mov #-1, r0
+ cmp/eq r0, r9
+ bf/s 99f
+ mov #LLL_PRIVATE, r5
+ mov #LLL_SHARED, r5
+99:
+ mov.l .Lwake6, r1
bsrf r1
- nop
-.Lmwake6b:
+ extu.b r5, r5
+.Lwake6b:
bra 8b
nop
9:
- mov #FUTEX_WAKE, r5
+ mov #-1, r0
+ cmp/eq r0, r9
+ bt/s 99f
+ mov #FUTEX_WAKE, r5
+#ifdef __ASSUME_PRIVATE_FUTEX
+ mov #(FUTEX_WAKE|FUTEX_PRIVATE_FLAG), r5
+ extu.b r5, r5
+#else
+ stc gbr, r1
+ mov.w .Lpfoff, r2
+ add r2, r1
+ mov.l @r1, r5
+ mov #FUTEX_WAKE, r0
+ or r0, r5
+#endif
+99:
mov #-1, r6
shlr r6 /* r6 = 0x7fffffff */
mov #0, r7
@@ -199,12 +245,17 @@ __pthread_cond_broadcast:
bra 10b
nop
+#ifndef __ASSUME_PRIVATE_FUTEX
+.Lpfoff:
+ .word PRIVATE_FUTEX - TLS_PRE_TCB_SIZE
+#endif
+
.align 2
-.Lmwait5:
- .long __lll_mutex_lock_wait-.Lmwait5b
-.Lmwake5:
- .long __lll_mutex_unlock_wake-.Lmwake5b
-.Lmwake6:
- .long __lll_mutex_unlock_wake-.Lmwake6b
+.Lwait5:
+ .long __lll_lock_wait-.Lwait5b
+.Lwake5:
+ .long __lll_unlock_wake-.Lwake5b
+.Lwake6:
+ .long __lll_unlock_wake-.Lwake6b
.size __pthread_cond_broadcast, .-__pthread_cond_broadcast
weak_alias (__pthread_cond_broadcast, pthread_cond_broadcast)
diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/sh/pthread_cond_signal.S b/libpthread/nptl/sysdeps/unix/sysv/linux/sh/pthread_cond_signal.S
index d92f11cbb..914a1bad0 100644
--- a/libpthread/nptl/sysdeps/unix/sysv/linux/sh/pthread_cond_signal.S
+++ b/libpthread/nptl/sysdeps/unix/sysv/linux/sh/pthread_cond_signal.S
@@ -1,4 +1,4 @@
-/* Copyright (C) 2003, 2004 Free Software Foundation, Inc.
+/* Copyright (C) 2003, 2004, 2007 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
@@ -17,16 +17,12 @@
02111-1307 USA. */
#include <sysdep.h>
+#include <lowlevellock.h>
#include <lowlevelcond.h>
#include <bits/kernel-features.h>
+#include <pthread-errnos.h>
#include "lowlevel-atomic.h"
-#define FUTEX_WAIT 0
-#define FUTEX_WAKE 1
-#define FUTEX_REQUEUE 3
-
-#define EINVAL 22
-
.text
/* int pthread_cond_signal (pthread_cond_t *cond) */
@@ -77,14 +73,63 @@ __pthread_cond_signal:
/* Wake up one thread. */
mov r8, r4
add #cond_futex, r4
- mov #FUTEX_WAKE, r5
+ mov.l @(dep_mutex,r8), r0
+ cmp/eq #-1, r0
+ bt/s 99f
+ mov #FUTEX_WAKE_OP, r5
+#ifdef __ASSUME_PRIVATE_FUTEX
+ mov #(FUTEX_WAKE_OP|FUTEX_PRIVATE_FLAG), r5
+ extu.b r5, r5
+#else
+ stc gbr, r1
+ mov.w .Lpfoff, r2
+ add r2, r1
+ mov.l @r1, r5
+ mov #FUTEX_WAKE_OP, r0
+ or r0, r5
+#endif
+99:
mov #1, r6
mov #0, r7
+ mov r8, r0
+ add #cond_lock, r0
+ mov.l .Lfutexop, r1
mov #SYS_futex, r3
extu.b r3, r3
trapa #0x14
SYSCALL_INST_PAD
+ /* For any kind of error, we try again with WAKE.
+ The general test also covers running on old kernels. */
+ mov r0, r1
+ mov #-12, r2
+ shad r2, r1
+ not r1, r1
+ tst r1, r1
+ bt 7f
+
+6:
+ mov #0, r0
+ lds.l @r15+, pr
+ rts
+ mov.l @r15+, r8
+
+#ifndef __ASSUME_PRIVATE_FUTEX
+.Lpfoff:
+ .word PRIVATE_FUTEX - TLS_PRE_TCB_SIZE
+#endif
+ .align 2
+.Lfutexop:
+ .long FUTEX_OP_CLEAR_WAKE_IF_GT_ONE
+
+7:
+ /* r5 should be either FUTEX_WAKE_OP or
+ FUTEX_WAKE_OP|FUTEX_PRIVATE_FLAG from the previous syscall. */
+ mov #(FUTEX_WAKE ^ FUTEX_WAKE_OP), r0
+ xor r0, r5
+ trapa #0x14
+ SYSCALL_INST_PAD
+
4:
/* Unlock. */
#if cond_lock != 0
@@ -93,12 +138,26 @@ __pthread_cond_signal:
DEC (@r8, r2)
#endif
tst r2, r2
- bf 5f
-6:
- mov #0, r0
- lds.l @r15+, pr
- rts
- mov.l @r15+, r8
+ bt 6b
+
+5:
+ /* Unlock in loop requires wakeup. */
+ mov r8, r4
+#if cond_lock != 0
+ add #cond_lock, r4
+#endif
+ mov.l @(dep_mutex,r8), r0
+ cmp/eq #-1, r0
+ bf/s 99f
+ mov #LLL_PRIVATE, r5
+ mov #LLL_SHARED, r5
+99:
+ mov.l .Lwake4, r1
+ bsrf r1
+ extu.b r5, r5
+.Lwake4b:
+ bra 6b
+ nop
1:
/* Initial locking failed. */
@@ -106,30 +165,24 @@ __pthread_cond_signal:
#if cond_lock != 0
add #cond_lock, r5
#endif
- mov.l .Lmwait4, r1
+ mov.l @(dep_mutex,r8), r0
+ cmp/eq #-1, r0
+ bf/s 99f
+ mov #LLL_PRIVATE, r6
+ mov #LLL_SHARED, r6
+99:
+ extu.b r6, r6
+ mov.l .Lwait4, r1
bsrf r1
mov r2, r4
-.Lmwait4b:
+.Lwait4b:
bra 2b
nop
-5:
- /* Unlock in loop requires wakeup. */
- mov r8, r4
-#if cond_lock != 0
- add #cond_lock, r4
-#endif
- mov.l .Lmwake4, r1
- bsrf r1
- nop
-.Lmwake4b:
- bra 6b
- nop
-
.align 2
-.Lmwait4:
- .long __lll_mutex_lock_wait-.Lmwait4b
-.Lmwake4:
- .long __lll_mutex_unlock_wake-.Lmwake4b
+.Lwait4:
+ .long __lll_lock_wait-.Lwait4b
+.Lwake4:
+ .long __lll_unlock_wake-.Lwake4b
.size __pthread_cond_signal, .-__pthread_cond_signal
weak_alias (__pthread_cond_signal, pthread_cond_signal)
diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/sh/pthread_cond_timedwait.S b/libpthread/nptl/sysdeps/unix/sysv/linux/sh/pthread_cond_timedwait.S
index 5812488b2..3e117564f 100644
--- a/libpthread/nptl/sysdeps/unix/sysv/linux/sh/pthread_cond_timedwait.S
+++ b/libpthread/nptl/sysdeps/unix/sysv/linux/sh/pthread_cond_timedwait.S
@@ -1,4 +1,4 @@
-/* Copyright (C) 2003, 2004 Free Software Foundation, Inc.
+/* Copyright (C) 2003, 2004, 2006, 2007 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
@@ -17,16 +17,13 @@
02111-1307 USA. */
#include <sysdep.h>
+#include <lowlevellock.h>
#include <lowlevelcond.h>
#include <pthread-errnos.h>
+#include <bits/kernel-features.h>
+#include <tcb-offsets.h>
#include "lowlevel-atomic.h"
-#define SYS_gettimeofday __NR_gettimeofday
-
-#define FUTEX_WAIT 0
-#define FUTEX_WAKE 1
-
-
.text
/* int pthread_cond_timedwait (pthread_cond_t *cond, pthread_mutex_t *mutex,
@@ -119,7 +116,7 @@ __pthread_cond_timedwait:
mov.l @(cond_futex,r8), r0
add r2, r0
mov.l r0, @(cond_futex,r8)
- mov #(1 << clock_bits), r2
+ mov #(1 << nwaiters_shift), r2
mov.l @(cond_nwaiters,r8), r0
add r2, r0
mov.l r0, @(cond_nwaiters,r8)
@@ -135,7 +132,7 @@ __pthread_cond_timedwait:
#ifdef __NR_clock_gettime
/* Get the clock number. */
mov.l @(cond_nwaiters,r8), r4
- mov #((1 << clock_bits) - 1), r0
+ mov #((1 << nwaiters_shift) - 1), r0
and r0, r4
/* Only clocks 0 and 1 are allowed. Both are handled in the
kernel. */
@@ -163,7 +160,7 @@ __pthread_cond_timedwait:
mov r15, r4
add #16, r4
mov #0, r5
- mov #SYS_gettimeofday, r3
+ mov #__NR_gettimeofday, r3
trapa #0x12
SYSCALL_INST_PAD
@@ -181,7 +178,7 @@ __pthread_cond_timedwait:
mov r15, r4
add #16, r4
mov #0, r5
- mov #SYS_gettimeofday, r3
+ mov #__NR_gettimeofday, r3
trapa #0x12
SYSCALL_INST_PAD
@@ -233,7 +230,22 @@ __pthread_cond_timedwait:
mov r15, r7
add #16, r7
- mov #FUTEX_WAIT, r5
+ mov.l @(dep_mutex,r8), r0
+ cmp/eq #-1, r0
+ bt/s 99f
+ mov #FUTEX_WAIT, r5
+#ifdef __ASSUME_PRIVATE_FUTEX
+ mov #(FUTEX_WAIT|FUTEX_PRIVATE_FLAG), r5
+ extu.b r5, r5
+#else
+ stc gbr, r1
+ mov.w .Lpfoff, r2
+ add r2, r1
+ mov.l @r1, r5
+ mov #FUTEX_WAIT, r0
+ or r0, r5
+#endif
+99:
mov.l @(8,r15), r6
mov r8, r4
add #cond_futex, r4
@@ -322,7 +334,7 @@ __pthread_cond_timedwait:
mov.l r1,@(woken_seq+4,r8)
24:
- mov #(1 << clock_bits), r2
+ mov #(1 << nwaiters_shift), r2
mov.l @(cond_nwaiters,r8),r0
sub r2, r0
mov.l r0,@(cond_nwaiters,r8)
@@ -334,7 +346,7 @@ __pthread_cond_timedwait:
not r0, r0
cmp/eq #0, r0
bf/s 25f
- mov #((1 << clock_bits) - 1), r1
+ mov #((1 << nwaiters_shift) - 1), r1
not r1, r1
mov.l @(cond_nwaiters,r8),r0
tst r1, r0
@@ -342,7 +354,22 @@ __pthread_cond_timedwait:
mov r8, r4
add #cond_nwaiters, r4
- mov #FUTEX_WAKE, r5
+ mov.l @(dep_mutex,r8), r0
+ cmp/eq #-1, r0
+ bt/s 99f
+ mov #FUTEX_WAKE, r5
+#ifdef __ASSUME_PRIVATE_FUTEX
+ mov #(FUTEX_WAKE|FUTEX_PRIVATE_FLAG), r5
+ extu.b r5, r5
+#else
+ stc gbr, r1
+ mov.w .Lpfoff, r2
+ add r2, r1
+ mov.l @r1, r5
+ mov #FUTEX_WAKE, r0
+ or r0, r5
+#endif
+99:
mov #1, r6
mov #0, r7
mov #SYS_futex, r3
@@ -382,6 +409,10 @@ __pthread_cond_timedwait:
rts
mov.l @r15+, r8
+#ifndef __ASSUME_PRIVATE_FUTEX
+.Lpfoff:
+ .word PRIVATE_FUTEX - TLS_PRE_TCB_SIZE
+#endif
.L1k:
.word 1000
.align 2
@@ -402,10 +433,17 @@ __pthread_cond_timedwait:
#if cond_lock != 0
add #cond_lock, r5
#endif
- mov.l .Lmwait2, r1
+ mov.l @(dep_mutex,r8), r0
+ cmp/eq #-1, r0
+ bf/s 99f
+ mov #LLL_PRIVATE, r6
+ mov #LLL_SHARED, r6
+99:
+ extu.b r6, r6
+ mov.l .Lwait2, r1
bsrf r1
mov r2, r4
-.Lmwait2b:
+.Lwait2b:
bra 2b
nop
@@ -415,10 +453,16 @@ __pthread_cond_timedwait:
#if cond_lock != 0
add #cond_lock, r4
#endif
- mov.l .Lmwake2, r1
+ mov.l @(dep_mutex,r8), r0
+ cmp/eq #-1, r0
+ bf/s 99f
+ mov #LLL_PRIVATE, r5
+ mov #LLL_SHARED, r5
+99:
+ mov.l .Lmwait2, r1
bsrf r1
- nop
-.Lmwake2b:
+ extu.b r5, r5
+.Lmwait2b:
bra 4b
nop
@@ -428,10 +472,17 @@ __pthread_cond_timedwait:
#if cond_lock != 0
add #cond_lock, r5
#endif
- mov.l .Lmwait3, r1
+ mov.l @(dep_mutex,r8), r0
+ cmp/eq #-1, r0
+ bf/s 99f
+ mov #LLL_PRIVATE, r6
+ mov #LLL_SHARED, r6
+99:
+ extu.b r6, r6
+ mov.l .Lwait3, r1
bsrf r1
mov r2, r4
-.Lmwait3b:
+.Lwait3b:
bra 6b
nop
@@ -441,10 +492,16 @@ __pthread_cond_timedwait:
#if cond_lock != 0
add #cond_lock, r4
#endif
- mov.l .Lmwake3, r1
+ mov.l @(dep_mutex,r8), r0
+ cmp/eq #-1, r0
+ bf/s 99f
+ mov #LLL_PRIVATE, r5
+ mov #LLL_SHARED, r5
+99:
+ mov.l .Lmwait3, r1
bsrf r1
- nop
-.Lmwake3b:
+ extu.b r5, r5
+.Lmwait3b:
bra 11b
nop
@@ -463,25 +520,31 @@ __pthread_cond_timedwait:
#if cond_lock != 0
add #cond_lock, r4
#endif
- mov.l .Lmwake4, r1
+ mov.l @(dep_mutex,r8), r0
+ cmp/eq #-1, r0
+ bf/s 99f
+ mov #LLL_PRIVATE, r5
+ mov #LLL_SHARED, r5
+99:
+ mov.l .Lmwait4, r1
bsrf r1
- nop
-.Lmwake4b:
+ extu.b r5, r5
+.Lmwait4b:
17:
bra 18b
mov.l @(24,r15), r0
.align 2
+.Lwait2:
+ .long __lll_lock_wait-.Lwait2b
.Lmwait2:
- .long __lll_mutex_lock_wait-.Lmwait2b
-.Lmwake2:
- .long __lll_mutex_unlock_wake-.Lmwake2b
+ .long __lll_unlock_wake-.Lmwait2b
+.Lwait3:
+ .long __lll_lock_wait-.Lwait3b
.Lmwait3:
- .long __lll_mutex_lock_wait-.Lmwait3b
-.Lmwake3:
- .long __lll_mutex_unlock_wake-.Lmwake3b
-.Lmwake4:
- .long __lll_mutex_unlock_wake-.Lmwake4b
+ .long __lll_unlock_wake-.Lmwait3b
+.Lmwait4:
+ .long __lll_unlock_wake-.Lmwait4b
.size __pthread_cond_timedwait, .-__pthread_cond_timedwait
weak_alias (__pthread_cond_timedwait, pthread_cond_timedwait)
@@ -505,10 +568,17 @@ __condvar_tw_cleanup:
#if cond_lock != 0
add #cond_lock, r5
#endif
- mov.l .Lmwait5, r1
+ mov.l @(dep_mutex,r8), r0
+ cmp/eq #-1, r0
+ bf/s 99f
+ mov #LLL_PRIVATE, r6
+ mov #LLL_SHARED, r6
+99:
+ extu.b r6, r6
+ mov.l .Lwait5, r1
bsrf r1
mov r2, r4
-.Lmwait5b:
+.Lwait5b:
1:
mov.l @(broadcast_seq,r8), r0
@@ -519,6 +589,21 @@ __condvar_tw_cleanup:
mov #1, r2
mov #0, r3
+ /* We increment the wakeup_seq counter only if it is lower than
+ total_seq. If this is not the case the thread was woken and
+ then canceled. In this case we ignore the signal. */
+ mov.l @(total_seq+4,r8), r0
+ mov.l @(wakeup_seq+4,r8), r1
+ cmp/hi r1, r0
+ bt/s 6f
+ cmp/hi r0, r1
+ bt 7f
+ mov.l @(total_seq,r8), r0
+ mov.l @(wakeup_seq,r8), r1
+ cmp/hs r0, r1
+ bt 7f
+
+6:
clrt
mov.l @(wakeup_seq,r8),r0
mov.l @(wakeup_seq+4,r8),r1
@@ -530,6 +615,7 @@ __condvar_tw_cleanup:
add r2, r0
mov.l r0,@(cond_futex,r8)
+7:
clrt
mov.l @(woken_seq,r8),r0
mov.l @(woken_seq+4,r8),r1
@@ -539,7 +625,7 @@ __condvar_tw_cleanup:
mov.l r1,@(woken_seq+4,r8)
3:
- mov #(1 << clock_bits), r2
+ mov #(1 << nwaiters_shift), r2
mov.l @(cond_nwaiters,r8),r0
sub r2, r0
mov.l r0,@(cond_nwaiters,r8)
@@ -552,7 +638,7 @@ __condvar_tw_cleanup:
not r0, r0
cmp/eq #0, r0
bf/s 4f
- mov #((1 << clock_bits) - 1), r1
+ mov #((1 << nwaiters_shift) - 1), r1
not r1, r1
mov.l @(cond_nwaiters,r8),r0
tst r1, r0
@@ -582,10 +668,16 @@ __condvar_tw_cleanup:
#if cond_lock != 0
add #cond_lock, r4
#endif
- mov.l .Lmwake5, r1
+ mov.l @(dep_mutex,r8), r0
+ cmp/eq #-1, r0
+ bf/s 99f
+ mov #LLL_PRIVATE, r5
+ mov #LLL_SHARED, r5
+99:
+ mov.l .Lmwait5, r1
bsrf r1
- nop
-.Lmwake5b:
+ extu.b r5, r5
+.Lmwait5b:
2:
/* Wake up all waiters to make sure no signal gets lost. */
@@ -618,10 +710,10 @@ __condvar_tw_cleanup:
sleep
.align 2
+.Lwait5:
+ .long __lll_lock_wait-.Lwait5b
.Lmwait5:
- .long __lll_mutex_lock_wait-.Lmwait5b
-.Lmwake5:
- .long __lll_mutex_unlock_wake-.Lmwake5b
+ .long __lll_unlock_wake-.Lmwait5b
.Lmlocki5:
.long __pthread_mutex_cond_lock-.Lmlocki5b
.Lresume:
diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/sh/pthread_cond_wait.S b/libpthread/nptl/sysdeps/unix/sysv/linux/sh/pthread_cond_wait.S
index c7df9bf86..5a897f6fe 100644
--- a/libpthread/nptl/sysdeps/unix/sysv/linux/sh/pthread_cond_wait.S
+++ b/libpthread/nptl/sysdeps/unix/sysv/linux/sh/pthread_cond_wait.S
@@ -1,4 +1,4 @@
-/* Copyright (C) 2003, 2004 Free Software Foundation, Inc.
+/* Copyright (C) 2003, 2004, 2006, 2007 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
@@ -17,13 +17,12 @@
02111-1307 USA. */
#include <sysdep.h>
+#include <lowlevellock.h>
#include <lowlevelcond.h>
+#include <tcb-offsets.h>
+#include <bits/kernel-features.h>
#include "lowlevel-atomic.h"
-#define FUTEX_WAIT 0
-#define FUTEX_WAKE 1
-
-
.text
/* int pthread_cond_wait (pthread_cond_t *cond, pthread_mutex_t *mutex) */
@@ -105,7 +104,7 @@ __pthread_cond_wait:
mov.l @(cond_futex,r8),r0
add r2, r0
mov.l r0,@(cond_futex,r8)
- mov #(1 << clock_bits), r2
+ mov #(1 << nwaiters_shift), r2
mov.l @(cond_nwaiters,r8), r0
add r2, r0
mov.l r0, @(cond_nwaiters,r8)
@@ -137,7 +136,22 @@ __pthread_cond_wait:
mov.l r0, @r15
mov #0, r7
- mov #FUTEX_WAIT, r5
+ mov.l @(dep_mutex,r8), r0
+ cmp/eq #-1, r0
+ bt/s 99f
+ mov #FUTEX_WAIT, r5
+#ifdef __ASSUME_PRIVATE_FUTEX
+ mov #(FUTEX_WAIT|FUTEX_PRIVATE_FLAG), r5
+ extu.b r5, r5
+#else
+ stc gbr, r1
+ mov.w .Lpfoff0, r2
+ add r2, r1
+ mov.l @r1, r5
+ mov #FUTEX_WAIT, r0
+ or r0, r5
+#endif
+99:
mov.l @(8,r15), r6
mov r8, r4
add #cond_futex, r4
@@ -195,7 +209,7 @@ __pthread_cond_wait:
mov.l r1,@(woken_seq+4,r8)
16:
- mov #(1 << clock_bits), r2
+ mov #(1 << nwaiters_shift), r2
mov.l @(cond_nwaiters,r8),r0
sub r2, r0
mov.l r0,@(cond_nwaiters,r8)
@@ -207,7 +221,7 @@ __pthread_cond_wait:
not r0, r0
cmp/eq #0, r0
bf/s 17f
- mov #((1 << clock_bits) - 1), r1
+ mov #((1 << nwaiters_shift) - 1), r1
not r1, r1
mov.l @(cond_nwaiters,r8),r0
tst r1, r0
@@ -215,7 +229,22 @@ __pthread_cond_wait:
mov r8, r4
add #cond_nwaiters, r4
- mov #FUTEX_WAKE, r5
+ mov.l @(dep_mutex,r8), r0
+ cmp/eq #-1, r0
+ bt/s 99f
+ mov #FUTEX_WAKE, r5
+#ifdef __ASSUME_PRIVATE_FUTEX
+ mov #(FUTEX_WAKE|FUTEX_PRIVATE_FLAG), r5
+ extu.b r5, r5
+#else
+ stc gbr, r1
+ mov.w .Lpfoff0, r2
+ add r2, r1
+ mov.l @r1, r5
+ mov #FUTEX_WAKE, r0
+ or r0, r5
+#endif
+99:
mov #1, r6
mov #0, r7
mov #SYS_futex, r3
@@ -249,6 +278,10 @@ __pthread_cond_wait:
rts
mov.l @r15+, r8
+#ifndef __ASSUME_PRIVATE_FUTEX
+.Lpfoff0:
+ .word PRIVATE_FUTEX - TLS_PRE_TCB_SIZE
+#endif
.align 2
.Lmunlock0:
.long __pthread_mutex_unlock_usercnt-.Lmunlock0b
@@ -265,10 +298,17 @@ __pthread_cond_wait:
#if cond_lock != 0
add #cond_lock, r5
#endif
- mov.l .Lmwait0, r1
+ mov.l @(dep_mutex,r8), r0
+ cmp/eq #-1, r0
+ bf/s 99f
+ mov #LLL_PRIVATE, r6
+ mov #LLL_SHARED, r6
+99:
+ extu.b r6, r6
+ mov.l .Lwait0, r1
bsrf r1
mov r2, r4
-.Lmwait0b:
+.Lwait0b:
bra 2b
nop
3:
@@ -277,10 +317,16 @@ __pthread_cond_wait:
#if cond_lock != 0
add #cond_lock, r4
#endif
- mov.l .Lmwake0, r1
+ mov.l @(dep_mutex,r8), r0
+ cmp/eq #-1, r0
+ bf/s 99f
+ mov #LLL_PRIVATE, r5
+ mov #LLL_SHARED, r5
+99:
+ mov.l .Lwake0, r1
bsrf r1
- nop
-.Lmwake0b:
+ extu.b r5, r5
+.Lwake0b:
bra 4b
nop
@@ -290,10 +336,17 @@ __pthread_cond_wait:
#if cond_lock != 0
add #cond_lock, r5
#endif
- mov.l .Lmwait1, r1
+ mov.l @(dep_mutex,r8), r0
+ cmp/eq #-1, r0
+ bf/s 99f
+ mov #LLL_PRIVATE, r6
+ mov #LLL_SHARED, r6
+99:
+ extu.b r6, r6
+ mov.l .Lwait1, r1
bsrf r1
mov r2, r4
-.Lmwait1b:
+.Lwait1b:
bra 6b
nop
@@ -303,10 +356,16 @@ __pthread_cond_wait:
#if cond_lock != 0
add #cond_lock, r4
#endif
- mov.l .Lmwake1, r1
+ mov.l @(dep_mutex,r8), r0
+ cmp/eq #-1, r0
+ bf/s 99f
+ mov #LLL_PRIVATE, r5
+ mov #LLL_SHARED, r5
+99:
+ mov.l .Lwake1, r1
bsrf r1
- nop
-.Lmwake1b:
+ extu.b r5, r5
+.Lwake1b:
bra 11b
nop
@@ -325,26 +384,32 @@ __pthread_cond_wait:
#if cond_lock != 0
add #cond_lock, r4
#endif
- mov.l .Lmwake2, r1
+ mov.l @(dep_mutex,r8), r0
+ cmp/eq #-1, r0
+ bf/s 99f
+ mov #LLL_PRIVATE, r5
+ mov #LLL_SHARED, r5
+99:
+ mov.l .Lwake2, r1
bsrf r1
- nop
-.Lmwake2b:
+ extu.b r5, r5
+.Lwake2b:
13:
bra 14b
mov.l @(12,r15), r0
.align 2
-.Lmwait0:
- .long __lll_mutex_lock_wait-.Lmwait0b
-.Lmwake0:
- .long __lll_mutex_unlock_wake-.Lmwake0b
-.Lmwait1:
- .long __lll_mutex_lock_wait-.Lmwait1b
-.Lmwake1:
- .long __lll_mutex_unlock_wake-.Lmwake1b
-.Lmwake2:
- .long __lll_mutex_unlock_wake-.Lmwake2b
+.Lwait0:
+ .long __lll_lock_wait-.Lwait0b
+.Lwake0:
+ .long __lll_unlock_wake-.Lwake0b
+.Lwait1:
+ .long __lll_lock_wait-.Lwait1b
+.Lwake1:
+ .long __lll_unlock_wake-.Lwake1b
+.Lwake2:
+ .long __lll_unlock_wake-.Lwake2b
.size __pthread_cond_wait, .-__pthread_cond_wait
weak_alias (__pthread_cond_wait, pthread_cond_wait)
@@ -368,10 +433,17 @@ __condvar_w_cleanup:
#if cond_lock != 0
add #cond_lock, r5
#endif
- mov.l .Lmwait3, r1
+ mov.l @(dep_mutex,r8), r0
+ cmp/eq #-1, r0
+ bf/s 99f
+ mov #LLL_PRIVATE, r6
+ mov #LLL_SHARED, r6
+99:
+ extu.b r6, r6
+ mov.l .Lwait3, r1
bsrf r1
mov r2, r4
-.Lmwait3b:
+.Lwait3b:
1:
mov.l @(broadcast_seq,r8), r0
@@ -382,6 +454,21 @@ __condvar_w_cleanup:
mov #1, r2
mov #0, r3
+ /* We increment the wakeup_seq counter only if it is lower than
+ total_seq. If this is not the case the thread was woken and
+ then canceled. In this case we ignore the signal. */
+ mov.l @(total_seq+4,r8), r0
+ mov.l @(wakeup_seq+4,r8), r1
+ cmp/hi r1, r0
+ bt/s 6f
+ cmp/hi r0, r1
+ bt 7f
+ mov.l @(total_seq,r8), r0
+ mov.l @(wakeup_seq,r8), r1
+ cmp/hs r0, r1
+ bt 7f
+
+6:
clrt
mov.l @(wakeup_seq,r8),r0
mov.l @(wakeup_seq+4,r8),r1
@@ -393,6 +480,7 @@ __condvar_w_cleanup:
add r2, r0
mov.l r0,@(cond_futex,r8)
+7:
clrt
mov.l @(woken_seq,r8),r0
mov.l @(woken_seq+4,r8),r1
@@ -402,7 +490,7 @@ __condvar_w_cleanup:
mov.l r1,@(woken_seq+4,r8)
3:
- mov #(1 << clock_bits), r2
+ mov #(1 << nwaiters_shift), r2
mov.l @(cond_nwaiters,r8),r0
sub r2, r0
mov.l r0,@(cond_nwaiters,r8)
@@ -415,7 +503,7 @@ __condvar_w_cleanup:
not r0, r0
cmp/eq #0, r0
bf/s 4f
- mov #((1 << clock_bits) - 1), r1
+ mov #((1 << nwaiters_shift) - 1), r1
not r1, r1
mov.l @(cond_nwaiters,r8),r0
tst r1, r0
@@ -423,7 +511,22 @@ __condvar_w_cleanup:
mov r8, r4
add #cond_nwaiters, r4
- mov #FUTEX_WAKE, r5
+ mov.l @(dep_mutex,r8), r0
+ cmp/eq #-1, r0
+ bt/s 99f
+ mov #FUTEX_WAKE, r5
+#ifdef __ASSUME_PRIVATE_FUTEX
+ mov #(FUTEX_WAKE|FUTEX_PRIVATE_FLAG), r5
+ extu.b r5, r5
+#else
+ stc gbr, r1
+ mov.w .Lpfoff1, r2
+ add r2, r1
+ mov.l @r1, r5
+ mov #FUTEX_WAKE, r0
+ or r0, r5
+#endif
+99:
mov #1, r6
mov #0, r7
mov #SYS_futex, r3
@@ -445,10 +548,16 @@ __condvar_w_cleanup:
#if cond_lock != 0
add #cond_lock, r4
#endif
- mov.l .Lmwake3, r1
+ mov.l @(dep_mutex,r8), r0
+ cmp/eq #-1, r0
+ bf/s 99f
+ mov #LLL_PRIVATE, r5
+ mov #LLL_SHARED, r5
+99:
+ mov.l .Lwake3, r1
bsrf r1
- nop
-.Lmwake3b:
+ extu.b r5, r5
+.Lwake3b:
2:
/* Wake up all waiters to make sure no signal gets lost. */
@@ -456,7 +565,22 @@ __condvar_w_cleanup:
bf/s 5f
mov r8, r4
add #cond_futex, r4
- mov #FUTEX_WAKE, r5
+ mov.l @(dep_mutex,r8), r0
+ cmp/eq #-1, r0
+ bt/s 99f
+ mov #FUTEX_WAKE, r5
+#ifdef __ASSUME_PRIVATE_FUTEX
+ mov #(FUTEX_WAKE|FUTEX_PRIVATE_FLAG), r5
+ extu.b r5, r5
+#else
+ stc gbr, r1
+ mov.w .Lpfoff1, r2
+ add r2, r1
+ mov.l @r1, r5
+ mov #FUTEX_WAKE, r0
+ or r0, r5
+#endif
+99:
mov #-1, r6
shlr r6 /* r6 = 0x7fffffff */
mov #0, r7
@@ -480,11 +604,15 @@ __condvar_w_cleanup:
mov r11, r4
sleep
+#ifndef __ASSUME_PRIVATE_FUTEX
+.Lpfoff1:
+ .word PRIVATE_FUTEX - TLS_PRE_TCB_SIZE
+#endif
.align 2
-.Lmwait3:
- .long __lll_mutex_lock_wait-.Lmwait3b
-.Lmwake3:
- .long __lll_mutex_unlock_wake-.Lmwake3b
+.Lwait3:
+ .long __lll_lock_wait-.Lwait3b
+.Lwake3:
+ .long __lll_unlock_wake-.Lwake3b
.Lmlocki3:
.long __pthread_mutex_cond_lock-.Lmlocki3b
.Lresume:
diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/sh/pthread_once.S b/libpthread/nptl/sysdeps/unix/sysv/linux/sh/pthread_once.S
index de83dec1b..caebb935a 100644
--- a/libpthread/nptl/sysdeps/unix/sysv/linux/sh/pthread_once.S
+++ b/libpthread/nptl/sysdeps/unix/sysv/linux/sh/pthread_once.S
@@ -1,4 +1,4 @@
-/* Copyright (C) 2003, 2004 Free Software Foundation, Inc.
+/* Copyright (C) 2003, 2004, 2007 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
@@ -18,10 +18,10 @@
#include <unwindbuf.h>
#include <sysdep.h>
+#include <bits/kernel-features.h>
+#include <lowlevellock.h>
#include "lowlevel-atomic.h"
-#define FUTEX_WAIT 0
-#define FUTEX_WAKE 1
.comm __fork_generation, 4, 4
@@ -94,7 +94,19 @@ __pthread_once:
bf 3f /* Different for generation -> run initializer. */
/* Somebody else got here first. Wait. */
- mov #FUTEX_WAIT, r5
+#ifdef __ASSUME_PRIVATE_FUTEX
+ mov #(FUTEX_PRIVATE_FLAG|FUTEX_WAIT), r5
+ extu.b r5, r5
+#else
+ stc gbr, r1
+ mov.w .Lpfoff, r2
+ add r2, r1
+ mov.l @r1, r5
+# if FUTEX_WAIT != 0
+ mov #FUTEX_WAIT, r0
+ or r0, r5
+# endif
+#endif
mov r3, r6
mov #0, r7
mov #SYS_futex, r3
@@ -156,7 +168,17 @@ __pthread_once:
INC (@r9, r2)
/* Wake up all other threads. */
mov r9, r4
- mov #FUTEX_WAKE, r5
+#ifdef __ASSUME_PRIVATE_FUTEX
+ mov #(FUTEX_PRIVATE_FLAG|FUTEX_WAKE), r5
+ extu.b r5, r5
+#else
+ stc gbr, r1
+ mov.w .Lpfoff, r2
+ add r2, r1
+ mov.l @r1, r5
+ mov #FUTEX_WAKE, r0
+ or r0, r5
+#endif
mov #-1, r6
shlr r6 /* r6 = 0x7fffffff */
mov #0, r7
@@ -191,7 +213,17 @@ __pthread_once:
mov #0, r7
mov.l r7, @r9
mov r9, r4
- mov #FUTEX_WAKE, r5
+#ifdef __ASSUME_PRIVATE_FUTEX
+ mov #(FUTEX_PRIVATE_FLAG|FUTEX_WAKE), r5
+#else
+ stc gbr, r1
+ mov.w .Lpfoff, r2
+ add r2, r1
+ mov.l @r1, r5
+ mov #FUTEX_WAKE, r0
+ or r0, r5
+#endif
+ extu.b r5, r5
mov #-1, r6
shlr r6 /* r6 = 0x7fffffff */
mov #SYS_futex, r3
@@ -207,6 +239,10 @@ __pthread_once:
sleep
cfi_endproc
+#ifndef __ASSUME_PRIVATE_FUTEX
+.Lpfoff:
+ .word PRIVATE_FUTEX - TLS_PRE_TCB_SIZE
+#endif
.align 2
.Lsigsetjmp:
.long __sigsetjmp@PLT-(.Lsigsetjmp0-.)
@@ -223,23 +259,3 @@ __pthread_once_internal = __pthread_once
.globl pthread_once
pthread_once = __pthread_once
-
-
- .type clear_once_control,@function
- .align 5
-clear_once_control:
- mov #0, r0
- mov.l r0, @r4
-
- mov #FUTEX_WAKE, r5
- mov #-1, r6
- shlr r6 /* r6 = 0x7fffffff */
- mov #0, r7
- mov #SYS_futex, r3
- extu.b r3, r3
- trapa #0x14
- SYSCALL_INST_PAD
-
- rts
- nop
- .size clear_once_control,.-clear_once_control
diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/sh/pthread_rwlock_rdlock.S b/libpthread/nptl/sysdeps/unix/sysv/linux/sh/pthread_rwlock_rdlock.S
index ce1ab37c8..52fe5de10 100644
--- a/libpthread/nptl/sysdeps/unix/sysv/linux/sh/pthread_rwlock_rdlock.S
+++ b/libpthread/nptl/sysdeps/unix/sysv/linux/sh/pthread_rwlock_rdlock.S
@@ -1,4 +1,4 @@
-/* Copyright (C) 2003 Free Software Foundation, Inc.
+/* Copyright (C) 2003, 2007 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
@@ -17,14 +17,13 @@
02111-1307 USA. */
#include <sysdep.h>
+#include <lowlevellock.h>
#include <lowlevelrwlock.h>
#include <pthread-errnos.h>
#include <tcb-offsets.h>
+#include <bits/kernel-features.h>
#include "lowlevel-atomic.h"
-#define FUTEX_WAIT 0
-#define FUTEX_WAKE 1
-
.text
@@ -54,7 +53,8 @@ __pthread_rwlock_rdlock:
mov.l @(WRITERS_QUEUED,r8), r0
tst r0, r0
bt 5f
- mov.l @(FLAGS,r8), r0
+ mov #FLAGS, r0
+ mov.b @(r0,r8), r0
tst r0, r0
bt 5f
3:
@@ -74,9 +74,28 @@ __pthread_rwlock_rdlock:
tst r2, r2
bf 10f
11:
+#ifdef __ASSUME_PRIVATE_FUTEX
+ mov #PSHARED, r0
+ mov.b @(r0,r8), r5
+ mov #(FUTEX_PRIVATE_FLAG|FUTEX_WAIT), r0
+ xor r0, r5
+ extu.b r5, r5
+#else
+ mov #PSHARED, r0
+ mov.b @(r0,r8), r5
+ extu.b r5, r5
+# if FUTEX_WAIT != 0
+ mov #FUTEX_WAIT, r0
+ or r0, r5
+# endif
+ stc gbr, r1
+ mov.w .Lpfoff, r2
+ add r2, r1
+ mov.l @r1, r0
+ xor r0, r5
+#endif
mov r8, r4
add #READERS_WAKEUP, r4
- mov #FUTEX_WAIT, r5
mov r9, r6
mov #0, r7
mov #SYS_futex, r3
@@ -123,15 +142,22 @@ __pthread_rwlock_rdlock:
rts
mov r3, r0
+#ifndef __ASSUME_PRIVATE_FUTEX
+.Lpfoff:
+ .word PRIVATE_FUTEX - TLS_PRE_TCB_SIZE
+#endif
+
1:
mov r8, r5
#if MUTEX != 0
add #MUTEX, r5
#endif
- mov r2, r4
+ mov #PSHARED, r0
+ mov.b @(r0,r8), r6
+ extu.b r6, r6
mov.l .Lwait0, r1
bsrf r1
- nop
+ mov r2, r4
.Lwait0b:
bra 2b
nop
@@ -154,6 +180,9 @@ __pthread_rwlock_rdlock:
#if MUTEX != 0
add #MUTEX, r4
#endif
+ mov #PSHARED, r0
+ mov.b @(r0,r8), r5
+ extu.b r5, r5
mov.l .Lwake0, r1
bsrf r1
nop
@@ -182,6 +211,9 @@ __pthread_rwlock_rdlock:
#if MUTEX != 0
add #MUTEX, r4
#endif
+ mov #PSHARED, r0
+ mov.b @(r0,r8), r5
+ extu.b r5, r5
mov.l .Lwake1, r1
bsrf r1
nop
@@ -194,23 +226,25 @@ __pthread_rwlock_rdlock:
#if MUTEX != 0
add #MUTEX, r5
#endif
- mov r2, r4
+ mov #PSHARED, r0
+ mov.b @(r0,r8), r6
+ extu.b r6, r6
mov.l .Lwait1, r1
bsrf r1
- nop
+ mov r2, r4
.Lwait1b:
bra 13b
nop
.align 2
.Lwait0:
- .long __lll_mutex_lock_wait-.Lwait0b
+ .long __lll_lock_wait-.Lwait0b
.Lwake0:
- .long __lll_mutex_unlock_wake-.Lwake0b
+ .long __lll_unlock_wake-.Lwake0b
.Lwait1:
- .long __lll_mutex_lock_wait-.Lwait1b
+ .long __lll_lock_wait-.Lwait1b
.Lwake1:
- .long __lll_mutex_unlock_wake-.Lwake1b
+ .long __lll_unlock_wake-.Lwake1b
.size __pthread_rwlock_rdlock,.-__pthread_rwlock_rdlock
.globl pthread_rwlock_rdlock
diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/sh/pthread_rwlock_timedrdlock.S b/libpthread/nptl/sysdeps/unix/sysv/linux/sh/pthread_rwlock_timedrdlock.S
index 8a4e7d3bc..6e7af21e9 100644
--- a/libpthread/nptl/sysdeps/unix/sysv/linux/sh/pthread_rwlock_timedrdlock.S
+++ b/libpthread/nptl/sysdeps/unix/sysv/linux/sh/pthread_rwlock_timedrdlock.S
@@ -1,4 +1,4 @@
-/* Copyright (C) 2003 Free Software Foundation, Inc.
+/* Copyright (C) 2003, 2007, 2008 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
@@ -17,15 +17,13 @@
02111-1307 USA. */
#include <sysdep.h>
+#include <lowlevellock.h>
#include <lowlevelrwlock.h>
#include <pthread-errnos.h>
#include <tcb-offsets.h>
+#include <bits/kernel-features.h>
#include "lowlevel-atomic.h"
-#define SYS_gettimeofday __NR_gettimeofday
-#define FUTEX_WAIT 0
-#define FUTEX_WAKE 1
-
.text
@@ -58,7 +56,8 @@ pthread_rwlock_timedrdlock:
mov.l @(WRITERS_QUEUED,r8), r0
tst r0, r0
bt 5f
- mov.l @(FLAGS,r8), r0
+ mov #FLAGS, r0
+ mov.b @(r0,r8), r0
tst r0, r0
bt 5f
3:
@@ -88,7 +87,7 @@ pthread_rwlock_timedrdlock:
/* Get current time. */
mov r15, r4
mov #0, r5
- mov #SYS_gettimeofday, r3
+ mov #__NR_gettimeofday, r3
trapa #0x12
SYSCALL_INST_PAD
@@ -116,7 +115,26 @@ pthread_rwlock_timedrdlock:
/* Futex call. */
mov r15, r7
- mov #FUTEX_WAIT, r5
+#ifdef __ASSUME_PRIVATE_FUTEX
+ mov #PSHARED, r0
+ mov.b @(r0,r8), r5
+ mov #(FUTEX_PRIVATE_FLAG|FUTEX_WAIT), r0
+ xor r0, r5
+ extu.b r5, r5
+#else
+ mov #PSHARED, r0
+ mov.b @(r0,r8), r5
+ extu.b r5, r5
+# if FUTEX_WAIT != 0
+ mov #FUTEX_WAIT, r0
+ or r0, r5
+# endif
+ stc gbr, r1
+ mov.w .Lpfoff, r2
+ add r2, r1
+ mov.l @r1, r0
+ xor r0, r5
+#endif
mov r10, r6
mov r8, r4
add #READERS_WAKEUP, r4
@@ -175,6 +193,10 @@ pthread_rwlock_timedrdlock:
rts
mov r3, r0
+#ifndef __ASSUME_PRIVATE_FUTEX
+.Lpfoff:
+ .word PRIVATE_FUTEX - TLS_PRE_TCB_SIZE
+#endif
.align 2
.L1k0:
.long 1000
@@ -186,10 +208,12 @@ pthread_rwlock_timedrdlock:
#if MUTEX != 0
add #MUTEX, r5
#endif
- mov r2, r4
+ mov #PSHARED, r0
+ mov.b @(r0,r8), r6
+ extu.b r6, r6
mov.l .Lwait2, r1
bsrf r1
- nop
+ mov r2, r4
.Lwait2b:
bra 2b
nop
@@ -208,16 +232,20 @@ pthread_rwlock_timedrdlock:
.word TID - TLS_PRE_TCB_SIZE
6:
+ mov r3, r10
mov r8, r4
#if MUTEX != 0
add #MUTEX, r4
#endif
+ mov #PSHARED, r0
+ mov.b @(r0,r8), r5
+ extu.b r5, r5
mov.l .Lwake2, r1
bsrf r1
nop
.Lwake2b:
bra 7b
- mov #0, r3
+ mov r10, r3
8:
/* Overflow. */
@@ -240,6 +268,9 @@ pthread_rwlock_timedrdlock:
#if MUTEX != 0
add #MUTEX, r4
#endif
+ mov #PSHARED, r0
+ mov.b @(r0,r8), r5
+ extu.b r5, r5
mov.l .Lwake3, r1
bsrf r1
nop
@@ -248,17 +279,20 @@ pthread_rwlock_timedrdlock:
nop
12:
+ mov r3, r10
mov r8, r5
#if MUTEX != 0
add #MUTEX, r5
#endif
- mov r2, r4
+ mov #PSHARED, r0
+ mov.b @(r0,r8), r6
+ extu.b r6, r6
mov.l .Lwait3, r1
bsrf r1
- nop
+ mov r2, r4
.Lwait3b:
bra 13b
- nop
+ mov r10, r3
16:
bra 17b
@@ -270,11 +304,11 @@ pthread_rwlock_timedrdlock:
.align 2
.Lwait2:
- .long __lll_mutex_lock_wait-.Lwait2b
+ .long __lll_lock_wait-.Lwait2b
.Lwake2:
- .long __lll_mutex_unlock_wake-.Lwake2b
+ .long __lll_unlock_wake-.Lwake2b
.Lwait3:
- .long __lll_mutex_lock_wait-.Lwait3b
+ .long __lll_lock_wait-.Lwait3b
.Lwake3:
- .long __lll_mutex_unlock_wake-.Lwake3b
+ .long __lll_unlock_wake-.Lwake3b
.size pthread_rwlock_timedrdlock,.-pthread_rwlock_timedrdlock
diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/sh/pthread_rwlock_timedwrlock.S b/libpthread/nptl/sysdeps/unix/sysv/linux/sh/pthread_rwlock_timedwrlock.S
index 6284140a6..1cb7cbdde 100644
--- a/libpthread/nptl/sysdeps/unix/sysv/linux/sh/pthread_rwlock_timedwrlock.S
+++ b/libpthread/nptl/sysdeps/unix/sysv/linux/sh/pthread_rwlock_timedwrlock.S
@@ -1,4 +1,4 @@
-/* Copyright (C) 2003 Free Software Foundation, Inc.
+/* Copyright (C) 2003, 2007, 2008 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
@@ -17,15 +17,13 @@
02111-1307 USA. */
#include <sysdep.h>
+#include <lowlevellock.h>
#include <lowlevelrwlock.h>
#include <pthread-errnos.h>
#include <tcb-offsets.h>
+#include <bits/kernel-features.h>
#include "lowlevel-atomic.h"
-#define SYS_gettimeofday __NR_gettimeofday
-#define FUTEX_WAIT 0
-#define FUTEX_WAKE 1
-
.text
@@ -85,7 +83,7 @@ pthread_rwlock_timedwrlock:
/* Get current time. */
mov r15, r4
mov #0, r5
- mov #SYS_gettimeofday, r3
+ mov #__NR_gettimeofday, r3
trapa #0x12
SYSCALL_INST_PAD
@@ -113,7 +111,26 @@ pthread_rwlock_timedwrlock:
/* Futex call. */
mov r15, r7
- mov #FUTEX_WAIT, r5
+#ifdef __ASSUME_PRIVATE_FUTEX
+ mov #PSHARED, r0
+ mov.b @(r0,r8), r5
+ mov #(FUTEX_PRIVATE_FLAG|FUTEX_WAIT), r0
+ xor r0, r5
+ extu.b r5, r5
+#else
+ mov #PSHARED, r0
+ mov.b @(r0,r8), r5
+ extu.b r5, r5
+# if FUTEX_WAIT != 0
+ mov #FUTEX_WAIT, r0
+ or r0, r5
+# endif
+ stc gbr, r1
+ mov.w .Lpfoff, r2
+ add r2, r1
+ mov.l @r1, r0
+ xor r0, r5
+#endif
mov r10, r6
mov r8, r4
add #WRITERS_WAKEUP, r4
@@ -174,6 +191,10 @@ pthread_rwlock_timedwrlock:
rts
mov r3, r0
+#ifndef __ASSUME_PRIVATE_FUTEX
+.Lpfoff:
+ .word PRIVATE_FUTEX - TLS_PRE_TCB_SIZE
+#endif
.L1k1:
.word 1000
.align 2
@@ -185,10 +206,12 @@ pthread_rwlock_timedwrlock:
#if MUTEX != 0
add #MUTEX, r5
#endif
- mov r2, r4
+ mov #PSHARED, r0
+ mov.b @(r0,r8), r6
+ extu.b r6, r6
mov.l .Lwait6, r1
bsrf r1
- nop
+ mov r2, r4
.Lwait6b:
bra 2b
nop
@@ -202,16 +225,20 @@ pthread_rwlock_timedwrlock:
bra 9b
mov #EDEADLK, r3
6:
+ mov r3, r10
mov r8, r4
#if MUTEX != 0
add #MUTEX, r4
#endif
+ mov #PSHARED, r0
+ mov.b @(r0,r8), r5
+ extu.b r5, r5
mov.l .Lwake6, r1
bsrf r1
nop
.Lwake6b:
bra 7b
- mov #0, r3
+ mov r10, r3
.Ltidoff:
.word TID - TLS_PRE_TCB_SIZE
@@ -229,6 +256,9 @@ pthread_rwlock_timedwrlock:
#if MUTEX != 0
add #MUTEX, r4
#endif
+ mov #PSHARED, r0
+ mov.b @(r0,r8), r5
+ extu.b r5, r5
mov.l .Lwake7, r1
bsrf r1
nop
@@ -237,17 +267,20 @@ pthread_rwlock_timedwrlock:
nop
12:
+ mov r3, r10
mov r8, r5
#if MUTEX != 0
add #MUTEX, r5
#endif
- mov r2, r4
+ mov #PSHARED, r0
+ mov.b @(r0,r8), r6
+ extu.b r6, r6
mov.l .Lwait7, r1
bsrf r1
- nop
+ mov r2, r4
.Lwait7b:
bra 13b
- nop
+ mov r10, r3
16:
bra 17b
@@ -255,11 +288,11 @@ pthread_rwlock_timedwrlock:
.align 2
.Lwait6:
- .long __lll_mutex_lock_wait-.Lwait6b
+ .long __lll_lock_wait-.Lwait6b
.Lwake6:
- .long __lll_mutex_unlock_wake-.Lwake6b
+ .long __lll_unlock_wake-.Lwake6b
.Lwait7:
- .long __lll_mutex_lock_wait-.Lwait7b
+ .long __lll_lock_wait-.Lwait7b
.Lwake7:
- .long __lll_mutex_unlock_wake-.Lwake7b
+ .long __lll_unlock_wake-.Lwake7b
.size pthread_rwlock_timedwrlock,.-pthread_rwlock_timedwrlock
diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/sh/pthread_rwlock_unlock.S b/libpthread/nptl/sysdeps/unix/sysv/linux/sh/pthread_rwlock_unlock.S
index 74f32f8f9..239090b20 100644
--- a/libpthread/nptl/sysdeps/unix/sysv/linux/sh/pthread_rwlock_unlock.S
+++ b/libpthread/nptl/sysdeps/unix/sysv/linux/sh/pthread_rwlock_unlock.S
@@ -1,4 +1,4 @@
-/* Copyright (C) 2003 Free Software Foundation, Inc.
+/* Copyright (C) 2003, 2007 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
@@ -17,12 +17,11 @@
02111-1307 USA. */
#include <sysdep.h>
+#include <lowlevellock.h>
#include <lowlevelrwlock.h>
+#include <bits/kernel-features.h>
#include "lowlevel-atomic.h"
-#define FUTEX_WAIT 0
-#define FUTEX_WAKE 1
-
.text
@@ -86,7 +85,24 @@ __pthread_rwlock_unlock:
bf 7f
8:
- mov #FUTEX_WAKE, r5
+#ifdef __ASSUME_PRIVATE_FUTEX
+ mov #PSHARED, r0
+ mov.b @(r0,r8), r5
+ mov #(FUTEX_PRIVATE_FLAG|FUTEX_WAKE), r0
+ xor r0, r5
+ extu.b r5, r5
+#else
+ mov #PSHARED, r0
+ mov.b @(r0,r8), r5
+ extu.b r5, r5
+ mov #FUTEX_WAKE, r0
+ or r0, r5
+ stc gbr, r1
+ mov.w .Lpfoff, r2
+ add r2, r1
+ mov.l @r1, r0
+ xor r0, r5
+#endif
mov #SYS_futex, r3
mov #0, r7
extu.b r3, r3
@@ -118,10 +134,12 @@ __pthread_rwlock_unlock:
#if MUTEX != 0
add #MUTEX, r5
#endif
- mov r2, r4
+ mov #PSHARED, r0
+ mov.b @(r0,r8), r6
+ extu.b r6, r6
mov.l .Lwait8, r1
bsrf r1
- nop
+ mov r2, r4
.Lwait8b:
bra 2b
nop
@@ -130,6 +148,9 @@ __pthread_rwlock_unlock:
#if MUTEX != 0
add #MUTEX, r4
#endif
+ mov #PSHARED, r0
+ mov.b @(r0,r8), r5
+ extu.b r5, r5
mov.l .Lwake8, r1
bsrf r1
nop
@@ -144,6 +165,9 @@ __pthread_rwlock_unlock:
#if MUTEX != 0
add #MUTEX, r4
#endif
+ mov #PSHARED, r0
+ mov.b @(r0,r8), r5
+ extu.b r5, r5
mov.l .Lwake9, r1
bsrf r1
nop
@@ -153,13 +177,17 @@ __pthread_rwlock_unlock:
bra 8b
mov.l @r15+, r4
+#ifndef __ASSUME_PRIVATE_FUTEX
+.Lpfoff:
+ .word PRIVATE_FUTEX - TLS_PRE_TCB_SIZE
+#endif
.align 2
.Lwait8:
- .long __lll_mutex_lock_wait-.Lwait8b
+ .long __lll_lock_wait-.Lwait8b
.Lwake8:
- .long __lll_mutex_unlock_wake-.Lwake8b
+ .long __lll_unlock_wake-.Lwake8b
.Lwake9:
- .long __lll_mutex_unlock_wake-.Lwake9b
+ .long __lll_unlock_wake-.Lwake9b
.size __pthread_rwlock_unlock,.-__pthread_rwlock_unlock
.globl pthread_rwlock_unlock
diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/sh/pthread_rwlock_wrlock.S b/libpthread/nptl/sysdeps/unix/sysv/linux/sh/pthread_rwlock_wrlock.S
index d071f7f03..3d37fb486 100644
--- a/libpthread/nptl/sysdeps/unix/sysv/linux/sh/pthread_rwlock_wrlock.S
+++ b/libpthread/nptl/sysdeps/unix/sysv/linux/sh/pthread_rwlock_wrlock.S
@@ -1,4 +1,4 @@
-/* Copyright (C) 2003 Free Software Foundation, Inc.
+/* Copyright (C) 2003, 2007 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
@@ -17,14 +17,13 @@
02111-1307 USA. */
#include <sysdep.h>
+#include <lowlevellock.h>
#include <lowlevelrwlock.h>
#include <pthread-errnos.h>
#include <tcb-offsets.h>
+#include <bits/kernel-features.h>
#include "lowlevel-atomic.h"
-#define FUTEX_WAIT 0
-#define FUTEX_WAKE 1
-
.text
@@ -73,7 +72,26 @@ __pthread_rwlock_wrlock:
11:
mov r8, r4
add #WRITERS_WAKEUP, r4
- mov #FUTEX_WAIT, r5
+#ifdef __ASSUME_PRIVATE_FUTEX
+ mov #PSHARED, r0
+ mov.b @(r0,r8), r5
+ mov #(FUTEX_PRIVATE_FLAG|FUTEX_WAIT), r0
+ xor r0, r5
+ extu.b r5, r5
+#else
+ mov #PSHARED, r0
+ mov.b @(r0,r8), r5
+ extu.b r5, r5
+# if FUTEX_WAIT != 0
+ mov #FUTEX_WAIT, r0
+ or r0, r5
+# endif
+ stc gbr, r1
+ mov.w .Lpfoff, r2
+ add r2, r1
+ mov.l @r1, r0
+ xor r0, r5
+#endif
mov r9, r6
mov #0, r7
mov #SYS_futex, r3
@@ -123,10 +141,12 @@ __pthread_rwlock_wrlock:
#if MUTEX != 0
add #MUTEX, r5
#endif
- mov r2, r4
+ mov #PSHARED, r0
+ mov.b @(r0,r8), r6
+ extu.b r6, r6
mov.l .Lwait4, r1
bsrf r1
- nop
+ mov r2, r4
.Lwait4b:
bra 2b
nop
@@ -144,6 +164,9 @@ __pthread_rwlock_wrlock:
#if MUTEX != 0
add #MUTEX, r4
#endif
+ mov #PSHARED, r0
+ mov.b @(r0,r8), r5
+ extu.b r5, r5
mov.l .Lwake4, r1
bsrf r1
nop
@@ -151,6 +174,10 @@ __pthread_rwlock_wrlock:
bra 7b
mov #0, r3
+#ifndef __ASSUME_PRIVATE_FUTEX
+.Lpfoff:
+ .word PRIVATE_FUTEX - TLS_PRE_TCB_SIZE
+#endif
.Ltidoff:
.word TID - TLS_PRE_TCB_SIZE
@@ -166,6 +193,9 @@ __pthread_rwlock_wrlock:
#if MUTEX != 0
add #MUTEX, r4
#endif
+ mov #PSHARED, r0
+ mov.b @(r0,r8), r5
+ extu.b r5, r5
mov.l .Lwake5, r1
bsrf r1
nop
@@ -178,23 +208,25 @@ __pthread_rwlock_wrlock:
#if MUTEX != 0
add #MUTEX, r5
#endif
- mov r2, r4
+ mov #PSHARED, r0
+ mov.b @(r0,r8), r6
+ extu.b r6, r6
mov.l .Lwait5, r1
bsrf r1
- nop
+ mov r2, r4
.Lwait5b:
bra 13b
nop
.align 2
.Lwait4:
- .long __lll_mutex_lock_wait-.Lwait4b
+ .long __lll_lock_wait-.Lwait4b
.Lwake4:
- .long __lll_mutex_unlock_wake-.Lwake4b
+ .long __lll_unlock_wake-.Lwake4b
.Lwait5:
- .long __lll_mutex_lock_wait-.Lwait5b
+ .long __lll_lock_wait-.Lwait5b
.Lwake5:
- .long __lll_mutex_unlock_wake-.Lwake5b
+ .long __lll_unlock_wake-.Lwake5b
.globl pthread_rwlock_wrlock
pthread_rwlock_wrlock = __pthread_rwlock_wrlock
diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/sh/sem_post.S b/libpthread/nptl/sysdeps/unix/sysv/linux/sh/sem_post.S
index 9755b7e16..f71cd930d 100644
--- a/libpthread/nptl/sysdeps/unix/sysv/linux/sh/sem_post.S
+++ b/libpthread/nptl/sysdeps/unix/sysv/linux/sh/sem_post.S
@@ -1,4 +1,4 @@
-/* Copyright (C) 2003, 2004 Free Software Foundation, Inc.
+/* Copyright (C) 2003, 2004, 2007, 2008 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
@@ -18,22 +18,34 @@
#include <sysdep.h>
#include <pthread-errnos.h>
+#include <structsem.h>
+#include <lowlevellock.h>
#include "lowlevel-atomic.h"
-#define SYS_gettimeofday __NR_gettimeofday
-#define FUTEX_WAIT 0
-#define FUTEX_WAKE 1
-
.text
.globl __new_sem_post
.type __new_sem_post,@function
.align 5
__new_sem_post:
- INC (@r4, r6)
-
+ mov.l @(VALUE,r4), r2
+0:
+ mov.l .Lmax, r1
+ cmp/eq r1, r2
+ bt/s 3f
+ mov r2, r3
+ mov r3, r5
+ add #1, r5
+ CMPXCHG (r3, @(VALUE,r4), r5, r2)
+ bf 0b
+ mov.l @(NWAITERS,r4), r2
+ tst r2, r2
+ bt 2f
mov #FUTEX_WAKE, r5
+ mov.l @(PRIVATE,r4), r1
+ or r1, r5
+ mov #1, r6
mov #0, r7
mov #SYS_futex, r3
extu.b r3, r3
@@ -42,11 +54,20 @@ __new_sem_post:
cmp/pz r0
bf 1f
+2:
rts
mov #0, r0
1:
- mov #EINVAL, r2
+ bra 4f
+ mov #EINVAL, r2
+
+3:
+ mov #EOVERFLOW, r2
+4:
+ mov.l r12, @-r15
+ mov.l r8, @-r15
+ sts.l pr, @-r15
mova .Lgot3, r0
mov.l .Lgot3, r12
add r0, r12
@@ -55,25 +76,30 @@ __new_sem_post:
mov.l .Lerrno3, r0
stc gbr, r1
mov.l @(r0, r12), r0
- bra .Lexit
- add r1, r0
- .align 2
+ bra .Lexit
+ add r1, r0
+ .align 2
.Lerrno3:
.long errno@GOTTPOFF
.Lexit:
+ mov.l r2, @r0
#else
+ mov r2, r8
mov.l .Lerrloc3, r1
bsrf r1
nop
.Lerrloc3b:
+ mov r8, @r0
#endif
- mov.l r2, @r0
lds.l @r15+, pr
+ mov.l @r15+, r8
mov.l @r15+, r12
rts
mov #-1, r0
.align 2
+.Lmax:
+ .long SEM_VALUE_MAX
.Lgot3:
.long _GLOBAL_OFFSET_TABLE_
#if !USE___THREAD
diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/sh/sem_timedwait.S b/libpthread/nptl/sysdeps/unix/sysv/linux/sh/sem_timedwait.S
index 40782fcaf..774442f23 100644
--- a/libpthread/nptl/sysdeps/unix/sysv/linux/sh/sem_timedwait.S
+++ b/libpthread/nptl/sysdeps/unix/sysv/linux/sh/sem_timedwait.S
@@ -1,4 +1,4 @@
-/* Copyright (C) 2003, 2004 Free Software Foundation, Inc.
+/* Copyright (C) 2003, 2004, 2007 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
@@ -19,31 +19,22 @@
#include <sysdep.h>
#include <pthread-errnos.h>
#include <tcb-offsets.h>
+#include <structsem.h>
+#include <lowlevellock.h>
#include "lowlevel-atomic.h"
-#define SYS_gettimeofday __NR_gettimeofday
-#define FUTEX_WAIT 0
-#define FUTEX_WAKE 1
+#if VALUE != 0
+# error "code needs to be rewritten for VALUE != 0"
+#endif
.text
.globl sem_timedwait
.type sem_timedwait,@function
.align 5
- cfi_startproc
sem_timedwait:
- /* First check for cancellation. */
- stc gbr, r0
- mov.w .Lchand, r1
- mov.l @(r0,r1), r0
- mov #0xf9, r1
- and r1, r0
- cmp/eq #8, r0
- bf 0f
- bra 10f
- stc gbr, r0
-0:
+.LSTARTCODE:
mov.l @r4, r0
2:
tst r0, r0
@@ -60,22 +51,17 @@ sem_timedwait:
1:
/* Check whether the timeout value is valid. */
mov.l r8, @-r15
- cfi_adjust_cfa_offset(4)
- cfi_rel_offset (r8, 0)
+.Lpush_r8:
mov.l r9, @-r15
- cfi_adjust_cfa_offset(4)
- cfi_rel_offset (r9, 0)
+.Lpush_r9:
mov.l r10, @-r15
- cfi_adjust_cfa_offset(4)
- cfi_rel_offset (r10, 0)
+.Lpush_r10:
mov.l r12, @-r15
- cfi_adjust_cfa_offset(4)
- cfi_rel_offset (r12, 0)
+.Lpush_r12:
sts.l pr, @-r15
- cfi_adjust_cfa_offset(4)
- cfi_rel_offset (pr, 0)
+.Lpush_pr:
add #-8, r15
- cfi_adjust_cfa_offset(8)
+.Lalloc:
mov r4, r8
mov r5, r9
@@ -85,17 +71,13 @@ sem_timedwait:
cmp/hs r1, r0
bt/s 6f
mov #EINVAL, r0
-7:
- mov.l .Lenable0, r1
- bsrf r1
- nop
-.Lenable0b:
- mov r0, r10
+ INC (@(NWAITERS,r8),r2)
+7:
/* Compute relative timeout. */
mov r15, r4
mov #0, r5
- mov #SYS_gettimeofday, r3
+ mov #__NR_gettimeofday, r3
trapa #0x12
SYSCALL_INST_PAD
@@ -116,15 +98,27 @@ sem_timedwait:
5:
cmp/pz r2
bf/s 6f /* Time is already up. */
- mov #ETIMEDOUT, r0
+ mov #ETIMEDOUT, r0
/* Store relative timeout. */
mov.l r2, @r15
mov.l r3, @(4,r15)
- /* Futex call. */
+.LcleanupSTART:
+ mov.l .Lenable0, r1
+ bsrf r1
+ nop
+.Lenable0b:
+ mov r0, r10
+
mov r8, r4
- mov #FUTEX_WAIT, r5
+#if FUTEX_WAIT == 0
+ mov.l @(PRIVATE,r8), r5
+#else
+ mov.l @(PRIVATE,r8), r5
+ mov #FUTEX_WAIT, r0
+ or r0, r5
+#endif
mov #0, r6
mov r15, r7
mov #SYS_futex, r3
@@ -138,6 +132,7 @@ sem_timedwait:
mov r0, r10
.Ldisable0b:
mov r10, r0
+.LcleanupEND:
tst r0, r0
bt 9f
@@ -156,6 +151,10 @@ sem_timedwait:
bf/s 8b
mov r2, r0
+ DEC (@(NWAITERS,r8), r2)
+ mov #0, r0
+
+10:
add #8, r15
lds.l @r15+, pr
mov.l @r15+, r12
@@ -163,12 +162,12 @@ sem_timedwait:
mov.l @r15+, r9
mov.l @r15+, r8
rts
- mov #0, r0
+ nop
3:
neg r0, r0
6:
- mov r0, r8
+ mov r0, r10
mova .Lgot2, r0
mov.l .Lgot2, r12
add r0, r12
@@ -177,11 +176,11 @@ sem_timedwait:
mov.l .Lerrno2, r0
stc gbr, r1
mov.l @(r0, r12), r0
- bra .Lexit
- add r1, r0
- .align 2
+ bra .Lexit
+ add r1, r0
+ .align 2
.Lerrno2:
- .long errno@GOTTPOFF
+ .long errno@GOTTPOFF
.Lexit:
#else
mov.l .Lerrloc2, r1
@@ -189,39 +188,13 @@ sem_timedwait:
nop
.Lerrloc2b:
#endif
- mov.l r8, @r0
- add #8, r15
- lds.l @r15+, pr
- mov.l @r15+, r12
- mov.l @r15+, r10
- mov.l @r15+, r9
- mov.l @r15+, r8
- rts
+ mov.l r10, @r0
+ DEC (@(NWAITERS,r8), r2)
+ bra 10b
mov #-1, r0
-10:
- /* Canceled. */
- mov.w .Lresult, r1
- mov #-1, r2
- mov.l r2, @(r0,r1)
- mov.w .Lchand, r0
- or.b #0x10, @(r0,gbr)
- stc gbr, r0
- mov.w .Lclbuf, r1
- mov.l .Lunwind, r2
- braf r2
- mov.l @(r0,r1), r4
-.Lunwindb:
- cfi_endproc
-
.L1k:
.word 1000
-.Lchand:
- .word CANCELHANDLING - TLS_PRE_TCB_SIZE
-.Lresult:
- .word RESULT - TLS_PRE_TCB_SIZE
-.Lclbuf:
- .word CLEANUP_JMP_BUF - TLS_PRE_TCB_SIZE
.align 2
.L1g:
.long 1000000000
@@ -235,6 +208,151 @@ sem_timedwait:
.long __pthread_enable_asynccancel-.Lenable0b
.Ldisable0:
.long __pthread_disable_asynccancel-.Ldisable0b
-.Lunwind:
- .long HIDDEN_JUMPTARGET (__pthread_unwind)-.Lunwindb
.size sem_timedwait,.-sem_timedwait
+
+ .type sem_wait_cleanup,@function
+sem_wait_cleanup:
+ DEC (@(NWAITERS,r8), r2)
+.LcallUR:
+ mov.l .Lresume, r1
+#ifdef PIC
+ add r12, r1
+#endif
+ jsr @r1
+ nop
+ sleep
+
+ .align 2
+.Lresume:
+#ifdef PIC
+ .long _Unwind_Resume@GOTOFF
+#else
+ .long _Unwind_Resume
+#endif
+.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:
+ .ualong .LENDCIE-.LSTARTCIE ! Length of the CIE.
+.LSTARTCIE:
+ .ualong 0 ! CIE ID.
+ .byte 1 ! Version number.
+#ifdef SHARED
+ .string "zPLR" ! NUL-terminated augmentation
+ ! string.
+#else
+ .string "zPL" ! NUL-terminated augmentation
+ ! string.
+#endif
+ .uleb128 1 ! Code alignment factor.
+ .sleb128 -4 ! Data alignment factor.
+ .byte 0x11 ! 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
+ .ualong DW.ref.__gcc_personality_v0-.
+ .byte 0x1b ! LSDA Encoding: DW_EH_PE_pcrel
+ ! + DW_EH_PE_sdata4.
+ .byte 0x1b ! FDE Encoding: DW_EH_PE_pcrel
+ ! + DW_EH_PE_sdata4.
+#else
+ .uleb128 6 ! Augmentation value length.
+ .byte 0x0 ! Personality: absolute
+ .ualong __gcc_personality_v0
+ .byte 0x0 ! LSDA Encoding: absolute
+#endif
+ .byte 0x0c ! DW_CFA_def_cfa
+ .uleb128 0xf
+ .uleb128 0
+ .align 4
+.LENDCIE:
+
+ .ualong .LENDFDE-.LSTARTFDE ! Length of the FDE.
+.LSTARTFDE:
+ .ualong .LSTARTFDE-.LSTARTFRAME ! CIE pointer.
+#ifdef SHARED
+ .ualong .LSTARTCODE-. ! PC-relative start address
+ ! of the code.
+#else
+ .ualong .LSTARTCODE ! Start address of the code.
+#endif
+ .ualong .LENDCODE-.LSTARTCODE ! Length of the code.
+ .uleb128 4 ! Augmentation size
+#ifdef SHARED
+ .ualong .LexceptSTART-.
+#else
+ .ualong .LexceptSTART
+#endif
+
+ .byte 4 ! DW_CFA_advance_loc4
+ .ualong .Lpush_r8-.LSTARTCODE
+ .byte 14 ! DW_CFA_def_cfa_offset
+ .uleb128 4
+ .byte 0x88 ! DW_CFA_offset r8
+ .uleb128 1
+ .byte 4 ! DW_CFA_advance_loc4
+ .ualong .Lpush_r9-.Lpush_r8
+ .byte 14 ! DW_CFA_def_cfa_offset
+ .uleb128 8
+ .byte 0x89 ! DW_CFA_offset r9
+ .uleb128 2
+ .byte 4 ! DW_CFA_advance_loc4
+ .ualong .Lpush_r10-.Lpush_r9
+ .byte 14 ! DW_CFA_def_cfa_offset
+ .uleb128 12
+ .byte 0x8a ! DW_CFA_offset r10
+ .uleb128 3
+ .byte 4 ! DW_CFA_advance_loc4
+ .ualong .Lpush_r12-.Lpush_r10
+ .byte 14 ! DW_CFA_def_cfa_offset
+ .uleb128 16
+ .byte 0x8c ! DW_CFA_offset r12
+ .uleb128 4
+ .byte 4 ! DW_CFA_advance_loc4
+ .ualong .Lpush_pr-.Lpush_r12
+ .byte 14 ! DW_CFA_def_cfa_offset
+ .uleb128 20
+ .byte 0x91 ! DW_CFA_offset pr
+ .uleb128 5
+ .byte 4 ! DW_CFA_advance_loc4
+ .ualong .Lalloc-.Lpush_pr
+ .byte 14 ! DW_CFA_def_cfa_offset
+ .uleb128 28
+ .align 4
+.LENDFDE:
+
+
+#ifdef SHARED
+ .hidden DW.ref.__gcc_personality_v0
+ .weak DW.ref.__gcc_personality_v0
+ .section .gnu.linkonce.d.DW.ref.__gcc_personality_v0,"aw",@progbits
+ .align 4
+ .type DW.ref.__gcc_personality_v0, @object
+ .size DW.ref.__gcc_personality_v0, 4
+DW.ref.__gcc_personality_v0:
+ .long __gcc_personality_v0
+#endif
diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/sh/sem_trywait.S b/libpthread/nptl/sysdeps/unix/sysv/linux/sh/sem_trywait.S
index 00c61f3bb..b46eb1a56 100644
--- a/libpthread/nptl/sysdeps/unix/sysv/linux/sh/sem_trywait.S
+++ b/libpthread/nptl/sysdeps/unix/sysv/linux/sh/sem_trywait.S
@@ -1,4 +1,4 @@
-/* Copyright (C) 2003, 2004 Free Software Foundation, Inc.
+/* Copyright (C) 2003, 2004, 2007 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
@@ -18,6 +18,7 @@
#include <sysdep.h>
#include <pthread-errnos.h>
+#include <lowlevellock.h>
#include "lowlevel-atomic.h"
@@ -59,9 +60,9 @@ __new_sem_trywait:
mov.l .Lerrno1, r0
stc gbr, r1
mov.l @(r0, r12), r0
- bra .Lexit
- add r1, r0
- .align 2
+ bra .Lexit
+ add r1, r0
+ .align 2
.Lerrno1:
.long errno@GOTTPOFF
.Lexit:
diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/sh/sem_wait.S b/libpthread/nptl/sysdeps/unix/sysv/linux/sh/sem_wait.S
index 7d13fa130..00a125bc5 100644
--- a/libpthread/nptl/sysdeps/unix/sysv/linux/sh/sem_wait.S
+++ b/libpthread/nptl/sysdeps/unix/sysv/linux/sh/sem_wait.S
@@ -1,4 +1,4 @@
-/* Copyright (C) 2003, 2004 Free Software Foundation, Inc.
+/* Copyright (C) 2003, 2004, 2007 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
@@ -19,43 +19,32 @@
#include <sysdep.h>
#include <pthread-errnos.h>
#include <tcb-offsets.h>
+#include <structsem.h>
+#include <lowlevellock.h>
#include "lowlevel-atomic.h"
-#define SYS_gettimeofday __NR_gettimeofday
-#define FUTEX_WAIT 0
-#define FUTEX_WAKE 1
+#if VALUE != 0
+# error "code needs to be rewritten for VALUE != 0"
+#endif
.text
.globl __new_sem_wait
.type __new_sem_wait,@function
.align 5
- cfi_startproc
__new_sem_wait:
- /* First check for cancellation. */
- stc gbr, r0
- mov.w .Lchand, r1
- mov.l @(r0,r1), r0
- mov #0xf9, r1
- and r1, r0
- cmp/eq #8, r0
- bt 5f
-
+.LSTARTCODE:
mov.l r8, @-r15
- cfi_adjust_cfa_offset(4)
- cfi_rel_offset (r8, 0)
+.Lpush_r8:
mov.l r10, @-r15
- cfi_adjust_cfa_offset(4)
- cfi_rel_offset (r10, 0)
+.Lpush_r10:
mov.l r12, @-r15
- cfi_adjust_cfa_offset(4)
- cfi_rel_offset (r12, 0)
+.Lpush_r12:
sts.l pr, @-r15
- cfi_adjust_cfa_offset(4)
- cfi_rel_offset (pr, 0)
+.Lpush_pr:
mov r4, r8
-3:
+
mov.l @r8, r0
2:
tst r0, r0
@@ -66,10 +55,21 @@ __new_sem_wait:
CMPXCHG (r4, @r8, r3, r2)
bf/s 2b
mov r2, r0
- bra 9f
- mov #0, r0
+7:
+ mov #0, r0
+9:
+ lds.l @r15+, pr
+ mov.l @r15+, r12
+ mov.l @r15+, r10
+ rts
+ mov.l @r15+, r8
+.Lafter_ret:
1:
+ INC (@(NWAITERS,r8),r2)
+
+.LcleanupSTART:
+6:
mov.l .Lenable0, r1
bsrf r1
nop
@@ -77,7 +77,13 @@ __new_sem_wait:
mov r0, r10
mov r8, r4
- mov #FUTEX_WAIT, r5
+#if FUTEX_WAIT == 0
+ mov.l @(PRIVATE,r8), r5
+#else
+ mov.l @(PRIVATE,r8), r5
+ mov #FUTEX_WAIT, r0
+ or r0, r5
+#endif
mov #0, r6
mov #0, r7
mov #SYS_futex, r3
@@ -91,14 +97,35 @@ __new_sem_wait:
mov r0, r10
.Ldisable0b:
mov r10, r0
+.LcleanupEND:
tst r0, r0
- bt 3b
+ bt 3f
cmp/eq #-EWOULDBLOCK, r0
- bt 3b
- neg r0, r0
+ bf 4f
+
+3:
+ mov.l @r8, r0
+5:
+ tst r0, r0
+ bt 6b
+
+ mov r0, r3
+ mov r0, r4
+ add #-1, r3
+ CMPXCHG (r4, @r8, r3, r2)
+ bf/s 5b
+ mov r2, r0
+
+ DEC (@(NWAITERS,r8), r2)
+ bra 7b
+ nop
- mov r0, r8
+4:
+ neg r0, r0
+ mov r0, r4
+ DEC (@(NWAITERS,r8), r2)
+ mov r4, r8
mova .Lgot0, r0
mov.l .Lgot0, r12
add r0, r12
@@ -107,9 +134,9 @@ __new_sem_wait:
mov.l .Lerrno0, r0
stc gbr, r1
mov.l @(r0, r12), r0
- bra .Lexit
- add r1, r0
- .align 2
+ bra .Lexit
+ add r1, r0
+ .align 2
.Lerrno0:
.long errno@GOTTPOFF
.Lexit:
@@ -120,35 +147,9 @@ __new_sem_wait:
.Lerrloc0b:
#endif
mov.l r8, @r0
- mov #-1, r0
-9:
- lds.l @r15+, pr
- mov.l @r15+, r12
- mov.l @r15+, r10
- rts
- mov.l @r15+, r8
-5:
- /* Canceled. */
- stc gbr, r0
- mov.w .Lresult, r1
- mov #-1, r2
- mov.l r2, @(r0,r1)
- mov.w .Lchand, r0
- or.b #0x10, @(r0,gbr)
- stc gbr, r0
- mov.w .Lclbuf, r1
- mov.l .Lunwind, r2
- braf r2
- mov.l @(r0,r1), r4
-.Lunwindb:
- cfi_endproc
-
-.Lchand:
- .word CANCELHANDLING - TLS_PRE_TCB_SIZE
-.Lresult:
- .word RESULT - TLS_PRE_TCB_SIZE
-.Lclbuf:
- .word CLEANUP_JMP_BUF - TLS_PRE_TCB_SIZE
+ bra 9b
+ mov #-1, r0
+
.align 2
.Lgot0:
.long _GLOBAL_OFFSET_TABLE_
@@ -160,7 +161,143 @@ __new_sem_wait:
.long __pthread_enable_asynccancel-.Lenable0b
.Ldisable0:
.long __pthread_disable_asynccancel-.Ldisable0b
-.Lunwind:
- .long HIDDEN_JUMPTARGET (__pthread_unwind)-.Lunwindb
.size __new_sem_wait,.-__new_sem_wait
weak_alias(__new_sem_wait, sem_wait)
+
+
+ .type sem_wait_cleanup,@function
+sem_wait_cleanup:
+ DEC (@(NWAITERS,r8), r2)
+.LcallUR:
+ mov.l .Lresume, r1
+#ifdef __PIC__
+ add r12, r1
+#endif
+ jsr @r1
+ nop
+ sleep
+
+ .align 2
+.Lresume:
+#ifdef __PIC__
+ .long _Unwind_Resume@GOTOFF
+#else
+ .long _Unwind_Resume
+#endif
+.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:
+ .ualong .LENDCIE-.LSTARTCIE ! Length of the CIE.
+.LSTARTCIE:
+ .ualong 0 ! CIE ID.
+ .byte 1 ! Version number.
+#ifdef SHARED
+ .string "zPLR" ! NUL-terminated augmentation
+ ! string.
+#else
+ .string "zPL" ! NUL-terminated augmentation
+ ! string.
+#endif
+ .uleb128 1 ! Code alignment factor.
+ .sleb128 -4 ! Data alignment factor.
+ .byte 0x11 ! 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
+ .ualong DW.ref.__gcc_personality_v0-.
+ .byte 0x1b ! LSDA Encoding: DW_EH_PE_pcrel
+ ! + DW_EH_PE_sdata4.
+ .byte 0x1b ! FDE Encoding: DW_EH_PE_pcrel
+ ! + DW_EH_PE_sdata4.
+#else
+ .uleb128 6 ! Augmentation value length.
+ .byte 0x0 ! Personality: absolute
+ .ualong __gcc_personality_v0
+ .byte 0x0 ! LSDA Encoding: absolute
+#endif
+ .byte 0x0c ! DW_CFA_def_cfa
+ .uleb128 0xf
+ .uleb128 0
+ .align 4
+.LENDCIE:
+
+ .ualong .LENDFDE-.LSTARTFDE ! Length of the FDE.
+.LSTARTFDE:
+ .ualong .LSTARTFDE-.LSTARTFRAME ! CIE pointer.
+#ifdef SHARED
+ .ualong .LSTARTCODE-. ! PC-relative start address
+ ! of the code.
+#else
+ .ualong .LSTARTCODE ! Start address of the code.
+#endif
+ .ualong .LENDCODE-.LSTARTCODE ! Length of the code.
+ .uleb128 4 ! Augmentation size
+#ifdef SHARED
+ .ualong .LexceptSTART-.
+#else
+ .ualong .LexceptSTART
+#endif
+
+ .byte 4 ! DW_CFA_advance_loc4
+ .ualong .Lpush_r8-.LSTARTCODE
+ .byte 14 ! DW_CFA_def_cfa_offset
+ .uleb128 4
+ .byte 0x88 ! DW_CFA_offset r8
+ .uleb128 1
+ .byte 4 ! DW_CFA_advance_loc4
+ .ualong .Lpush_r10-.Lpush_r8
+ .byte 14 ! DW_CFA_def_cfa_offset
+ .uleb128 8
+ .byte 0x8a ! DW_CFA_offset r10
+ .uleb128 2
+ .byte 4 ! DW_CFA_advance_loc4
+ .ualong .Lpush_r12-.Lpush_r10
+ .byte 14 ! DW_CFA_def_cfa_offset
+ .uleb128 12
+ .byte 0x8c ! DW_CFA_offset r12
+ .uleb128 3
+ .byte 4 ! DW_CFA_advance_loc4
+ .ualong .Lpush_pr-.Lpush_r12
+ .byte 14 ! DW_CFA_def_cfa_offset
+ .uleb128 16
+ .byte 0x91 ! DW_CFA_offset pr
+ .uleb128 4
+ .align 4
+.LENDFDE:
+
+
+#ifdef SHARED
+ .hidden DW.ref.__gcc_personality_v0
+ .weak DW.ref.__gcc_personality_v0
+ .section .gnu.linkonce.d.DW.ref.__gcc_personality_v0,"aw",@progbits
+ .align 4
+ .type DW.ref.__gcc_personality_v0, @object
+ .size DW.ref.__gcc_personality_v0, 4
+DW.ref.__gcc_personality_v0:
+ .long __gcc_personality_v0
+#endif
diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/sh/sysdep-cancel.h b/libpthread/nptl/sysdeps/unix/sysv/linux/sh/sysdep-cancel.h
index dbaa44385..ad2ca40ac 100644
--- a/libpthread/nptl/sysdeps/unix/sysv/linux/sh/sysdep-cancel.h
+++ b/libpthread/nptl/sysdeps/unix/sysv/linux/sh/sysdep-cancel.h
@@ -1,4 +1,4 @@
-/* Copyright (C) 2003, 2004 Free Software Foundation, Inc.
+/* Copyright (C) 2003, 2004, 2005, 2006 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
@@ -49,27 +49,32 @@
.size __##syscall_name##_nocancel,.-__##syscall_name##_nocancel; \
.Lpseudo_cancel: \
sts.l pr,@-r15; \
- .LCFI0: \
+ cfi_adjust_cfa_offset (4); \
+ cfi_rel_offset (pr, 0); \
add _IMM16,r15; \
+ cfi_adjust_cfa_offset (16); \
SAVE_ARGS_##args; \
- .LCFI1: \
CENABLE; \
LOAD_ARGS_##args; \
add _IMP16,r15; \
- .LCFI2: \
+ cfi_adjust_cfa_offset (-16); \
lds.l @r15+,pr; \
- .LCFI3: \
+ cfi_adjust_cfa_offset (-4); \
+ cfi_restore (pr); \
DO_CALL(syscall_name, args); \
SYSCALL_INST_PAD; \
sts.l pr,@-r15; \
- .LCFI4: \
+ cfi_adjust_cfa_offset (4); \
+ cfi_rel_offset (pr, 0); \
mov.l r0,@-r15; \
- .LCFI5: \
+ cfi_adjust_cfa_offset (4); \
+ cfi_rel_offset (r0, 0); \
CDISABLE; \
mov.l @r15+,r0; \
- .LCFI6: \
+ cfi_adjust_cfa_offset (-4); \
lds.l @r15+,pr; \
- .LCFI7: \
+ cfi_adjust_cfa_offset (-4); \
+ cfi_restore (pr); \
mov r0,r1; \
mov _IMM12,r2; \
shad r2,r1; \
@@ -78,106 +83,17 @@
bf .Lpseudo_end; \
.Lsyscall_error: \
SYSCALL_ERROR_HANDLER; \
- .Lpseudo_end: \
- /* Create unwinding information for the syscall wrapper. */ \
- .section .eh_frame,"a",@progbits; \
- .Lframe1: \
- .ualong .LECIE1-.LSCIE1; \
- .LSCIE1: \
- .ualong 0x0; \
- .byte 0x1; \
- AUGMENTATION_STRING; \
- .uleb128 0x1; \
- .sleb128 -4; \
- .byte 0x11; \
- AUGMENTATION_PARAM; \
- .byte 0xc; \
- .uleb128 0xf; \
- .uleb128 0x0; \
- .align 2; \
- .LECIE1: \
- .LSFDE1: \
- .ualong .LEFDE1-.LASFDE1; \
- .LASFDE1: \
- .ualong .LASFDE1-.Lframe1; \
- START_SYMBOL_REF; \
- .ualong .Lpseudo_end - .Lpseudo_start; \
- AUGMENTATION_PARAM_FDE; \
- .byte 0x4; \
- .ualong .LCFI0-.Lpseudo_start; \
- .byte 0xe; \
- .uleb128 0x4; \
- .byte 0x91; \
- .uleb128 0x1; \
- .byte 0x4; \
- .ualong .LCFI1-.LCFI0; \
- .byte 0xe; \
- .uleb128 0x14; \
- FRAME_REG_##args; \
- .byte 0x4; \
- .ualong .LCFI2-.LCFI1; \
- .byte 0xe; \
- .uleb128 0x4; \
- .byte 0x4; \
- .ualong .LCFI3-.LCFI2; \
- .byte 0xe; \
- .uleb128 0x0; \
- .byte 0xd1; \
- .byte 0x4; \
- .ualong .LCFI4-.LCFI3; \
- .byte 0xe; \
- .uleb128 0x4; \
- .byte 0x91; \
- .uleb128 0x1; \
- .byte 0x4; \
- .ualong .LCFI5-.LCFI4; \
- .byte 0xe; \
- .uleb128 0x8; \
- .byte 0x80; \
- .uleb128 0x2; \
- .byte 0x4; \
- .ualong .LCFI6-.LCFI5; \
- .byte 0xe; \
- .uleb128 0x4; \
- .byte 0xc0; \
- .byte 0x4; \
- .ualong .LCFI7-.LCFI6; \
- .byte 0xe; \
- .uleb128 0x0; \
- .byte 0xd1; \
- .align 2; \
- .LEFDE1: \
- .previous
-
-# ifdef SHARED
-# define AUGMENTATION_STRING .string "zR"
-# define AUGMENTATION_PARAM .uleb128 1; .byte 0x1b
-# define AUGMENTATION_PARAM_FDE .uleb128 0
-# define START_SYMBOL_REF .long .Lpseudo_start-.
-# else
-# define AUGMENTATION_STRING .ascii "\0"
-# define AUGMENTATION_PARAM
-# define AUGMENTATION_PARAM_FDE
-# define START_SYMBOL_REF .long .Lpseudo_start
-# endif
-
-# define FRAME_REG_0 /* Nothing. */
-# define FRAME_REG_1 FRAME_REG_0; .byte 0x84; .uleb128 5
-# define FRAME_REG_2 FRAME_REG_1; .byte 0x85; .uleb128 4
-# define FRAME_REG_3 FRAME_REG_2; .byte 0x86; .uleb128 3
-# define FRAME_REG_4 FRAME_REG_3; .byte 0x87; .uleb128 2
-# define FRAME_REG_5 FRAME_REG_4
-# define FRAME_REG_6 FRAME_REG_5
+ .Lpseudo_end:
# undef PSEUDO_END
# define PSEUDO_END(sym) \
END (sym)
# define SAVE_ARGS_0 /* Nothing. */
-# define SAVE_ARGS_1 SAVE_ARGS_0; mov.l r4,@(0,r15)
-# define SAVE_ARGS_2 SAVE_ARGS_1; mov.l r5,@(4,r15)
-# define SAVE_ARGS_3 SAVE_ARGS_2; mov.l r6,@(8,r15)
-# define SAVE_ARGS_4 SAVE_ARGS_3; mov.l r7,@(12,r15)
+# define SAVE_ARGS_1 SAVE_ARGS_0; mov.l r4,@(0,r15); cfi_offset (r4,-4)
+# define SAVE_ARGS_2 SAVE_ARGS_1; mov.l r5,@(4,r15); cfi_offset (r5,-8)
+# define SAVE_ARGS_3 SAVE_ARGS_2; mov.l r6,@(8,r15); cfi_offset (r6,-12)
+# define SAVE_ARGS_4 SAVE_ARGS_3; mov.l r7,@(12,r15); cfi_offset (r7,-16)
# define SAVE_ARGS_5 SAVE_ARGS_4
# define SAVE_ARGS_6 SAVE_ARGS_5
@@ -245,3 +161,9 @@
# define NO_CANCELLATION 1
#endif
+
+#ifndef __ASSEMBLER__
+# define RTLD_SINGLE_THREAD_P \
+ __builtin_expect (THREAD_GETMEM (THREAD_SELF, \
+ header.multiple_threads) == 0, 1)
+#endif
diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/sh/vfork.S b/libpthread/nptl/sysdeps/unix/sysv/linux/sh/vfork.S
index a45c09fd6..5433eacbe 100644
--- a/libpthread/nptl/sysdeps/unix/sysv/linux/sh/vfork.S
+++ b/libpthread/nptl/sysdeps/unix/sysv/linux/sh/vfork.S
@@ -66,6 +66,6 @@ ENTRY (__vfork)
.word PID - TLS_PRE_TCB_SIZE
.align 2
PSEUDO_END (__vfork)
-hidden_def (vfork)
+libc_hidden_def (__vfork)
weak_alias (__vfork, vfork)