summaryrefslogtreecommitdiff
path: root/nptl/sysdeps/unix/sysv/linux/sh
diff options
context:
space:
mode:
Diffstat (limited to 'nptl/sysdeps/unix/sysv/linux/sh')
-rw-r--r--nptl/sysdeps/unix/sysv/linux/sh/bits/pthreadtypes.h16
-rw-r--r--nptl/sysdeps/unix/sysv/linux/sh/clone.S11
-rw-r--r--nptl/sysdeps/unix/sysv/linux/sh/lowlevellock.S30
-rw-r--r--nptl/sysdeps/unix/sysv/linux/sh/lowlevellock.h142
-rw-r--r--nptl/sysdeps/unix/sysv/linux/sh/lowlevelrobustlock.S224
-rw-r--r--nptl/sysdeps/unix/sysv/linux/sh/pthread_cond_broadcast.S8
-rw-r--r--nptl/sysdeps/unix/sysv/linux/sh/pthread_cond_timedwait.S18
-rw-r--r--nptl/sysdeps/unix/sysv/linux/sh/pthread_cond_wait.S18
-rw-r--r--nptl/sysdeps/unix/sysv/linux/sh/sh4/lowlevellock.h2
-rw-r--r--nptl/sysdeps/unix/sysv/linux/sh/sysdep-cancel.h128
10 files changed, 477 insertions, 120 deletions
diff --git a/nptl/sysdeps/unix/sysv/linux/sh/bits/pthreadtypes.h b/nptl/sysdeps/unix/sysv/linux/sh/bits/pthreadtypes.h
index 5125408dcb..969686dd5a 100644
--- a/nptl/sysdeps/unix/sysv/linux/sh/bits/pthreadtypes.h
+++ b/nptl/sysdeps/unix/sysv/linux/sh/bits/pthreadtypes.h
@@ -1,4 +1,4 @@
-/* Copyright (C) 2002, 2003, 2004 Free Software Foundation, Inc.
+/* Copyright (C) 2002, 2003, 2004, 2005, 2006 Free Software Foundation, Inc.
This file is part of the GNU C Library.
Contributed by Ulrich Drepper <drepper@redhat.com>, 2002.
@@ -44,11 +44,17 @@ typedef union
} pthread_attr_t;
+typedef struct __pthread_internal_slist
+{
+ struct __pthread_internal_slist *__next;
+} __pthread_slist_t;
+
+
/* Data structures for mutex handling. The structure of the attribute
type is not exposed on purpose. */
typedef union
{
- struct
+ struct __pthread_mutex_s
{
int __lock;
unsigned int __count;
@@ -57,7 +63,11 @@ typedef union
binary compatibility. */
int __kind;
unsigned int __nusers;
- int __spins;
+ __extension__ union
+ {
+ int __spins;
+ __pthread_slist_t __list;
+ };
} __data;
char __size[__SIZEOF_PTHREAD_MUTEX_T];
long int __align;
diff --git a/nptl/sysdeps/unix/sysv/linux/sh/clone.S b/nptl/sysdeps/unix/sysv/linux/sh/clone.S
index 62a11972d8..675a997e97 100644
--- a/nptl/sysdeps/unix/sysv/linux/sh/clone.S
+++ b/nptl/sysdeps/unix/sysv/linux/sh/clone.S
@@ -1,2 +1,9 @@
-#define RESET_PID
-#include <sysdeps/unix/sysv/linux/sh/clone.S>
+/* We want an #include_next, but we are the main source file.
+ So, #include ourselves and in that incarnation we can use #include_next. */
+#ifndef INCLUDED_SELF
+# define INCLUDED_SELF
+# include <clone.S>
+#else
+# define RESET_PID
+# include_next <clone.S>
+#endif
diff --git a/nptl/sysdeps/unix/sysv/linux/sh/lowlevellock.S b/nptl/sysdeps/unix/sysv/linux/sh/lowlevellock.S
index bcb15615e5..ac3169889f 100644
--- a/nptl/sysdeps/unix/sysv/linux/sh/lowlevellock.S
+++ b/nptl/sysdeps/unix/sysv/linux/sh/lowlevellock.S
@@ -1,4 +1,4 @@
-/* Copyright (C) 2003, 2004 Free Software Foundation, Inc.
+/* Copyright (C) 2003, 2004, 2005 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
@@ -32,8 +32,11 @@
.type __lll_mutex_lock_wait,@function
.hidden __lll_mutex_lock_wait
.align 5
+ cfi_startproc
__lll_mutex_lock_wait:
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. */
@@ -51,14 +54,15 @@ __lll_mutex_lock_wait:
SYSCALL_INST_PAD
2:
- mov #2, r4
- XCHG (r4, @r8, r2)
+ mov #2, r6
+ XCHG (r6, @r8, r2)
tst r2, r2
bf 1b
mov.l @r15+, r8
ret
mov r2, r0
+ cfi_endproc
.size __lll_mutex_lock_wait,.-__lll_mutex_lock_wait
@@ -67,6 +71,7 @@ __lll_mutex_lock_wait:
.type __lll_mutex_timedlock_wait,@function
.hidden __lll_mutex_timedlock_wait
.align 5
+ cfi_startproc
__lll_mutex_timedlock_wait:
/* Check for a valid timeout value. */
mov.l @(4,r6), r1
@@ -75,14 +80,21 @@ __lll_mutex_timedlock_wait:
bt 3f
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 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. */
@@ -162,6 +174,7 @@ __lll_mutex_timedlock_wait:
5:
bra 6b
mov #ETIMEDOUT, r0
+ cfi_endproc
.L1k:
.word 1000
@@ -178,6 +191,7 @@ __lll_mutex_timedlock_wait:
.type lll_unlock_wake_cb,@function
.hidden lll_unlock_wake_cb
.align 5
+ cfi_startproc
lll_unlock_wake_cb:
DEC (@r4, r2)
tst r2, r2
@@ -195,6 +209,7 @@ lll_unlock_wake_cb:
1:
rts
nop
+ cfi_endproc
.size lll_unlock_wake_cb,.-lll_unlock_wake_cb
#endif
@@ -203,6 +218,7 @@ lll_unlock_wake_cb:
.type __lll_mutex_unlock_wake,@function
.hidden __lll_mutex_unlock_wake
.align 5
+ cfi_startproc
__lll_mutex_unlock_wake:
mov #FUTEX_WAKE, r5
mov #1, r6 /* Wake one thread. */
@@ -214,6 +230,7 @@ __lll_mutex_unlock_wake:
SYSCALL_INST_PAD
rts
nop
+ cfi_endproc
.size __lll_mutex_unlock_wake,.-__lll_mutex_unlock_wake
@@ -222,14 +239,20 @@ __lll_mutex_unlock_wake:
.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. */
@@ -292,6 +315,7 @@ __lll_timedwait_tid:
6:
bra 3b
mov #ETIMEDOUT, r0
+ cfi_endproc
.L1k2:
.word 1000
diff --git a/nptl/sysdeps/unix/sysv/linux/sh/lowlevellock.h b/nptl/sysdeps/unix/sysv/linux/sh/lowlevellock.h
index d9376d45a0..0eb1f0114c 100644
--- a/nptl/sysdeps/unix/sysv/linux/sh/lowlevellock.h
+++ b/nptl/sysdeps/unix/sysv/linux/sh/lowlevellock.h
@@ -1,4 +1,4 @@
-/* Copyright (C) 2003, 2004 Free Software Foundation, Inc.
+/* Copyright (C) 2003, 2004, 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
@@ -26,6 +26,9 @@
#define SYS_futex 240
#define FUTEX_WAIT 0
#define FUTEX_WAKE 1
+#define FUTEX_LOCK_PI 6
+#define FUTEX_UNLOCK_PI 7
+#define FUTEX_TRYLOCK_PI 8
/* Initializer for compatibility lock. */
@@ -62,6 +65,28 @@ extern int __lll_mutex_unlock_wake (int *__futex) attribute_hidden;
: "r0", "r1", "r2", "t", "memory"); \
__result; })
+#define lll_robust_mutex_trylock(futex, id) \
+ ({ 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" (id), \
+ "r" (LLL_MUTEX_LOCK_INITIALIZER) \
+ : "r0", "r1", "r2", "t", "memory"); \
+ __result; })
+
#define lll_mutex_cond_trylock(futex) \
({ unsigned char __result; \
__asm __volatile ("\
@@ -102,6 +127,25 @@ extern int __lll_mutex_unlock_wake (int *__futex) attribute_hidden;
if (__result) \
__lll_mutex_lock_wait (__result, __futex); })
+#define lll_robust_mutex_lock(futex, id) \
+ ({ int __result, val, *__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_mutex_lock_wait (__result, __futex); \
+ __result; })
+
/* Special version of lll_mutex_lock which causes the unlock function to
always wakeup waiters. */
#define lll_mutex_cond_lock(futex) \
@@ -122,6 +166,25 @@ extern int __lll_mutex_unlock_wake (int *__futex) attribute_hidden;
if (__result) \
__lll_mutex_lock_wait (__result, __futex); })
+#define lll_robust_mutex_cond_lock(futex, id) \
+ ({ int __result, val, *__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_mutex_lock_wait (__result, __futex); \
+ __result; })
+
#define lll_mutex_timedlock(futex, timeout) \
({ int __result, val, *__futex = &(futex); \
__asm __volatile ("\
@@ -141,6 +204,26 @@ extern int __lll_mutex_unlock_wake (int *__futex) attribute_hidden;
__result = __lll_mutex_timedlock_wait (__result, __futex, timeout); \
__result; })
+#define lll_robust_mutex_timedlock(futex, timeout, id) \
+ ({ int __result, val, *__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_mutex_timedlock_wait (__result, __futex, \
+ timeout); \
+ __result; })
+
#define lll_mutex_unlock(futex) \
(void) ({ int __result, *__futex = &(futex); \
__asm __volatile ("\
@@ -157,6 +240,37 @@ extern int __lll_mutex_unlock_wake (int *__futex) attribute_hidden;
if (__result) \
__lll_mutex_unlock_wake (__futex); })
+#define lll_robust_mutex_unlock(futex) \
+ (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_TID_MASK) \
+ : "r0", "r1", "memory"); \
+ if (__result) \
+ __lll_mutex_unlock_wake (__futex); })
+
+#define lll_robust_mutex_dead(futex) \
+ (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); })
+
#define lll_mutex_islocked(futex) \
(futex != 0)
@@ -181,19 +295,37 @@ typedef int lll_lock_t;
# endif
#define lll_futex_wait(futex, val) \
- do { \
- int __ignore; \
+ ({ \
+ 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 __r6 asm ("r6") = (unsigned long) (val); \
register unsigned long __r7 asm ("r7") = 0; \
__asm __volatile (SYSCALL_WITH_INST_PAD \
- : "=z" (__ignore) \
+ : "=z" (__status) \
: "r" (__r3), "r" (__r4), "r" (__r5), \
"r" (__r6), "r" (__r7) \
: "memory", "t"); \
- } while (0)
+ __status; \
+ })
+
+
+#define lll_futex_timed_wait(futex, val, timeout) \
+ ({ \
+ 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 __r6 asm ("r6") = (unsigned long) (val); \
+ register unsigned long __r7 asm ("r7") = (timeout); \
+ __asm __volatile (SYSCALL_WITH_INST_PAD \
+ : "=z" (__status) \
+ : "r" (__r3), "r" (__r4), "r" (__r5), \
+ "r" (__r6), "r" (__r7) \
+ : "memory", "t"); \
+ __status; \
+ })
#define lll_futex_wake(futex, nr) \
diff --git a/nptl/sysdeps/unix/sysv/linux/sh/lowlevelrobustlock.S b/nptl/sysdeps/unix/sysv/linux/sh/lowlevelrobustlock.S
new file mode 100644
index 0000000000..c57d3cff18
--- /dev/null
+++ b/nptl/sysdeps/unix/sysv/linux/sh/lowlevelrobustlock.S
@@ -0,0 +1,224 @@
+/* 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
+ 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 <lowlevelrobustlock.h>
+#include "lowlevel-atomic.h"
+
+ .text
+
+#define SYS_gettimeofday __NR_gettimeofday
+#define SYS_futex 240
+#define FUTEX_WAIT 0
+#define FUTEX_WAKE 1
+#define FUTEX_WAITERS 0x80000000
+#define FUTEX_OWNER_DIED 0x40000000
+
+
+ .globl __lll_robust_mutex_lock_wait
+ .type __lll_robust_mutex_lock_wait,@function
+ .hidden __lll_robust_mutex_lock_wait
+ .align 5
+ cfi_startproc
+__lll_robust_mutex_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 #FUTEX_WAIT, r5
+
+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_mutex_lock_wait,.-__lll_robust_mutex_lock_wait
+
+
+ .globl __lll_robust_mutex_timedlock_wait
+ .type __lll_robust_mutex_timedlock_wait,@function
+ .hidden __lll_robust_mutex_timedlock_wait
+ .align 5
+ cfi_startproc
+__lll_robust_mutex_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 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 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 #SYS_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 #FUTEX_WAIT, r5
+ 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
+ rts
+ mov.l @r15+, r10
+
+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_mutex_timedlock_wait,.-__lll_robust_mutex_timedlock_wait
diff --git a/nptl/sysdeps/unix/sysv/linux/sh/pthread_cond_broadcast.S b/nptl/sysdeps/unix/sysv/linux/sh/pthread_cond_broadcast.S
index 6bd6e60ec1..56f0aa95de 100644
--- a/nptl/sysdeps/unix/sysv/linux/sh/pthread_cond_broadcast.S
+++ b/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 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
@@ -20,6 +20,7 @@
#include <shlib-compat.h>
#include <lowlevelcond.h>
#include <kernel-features.h>
+#include <pthread-pi-defines.h>
#include "lowlevel-atomic.h"
#define SYS_futex 240
@@ -98,6 +99,11 @@ __pthread_cond_broadcast:
bt/s 9f
add #cond_futex, r4
+ /* XXX: The kernel so far doesn't support requeue to PI futex. */
+ mov.l @(MUTEX_KIND,r9), r0
+ tst #PI_BIT, r0
+ bf 9f
+
/* Wake up all threads. */
mov #FUTEX_CMP_REQUEUE, r5
mov #1, r6
diff --git a/nptl/sysdeps/unix/sysv/linux/sh/pthread_cond_timedwait.S b/nptl/sysdeps/unix/sysv/linux/sh/pthread_cond_timedwait.S
index 74206a71ec..6c782c8a76 100644
--- a/nptl/sysdeps/unix/sysv/linux/sh/pthread_cond_timedwait.S
+++ b/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 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
@@ -521,6 +521,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
@@ -532,6 +547,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
diff --git a/nptl/sysdeps/unix/sysv/linux/sh/pthread_cond_wait.S b/nptl/sysdeps/unix/sysv/linux/sh/pthread_cond_wait.S
index 2d6b685668..6c59f3e6c0 100644
--- a/nptl/sysdeps/unix/sysv/linux/sh/pthread_cond_wait.S
+++ b/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 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
@@ -385,6 +385,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
@@ -396,6 +411,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
diff --git a/nptl/sysdeps/unix/sysv/linux/sh/sh4/lowlevellock.h b/nptl/sysdeps/unix/sysv/linux/sh/sh4/lowlevellock.h
index 8cdcac5560..90be7bd8d0 100644
--- a/nptl/sysdeps/unix/sysv/linux/sh/sh4/lowlevellock.h
+++ b/nptl/sysdeps/unix/sysv/linux/sh/sh4/lowlevellock.h
@@ -1,4 +1,4 @@
/* 4 instruction cycles not accessing cache and TLB are needed after
trapa instruction to avoid an SH-4 silicon bug. */
#define NEED_SYSCALL_INST_PAD
-#include <sysdeps/unix/sysv/linux/sh/lowlevellock.h>
+#include_next <lowlevellock.h>
diff --git a/nptl/sysdeps/unix/sysv/linux/sh/sysdep-cancel.h b/nptl/sysdeps/unix/sysv/linux/sh/sysdep-cancel.h
index fc3c2340b6..a8065c6a8c 100644
--- a/nptl/sysdeps/unix/sysv/linux/sh/sysdep-cancel.h
+++ b/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