diff options
author | Austin Foxley <austinf@cetoncorp.com> | 2010-02-16 12:27:18 -0800 |
---|---|---|
committer | Austin Foxley <austinf@cetoncorp.com> | 2010-02-16 12:27:18 -0800 |
commit | a032a6587011cbdac8c2f7e11f15dc4e592bbb55 (patch) | |
tree | b8d8dfc6abf0168e098223c2134a3e4bd7640942 /libpthread/nptl/sysdeps/unix/sysv/linux/sh | |
parent | 70f1d42b13a741f603472f405299e5d2938aa728 (diff) |
mass sync with glibc nptl
Signed-off-by: Austin Foxley <austinf@cetoncorp.com>
Diffstat (limited to 'libpthread/nptl/sysdeps/unix/sysv/linux/sh')
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\ |