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) | |
| download | uClibc-alpine-a032a6587011cbdac8c2f7e11f15dc4e592bbb55.tar.bz2 uClibc-alpine-a032a6587011cbdac8c2f7e11f15dc4e592bbb55.tar.xz | |
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\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) | 
