2003-02-08  kaz Kojima  <kkojima@rr.iij4u.or.jp>

	* sysdeps/sh/Makefile: New file.
	* sysdeps/sh/bits/atomic.h: New file.
	* sysdeps/sh/pthread_spin_init.c: New file.
	* sysdeps/sh/pthread_spin_lock.c: New file.
	* sysdeps/sh/pthread_spin_trylock.S: New file.
	* sysdeps/sh/pthread_spin_unlock.S: New file.
	* sysdeps/sh/pthreaddef.h: New file.
	* sysdeps/sh/tcb-offsets.sym: New file.
	* sysdeps/sh/td_ta_map_lwp2thr.c: New file.
	* sysdeps/sh/tls.h: New file.
	* sysdeps/unix/sysv/linux/sh/bits/pthreadtypes.h: New file.
	* sysdeps/unix/sysv/linux/sh/bits/semaphore.h: New file.
	* sysdeps/unix/sysv/linux/sh/createthread.c: New file.
	* sysdeps/unix/sysv/linux/sh/fork.c: New file.
	* sysdeps/unix/sysv/linux/sh/libc-lowlevellock.S: New file.
	* sysdeps/unix/sysv/linux/sh/libc-lowlevelmutex.S: New file.
	* sysdeps/unix/sysv/linux/sh/lowlevel-atomic.h: New file.
	* sysdeps/unix/sysv/linux/sh/lowlevelcond.h: New file.
	* sysdeps/unix/sysv/linux/sh/lowlevellock.S: New file.
	* sysdeps/unix/sysv/linux/sh/lowlevellock.h: New file.
	* sysdeps/unix/sysv/linux/sh/lowlevelmutex.S: New file.
	* sysdeps/unix/sysv/linux/sh/lowlevelrwlock.h: New file.
	* sysdeps/unix/sysv/linux/sh/pt-initfini.c: New file.
	* sysdeps/unix/sysv/linux/sh/pt-vfork.S: New file.
	* sysdeps/unix/sysv/linux/sh/pthread_barrier_wait.S: New file.
	* sysdeps/unix/sysv/linux/sh/pthread_cond_broadcast.S: New file.
	* sysdeps/unix/sysv/linux/sh/pthread_cond_signal.S: New file.
	* sysdeps/unix/sysv/linux/sh/pthread_cond_timedwait.S: New file.
	* sysdeps/unix/sysv/linux/sh/pthread_cond_wait.S: New file.
	* sysdeps/unix/sysv/linux/sh/pthread_once.S: New file.
	* sysdeps/unix/sysv/linux/sh/pthread_rwlock_rdlock.S: New file.
	* sysdeps/unix/sysv/linux/sh/pthread_rwlock_timedrdlock.S: New file.
	* sysdeps/unix/sysv/linux/sh/pthread_rwlock_timedwrlock.S: New file.
	* sysdeps/unix/sysv/linux/sh/pthread_rwlock_unlock.S: New file.
	* sysdeps/unix/sysv/linux/sh/pthread_rwlock_wrlock.S: New file.
	* sysdeps/unix/sysv/linux/sh/sem_post.S: New file.
	* sysdeps/unix/sysv/linux/sh/sem_timedwait.S: New file.
	* sysdeps/unix/sysv/linux/sh/sem_trywait.S: New file.
	* sysdeps/unix/sysv/linux/sh/sem_wait.S: New file.
	* sysdeps/unix/sysv/linux/sh/sysdep-cancel.h: New file.
This commit is contained in:
Ulrich Drepper 2003-02-10 09:24:12 +00:00
parent f954eb1691
commit a54e8d33d1
40 changed files with 5396 additions and 0 deletions

View File

@ -1,3 +1,46 @@
2003-02-08 kaz Kojima <kkojima@rr.iij4u.or.jp>
* sysdeps/sh/Makefile: New file.
* sysdeps/sh/bits/atomic.h: New file.
* sysdeps/sh/pthread_spin_init.c: New file.
* sysdeps/sh/pthread_spin_lock.c: New file.
* sysdeps/sh/pthread_spin_trylock.S: New file.
* sysdeps/sh/pthread_spin_unlock.S: New file.
* sysdeps/sh/pthreaddef.h: New file.
* sysdeps/sh/tcb-offsets.sym: New file.
* sysdeps/sh/td_ta_map_lwp2thr.c: New file.
* sysdeps/sh/tls.h: New file.
* sysdeps/unix/sysv/linux/sh/bits/pthreadtypes.h: New file.
* sysdeps/unix/sysv/linux/sh/bits/semaphore.h: New file.
* sysdeps/unix/sysv/linux/sh/createthread.c: New file.
* sysdeps/unix/sysv/linux/sh/fork.c: New file.
* sysdeps/unix/sysv/linux/sh/libc-lowlevellock.S: New file.
* sysdeps/unix/sysv/linux/sh/libc-lowlevelmutex.S: New file.
* sysdeps/unix/sysv/linux/sh/lowlevel-atomic.h: New file.
* sysdeps/unix/sysv/linux/sh/lowlevelcond.h: New file.
* sysdeps/unix/sysv/linux/sh/lowlevellock.S: New file.
* sysdeps/unix/sysv/linux/sh/lowlevellock.h: New file.
* sysdeps/unix/sysv/linux/sh/lowlevelmutex.S: New file.
* sysdeps/unix/sysv/linux/sh/lowlevelrwlock.h: New file.
* sysdeps/unix/sysv/linux/sh/pt-initfini.c: New file.
* sysdeps/unix/sysv/linux/sh/pt-vfork.S: New file.
* sysdeps/unix/sysv/linux/sh/pthread_barrier_wait.S: New file.
* sysdeps/unix/sysv/linux/sh/pthread_cond_broadcast.S: New file.
* sysdeps/unix/sysv/linux/sh/pthread_cond_signal.S: New file.
* sysdeps/unix/sysv/linux/sh/pthread_cond_timedwait.S: New file.
* sysdeps/unix/sysv/linux/sh/pthread_cond_wait.S: New file.
* sysdeps/unix/sysv/linux/sh/pthread_once.S: New file.
* sysdeps/unix/sysv/linux/sh/pthread_rwlock_rdlock.S: New file.
* sysdeps/unix/sysv/linux/sh/pthread_rwlock_timedrdlock.S: New file.
* sysdeps/unix/sysv/linux/sh/pthread_rwlock_timedwrlock.S: New file.
* sysdeps/unix/sysv/linux/sh/pthread_rwlock_unlock.S: New file.
* sysdeps/unix/sysv/linux/sh/pthread_rwlock_wrlock.S: New file.
* sysdeps/unix/sysv/linux/sh/sem_post.S: New file.
* sysdeps/unix/sysv/linux/sh/sem_timedwait.S: New file.
* sysdeps/unix/sysv/linux/sh/sem_trywait.S: New file.
* sysdeps/unix/sysv/linux/sh/sem_wait.S: New file.
* sysdeps/unix/sysv/linux/sh/sysdep-cancel.h: New file.
2003-02-08 Ulrich Drepper <drepper@redhat.com>
* tst-cond2.c: Rearrange code to not rely on behavior undefined

View File

@ -0,0 +1,405 @@
/* Copyright (C) 2003 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 <stdint.h>
typedef int8_t atomic8_t;
typedef uint8_t uatomic8_t;
typedef int_fast8_t atomic_fast8_t;
typedef uint_fast8_t uatomic_fast8_t;
typedef int16_t atomic16_t;
typedef uint16_t uatomic16_t;
typedef int_fast16_t atomic_fast16_t;
typedef uint_fast16_t uatomic_fast16_t;
typedef int32_t atomic32_t;
typedef uint32_t uatomic32_t;
typedef int_fast32_t atomic_fast32_t;
typedef uint_fast32_t uatomic_fast32_t;
typedef int64_t atomic64_t;
typedef uint64_t uatomic64_t;
typedef int_fast64_t atomic_fast64_t;
typedef uint_fast64_t uatomic_fast64_t;
typedef intptr_t atomicptr_t;
typedef uintptr_t uatomicptr_t;
typedef intmax_t atomic_max_t;
typedef uintmax_t uatomic_max_t;
#define __arch_compare_and_exchange_8_acq(mem, newval, oldval) \
({ unsigned char __result; \
__asm __volatile ("\
.align 2\n\
mova 1f,r0\n\
nop\n\
mov r15,r1\n\
mov #-8,r15\n\
0: mov.b @%1,r2\n\
cmp/eq r2,%3\n\
bf 1f\n\
mov.b %2,@%1\n\
1: mov r1,r15\n\
mov #-1,%0\n\
negc %0,%0"\
: "=r" (__result) : "r" (mem), "r" (newval), "r" (oldval) \
: "r0", "r1", "r2", "t", "memory"); \
__result; })
#define __arch_compare_and_exchange_16_acq(mem, newval, oldval) \
({ unsigned char __result; \
__asm __volatile ("\
.align 2\n\
mova 1f,r0\n\
nop\n\
mov r15,r1\n\
mov #-8,r15\n\
0: mov.w @%1,r2\n\
cmp/eq r2,%3\n\
bf 1f\n\
mov.w %2,@%1\n\
1: mov r1,r15\n\
mov #-1,%0\n\
negc %0,%0"\
: "=r" (__result) : "r" (mem), "r" (newval), "r" (oldval) \
: "r0", "r1", "r2", "t", "memory"); \
__result; })
#define __arch_compare_and_exchange_32_acq(mem, newval, oldval) \
({ 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" (mem), "r" (newval), "r" (oldval) \
: "r0", "r1", "r2", "t", "memory"); \
__result; })
/* XXX We do not really need 64-bit compare-and-exchange. At least
not in the moment. Using it would mean causing portability
problems since not many other 32-bit architectures have support for
such an operation. So don't define any code for now. */
# define __arch_compare_and_exchange_64_acq(mem, newval, oldval) \
(abort (), 0)
#define atomic_exchange_and_add(mem, value) \
({ __typeof (*mem) __result; \
if (sizeof (*mem) == 1) \
__asm __volatile ("\
.align 2\n\
mova 1f,r0\n\
mov r15,r1\n\
mov #-6,r15\n\
0: mov.b @%2,%0\n\
add %0,%1\n\
mov.b %1,@%2\n\
1: mov r1,r15"\
: "=&r" (__result), "=&r" (value) : "r" (mem), "1" (value) \
: "r0", "r1", "memory"); \
else if (sizeof (*mem) == 2) \
__asm __volatile ("\
.align 2\n\
mova 1f,r0\n\
mov r15,r1\n\
mov #-6,r15\n\
0: mov.w @%2,%0\n\
add %0,%1\n\
mov.w %1,@%2\n\
1: mov r1,r15"\
: "=&r" (__result), "=&r" (value) : "r" (mem), "1" (value) \
: "r0", "r1", "memory"); \
else if (sizeof (*mem) == 4) \
__asm __volatile ("\
.align 2\n\
mova 1f,r0\n\
mov r15,r1\n\
mov #-6,r15\n\
0: mov.l @%2,%0\n\
add %0,%1\n\
mov.l %1,@%2\n\
1: mov r1,r15"\
: "=&r" (__result), "=&r" (value) : "r" (mem), "1" (value) \
: "r0", "r1", "memory"); \
else \
{ \
__typeof (value) addval = (value); \
__typeof (*mem) oldval; \
__typeof (mem) memp = (mem); \
do \
__result = (oldval = *memp) + addval; \
while (!__arch_compare_and_exchange_64_acq (memp, __result, oldval));\
(void) addval; \
} \
__result; })
#define atomic_add(mem, value) \
(void) ({ if (sizeof (*mem) == 1) \
__asm __volatile ("\
.align 2\n\
mova 1f,r0\n\
mov r15,r1\n\
mov #-6,r15\n\
0: mov.b @%1,r2\n\
add r2,%0\n\
mov.b %0,@%1\n\
1: mov r1,r15"\
: "=&r" (value) : "r" (mem), "0" (value) \
: "r0", "r1", "r2", "memory"); \
else if (sizeof (*mem) == 2) \
__asm __volatile ("\
.align 2\n\
mova 1f,r0\n\
mov r15,r1\n\
mov #-6,r15\n\
0: mov.w @%1,r2\n\
add r2,%0\n\
mov.w %0,@%1\n\
1: mov r1,r15"\
: "=&r" (value) : "r" (mem), "0" (value) \
: "r0", "r1", "r2", "memory"); \
else if (sizeof (*mem) == 4) \
__asm __volatile ("\
.align 2\n\
mova 1f,r0\n\
mov r15,r1\n\
mov #-6,r15\n\
0: mov.l @%1,r2\n\
add r2,%0\n\
mov.l %0,@%1\n\
1: mov r1,r15"\
: "=&r" (value) : "r" (mem), "0" (value) \
: "r0", "r1", "r2", "memory"); \
else \
{ \
__typeof (value) addval = (value); \
__typeof (*mem) oldval; \
__typeof (mem) memp = (mem); \
do \
oldval = *memp; \
while (! __arch_compare_and_exchange_64_acq (memp, \
oldval + addval, \
oldval)); \
(void) addval; \
} \
})
#define atomic_add_negative(mem, value) \
({ unsigned char __result; \
if (sizeof (*mem) == 1) \
__asm __volatile ("\
.align 2\n\
mova 1f,r0\n\
mov r15,r1\n\
mov #-6,r15\n\
0: mov.b @%2,r2\n\
add r2,%1\n\
mov.b %1,@%2\n\
1: mov r1,r15\n\
shal %1\n\
movt %0"\
: "=r" (__result), "=&r" (value) : "r" (mem), "1" (value) \
: "r0", "r1", "r2", "t", "memory"); \
else if (sizeof (*mem) == 2) \
__asm __volatile ("\
.align 2\n\
mova 1f,r0\n\
mov r15,r1\n\
mov #-6,r15\n\
0: mov.w @%2,r2\n\
add r2,%1\n\
mov.w %1,@%2\n\
1: mov r1,r15\n\
shal %1\n\
movt %0"\
: "=r" (__result), "=&r" (value) : "r" (mem), "1" (value) \
: "r0", "r1", "r2", "t", "memory"); \
else if (sizeof (*mem) == 4) \
__asm __volatile ("\
.align 2\n\
mova 1f,r0\n\
mov r15,r1\n\
mov #-6,r15\n\
0: mov.l @%2,r2\n\
add r2,%1\n\
mov.l %1,@%2\n\
1: mov r1,r15\n\
shal %1\n\
movt %0"\
: "=r" (__result), "=&r" (value) : "r" (mem), "1" (value) \
: "r0", "r1", "r2", "t", "memory"); \
else \
abort (); \
__result; })
#define atomic_add_zero(mem, value) \
({ unsigned char __result; \
if (sizeof (*mem) == 1) \
__asm __volatile ("\
.align 2\n\
mova 1f,r0\n\
mov r15,r1\n\
mov #-6,r15\n\
0: mov.b @%2,r2\n\
add r2,%1\n\
mov.b %1,@%2\n\
1: mov r1,r15\n\
tst %1,%1\n\
movt %0"\
: "=r" (__result), "=&r" (value) : "r" (mem), "1" (value) \
: "r0", "r1", "r2", "t", "memory"); \
else if (sizeof (*mem) == 2) \
__asm __volatile ("\
.align 2\n\
mova 1f,r0\n\
mov r15,r1\n\
mov #-6,r15\n\
0: mov.w @%2,r2\n\
add r2,%1\n\
mov.w %1,@%2\n\
1: mov r1,r15\n\
tst %1,%1\n\
movt %0"\
: "=r" (__result), "=&r" (value) : "r" (mem), "1" (value) \
: "r0", "r1", "r2", "t", "memory"); \
else if (sizeof (*mem) == 4) \
__asm __volatile ("\
.align 2\n\
mova 1f,r0\n\
mov r15,r1\n\
mov #-6,r15\n\
0: mov.l @%2,r2\n\
add r2,%1\n\
mov.l %1,@%2\n\
1: mov r1,r15\n\
tst %1,%1\n\
movt %0"\
: "=r" (__result), "=&r" (value) : "r" (mem), "1" (value) \
: "r0", "r1", "r2", "t", "memory"); \
else \
abort (); \
__result; })
#define atomic_increment_and_test(mem) atomic_add_zero((mem), 1)
#define atomic_decrement_and_test(mem) atomic_add_zero((mem), -1)
#define atomic_bit_set(mem, bit) \
(void) ({ unsigned int __mask = 1 << (bit); \
if (sizeof (*mem) == 1) \
__asm __volatile ("\
.align 2\n\
mova 1f,r0\n\
mov r15,r1\n\
mov #-6,r15\n\
0: mov.b @%0,r2\n\
or %1,r2\n\
mov.b r2,@%0\n\
1: mov r1,r15"\
: : "r" (mem), "r" (__mask) \
: "r0", "r1", "r2", "memory"); \
else if (sizeof (*mem) == 2) \
__asm __volatile ("\
.align 2\n\
mova 1f,r0\n\
mov r15,r1\n\
mov #-6,r15\n\
0: mov.w @%0,r2\n\
or %1,r2\n\
mov.w r2,@%0\n\
1: mov r1,r15"\
: : "r" (mem), "r" (__mask) \
: "r0", "r1", "r2", "memory"); \
else if (sizeof (*mem) == 4) \
__asm __volatile ("\
.align 2\n\
mova 1f,r0\n\
mov r15,r1\n\
mov #-6,r15\n\
0: mov.l @%0,r2\n\
or %1,r2\n\
mov.l r2,@%0\n\
1: mov r1,r15"\
: : "r" (mem), "r" (__mask) \
: "r0", "r1", "r2", "memory"); \
else \
abort (); \
})
#define atomic_bit_test_set(mem, bit) \
({ unsigned int __mask = 1 << (bit); \
unsigned int __result = __mask; \
if (sizeof (*mem) == 1) \
__asm __volatile ("\
.align 2\n\
mova 1f,r0\n\
nop\n\
mov r15,r1\n\
mov #-8,r15\n\
0: mov.b @%2,r2\n\
or r2,%1\n\
and r2,%0\n\
mov.b %1,@%2\n\
1: mov r1,r15"\
: "=&r" (__result), "=&r" (__mask) \
: "r" (mem), "0" (__result), "1" (__mask) \
: "r0", "r1", "r2", "memory"); \
else if (sizeof (*mem) == 2) \
__asm __volatile ("\
.align 2\n\
mova 1f,r0\n\
nop\n\
mov r15,r1\n\
mov #-8,r15\n\
0: mov.w @%2,r2\n\
or r2,%1\n\
and r2,%0\n\
mov.w %1,@%2\n\
1: mov r1,r15"\
: "=&r" (__result), "=&r" (__mask) \
: "r" (mem), "0" (__result), "1" (__mask) \
: "r0", "r1", "r2", "memory"); \
else if (sizeof (*mem) == 4) \
__asm __volatile ("\
.align 2\n\
mova 1f,r0\n\
nop\n\
mov r15,r1\n\
mov #-8,r15\n\
0: mov.l @%2,r2\n\
or r2,%1\n\
and r2,%0\n\
mov.l %1,@%2\n\
1: mov r1,r15"\
: "=&r" (__result), "=&r" (__mask) \
: "r" (mem), "0" (__result), "1" (__mask) \
: "r0", "r1", "r2", "memory"); \
else \
abort (); \
__result; })

View File

@ -0,0 +1,20 @@
/* Copyright (C) 2002 Free Software Foundation, Inc.
This file is part of the GNU C Library.
Contributed by Ulrich Drepper <drepper@redhat.com>, 2002.
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. */
/* Not needed. pthread_spin_init is an alias for pthread_spin_unlock. */

View File

@ -0,0 +1,35 @@
/* Copyright (C) 2003 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 "pthreadP.h"
int
pthread_spin_lock (lock)
pthread_spinlock_t *lock;
{
unsigned int val;
do
asm volatile ("tas.b @%1; movt %0"
: "=&r" (val)
: "r" (lock)
: "memory");
while (val == 0);
return 0;
}

View File

@ -0,0 +1,32 @@
/* Copyright (C) 2003 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. */
#define EBUSY 16
.globl pthread_spin_trylock
.type pthread_spin_trylock,@function
.align 5
pthread_spin_trylock:
tas.b @r4
bf/s 1f
mov #EBUSY, r0
mov #0, r0
1:
rts
nop
.size pthread_spin_trylock,.-pthread_spin_trylock

View File

@ -0,0 +1,30 @@
/* Copyright (C) 2003 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. */
.globl pthread_spin_unlock
.type pthread_spin_unlock,@function
.align 5
pthread_spin_unlock:
mov #0,r0
rts
mov.l r0,@r4
.size pthread_spin_unlock,.-pthread_spin_unlock
/* The implementation of pthread_spin_init is identical. */
.globl pthread_spin_init
pthread_spin_init = pthread_spin_unlock

View File

@ -0,0 +1,52 @@
/* Copyright (C) 2003 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>
/* Default stack size. */
#define ARCH_STACK_DEFAULT_SIZE (2 * 1024 * 1024)
/* Required stack pointer alignment at beginning. */
#define STACK_ALIGN 8
/* Minimal stack size after allocating thread descriptor and guard size. */
#define MINIMAL_REST_STACK 2048
/* Alignment requirement for TCB. */
#define TCB_ALIGNMENT 8
/* The signal used for asynchronous cancelation. */
#define SIGCANCEL __SIGRTMIN
/* Location of current stack frame. */
#define CURRENT_STACK_FRAME __builtin_frame_address (0)
/* XXX Until we have a better place keep the definitions here. */
/* While there is no such syscall. */
#define __exit_thread_inline(val) \
while (1) { \
if (__builtin_constant_p (val) && (val) == 0) \
asm volatile ("mov #0,r4; mov %0,r3; trapa #0x11\n\t" SYSCALL_INST_PAD \
:: "i" (__NR_exit)); \
else \
asm volatile ("mov %1,r4; mov %0,r3; trapa #0x11\n\t" SYSCALL_INST_PAD \
:: "i" (__NR_exit), "r" (val)); \
}

View File

@ -0,0 +1,5 @@
#include <sysdep.h>
#include <tls.h>
MULTIPLE_THREADS_OFFSET offsetof (struct pthread, header.data.multiple_threads)
TLS_PRE_TCB_SIZE sizeof (struct pthread)

View File

@ -0,0 +1,44 @@
/* Which thread is running on an LWP? Stub version.
Copyright (C) 2003 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 "thread_dbP.h"
#include <tls.h>
#include <sys/reg.h>
td_err_e
td_ta_map_lwp2thr (const td_thragent_t *ta, lwpid_t lwpid, td_thrhandle_t *th)
{
LOG ("td_ta_map_lwp2thr");
/* Test whether the TA parameter is ok. */
if (! ta_ok (ta))
return TD_BADTA;
prgregset_t regs;
if (ps_lgetregs (ta->ph, lwpid, regs) != PS_OK)
return TD_ERR;
th->th_unique = regs[REG_GBR];
/* Found it. Now complete the `td_thrhandle_t' object. */
th->th_ta_p = (td_thragent_t *) ta;
return TD_OK;
}

135
nptl/sysdeps/sh/tls.h Normal file
View File

@ -0,0 +1,135 @@
/* Definition for thread-local data handling. NPTL/SH version.
Copyright (C) 2003 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. */
#ifndef _TLS_H
#define _TLS_H
# include <dl-sysdep.h>
#ifndef __ASSEMBLER__
# include <stddef.h>
# include <stdint.h>
/* Type for the dtv. */
typedef union dtv
{
size_t counter;
void *pointer;
} dtv_t;
typedef struct
{
dtv_t *dtv;
void *private;
} tcbhead_t;
#else /* __ASSEMBLER__ */
# include <tcb-offsets.h>
#endif /* __ASSEMBLER__ */
/* We require TLS support in the tools. */
#ifndef HAVE_TLS_SUPPORT
# error "TLS support is required."
#endif
/* Signal that TLS support is available. */
# define USE_TLS 1
#ifndef __ASSEMBLER__
/* Get system call information. */
# include <sysdep.h>
/* Get the thread descriptor definition. */
# include <nptl/descr.h>
/* This is the size of the initial TCB. */
# define TLS_INIT_TCB_SIZE sizeof (tcbhead_t)
/* Alignment requirements for the initial TCB. */
# define TLS_INIT_TCB_ALIGN __alignof__ (tcbhead_t)
/* This is the size of the TCB. */
# define TLS_TCB_SIZE sizeof (tcbhead_t)
/* This is the size we need before TCB. */
# define TLS_PRE_TCB_SIZE sizeof (struct pthread)
/* Alignment requirements for the TCB. */
# define TLS_TCB_ALIGN __alignof__ (struct pthread)
/* The TLS blocks start right after the TCB. */
# define TLS_DTV_AT_TP 1
/* Install the dtv pointer. The pointer passed is to the element with
index -1 which contain the length. */
# define INSTALL_DTV(tcbp, dtvp) \
((tcbhead_t *) (tcbp))->dtv = dtvp + 1
/* Install new dtv for current thread. */
# define INSTALL_NEW_DTV(dtv) \
({ tcbhead_t *__tcbp; \
__asm __volatile ("stc gbr,%0" : "=r" (__tcbp)); \
__tcbp->dtv = (dtv);})
/* Return dtv of given thread descriptor. */
# define GET_DTV(tcbp) \
(((tcbhead_t *) (tcbp))->dtv)
/* Code to initially initialize the thread pointer. This might need
special attention since 'errno' is not yet available and if the
operation can cause a failure 'errno' must not be touched. */
# define TLS_INIT_TP(tcbp, secondcall) \
({ __asm __volatile ("ldc %0,gbr" : : "r" (tcbp)); 0; })
/* Return the address of the dtv for the current thread. */
# define THREAD_DTV() \
({ tcbhead_t *__tcbp; \
__asm __volatile ("stc gbr,%0" : "=r" (__tcbp)); \
__tcbp->dtv;})
/* Return the thread descriptor for the current thread.
The contained asm must *not* be marked volatile since otherwise
assignments like
struct pthread *self = thread_self();
do not get optimized away. */
# define THREAD_SELF \
({ struct pthread *__self; \
__asm ("stc gbr,%0" : "=r" (__self)); \
__self - 1;})
/* Read member of the thread descriptor directly. */
# define THREAD_GETMEM(descr, member) ((THREAD_SELF)->member)
/* Same as THREAD_GETMEM, but the member offset can be non-constant. */
# define THREAD_GETMEM_NC(descr, member, idx) ((THREAD_SELF)->member[idx])
/* Set member of the thread descriptor directly. */
# define THREAD_SETMEM(descr, member, value) \
(THREAD_SELF)->member = (value)
/* Same as THREAD_SETMEM, but the member offset can be non-constant. */
# define THREAD_SETMEM_NC(descr, member, idx, value) \
(THREAD_SELF)->member[idx] = (value)
#endif /* __ASSEMBLER__ */
#endif /* tls.h */

View File

@ -0,0 +1,152 @@
/* Copyright (C) 2002 Free Software Foundation, Inc.
This file is part of the GNU C Library.
Contributed by Ulrich Drepper <drepper@redhat.com>, 2002.
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. */
#ifndef _BITS_PTHREADTYPES_H
#define _BITS_PTHREADTYPES_H 1
#define __SIZEOF_PTHREAD_ATTR_T 36
#define __SIZEOF_PTHREAD_MUTEX_T 24
#define __SIZEOF_PTHREAD_MUTEXATTR_T 4
#define __SIZEOF_PTHREAD_COND_T 48
#define __SIZEOF_PTHREAD_COND_COMPAT_T 12
#define __SIZEOF_PTHREAD_CONDATTR_T 4
#define __SIZEOF_PTHREAD_RWLOCK_T 32
#define __SIZEOF_PTHREAD_RWLOCKATTR_T 8
#define __SIZEOF_PTHREAD_BARRIER_T 20
#define __SIZEOF_PTHREAD_BARRIERATTR_T 4
/* Thread identifiers. The structure of the attribute type is not
exposed on purpose. */
typedef struct __opaque_pthread *pthread_t;
typedef union
{
char __size[__SIZEOF_PTHREAD_ATTR_T];
long int __align;
} pthread_attr_t;
/* Data structures for mutex handling. The structure of the attribute
type is not exposed on purpose. */
typedef union
{
struct
{
int __lock;
unsigned int __count;
struct pthread *__owner;
/* KIND must stay at this position in the structure to maintain
binary compatibility. */
int __kind;
} __data;
char __size[__SIZEOF_PTHREAD_MUTEX_T];
long int __align;
} pthread_mutex_t;
typedef union
{
char __size[__SIZEOF_PTHREAD_MUTEXATTR_T];
long int __align;
} pthread_mutexattr_t;
/* Data structure for conditional variable handling. The structure of
the attribute type is not exposed on purpose. */
typedef union
{
struct
{
int __lock;
unsigned long long int __total_seq;
unsigned long long int __wakeup_seq;
unsigned long long int __woken_seq;
} __data;
char __size[__SIZEOF_PTHREAD_COND_T];
long long int __align;
} pthread_cond_t;
typedef union
{
char __size[__SIZEOF_PTHREAD_CONDATTR_T];
long int __align;
} pthread_condattr_t;
/* Keys for thread-specific data */
typedef unsigned int pthread_key_t;
/* Once-only execution */
typedef int pthread_once_t;
#ifdef __USE_UNIX98
/* Data structure for read-write lock variable handling. The
structure of the attribute type is not exposed on purpose. */
typedef union
{
struct
{
int __lock;
unsigned int __nr_readers;
unsigned int __readers_wakeup;
unsigned int __writer_wakeup;
unsigned int __nr_readers_queued;
unsigned int __nr_writers_queued;
/* FLAGS must stay at this position in the structure to maintain
binary compatibility. */
unsigned int __flags;
pthread_t __writer;
} __data;
char __size[__SIZEOF_PTHREAD_RWLOCK_T];
long int __align;
} pthread_rwlock_t;
typedef union
{
char __size[__SIZEOF_PTHREAD_RWLOCKATTR_T];
long int __align;
} pthread_rwlockattr_t;
#endif
#ifdef __USE_XOPEN2K
/* POSIX spinlock data type. */
typedef volatile int pthread_spinlock_t;
/* POSIX barriers data type. The structure of the type is
deliberately not exposed. */
typedef union
{
char __size[__SIZEOF_PTHREAD_BARRIER_T];
long int __align;
} pthread_barrier_t;
typedef union
{
char __size[__SIZEOF_PTHREAD_BARRIERATTR_T];
int __align;
} pthread_barrierattr_t;
#endif
#endif /* bits/pthreadtypes.h */

View File

@ -0,0 +1,39 @@
/* Copyright (C) 2002 Free Software Foundation, Inc.
This file is part of the GNU C Library.
Contributed by Ulrich Drepper <drepper@redhat.com>, 2002.
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. */
#ifndef _SEMAPHORE_H
# error "Never use <bits/semaphore.h> directly; include <semaphore.h> instead."
#endif
#define __SIZEOF_SEM_T 16
/* Value returned if `sem_open' failed. */
#define SEM_FAILED ((sem_t *) 0)
/* Maximum value the semaphore can have. */
#define SEM_VALUE_MAX ((int) ((~0u) >> 1))
typedef union
{
char __size[__SIZEOF_SEM_T];
long int __align;
} sem_t;

View File

@ -0,0 +1,24 @@
/* Copyright (C) 2003 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. */
/* Value passed to 'clone' for initialization of the thread register. */
#define TLS_VALUE (pd + 1)
/* Get the real implementation. */
#include <nptl/sysdeps/pthread/createthread.c>

View File

@ -0,0 +1,30 @@
/* Copyright (C) 2003 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 <sched.h>
#include <signal.h>
#include <sysdep.h>
#include <tls.h>
/* TLS pointer argument is passed as the 5-th argument. */
#define ARCH_FORK() \
INLINE_SYSCALL (clone, 5, \
CLONE_CHILD_SETTID | CLONE_CHILD_CLEARTID | SIGCHLD, 0, \
NULL, &THREAD_SELF->tid, NULL)
#include "../fork.c"

View File

@ -0,0 +1,221 @@
/* Copyright (C) 2003 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 <tls.h>
#include "lowlevel-atomic.h"
.text
#define SYS_gettimeofday __NR_gettimeofday
#define SYS_futex 240
#define FUTEX_WAIT 0
#define FUTEX_WAKE 1
#define ETIMEDOUT 110
.globl __lll_lock_wait
.type __lll_lock_wait,@function
.hidden __lll_lock_wait
.align 5
__lll_lock_wait:
mov r4, r6
mov r5, r4
mov #0, r7 /* No timeout. */
mov #FUTEX_WAIT, r5
2:
add #-1, r6 /* account for the preceeded xadd. */
mov #SYS_futex, r3
extu.b r3, r3
trapa #0x14
SYSCALL_INST_PAD
mov #-1, r3
XADD (r3, @r4, r2)
tst r3, r3
bf/s 2b
mov r2, r6
mov #-1, r1
mov.l r1, @r4
rts
mov r2, r0
.size __lll_lock_wait,.-__lll_lock_wait
.type lll_unlock_wake_cb,@function
.align 5
lll_unlock_wake_cb:
.align 2
mova 1f, r0
mov r15, r1
mov #-6, r15
0:
mov.l @r4, r2
add #1, r2
mov.l r2, @r4
1:
mov r1, r15
cmp/pl r2
bf 2f
rts
nop
.size lll_unlock_wake_cb,.-lll_unlock_wake_cb
.globl __lll_unlock_wake
.type __lll_unlock_wake,@function
.hidden __lll_unlock_wake
__lll_unlock_wake:
2:
mov #FUTEX_WAKE, r5
mov #1, r6 /* Wake one thread. */
mov #0, r7
mov.l r6, @r4 /* Stores 1. */
mov #SYS_futex, r3
extu.b r3, r3
trapa #0x14
SYSCALL_INST_PAD
rts
nop
.size __lll_unlock_wake,.-__lll_unlock_wake
.globl __lll_wait_tid
.type __lll_wait_tid,@function
.hidden __lll_wait_tid
__lll_wait_tid:
mov.l @r4, r6
1:
mov #FUTEX_WAIT, r5
mov #0, r7
mov #SYS_futex, r3
extu.b r3, r3
trapa #0x14
SYSCALL_INST_PAD
mov r0, r1
mov.l @r4, r0
tst r0, r0
bf/s 1b
mov r0, r6
rts
nop
.size __lll_wait_tid,.-__lll_wait_tid
.globl __lll_timedwait_tid
.type __lll_timedwait_tid,@function
.hidden __lll_timedwait_tid
__lll_timedwait_tid:
mov.l r9, @-r15
mov.l r8, @-r15
mov r4, r8
mov r5, r9
add #-8, r15
2:
/* Get current time. */
mov r15, r4
mov #0, r5
mov #SYS_gettimeofday, r3
trapa #0x12
SYSCALL_INST_PAD
/* Compute relative timeout. */
mov.l @(4,r15), r0
mov.w .L1k, r1
dmulu.l r0, r1 /* Milli 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 5f
mov.l .L1g, r1
add r1, r3
add #-1, r2
5:
cmp/pz r2
bf 6f /* Time is already up. */
mov.l r2, @r15 /* Store relative timeout. */
mov.l r3, @(4,r15)
mov.l @r8, r6
tst r6, r6
bt 4f
mov r8, r4
mov #FUTEX_WAIT, r5
mov r15, r7
mov #SYS_futex, r3
extu.b r3, r3
trapa #0x14
SYSCALL_INST_PAD
mov r0, r1
mov.l @r8, r0
tst r0, r0
bf 1f
4:
mov #0, r0
3:
add #8, r15
mov.l @r15+, r8
rts
mov.l @r15+, r9
1:
mov #-ETIMEDOUT, r1
cmp/eq r0, r1
bf 2b
6:
bra 3b
mov #ETIMEDOUT, r0
.L1k:
.word 1000
.align 2
.L1g:
.long 1000000000
.size __lll_timedwait_tid,.-__lll_timedwait_tid
.globl __lll_wake_tid
.type __lll_wake_tid,@function
.hidden __lll_wake_tid
__lll_wake_tid:
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 __lll_wake_tid,.-__lll_wake_tid

View File

@ -0,0 +1,174 @@
/* Copyright (C) 2003 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 "lowlevel-atomic.h"
.text
#define SYS_gettimeofday __NR_gettimeofday
#define SYS_futex 240
#define FUTEX_WAIT 0
#define FUTEX_WAKE 1
#define EWOULDBLOCK 11
#define EINVAL 22
#define ETIMEDOUT 110
.globl __lll_mutex_lock_wait
.type __lll_mutex_lock_wait,@function
.hidden __lll_mutex_lock_wait
.align 5
__lll_mutex_lock_wait:
mov r4, r6
mov r5, r4
mov #0, r7 /* No timeout. */
mov #FUTEX_WAIT, r5
1:
add #1, r6 /* account for the preceeded xadd. */
mov #SYS_futex, r3
extu.b r3, r3
trapa #0x14
SYSCALL_INST_PAD
mov #1, r3
XADD (r3, @r4, r6)
tst r6, r6
bf 1b
mov #2, r1
mov.l r1, @r4
ret
mov #0, r0
.size __lll_mutex_lock_wait,.-__lll_mutex_lock_wait
.globl __lll_mutex_timedlock_wait
.type __lll_mutex_timedlock_wait,@function
.hidden __lll_mutex_timedlock_wait
.align 5
__lll_mutex_timedlock_wait:
/* Check for a valid timeout value. */
mov.l @(4,r6), r1
mov.l .L1g, r0
cmp/hs r0, r1
bt 3f
mov.l r10, @-r15
mov.l r9, @-r15
mov.l r8, @-r15
mov r5, r8
mov r6, r9
mov r4, r10
add #1, r10
/* Stack frame for the timespec and timeval structs. */
add #-8, r15
1:
/* Get current time. */
mov r15, r4
mov #0, r5
mov #SYS_gettimeofday, r3
trapa #0x12
SYSCALL_INST_PAD
/* Compute relative timeout. */
mov.l @(4,r15), r0
mov.w .L1k, r1
dmulu.l r0, r1 /* Micro seconds to nano seconds. */
mov.l @r9, r2
mov.l @(4,r9), r3
mov.l @r15, r0
sts macl, r1
sub r0, r2
clrt
subc r1, r3
bf 4f
mov.l .L1g, r1
add r1, r3
add #-1, r2
4:
cmp/pz r2
bf 5f /* Time is already up. */
mov.l r2, @r15 /* Store relative timeout. */
mov.l r3, @(4,r15)
mov r8, r4
mov #FUTEX_WAIT, r5
mov r10, r6
mov r15, r7
mov #SYS_futex, r3
extu.b r3, r3
trapa #0x14
SYSCALL_INST_PAD
mov #1, r3
XADD (r3, @r8, r10)
tst r10, r10
bf 7f
mov #2, r1
mov.l r1, @r8
mov #0, r0
6:
add #8, r15
mov.l @r15+, r8
mov.l @r15+, r9
rts
mov.l @r15+, r10
7:
/* Check whether the time expired. */
mov #-ETIMEDOUT, r1
cmp/eq r0, r1
bt 5f
bra 1b
nop
3:
rts
mov #EINVAL, r0
5:
bra 6b
mov #ETIMEDOUT, r0
.L1k:
.word 1000
.align 2
.L1g:
.long 1000000000
.size __lll_mutex_timedlock_wait,.-__lll_mutex_timedlock_wait
.globl __lll_mutex_unlock_wake
.type __lll_mutex_unlock_wake,@function
.hidden __lll_mutex_unlock_wake
.align 5
__lll_mutex_unlock_wake:
mov #FUTEX_WAKE, r5
mov #1, r6 /* Wake one thread. */
mov #0, r7
mov.l r7, @r4 /* Stores 0. */
mov #SYS_futex, r3
extu.b r3, r3
trapa #0x14
SYSCALL_INST_PAD
rts
nop
.size __lll_mutex_unlock_wake,.-__lll_mutex_unlock_wake

View File

@ -0,0 +1,68 @@
/* Copyright (C) 2003 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. */
#ifdef __ASSEMBLER__
#define _IMP1 #1
#define _IMM1 #-1
#define _IMM6 #-6
#define _IMM8 #-8
#define INC(mem, reg) \
.align 2; \
mova 99f, r0; \
mov r15, r1; \
mov _IMM6, r15; \
98: mov.l mem, reg; \
add _IMP1, reg; \
mov.l reg, mem; \
99: mov r1, r15
#define DEC(mem, reg) \
.align 2; \
mova 99f, r0; \
mov r15, r1; \
mov _IMM6, r15; \
98: mov.l mem, reg; \
add _IMM1, reg; \
mov.l reg, mem; \
99: mov r1, r15
#define XADD(reg, mem, old) \
.align 2; \
mova 99f, r0; \
mov r15, r1; \
mov _IMM6, r15; \
98: mov.l mem, old; \
add old, reg; \
mov.l reg, mem; \
99: mov r1, r15
#define CMPXCHG(reg, mem, new, old) \
.align 2; \
mova 99f, r0; \
nop; \
mov r15, r1; \
mov _IMM8, r15; \
98: mov.l mem, old; \
cmp/eq old, reg; \
bf 99f; \
mov.l new, mem; \
99: mov r1, r15
#endif /* __ASSEMBLER__ */

View File

@ -0,0 +1,23 @@
/* Copyright (C) 2002, 2003 Free Software Foundation, Inc.
This file is part of the GNU C Library.
Contributed by Ulrich Drepper <drepper@redhat.com>, 2002.
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. */
#define cond_lock 0
#define total_seq 4
#define wakeup_seq 12
#define woken_seq 20

View File

@ -0,0 +1,224 @@
/* Copyright (C) 2003 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 "lowlevel-atomic.h"
.text
#define SYS_gettimeofday __NR_gettimeofday
#define SYS_futex 240
#define FUTEX_WAIT 0
#define FUTEX_WAKE 1
#define ETIMEDOUT 110
.globl __lll_lock_wait
.type __lll_lock_wait,@function
.hidden __lll_lock_wait
.align 5
__lll_lock_wait:
mov r4, r6
mov r5, r4
mov #0, r7 /* No timeout. */
mov #FUTEX_WAIT, r5
2:
add #-1, r6 /* account for the preceeded xadd. */
mov #SYS_futex, r3
extu.b r3, r3
trapa #0x14
SYSCALL_INST_PAD
mov #-1, r3
XADD (r3, @r4, r2)
tst r3, r3
bf/s 2b
mov r2, r6
mov #-1, r1
mov.l r1, @r4
rts
mov r2, r0
.size __lll_lock_wait,.-__lll_lock_wait
.globl lll_unlock_wake_cb
.type lll_unlock_wake_cb,@function
.hidden lll_unlock_wake_cb
.align 5
lll_unlock_wake_cb:
.align 2
mova 1f, r0
mov r15, r1
mov #-6, r15
0:
mov.l @r4, r2
add #1, r2
mov.l r2, @r4
1:
mov r1, r15
cmp/pl r2
bf 2f
rts
nop
.size lll_unlock_wake_cb,.-lll_unlock_wake_cb
.globl __lll_unlock_wake
.type __lll_unlock_wake,@function
.hidden __lll_unlock_wake
__lll_unlock_wake:
2:
mov #FUTEX_WAKE, r5
mov #1, r6 /* Wake one thread. */
mov #0, r7
mov.l r6, @r4 /* Stores 1. */
mov #SYS_futex, r3
extu.b r3, r3
trapa #0x14
SYSCALL_INST_PAD
rts
nop
.size __lll_unlock_wake,.-__lll_unlock_wake
.globl __lll_wait_tid
.type __lll_wait_tid,@function
.hidden __lll_wait_tid
__lll_wait_tid:
mov.l @r4, r6
1:
mov #FUTEX_WAIT, r5
mov #0, r7
mov #SYS_futex, r3
extu.b r3, r3
trapa #0x14
SYSCALL_INST_PAD
mov r0, r1
mov.l @r4, r0
tst r0, r0
bf/s 1b
mov r0, r6
rts
nop
.size __lll_wait_tid,.-__lll_wait_tid
.globl __lll_timedwait_tid
.type __lll_timedwait_tid,@function
.hidden __lll_timedwait_tid
__lll_timedwait_tid:
mov.l r9, @-r15
mov.l r8, @-r15
mov r4, r8
mov r5, r9
add #-8, r15
2:
/* Get current time. */
mov r15, r4
mov #0, r5
mov #SYS_gettimeofday, r3
trapa #0x12
SYSCALL_INST_PAD
/* Compute relative timeout. */
mov.l @(4,r15), r0
mov.w .L1k, r1
dmulu.l r0, r1 /* Milli 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 5f
mov.l .L1g, r1
add r1, r3
add #-1, r2
5:
cmp/pz r2
bf 6f /* Time is already up. */
mov.l r2, @r15 /* Store relative timeout. */
mov.l r3, @(4,r15)
mov.l @r8, r6
tst r6, r6
bt 4f
mov r8, r4
mov #FUTEX_WAIT, r5
mov r15, r7
mov #SYS_futex, r3
extu.b r3, r3
trapa #0x14
SYSCALL_INST_PAD
mov r0, r1
mov.l @r8, r0
tst r0, r0
bf 1f
4:
mov #0, r0
3:
add #8, r15
mov.l @r15+, r8
rts
mov.l @r15+, r9
1:
mov #-ETIMEDOUT, r1
cmp/eq r0, r1
bf 2b
6:
bra 3b
mov #ETIMEDOUT, r0
.L1k:
.word 1000
.align 2
.L1g:
.long 1000000000
.size __lll_timedwait_tid,.-__lll_timedwait_tid
.globl __lll_wake_tid
.type __lll_wake_tid,@function
.hidden __lll_wake_tid
__lll_wake_tid:
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 __lll_wake_tid,.-__lll_wake_tid

View File

@ -0,0 +1,245 @@
/* Copyright (C) 2003 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. */
#ifndef _LOWLEVELLOCK_H
#define _LOWLEVELLOCK_H 1
#include <time.h>
#include <sys/param.h>
#include <bits/pthreadtypes.h>
#define SYS_futex 240
#define FUTEX_WAIT 0
#define FUTEX_WAKE 1
/* Initializer for compatibility lock. */
#define LLL_MUTEX_LOCK_INITIALIZER (0)
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_mutex_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" (1), "r" (0) \
: "r0", "r1", "r2", "t", "memory"); \
__result; })
#define lll_mutex_lock(futex) \
(void) ({ int __result, val, *__futex = &(futex); \
__asm __volatile ("\
.align 2\n\
mova 1f,r0\n\
mov r15,r1\n\
mov #-6,r15\n\
0: mov.l @%2,%0\n\
add %0,%1\n\
mov.l %1,@%2\n\
1: mov r1,r15"\
: "=&r" (__result), "=&r" (val) : "r" (__futex), "1" (1) \
: "r0", "r1", "memory"); \
if (__result) \
__lll_mutex_lock_wait (__result, __futex); })
#define lll_mutex_timedlock(futex, timeout) \
({ int __result, val, *__futex = &(futex); \
__asm __volatile ("\
.align 2\n\
mova 1f,r0\n\
mov r15,r1\n\
mov #-6,r15\n\
0: mov.l @%2,%0\n\
add %0,%1\n\
mov.l %1,@%2\n\
1: mov r1,r15"\
: "=&r" (__result), "=&r" (val) : "r" (__futex), "1" (1) \
: "r0", "r1", "memory"); \
if (__result) \
__result = __lll_mutex_timedlock_wait (__result, __futex, timeout); \
__result; })
#define lll_mutex_unlock(futex) \
(void) ({ int __result, *__futex = &(futex); \
__asm __volatile ("\
.align 2\n\
mova 1f,r0\n\
mov r15,r1\n\
mov #-6,r15\n\
0: mov.l @%1,%0\n\
add #-1,%0\n\
mov.l %0,@%1\n\
1: mov r1,r15"\
: "=&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 (1)
#define LLL_LOCK_INITIALIZER_LOCKED (0)
extern int __lll_lock_wait (int val, int *__futex) attribute_hidden;
extern int __lll_unlock_wake (int *__futex) attribute_hidden;
extern int lll_unlock_wake_cb (int *__futex) attribute_hidden;
/* The states of a lock are:
1 - untaken
0 - taken by one user
<0 - taken by more users */
#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" (0), "r" (1) \
: "r0", "r1", "r2", "t", "memory"); \
__result; })
#define lll_lock(futex) \
(void) ({ int __result, val, *__futex = &(futex); \
__asm __volatile ("\
.align 2\n\
mova 1f,r0\n\
mov r15,r1\n\
mov #-6,r15\n\
0: mov.l @%2,%0\n\
add %0,%1\n\
mov.l %1,@%2\n\
1: mov r1,r15"\
: "=&r" (__result), "=&r" (val) : "r" (__futex), "1" (-1) \
: "r0", "r1", "memory"); \
if (val < 0) \
__lll_lock_wait (__result, __futex); })
#define lll_unlock(futex) \
(void) ({ int __result, *__futex = &(futex); \
__asm __volatile ("\
.align 2\n\
mova 1f,r0\n\
mov r15,r1\n\
mov #-6,r15\n\
0: mov.l @%1,%0\n\
add #1,%0\n\
mov.l %0,@%1\n\
1: mov r1,r15"\
: "=&r" (__result) : "r" (__futex) \
: "r0", "r1", "memory"); \
if (__result <= 0) \
__lll_unlock_wake (__futex); })
#define lll_islocked(futex) \
(futex <= 0)
/* 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); \
if (*__tid != 0) \
__lll_wait_tid (__tid); \
} while (0)
extern int __lll_timedwait_tid (int *tid, const struct timespec *abstime)
attribute_hidden;
#define lll_timedwait_tid(tid, abstime) \
({ \
int __result = 0; \
if (tid != 0) \
{ \
if (abstime == NULL || abstime->tv_nsec >= 1000000000) \
__result = EINVAL; \
else \
__result = __lll_timedwait_tid (&tid, abstime); \
} \
__result; })
extern int __lll_wake_tid (int *tid) attribute_hidden;
#define lll_wake_tid(tid) \
do { \
(tid) = 0; \
___lll_wake_tid (&tid); \
} while (0)
/* 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 /* lowlevellock.h */

View File

@ -0,0 +1,174 @@
/* Copyright (C) 2003 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 "lowlevel-atomic.h"
.text
#define SYS_gettimeofday __NR_gettimeofday
#define SYS_futex 240
#define FUTEX_WAIT 0
#define FUTEX_WAKE 1
#define EWOULDBLOCK 11
#define EINVAL 22
#define ETIMEDOUT 110
.globl __lll_mutex_lock_wait
.type __lll_mutex_lock_wait,@function
.hidden __lll_mutex_lock_wait
.align 5
__lll_mutex_lock_wait:
mov r4, r6
mov r5, r4
mov #0, r7 /* No timeout. */
mov #FUTEX_WAIT, r5
1:
add #1, r6 /* account for the preceeded xadd. */
mov #SYS_futex, r3
extu.b r3, r3
trapa #0x14
SYSCALL_INST_PAD
mov #1, r3
XADD (r3, @r4, r6)
tst r6, r6
bf 1b
mov #2, r1
mov.l r1, @r4
ret
mov #0, r0
.size __lll_mutex_lock_wait,.-__lll_mutex_lock_wait
.globl __lll_mutex_timedlock_wait
.type __lll_mutex_timedlock_wait,@function
.hidden __lll_mutex_timedlock_wait
.align 5
__lll_mutex_timedlock_wait:
/* Check for a valid timeout value. */
mov.l @(4,r6), r1
mov.l .L1g, r0
cmp/hs r0, r1
bt 3f
mov.l r10, @-r15
mov.l r9, @-r15
mov.l r8, @-r15
mov r5, r8
mov r6, r9
mov r4, r10
add #1, r10
/* Stack frame for the timespec and timeval structs. */
add #-8, r15
1:
/* Get current time. */
mov r15, r4
mov #0, r5
mov #SYS_gettimeofday, r3
trapa #0x12
SYSCALL_INST_PAD
/* Compute relative timeout. */
mov.l @(4,r15), r0
mov.w .L1k, r1
dmulu.l r0, r1 /* Micro seconds to nano seconds. */
mov.l @r9, r2
mov.l @(4,r9), r3
mov.l @r15, r0
sts macl, r1
sub r0, r2
clrt
subc r1, r3
bf 4f
mov.l .L1g, r1
add r1, r3
add #-1, r2
4:
cmp/pz r2
bf 5f /* Time is already up. */
mov.l r2, @r15 /* Store relative timeout. */
mov.l r3, @(4,r15)
mov r8, r4
mov #FUTEX_WAIT, r5
mov r10, r6
mov r15, r7
mov #SYS_futex, r3
extu.b r3, r3
trapa #0x14
SYSCALL_INST_PAD
mov #1, r3
XADD (r3, @r8, r10)
tst r10, r10
bf 7f
mov #2, r1
mov.l r1, @r8
mov #0, r0
6:
add #8, r15
mov.l @r15+, r8
mov.l @r15+, r9
rts
mov.l @r15+, r10
7:
/* Check whether the time expired. */
mov #-ETIMEDOUT, r1
cmp/eq r0, r1
bt 5f
bra 1b
nop
3:
rts
mov #EINVAL, r0
5:
bra 6b
mov #ETIMEDOUT, r0
.L1k:
.word 1000
.align 2
.L1g:
.long 1000000000
.size __lll_mutex_timedlock_wait,.-__lll_mutex_timedlock_wait
.globl __lll_mutex_unlock_wake
.type __lll_mutex_unlock_wake,@function
.hidden __lll_mutex_unlock_wake
.align 5
__lll_mutex_unlock_wake:
mov #FUTEX_WAKE, r5
mov #1, r6 /* Wake one thread. */
mov #0, r7
mov.l r7, @r4 /* Stores 0. */
mov #SYS_futex, r3
extu.b r3, r3
trapa #0x14
SYSCALL_INST_PAD
rts
nop
.size __lll_mutex_unlock_wake,.-__lll_mutex_unlock_wake

View File

@ -0,0 +1,28 @@
/* Copyright (C) 2002, 2003 Free Software Foundation, Inc.
This file is part of the GNU C Library.
Contributed by Ulrich Drepper <drepper@redhat.com>, 2002.
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. */
/* Offsets in the pthread_rwlock_t structure. */
#define MUTEX 0
#define NR_READERS 4
#define READERS_WAKEUP 8
#define WRITERS_WAKEUP 12
#define READERS_QUEUED 16
#define WRITERS_QUEUED 20
#define FLAGS 24
#define WRITER 28

View File

@ -0,0 +1,143 @@
/* Special .init and .fini section support for SH. NPTL version.
Copyright (C) 2003 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 Library General Public
License as published by the Free Software Foundation; either
version 2 of the License, or (at your option) any later version.
In addition to the permissions in the GNU Library General Public
License, the Free Software Foundation gives you unlimited
permission to link the compiled version of this file with other
programs, and to distribute those programs without any restriction
coming from the use of this file. (The Library General Public
License restrictions do apply in other respects; for example, they
cover modification of the file, and distribution when not linked
into another program.)
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 Library General Public License for more details.
You should have received a copy of the GNU Library General Public
License along with the GNU C Library; see the file COPYING.LIB. If not,
write to the Free Software Foundation, 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
/* This file is compiled into assembly code which is then munged by a sed
script into two files: crti.s and crtn.s.
* crti.s puts a function prologue at the beginning of the
.init and .fini sections and defines global symbols for
those addresses, so they can be called as functions.
* crtn.s puts the corresponding function epilogues
in the .init and .fini sections. */
__asm__ ("\n\
\n\
#include \"defs.h\"\n\
\n\
/*@HEADER_ENDS*/\n\
\n\
/*@TESTS_BEGIN*/\n\
\n\
/*@TESTS_END*/\n\
\n\
/*@_init_PROLOG_BEGINS*/\n\
.section .init\n\
.align 5\n\
.global _init\n\
.type _init,@function\n\
_init:\n\
mov.l r12,@-r15\n\
mov.l r14,@-r15\n\
sts.l pr,@-r15\n\
mova .L22,r0\n\
mov.l .L22,r12\n\
add r0,r12\n\
mova .L24,r0\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\
ALIGN\n\
END_INIT\n\
\n\
/*@_init_PROLOG_ENDS*/\n\
\n\
/*@_init_EPILOG_BEGINS*/\n\
.section .init\n\
mov r14,r15\n\
lds.l @r15+,pr\n\
mov.l @r15+,r14\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\
/*@_fini_PROLOG_BEGINS*/\n\
.section .fini\n\
.align 5\n\
.global _fini\n\
.type _fini,@function\n\
_fini:\n\
mov.l r12,@-r15\n\
mov.l r14,@-r15\n\
sts.l pr,@-r15\n\
mova .L27,r0\n\
mov.l .L27,r12\n\
add r0,r12\n\
mov r15,r14\n\
ALIGN\n\
END_FINI\n\
bra 1f\n\
nop\n\
.align 2\n\
.L27:\n\
.long _GLOBAL_OFFSET_TABLE_\n\
1:\n\
/*@_fini_PROLOG_ENDS*/\n\
\n\
/*@_fini_EPILOG_BEGINS*/\n\
.section .fini\n\
mov r14,r15\n\
lds.l @r15+,pr\n\
mov.l @r15+,r14\n\
rts \n\
mov.l @r15+,r12\n\
\n\
END_FINI\n\
\n\
/*@_fini_EPILOG_ENDS*/\n\
\n\
/*@TRAILER_BEGINS*/\n\
");

View File

@ -0,0 +1 @@
#include <sysdeps/unix/sysv/linux/sh/vfork.S>

View File

@ -0,0 +1,164 @@
/* Copyright (C) 2003 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 "lowlevel-atomic.h"
#define SYS_futex 240
#define FUTEX_WAIT 0
#define FUTEX_WAKE 1
#define CURR_EVENT 0
#define MUTEX 4
#define LEFT 8
#define INIT_COUNT 12
.text
.globl pthread_barrier_wait
.type pthread_barrier_wait,@function
.align 5
pthread_barrier_wait:
mov.l r9, @-r15
mov.l r8, @-r15
sts.l pr, @-r15
mov r4, r8
/* Get the mutex. */
mov #-1, r3
XADD (r3, @(MUTEX,r8), r2)
tst r3, r3
bf 1f
/* One less waiter. If this was the last one needed wake
everybody. */
2:
mov.l @(LEFT,r8), r0
add #-1, r0
mov.l r0, @(LEFT,r8)
tst r0, r0
bt 3f
/* There are more threads to come. */
mov.l @(CURR_EVENT,r8), r6
/* Release the mutex. */
INC (@(MUTEX,r8), r2)
cmp/pl r2
bf 6f
7:
/* Wait for the remaining threads. The call will return immediately
if the CURR_EVENT memory has meanwhile been changed. */
mov r8, r4
#if CURR_EVENT != 0
add #CURR_EVENT, r4
#endif
mov #FUTEX_WAIT, r5
mov #0, r7
8:
mov #SYS_futex, r3
extu.b r3, r3
trapa #0x14
SYSCALL_INST_PAD
/* Don't return on spurious wakeups. The syscall does not change
any register except r0 so there is no need to reload any of
them. */
mov.l @(CURR_EVENT,r8), r0
cmp/eq r0, r6
bt 8b
mov #0, r0 /* != PTHREAD_BARRIER_SERIAL_THREAD */
lds.l @r15+, pr
mov.l @r15+, r8
rts
mov.l @r15+, r9
3:
/* The necessary number of threads arrived. */
mov.l @(INIT_COUNT,r8), r0
mov.l r0, @(LEFT,r8)
mov.l @(CURR_EVENT,r8), r1
add #1, r1
mov.l r1, @(CURR_EVENT,r8)
/* Wake up all waiters. The count is a signed number in the kernel
so 0x7fffffff is the highest value. */
mov.l .Lall, r6
mov r8, r4
#if CURR_EVENT != 0
add #CURR_EVENT, r4
#endif
mov #0, r7
mov #FUTEX_WAKE, r5
mov #SYS_futex, r3
extu.b r3, r3
trapa #0x14
SYSCALL_INST_PAD
/* Release the mutex. */
INC (@(MUTEX,r8), r2)
cmp/pl r2
bf 4f
5:
mov #-1, r0 /* == PTHREAD_BARRIER_SERIAL_THREAD */
lds.l @r15+, pr
mov.l @r15+, r8
ret
mov.l @r15+, r9
1:
mov r2, r4
mov r8, r5
mov.l .Lwait0, r1
bsrf r1
add #MUTEX, r5
.Lwait0b:
bra 2b
nop
4:
mov r8, r4
mov.l .Lwake0, r1
bsrf r1
add #MUTEX, r4
.Lwake0b:
bra 5b
nop
6:
mov r6, r9
mov r8, r4
mov.l .Lwake1, r1
bsrf r1
add #MUTEX, r4
.Lwake1b:
bra 7b
mov r9, r6
.align 2
.Lall:
.long 0x7fffffff
.Lwait0:
.long __lll_lock_wait-.Lwait0b
.Lwake0:
.long __lll_unlock_wake-.Lwake0b
.Lwake1:
.long __lll_unlock_wake-.Lwake1b
.size pthread_barrier_wait,.-pthread_barrier_wait

View File

@ -0,0 +1,126 @@
/* Copyright (C) 2003 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 <shlib-compat.h>
#include <lowlevelcond.h>
#include "lowlevel-atomic.h"
#define SYS_futex 240
#define FUTEX_WAIT 0
#define FUTEX_WAKE 1
.text
/* int pthread_cond_broadcast (pthread_cond_t *cond) */
.globl __pthread_cond_broadcast
.type __pthread_cond_broadcast, @function
.align 5
__pthread_cond_broadcast:
mov.l r8, @-r15
sts.l pr, @-r15
mov r4, r8
/* Get internal lock. */
mov #1, r3
#if cond_lock != 0
XADD (r3, @(cond_lock,r8), r2)
#else
XADD (r3, @r8, r2)
#endif
tst r2, r2
bf 1f
2:
mov.l @(total_seq+4,r8),r0
mov.l @(total_seq,r8),r1
mov.l @(wakeup_seq+4,r8), r2
cmp/hi r2, r0
bt 3f
cmp/hi r0, r2
bt 4f
mov.l @(wakeup_seq,r8), r2
cmp/hi r2, r1
bf 4f
3:
/* Case all currently waiting threads to wake up. */
mov.l r1, @(wakeup_seq,r8)
mov.l r0, @(wakeup_seq+4,r8)
/* Wake up all threads. */
mov r8, r4
add #wakeup_seq, 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
4:
/* Unlock. */
#if cond_lock != 0
DEC (@(cond_lock,r8), r2)
#else
DEC (@r8, r2)
#endif
tst r2, r2
bf 5f
6:
mov #0, r0
lds.l @r15+, pr
rts
mov.l @r15+, r8
1:
/* Initial locking failed. */
mov r8, r5
#if cond_lock != 0
add #cond_lock, r5
#endif
mov.l .Lmwait5, r1
bsrf r1
mov r2, r4
.Lmwait5b:
bra 2b
nop
5:
/* Unlock in loop requires waekup. */
mov r8, r4
#if cond_lock != 0
add #cond_lock, r4
#endif
mov.l .Lmwake5, r1
bsrf r1
nop
.Lmwake5b:
bra 6b
nop
.align 2
.Lmwait5:
.long __lll_mutex_lock_wait-.Lmwait5b
.Lmwake5:
.long __lll_mutex_unlock_wake-.Lmwake5b
.size __pthread_cond_broadcast, .-__pthread_cond_broadcast
versioned_symbol (libpthread, __pthread_cond_broadcast, pthread_cond_broadcast,
GLIBC_2_3_2)

View File

@ -0,0 +1,133 @@
/* Copyright (C) 2003 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 <shlib-compat.h>
#include <lowlevelcond.h>
#include "lowlevel-atomic.h"
#define SYS_futex 240
#define FUTEX_WAIT 0
#define FUTEX_WAKE 1
.text
/* int pthread_cond_signal (pthread_cond_t *cond) */
.globl __pthread_cond_signal
.type __pthread_cond_signal, @function
.align 5
__pthread_cond_signal:
mov.l r8, @-r15
sts.l pr, @-r15
mov r4, r8
/* Get internal lock. */
mov #1, r3
#if cond_lock != 0
XADD (r3, @(cond_lock,r8), r2)
#else
XADD (r3, @r8, r2)
#endif
tst r2, r2
bf 1f
2:
mov.l @(total_seq+4,r8),r0
mov.l @(total_seq,r8),r1
mov.l @(wakeup_seq+4,r8), r2
cmp/hi r2, r0
bt 3f
cmp/hi r0, r2
bt 4f
mov.l @(wakeup_seq,r8), r2
cmp/hi r2, r1
bf 4f
3:
/* Bump the wakeup number. */
mov #1, r2
mov #0, r3
clrt
mov.l @(wakeup_seq,r8),r0
mov.l @(wakeup_seq+4,r8),r1
addc r2, r0
addc r3, r1
mov.l r0,@(wakeup_seq,r8)
mov.l r1,@(wakeup_seq+4,r8)
/* Wake up one thread. */
mov r8, r4
add #wakeup_seq, r4
mov #FUTEX_WAKE, r5
mov #1, r6
mov #0, r7
mov #SYS_futex, r3
extu.b r3, r3
trapa #0x14
SYSCALL_INST_PAD
4:
/* Unlock. */
#if cond_lock != 0
DEC (@(cond_lock,r8), r2)
#else
DEC (@r8, r2)
#endif
tst r2, r2
bf 5f
6:
mov #0, r0
lds.l @r15+, pr
rts
mov.l @r15+, r8
1:
/* Initial locking failed. */
mov r8, r5
#if cond_lock != 0
add #cond_lock, r5
#endif
mov.l .Lmwait4, r1
bsrf r1
mov r2, r4
.Lmwait4b:
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
.size __pthread_cond_signal, .-__pthread_cond_signal
versioned_symbol (libpthread, __pthread_cond_signal, pthread_cond_signal,
GLIBC_2_3_2)

View File

@ -0,0 +1,361 @@
/* Copyright (C) 2003 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 <shlib-compat.h>
#include <lowlevelcond.h>
#include "lowlevel-atomic.h"
#define SYS_gettimeofday __NR_gettimeofday
#define SYS_futex 240
#define FUTEX_WAIT 0
#define FUTEX_WAKE 1
#define ETIMEDOUT 110
.text
/* int pthread_cond_timedwait (pthread_cond_t *cond, pthread_mutex_t *mutex,
const struct timespec *abstime) */
.globl __pthread_cond_timedwait
.type __pthread_cond_timedwait, @function
.align 5
__pthread_cond_timedwait:
mov.l r12, @-r15
mov.l r10, @-r15
mov.l r9, @-r15
mov.l r8, @-r15
sts.l pr, @-r15
add #-48, r15
mov r4, r8
mov r5, r9
mov r6, r10
/* Get internal lock. */
mov #1, r3
#if cond_lock != 0
XADD (r3, @(cond_lock,r8), r2)
#else
XADD (r3, @r8, r2)
#endif
tst r2, r2
bt 2f
bra 1f
nop
2:
/* Unlock the mutex. */
mov.l .Lmunlock1, r1
bsrf r1
mov r9, r4
.Lmunlock1b:
mov #1, r2
mov #0, r3
clrt
mov.l @(total_seq,r8),r0
mov.l @(total_seq+4,r8),r1
addc r2, r0
addc r3, r1
mov.l r0,@(total_seq,r8)
mov.l r1,@(total_seq+4,r8)
/* Install cancellation handler. */
#ifdef PIC
mova .Lgot1, r0
mov.l .Lgot1, r12
add r0, r12
mov.l .Lccleanup1, r5
add r12, r5
#else
mov.l .Lccleanup1, r5
#endif
mov r15, r4
add #28, r4
mov.l .Lccpush1, r1
bsrf r1
mov r8, r6
.Lccpush1b:
/* Get and store current wakeup_seq value. */
mov.l @(wakeup_seq,r8), r0
mov.l @(wakeup_seq+4,r8), r1
mov.l r0, @(12,r15)
mov.l r1, @(16,r15)
/* Unlock. */
8:
#if cond_lock != 0
DEC (@(cond_lock,r8), r2)
#else
DEC (@r8, r2)
#endif
tst r2, r2
bt 4f
bra 3f
nop
4:
mov.l .Lenable1, r1
bsrf r1
nop
.Lenable1b:
mov.l r0, @r15
/* Get current time. */
mov r15, r4
add #4, r4
mov #0, r5
mov #SYS_gettimeofday, r3
trapa #0x12
SYSCALL_INST_PAD
/* Compute relative timeout. */
mov.l @(8,r15), r0
mov.w .L1k, r1
dmulu.l r0, r1 /* Milli seconds to nano seconds. */
mov.l @r10, r2
mov.l @(4,r10), r3
mov.l @(4,r15), r0
sts macl, r1
sub r0, r2
clrt
subc r1, r3
bf 12f
mov.l .L1g, r1
add r1, r3
add #-1, r2
12:
cmp/pz r2
bf 13f /* Time is already up. */
/* Store relative timeout. */
mov.l r2, @(4,r15)
mov.l r3, @(8,r15)
mov r15, r7
add #4, r7
mov #FUTEX_WAIT, r5
mov.l @(12,r15), r6
mov r8, r4
add #wakeup_seq, r4
mov #SYS_futex, r3
extu.b r3, r3
trapa #0x14
SYSCALL_INST_PAD
mov.l r0, @(20,r15)
mov.l .Ldisable1, r1
bsrf r1
mov.l @r15, r4
.Ldisable1b:
/* Lock. */
mov #1, r3
#if cond_lock != 0
XADD (r3, @(cond_lock,r8), r2)
#else
XADD (r3, @r8, r2)
#endif
tst r2, r2
bf 5f
6:
mov.l @(woken_seq,r8), r0
mov.l @(woken_seq+4,r8), r1
mov.l @(wakeup_seq,r8), r2
mov.l @(wakeup_seq+4,r8), r3
mov.l @(16,r15), r5
cmp/hi r5, r1
bt 7f
cmp/hi r1, r5
bt 15f
mov.l @(12,r15), r5
cmp/hi r0, r5
bt 15f
7:
cmp/hi r1, r3
bt 9f
cmp/hi r3, r1
bt 15f
cmp/hi r0, r2
bt 9f
15:
mov.l @(20,r15),r0
cmp/eq #-ETIMEDOUT, r0
bf 8b
13:
mov #1, r2
mov #0, r3
clrt
mov.l @(wakeup_seq,r8),r0
mov.l @(wakeup_seq+4,r8),r1
addc r2, r0
addc r3, r1
mov.l r0,@(wakeup_seq,r8)
mov.l r1,@(wakeup_seq+4,r8)
mov #ETIMEDOUT, r0
bra 14f
mov.l r0, @(24,r15)
9:
mov #0, r0
mov.l r0, @(24,r15)
14:
mov #1, r2
mov #0, r3
clrt
mov.l @(woken_seq,r8),r0
mov.l @(woken_seq+4,r8),r1
addc r2, r0
addc r3, r1
mov.l r0,@(woken_seq,r8)
mov.l r1,@(woken_seq+4,r8)
#if cond_lock != 0
DEC (@(cond_lock,r8), r2)
#else
DEC (@r8, r2)
#endif
tst r2, r2
bf 10f
11:
/* Remove cancellation handler. */
mov r15, r4
add #28, r4
mov.l .Lcpop1, r1
bsrf r1
mov #0, r5
.Lcpop1b:
mov r9, r4
mov.l .Lmlocki1, r1
bsrf r1
mov #0, r5
.Lmlocki1b:
mov.l @(24,r15), r0
add #48, r15
/* We return the result of the mutex_lock operation. */
lds.l @r15+, pr
mov.l @r15+, r8
mov.l @r15+, r9
mov.l @r15+, r10
rts
mov.l @r15+, r12
ret
.L1k:
.word 1000
.align 2
.Lmunlock1:
.long __pthread_mutex_unlock_internal-.Lmunlock1b
#ifdef PIC
.Lgot1:
.long _GLOBAL_OFFSET_TABLE_
.Lccleanup1:
.long __condvar_cleanup@GOTOFF
#else
.Lccleanup1:
.long __condvar_cleanup
#endif
.Lccpush1:
.long __pthread_cleanup_push-.Lccpush1b
.Lenable1:
.long __pthread_enable_asynccancel-.Lenable1b
.Ldisable1:
.long __pthread_disable_asynccancel-.Ldisable1b
.Lcpop1:
.long __pthread_cleanup_pop-.Lcpop1b
.Lmlocki1:
.long __pthread_mutex_lock_internal-.Lmlocki1b
.L1g:
.long 1000000000
1:
/* Initial locking failed. */
mov r8, r5
#if cond_lock != 0
add #cond_lock, r5
#endif
mov.l .Lmwait2, r1
bsrf r1
mov r2, r4
.Lmwait2b:
bra 2b
nop
3:
/* Unlock in loop requires waekup. */
mov r8, r4
#if cond_lock != 0
add #cond_lock, r4
#endif
mov.l .Lmwake2, r1
bsrf r1
nop
.Lmwake2b:
bra 4b
nop
5:
/* Locking in loop failed. */
mov r8, r5
#if cond_lock != 0
add #cond_lock, r5
#endif
mov.l .Lmwait3, r1
bsrf r1
mov r2, r4
.Lmwait3b:
bra 6b
nop
10:
/* Unlock after loop requires waekup. */
mov r8, r4
#if cond_lock != 0
add #cond_lock, r4
#endif
mov.l .Lmwake3, r1
bsrf r1
nop
.Lmwake3b:
bra 11b
nop
.align 2
.Lmwait2:
.long __lll_mutex_lock_wait-.Lmwait2b
.Lmwake2:
.long __lll_mutex_unlock_wake-.Lmwake2b
.Lmwait3:
.long __lll_mutex_lock_wait-.Lmwait3b
.Lmwake3:
.long __lll_mutex_unlock_wake-.Lmwake3b
.size __pthread_cond_timedwait, .-__pthread_cond_timedwait
versioned_symbol (libpthread, __pthread_cond_timedwait, pthread_cond_timedwait,
GLIBC_2_3_2)

View File

@ -0,0 +1,364 @@
/* Copyright (C) 2003 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 <shlib-compat.h>
#include <lowlevelcond.h>
#include "lowlevel-atomic.h"
#define SYS_futex 240
#define FUTEX_WAIT 0
#define FUTEX_WAKE 1
.text
.align 5
.type __condvar_cleanup, @function
.globl __condvar_cleanup
.hidden __condvar_cleanup
__condvar_cleanup:
mov.l r8, @-r15
sts.l pr, @-r15
mov r4, r8
/* Get internal lock. */
mov #1, r3
#if cond_lock != 0
XADD (r3, @(cond_lock,r8), r2)
#else
XADD (r3, @r8, r2)
#endif
tst r2, r2
bt 1f
mov r8, r5
#if cond_lock != 0
add #cond_lock, r5
#endif
mov r2, r4
mov.l .Lwait0, r1
bsrf r1
nop
.Lwait0b:
1:
mov #1, r2
mov #0, r3
clrt
mov.l @(wakeup_seq,r8),r0
mov.l @(wakeup_seq+4,r8),r1
addc r2, r0
addc r3, r1
mov.l r0,@(wakeup_seq,r8)
mov.l r1,@(wakeup_seq+4,r8)
clrt
mov.l @(woken_seq,r8),r0
mov.l @(woken_seq+4,r8),r1
addc r2, r0
addc r3, r1
mov.l r0,@(woken_seq,r8)
mov.l r1,@(woken_seq+4,r8)
/* Release internal lock. */
#if cond_lock != 0
DEC (@(cond_lock,r8), r2)
#else
DEC (@r8, r2)
#endif
tst r2, r2
bt 2f
mov r8, r4
#if cond_lock != 0
add #cond_lock, r4
#endif
mov.l .Lwake0, r1
bsrf r1
nop
.Lwake0b:
2:
lds.l @r15+, pr
rts
mov.l @r15+, r8
.align 2
.Lwait0:
.long __lll_mutex_lock_wait-.Lwait0b
.Lwake0:
.long __lll_mutex_unlock_wake-.Lwake0b
.size __condvar_cleanup, .-__condvar_cleanup
/* int pthread_cond_wait (pthread_cond_t *cond, pthread_mutex_t *mutex) */
.globl __pthread_cond_wait
.type __pthread_cond_wait, @function
.align 5
__pthread_cond_wait:
mov.l r12, @-r15
mov.l r9, @-r15
mov.l r8, @-r15
sts.l pr, @-r15
add #-32, r15
mov r4, r8
mov r5, r9
/* Get internal lock. */
mov #1, r3
#if cond_lock != 0
XADD (r3, @(cond_lock,r8), r2)
#else
XADD (r3, @r8, r2)
#endif
tst r2, r2
bf 1f
2:
/* Unlock the mutex. */
mov.l .Lmunlock0, r1
bsrf r1
mov r9, r4
.Lmunlock0b:
mov #1, r2
mov #0, r3
clrt
mov.l @(total_seq,r8),r0
mov.l @(total_seq+4,r8),r1
addc r2, r0
addc r3, r1
mov.l r0,@(total_seq,r8)
mov.l r1,@(total_seq+4,r8)
/* Install cancellation handler. */
#ifdef PIC
mova .Lgot0, r0
mov.l .Lgot0, r12
add r0, r12
mov.l .Lccleanup0, r5
add r12, r5
#else
mov.l .Lccleanup0, r5
#endif
mov r15, r4
add #12, r4
mov.l .Lccpush0, r1
bsrf r1
mov r8, r6
.Lccpush0b:
/* Get and store current wakeup_seq value. */
mov.l @(wakeup_seq,r8), r0
mov.l @(wakeup_seq+4,r8), r1
mov.l r0, @(4,r15)
mov.l r1, @(8,r15)
8:
/* Unlock. */
#if cond_lock != 0
DEC (@(cond_lock,r8), r2)
#else
DEC (@r8, r2)
#endif
tst r2, r2
bf 3f
4:
mov.l .Lenable0, r1
bsrf r1
nop
.Lenable0b:
mov.l r0, @r15
mov #0, r7
mov #FUTEX_WAIT, r5
mov.l @(4,r15), r6
mov r8, r4
add #wakeup_seq, r4
mov #SYS_futex, r3
extu.b r3, r3
trapa #0x14
SYSCALL_INST_PAD
mov.l .Ldisable0, r1
bsrf r1
mov.l @r15, r4
.Ldisable0b:
/* Lock. */
mov #1, r3
#if cond_lock != 0
XADD (r3, @(cond_lock,r8), r2)
#else
XADD (r3, @r8, r2)
#endif
tst r2, r2
bf 5f
6:
mov.l @(woken_seq,r8), r0
mov.l @(woken_seq+4,r8), r1
mov.l @(wakeup_seq,r8), r2
mov.l @(wakeup_seq+4,r8), r3
mov.l @(8,r15), r5
cmp/hi r5, r1
bt 7f
cmp/hi r1, r5
bt 8b
mov.l @(4,r15), r5
cmp/hi r0, r5
bt 8b
7:
cmp/hi r1, r3
bt 9f
cmp/hi r3, r1
bt 8b
cmp/hi r0, r2
bf 8b
9:
mov #1, r2
mov #0, r3
clrt
mov.l @(woken_seq,r8),r0
mov.l @(woken_seq+4,r8),r1
addc r2, r0
addc r3, r1
mov.l r0,@(woken_seq,r8)
mov.l r1,@(woken_seq+4,r8)
#if cond_lock != 0
DEC (@(cond_lock,r8), r2)
#else
DEC (@r8, r2)
#endif
tst r2, r2
bf 10f
11:
/* Remove cancellation handler. */
mov r15, r4
add #12, r4
mov.l .Lcpop0, r1
bsrf r1
mov #0, r5
.Lcpop0b:
mov r9, r4
mov.l .Lmlocki0, r1
bsrf r1
mov #0, r5
.Lmlocki0b:
add #32, r15
/* We return the result of the mutex_lock operation. */
lds.l @r15+, pr
mov.l @r15+, r8
mov.l @r15+, r9
rts
mov.l @r15+, r12
.align 2
.Lmunlock0:
.long __pthread_mutex_unlock_internal-.Lmunlock0b
#ifdef PIC
.Lgot0:
.long _GLOBAL_OFFSET_TABLE_
.Lccleanup0:
.long __condvar_cleanup@GOTOFF
#else
.Lccleanup0:
.long __condvar_cleanup
#endif
.Lccpush0:
.long __pthread_cleanup_push-.Lccpush0b
.Lenable0:
.long __pthread_enable_asynccancel-.Lenable0b
.Ldisable0:
.long __pthread_disable_asynccancel-.Ldisable0b
.Lcpop0:
.long __pthread_cleanup_pop-.Lcpop0b
.Lmlocki0:
.long __pthread_mutex_lock_internal-.Lmlocki0b
1:
/* Initial locking failed. */
mov r8, r5
#if cond_lock != 0
add #cond_lock, r5
#endif
mov.l .Lmwait0, r1
bsrf r1
mov r2, r4
.Lmwait0b:
bra 2b
nop
3:
/* Unlock in loop requires waekup. */
mov r8, r4
#if cond_lock != 0
add #cond_lock, r4
#endif
mov.l .Lmwake0, r1
bsrf r1
nop
.Lmwake0b:
bra 4b
nop
5:
/* Locking in loop failed. */
mov r8, r5
#if cond_lock != 0
add #cond_lock, r5
#endif
mov.l .Lmwait1, r1
bsrf r1
mov r2, r4
.Lmwait1b:
bra 6b
nop
10:
/* Unlock after loop requires wakeup. */
mov r8, r4
#if cond_lock != 0
add #cond_lock, r4
#endif
mov.l .Lmwake1, r1
bsrf r1
nop
.Lmwake1b:
bra 11b
nop
.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
.size __pthread_cond_wait, .-__pthread_cond_wait
versioned_symbol (libpthread, __pthread_cond_wait, pthread_cond_wait,
GLIBC_2_3_2)

View File

@ -0,0 +1,197 @@
/* Copyright (C) 2003 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 "lowlevel-atomic.h"
#define SYS_futex 240
#define FUTEX_WAIT 0
#define FUTEX_WAKE 1
.comm __fork_generation, 4, 4
.text
.globl __pthread_once
.type __pthread_once,@function
.align 5
__pthread_once:
mov.l @r4, r0
tst #2, r0
bt 1f
rts
mov #0, r0
1:
mov.l r12, @-r15
mov.l r9, @-r15
mov.l r8, @-r15
sts.l pr, @-r15
mov r5, r8
/* Not yet initialized or initialization in progress.
Get the fork generation counter now. */
6:
mov.l @r4, r1
#ifdef PIC
mova .Lgot, r0
mov.l .Lgot, r12
add r0, r12
#endif
5:
mov r1, r0
tst #2, r0
bf 4f
and #3, r0
mov.l .Lfgen, r2
#ifdef PIC
add r12, r2
#endif
mov.l @r2, r3
or r3, r0
or #1, r0
mov r0, r3
mov r1, r5
CMPXCHG (r5, @r4, r3, r2)
bf 5b
/* Check whether another thread already runs the initializer. */
mov r2, r0
tst #1, r0
bt 3f /* No -> do it. */
/* Check whether the initializer execution was interrupted
by a fork. */
xor r3, r0
mov #-4, r1 /* -4 = 0xfffffffc */
tst r1, r0
bf 3f /* Different for generation -> run initializer. */
/* Somebody else got here first. Wait. */
mov #FUTEX_WAIT, r5
mov r3, r6
mov #0, r7
mov #SYS_futex, r3
extu.b r3, r3
trapa #0x14
SYSCALL_INST_PAD
bra 6b
nop
.align 2
#ifdef PIC
.Lgot:
.long _GLOBAL_OFFSET_TABLE_
.Lfgen:
.long __fork_generation@GOTOFF
#else
.Lfgen:
.long __fork_generation
#endif
3:
/* Call the initializer function after setting up the
cancellation handler. */
/* Allocate a _pthread_cleanup_buffer on stack. */
add #-16, r15
/* Push the cleanup handler. */
mov r4, r9
mov r15, r4
mov.l .Lconce, r5
#ifdef PIC
add r12, r5
#endif
mov.l .Lcpush, r1
bsrf r1
mov r3, r6
.Lcpush0:
jsr @r8
nop
/* Pop the cleanup handler. */
mov r15, r4
mov.l .Lcpop, r1
bsrf r1
mov #0, r5
.Lcpop0:
add #16, r15
/* Sucessful run of the initializer. Signal that we are done. */
INC (@r9, r2)
/* Wake up all other threads. */
mov r9, 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
4:
lds.l @r15+, pr
mov.l @r15+, r8
mov.l @r15+, r9
mov.l @r15+, r12
rts
mov #0, r0
.align 2
.Lconce:
#ifdef PIC
.long clear_once_control@GOTOFF
#else
.long clear_once_control
#endif
.Lcpush:
.long __pthread_cleanup_push - .Lcpush0 /* Note: no @PLT. */
.Lcpop:
.long __pthread_cleanup_pop - .Lcpop0 /* Note: no @PLT. */
.size __pthread_once,.-__pthread_once
.globl __pthread_once_internal
__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

View File

@ -0,0 +1,220 @@
/* Copyright (C) 2003 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 <lowlevelrwlock.h>
#include <tcb-offsets.h>
#include "lowlevel-atomic.h"
#define SYS_futex 240
#define FUTEX_WAIT 0
#define FUTEX_WAKE 1
#define EAGAIN 11
#define EDEADLK 35
.text
.globl __pthread_rwlock_rdlock
.type __pthread_rwlock_rdlock,@function
.align 5
__pthread_rwlock_rdlock:
mov.l r12, @-r15
mov.l r8, @-r15
sts.l pr, @-r15
mov r4, r8
/* Get the lock. */
mov #1, r3
#if MUTEX == 0
XADD (r3, @r4, r2)
#else
XADD (r3, @(MUTEX,r4), r2)
#endif
tst r2, r2
bf 1f
2:
mov.l @(WRITER,r8), r0
tst r0, r0
bf 14f
mov.l @(WRITERS_QUEUED,r8), r0
tst r0, r0
bt 5f
mov.l @(FLAGS,r8), r0
tst r0, r0
bt 5f
3:
mov.l @(READERS_QUEUED,r8), r0
add #1, r0
mov.l r0, @(READERS_QUEUED,r8)
tst r0, r0
bt 4f
#if MUTEX == 0
DEC (@r8, r2)
#else
DEC (@(MUTEX,r8), r2)
#endif
tst r2, r2
bf 10f
11:
mov r8, r4
add #READERS_WAKEUP, r4
mov #FUTEX_WAIT, r5
mov #0, r6
mov #SYS_futex, r3
extu.b r3, r3
trapa #0x14
SYSCALL_INST_PAD
/* Reget the lock. */
mov #1, r3
#if MUTEX == 0
XADD (r3, @r4, r2)
#else
XADD (r3, @(MUTEX,r4), r2)
#endif
tst r2, r2
bf 12f
13:
mov.l @(READERS_QUEUED,r8), r0
add #-1, r0
mov.l r0, @(READERS_QUEUED,r8)
tst r0, r0
bf 2b
bra 2b
mov.l r0, @(READERS_WAKEUP,r8)
5:
mov #0, r3
mov.l @(NR_READERS,r8), r0
add #1, r0
mov.l r0, @(NR_READERS,r8)
tst r0, r0
bt 8f
9:
#if MUTEX == 0
DEC (@r8, r2)
#else
DEC (@(MUTEX,r8), r2)
#endif
tst r2, r2
bf 6f
7:
lds.l @r15+, pr
mov.l @r15+, r8
mov.l @r15+, r12
rts
mov r3, r0
1:
mov r8, r5
#if MUTEX != 0
add #MUTEX, r5
#endif
mov r2, r4
mov.l .Lwait0, r1
bsrf r1
nop
.Lwait0b:
bra 2b
nop
14:
stc gbr, r1
mov.w .Ltcboff,r2
sub r2,r1
mov.l @(8,r1),r1
cmp/eq r1, r0
bf 3b
/* Deadlock detected. */
bra 9b
mov #EDEADLK, r3
6:
mov r8, r4
#if MUTEX != 0
add #MUTEX, r4
#endif
mov.l .Lwake0, r1
bsrf r1
nop
.Lwake0b:
bra 7b
mov #0, r3
8:
/* Overflow. */
mov.l @(NR_READERS,r8), r1
add #-1, r1
mov.l r1, @(NR_READERS,r8)
bra 9b
mov #EAGAIN, r3
4:
/* Overflow. */
mov.l @(READERS_QUEUED,r8), r1
add #-1, r1
mov.l r1, @(READERS_QUEUED,r8)
bra 9b
mov #EAGAIN, r3
10:
mov r8, r4
#if MUTEX != 0
add #MUTEX, r4
#endif
mov.l .Lwake1, r1
bsrf r1
nop
.Lwake1b:
bra 11b
nop
12:
mov r8, r5
#if MUTEX != 0
add #MUTEX, r5
#endif
mov r2, r4
mov.l .Lwait1, r1
bsrf r1
nop
.Lwait1b:
bra 13b
nop
.Ltcboff:
.word TLS_PRE_TCB_SIZE
.align 2
.Lwait0:
.long __lll_mutex_lock_wait-.Lwait0b
.Lwake0:
.long __lll_mutex_unlock_wake-.Lwake0b
.Lwait1:
.long __lll_mutex_lock_wait-.Lwait1b
.Lwake1:
.long __lll_mutex_unlock_wake-.Lwake1b
.size __pthread_rwlock_rdlock,.-__pthread_rwlock_rdlock
.globl pthread_rwlock_rdlock
pthread_rwlock_rdlock = __pthread_rwlock_rdlock
.globl __pthread_rwlock_rdlock_internal
__pthread_rwlock_rdlock_internal = __pthread_rwlock_rdlock

View File

@ -0,0 +1,274 @@
/* Copyright (C) 2003 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 <lowlevelrwlock.h>
#include <tcb-offsets.h>
#include "lowlevel-atomic.h"
#define SYS_gettimeofday __NR_gettimeofday
#define SYS_futex 240
#define FUTEX_WAIT 0
#define FUTEX_WAKE 1
#define EAGAIN 11
#define EDEADLK 35
#define ETIMEDOUT 110
.text
.globl pthread_rwlock_timedrdlock
.type pthread_rwlock_timedrdlock,@function
.align 5
pthread_rwlock_timedrdlock:
mov.l r12, @-r15
mov.l r9, @-r15
mov.l r8, @-r15
sts.l pr, @-r15
add #-8, r15
mov r4, r8
mov r5, r9
/* Get the lock. */
mov #1, r3
#if MUTEX == 0
XADD (r3, @r4, r2)
#else
XADD (r3, @(MUTEX,r4), r2)
#endif
tst r2, r2
bf 1f
2:
mov.l @(WRITER,r8), r0
tst r0, r0
bf 14f
mov.l @(WRITERS_QUEUED,r8), r0
tst r0, r0
bt 5f
mov.l @(FLAGS,r8), r0
tst r0, r0
bt 5f
3:
mov.l @(READERS_QUEUED,r8), r0
add #1, r0
mov.l r0, @(READERS_QUEUED,r8)
tst r0, r0
bt 4f
#if MUTEX == 0
DEC (@r8, r2)
#else
DEC (@(MUTEX,r8), r2)
#endif
tst r2, r2
bf 10f
11:
/* Get current time. */
mov r15, r4
mov #0, r5
mov #SYS_gettimeofday, r3
trapa #0x12
SYSCALL_INST_PAD
mov.l @(4,r15), r0
mov.w .L1k0, r1
dmulu.l r0, r1 /* Milli 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 15f
mov.l .L1g0, r1
add r1, r3
add #-1, r2
15:
cmp/pz r2
bf 16f /* Time is already up. */
/* Store relative timeout. */
mov.l r2, @r15
mov.l r3, @(4,r15)
/* Futex call. */
mov r15, r7
mov #FUTEX_WAIT, r5
mov #0, r6
mov r8, r4
add #READERS_WAKEUP, r4
mov #SYS_futex, r3
extu.b r3, r3
trapa #0x14
SYSCALL_INST_PAD
mov r0, r3
17:
/* Reget the lock. */
mov r8, r4
mov #1, r5
#if MUTEX == 0
XADD (r5, @r4, r2)
#else
XADD (r5, @(MUTEX,r4), r2)
#endif
tst r2, r2
bf 12f
13:
mov #-ETIMEDOUT, r0
cmp/eq r0, r3
bt 18f
mov.l @(READERS_QUEUED,r8), r0
add #-1, r0
mov.l r0, @(READERS_QUEUED,r8)
tst r0, r0
bf 2b
bra 2b
mov.l r0, @(READERS_WAKEUP,r8)
5:
mov #0, r3
mov.l @(NR_READERS,r8), r0
add #1, r0
mov.l r0, @(NR_READERS,r8)
tst r0, r0
bt 8f
9:
#if MUTEX == 0
DEC (@r8, r2)
#else
DEC (@(MUTEX,r8), r2)
#endif
tst r2, r2
bf 6f
7:
add #8,r15
lds.l @r15+, pr
mov.l @r15+, r8
mov.l @r15+, r9
mov.l @r15+, r12
rts
mov r3, r0
.align 2
.L1k0:
.long 1000
.L1g0:
.long 1000000000
1:
mov r8, r5
#if MUTEX != 0
add #MUTEX, r5
#endif
mov r2, r4
mov.l .Lwait2, r1
bsrf r1
nop
.Lwait2b:
bra 2b
nop
14:
stc gbr, r1
mov.w .Ltcboff,r2
sub r2,r1
mov.l @(8,r1),r1
cmp/eq r1, r0
bf 3b
/* Deadlock detected. */
bra 9b
mov #EDEADLK, r3
6:
mov r8, r4
#if MUTEX != 0
add #MUTEX, r4
#endif
mov.l .Lwake2, r1
bsrf r1
nop
.Lwake2b:
bra 7b
mov #0, r3
8:
/* Overflow. */
mov.l @(NR_READERS,r8), r1
add #-1, r1
mov.l r1, @(NR_READERS,r8)
bra 9b
mov #EAGAIN, r3
4:
/* Overflow. */
mov.l @(READERS_QUEUED,r8), r1
add #-1, r1
mov.l r1, @(READERS_QUEUED,r8)
bra 9b
mov #EAGAIN, r3
10:
mov r8, r4
#if MUTEX != 0
add #MUTEX, r4
#endif
mov.l .Lwake3, r1
bsrf r1
nop
.Lwake3b:
bra 11b
nop
12:
mov r8, r5
#if MUTEX != 0
add #MUTEX, r5
#endif
mov r2, r4
mov.l .Lwait3, r1
bsrf r1
nop
.Lwait3b:
bra 13b
nop
16:
bra 17b
mov #-ETIMEDOUT, r3
18:
bra 9b
mov #ETIMEDOUT, r3
.Ltcboff:
.word TLS_PRE_TCB_SIZE
.align 2
.Lwait2:
.long __lll_mutex_lock_wait-.Lwait2b
.Lwake2:
.long __lll_mutex_unlock_wake-.Lwake2b
.Lwait3:
.long __lll_mutex_lock_wait-.Lwait3b
.Lwake3:
.long __lll_mutex_unlock_wake-.Lwake3b
.size pthread_rwlock_timedrdlock,.-pthread_rwlock_timedrdlock

View File

@ -0,0 +1,259 @@
/* Copyright (C) 2003 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 <lowlevelrwlock.h>
#include <tcb-offsets.h>
#include "lowlevel-atomic.h"
#define SYS_gettimeofday __NR_gettimeofday
#define SYS_futex 240
#define FUTEX_WAIT 0
#define FUTEX_WAKE 1
#define EAGAIN 11
#define EDEADLK 35
#define ETIMEDOUT 110
.text
.globl pthread_rwlock_timedwrlock
.type pthread_rwlock_timedwrlock,@function
.align 5
pthread_rwlock_timedwrlock:
mov.l r12, @-r15
mov.l r9, @-r15
mov.l r8, @-r15
sts.l pr, @-r15
add #-8, r15
mov r4, r8
mov r5, r9
/* Get the lock. */
mov #1, r3
#if MUTEX == 0
XADD (r3, @r4, r2)
#else
XADD (r3, @(MUTEX,r4), r2)
#endif
tst r2, r2
bf 1f
2:
mov.l @(WRITER,r8), r0
tst r0, r0
bf 14f
mov.l @(NR_READERS,r8), r0
tst r0, r0
bt 5f
3:
mov.l @(WRITERS_QUEUED,r8), r0
add #1, r0
mov.l r0, @(WRITERS_QUEUED,r8)
tst r0, r0
bt 4f
#if MUTEX == 0
DEC (@r8, r2)
#else
DEC (@(MUTEX,r8), r2)
#endif
tst r2, r2
bf 10f
11:
/* Get current time. */
mov r15, r4
mov #0, r5
mov #SYS_gettimeofday, r3
trapa #0x12
SYSCALL_INST_PAD
mov.l @(4,r15), r0
mov.w .L1k1, r1
dmulu.l r0, r1 /* Milli 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 15f
mov.l .L1g1, r1
add r1, r3
add #-1, r2
15:
cmp/pz r2
bf 16f /* Time is already up. */
/* Store relative timeout. */
mov.l r2, @r15
mov.l r3, @(4,r15)
/* Futex call. */
mov r15, r7
mov #FUTEX_WAIT, r5
mov #0, r6
mov r8, r4
add #WRITERS_WAKEUP, r4
mov #SYS_futex, r3
extu.b r3, r3
trapa #0x14
SYSCALL_INST_PAD
mov r0, r3
17:
/* Reget the lock. */
mov r8, r4
mov #1, r5
#if MUTEX == 0
XADD (r5, @r4, r2)
#else
XADD (r5, @(MUTEX,r4), r2)
#endif
tst r2, r2
bf 12f
13:
mov #-ETIMEDOUT, r0
cmp/eq r0, r3
bt 18f
mov.l @(WRITERS_QUEUED,r8), r0
add #-1, r0
mov.l r0, @(WRITERS_QUEUED,r8)
mov #0, r0
bra 2b
mov.l r0, @(WRITERS_WAKEUP,r8)
5:
mov #0, r3
stc gbr, r1
mov.w .Ltcboff,r2
sub r2,r1
mov.l @(8,r1),r0
mov.l r0, @(WRITER,r8)
9:
#if MUTEX == 0
DEC (@r8, r2)
#else
DEC (@(MUTEX,r8), r2)
#endif
tst r2, r2
bf 6f
7:
add #8,r15
lds.l @r15+, pr
mov.l @r15+, r8
mov.l @r15+, r9
mov.l @r15+, r12
rts
mov r3, r0
.L1k1:
.word 1000
.align 2
.L1g1:
.long 1000000000
1:
mov r8, r5
#if MUTEX != 0
add #MUTEX, r5
#endif
mov r2, r4
mov.l .Lwait6, r1
bsrf r1
nop
.Lwait6b:
bra 2b
nop
14:
stc gbr, r1
mov.w .Ltcboff,r2
sub r2,r1
mov.l @(8,r1),r1
cmp/eq r1, r0
bf 3b
bra 9b
mov #EDEADLK, r3
6:
mov r8, r4
#if MUTEX != 0
add #MUTEX, r4
#endif
mov.l .Lwake6, r1
bsrf r1
nop
.Lwake6b:
bra 7b
mov #0, r3
4:
/* Overflow. */
mov.l @(WRITERS_QUEUED,r8), r1
add #-1, r1
mov.l r1, @(WRITERS_QUEUED,r8)
bra 9b
mov #EAGAIN, r3
10:
mov r8, r4
#if MUTEX != 0
add #MUTEX, r4
#endif
mov.l .Lwake7, r1
bsrf r1
nop
.Lwake7b:
bra 11b
nop
12:
mov r8, r5
#if MUTEX != 0
add #MUTEX, r5
#endif
mov r2, r4
mov.l .Lwait7, r1
bsrf r1
nop
.Lwait7b:
bra 13b
nop
16:
bra 17b
mov #-ETIMEDOUT, r3
18:
bra 9b
mov #ETIMEDOUT, r3
.Ltcboff:
.word TLS_PRE_TCB_SIZE
.align 2
.Lwait6:
.long __lll_mutex_lock_wait-.Lwait6b
.Lwake6:
.long __lll_mutex_unlock_wake-.Lwake6b
.Lwait7:
.long __lll_mutex_lock_wait-.Lwait7b
.Lwake7:
.long __lll_mutex_unlock_wake-.Lwake7b
.size pthread_rwlock_timedwrlock,.-pthread_rwlock_timedwrlock

View File

@ -0,0 +1,128 @@
/* Copyright (C) 2003 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 <lowlevelrwlock.h>
#include "lowlevel-atomic.h"
#define SYS_futex 240
#define FUTEX_WAIT 0
#define FUTEX_WAKE 1
.text
.globl __pthread_rwlock_unlock
.type __pthread_rwlock_unlock,@function
.align 5
__pthread_rwlock_unlock:
mov.l r12, @-r15
mov.l r8, @-r15
sts.l pr, @-r15
mov r4, r8
/* Get the lock. */
mov #1, r3
#if MUTEX == 0
XADD (r3, @r4, r2)
#else
XADD (r3, @(MUTEX,r4), r2)
#endif
tst r2, r2
bf 1f
2:
mov.l @(WRITER,r8), r0
tst r0, r0
bf 5f
mov.l @(NR_READERS,r8), r0
add #-1, r0
mov.l r0, @(NR_READERS,r8)
tst r0, r0
bf 6f
5:
mov #0, r0
mov.l r0, @(WRITER,r8)
mov r8, r4
mov.l @(WRITERS_QUEUED,r8), r0
tst r0, r0
bf 9f
mov #-1, r6
shlr r6 /* r6 = 0x7fffffff */
bra 0f
add #READERS_WAKEUP, r4
9:
mov #1, r6
add #WRITERS_WAKEUP, r4
0:
mov #FUTEX_WAKE, r5
mov #SYS_futex, r3
extu.b r3, r3
trapa #0x14
SYSCALL_INST_PAD
6:
#if MUTEX == 0
DEC (@r8, r2)
#else
DEC (@(MUTEX,r8), r2)
#endif
tst r2, r2
bf 3f
4:
lds.l @r15+, pr
mov.l @r15+, r8
mov.l @r15+, r12
rts
mov #0, r0
1:
mov r8, r5
#if MUTEX != 0
add #MUTEX, r5
#endif
mov r2, r4
mov.l .Lwait8, r1
bsrf r1
nop
.Lwait8b:
bra 2b
nop
3:
mov r8, r4
#if MUTEX != 0
add #MUTEX, r4
#endif
mov.l .Lwake8, r1
bsrf r1
nop
.Lwake8b:
bra 4b
nop
.align 2
.Lwait8:
.long __lll_mutex_lock_wait-.Lwait8b
.Lwake8:
.long __lll_mutex_unlock_wake-.Lwake8b
.size __pthread_rwlock_unlock,.-__pthread_rwlock_unlock
.globl pthread_rwlock_unlock
pthread_rwlock_unlock = __pthread_rwlock_unlock
.globl __pthread_rwlock_unlock_internal
__pthread_rwlock_unlock_internal = __pthread_rwlock_unlock

View File

@ -0,0 +1,202 @@
/* Copyright (C) 2003 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 <lowlevelrwlock.h>
#include <tcb-offsets.h>
#include "lowlevel-atomic.h"
#define SYS_futex 240
#define FUTEX_WAIT 0
#define FUTEX_WAKE 1
#define EAGAIN 11
#define EDEADLK 35
.text
.globl __pthread_rwlock_wrlock
.type __pthread_rwlock_wrlock,@function
.align 5
__pthread_rwlock_wrlock:
mov.l r12, @-r15
mov.l r8, @-r15
sts.l pr, @-r15
mov r4, r8
/* Get the lock. */
mov #1, r3
#if MUTEX == 0
XADD (r3, @r4, r2)
#else
XADD (r3, @(MUTEX,r4), r2)
#endif
tst r2, r2
bf 1f
2:
mov.l @(WRITER,r8), r0
tst r0, r0
bf 14f
mov.l @(NR_READERS,r8), r0
tst r0, r0
bt 5f
3:
mov.l @(WRITERS_QUEUED,r8), r0
add #1, r0
mov.l r0, @(WRITERS_QUEUED,r8)
tst r0, r0
bt 4f
#if MUTEX == 0
DEC (@r8, r2)
#else
DEC (@(MUTEX,r8), r2)
#endif
tst r2, r2
bf 10f
11:
mov r8, r4
add #WRITERS_WAKEUP, r4
mov #FUTEX_WAIT, r5
mov #0, r6
mov #SYS_futex, r3
extu.b r3, r3
trapa #0x14
SYSCALL_INST_PAD
/* Reget the lock. */
mov #1, r3
#if MUTEX == 0
XADD (r3, @r4, r2)
#else
XADD (r3, @(MUTEX,r4), r2)
#endif
tst r2, r2
bf 12f
13:
mov.l @(READERS_QUEUED,r8), r0
add #-1, r0
mov.l r0, @(READERS_QUEUED,r8)
mov #0, r0
bra 2b
mov.l r0, @(WRITERS_WAKEUP,r8)
5:
mov #0, r3
stc gbr, r1
mov.w .Ltcboff,r2
sub r2,r1
mov.l @(8,r1),r0
mov.l r0, @(WRITER,r8)
9:
#if MUTEX == 0
DEC (@r8, r2)
#else
DEC (@(MUTEX,r8), r2)
#endif
tst r2, r2
bf 6f
7:
lds.l @r15+, pr
mov.l @r15+, r8
mov.l @r15+, r12
rts
mov r3, r0
1:
mov r8, r5
#if MUTEX != 0
add #MUTEX, r5
#endif
mov r2, r4
mov.l .Lwait4, r1
bsrf r1
nop
.Lwait4b:
bra 2b
nop
14:
stc gbr, r1
mov.w .Ltcboff,r2
sub r2,r1
mov.l @(8,r1),r1
cmp/eq r1, r0
bf 3b
bra 9b
mov #EDEADLK, r3
6:
mov r8, r4
#if MUTEX != 0
add #MUTEX, r4
#endif
mov.l .Lwake4, r1
bsrf r1
nop
.Lwake4b:
bra 7b
mov #0, r3
4:
mov.l @(WRITERS_QUEUED,r8), r1
add #-1, r1
mov.l r1, @(WRITERS_QUEUED,r8)
bra 9b
mov #EAGAIN, r3
10:
mov r8, r4
#if MUTEX != 0
add #MUTEX, r4
#endif
mov.l .Lwake5, r1
bsrf r1
nop
.Lwake5b:
bra 11b
nop
12:
mov r8, r5
#if MUTEX != 0
add #MUTEX, r5
#endif
mov r2, r4
mov.l .Lwait5, r1
bsrf r1
nop
.Lwait5b:
bra 13b
nop
.Ltcboff:
.word TLS_PRE_TCB_SIZE
.align 2
.Lwait4:
.long __lll_mutex_lock_wait-.Lwait4b
.Lwake4:
.long __lll_mutex_unlock_wake-.Lwake4b
.Lwait5:
.long __lll_mutex_lock_wait-.Lwait5b
.Lwake5:
.long __lll_mutex_unlock_wake-.Lwake5b
.globl pthread_rwlock_wrlock
pthread_rwlock_wrlock = __pthread_rwlock_wrlock
.globl __pthread_rwlock_wrlock_internal
__pthread_rwlock_wrlock_internal = __pthread_rwlock_wrlock

View File

@ -0,0 +1,92 @@
/* Copyright (C) 2003 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 <shlib-compat.h>
#include "lowlevel-atomic.h"
#define SYS_gettimeofday __NR_gettimeofday
#define SYS_futex 240
#define FUTEX_WAIT 0
#define FUTEX_WAKE 1
#define EINTR 4
#define EAGAIN 11
#define EWOULDBLOCK EAGAIN
#define EINVAL 22
#define ETIMEDOUT 110
.text
.globl __new_sem_post
.type __new_sem_post,@function
.align 5
__new_sem_post:
mov #1, r3
XADD (r3, @r4, r2)
mov #FUTEX_WAKE, r5
mov r2, r6
add #1, r6
mov #0, r7
mov #SYS_futex, r3
extu.b r3, r3
trapa #0x14
SYSCALL_INST_PAD
cmp/pz r0
bf 1f
rts
mov #0, r0
1:
mov #EAGAIN, r2
mova .Lgot3, r0
mov.l .Lgot3, r12
add r0, r12
#if USE___THREAD
mov.l .Lerrno3, r0
stc gbr, r1
mov.l @(r0, r12), r0
add r1, r0
#else
mov.l .Lerrloc3, r1
bsrf r1
nop
.Lerrloc3b:
#endif
mov.l r2, @r0
lds.l @r15+, pr
mov.l @r15+, r12
rts
mov #-1, r0
.align 2
.Lgot3:
.long _GLOBAL_OFFSET_TABLE_
#if USE___THREAD
.Lerrno3:
.long errno@GOTTPOFF
#else
.Lerrloc3:
.long __errno_location@PLT-(.Lerrloc3b+2-.)
#endif
.size __new_sem_post,.-__new_sem_post
.symver __new_sem_post, sem_post@@GLIBC_2.2

View File

@ -0,0 +1,178 @@
/* Copyright (C) 2003 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 <shlib-compat.h>
#include "lowlevel-atomic.h"
#define SYS_gettimeofday __NR_gettimeofday
#define SYS_futex 240
#define FUTEX_WAIT 0
#define FUTEX_WAKE 1
#define EINTR 4
#define EAGAIN 11
#define EWOULDBLOCK EAGAIN
#define EINVAL 22
#define ETIMEDOUT 110
.text
.globl sem_timedwait
.type sem_timedwait,@function
.align 5
sem_timedwait:
mov.l @r4, r0
2:
tst r0, r0
bt 1f
mov r0, r3
mov r0, r6
add #-1, r3
CMPXCHG (r6, @r4, r3, r2)
bf/s 2b
mov r2, r0
rts
mov #0, r0
1:
/* Check whether the timeout value is valid. */
mov.l r12, @-r15
mov.l r9, @-r15
mov.l r8, @-r15
sts.l pr, @-r15
add #-8, r15
mov r4, r8
mov r5, r9
/* Check for invalid nanosecond field. */
mov.l @(4,r9), r0
mov.l .L1g, r1
cmp/hs r1, r0
bt/s 6f
mov #EINVAL, r0
7:
/* Compute relative timeout. */
mov r15, r4
mov #0, r5
mov #SYS_gettimeofday, r3
trapa #0x12
SYSCALL_INST_PAD
mov.l @(4,r15), r0
mov.w .L1k, r1
dmulu.l r0, r1 /* Milli 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 5f
mov.l .L1g, r1
add r1, r3
add #-1, r2
5:
cmp/pz r2
bf 6f /* Time is already up. */
/* Store relative timeout. */
mov.l r2, @r15
mov.l r3, @(4,r15)
/* Futex call. */
mov r8, r4
mov #FUTEX_WAIT, r5
mov #0, r6
mov r15, r7
mov #SYS_futex, r3
extu.b r3, r3
trapa #0x14
SYSCALL_INST_PAD
tst r0, r0
bt 9f
cmp/eq #-EWOULDBLOCK, r0
bf 3f
9:
mov.l @r8, r0
8:
tst r0, r0
bt 7b
mov r0, r3
mov r0, r4
add #-1, r3
CMPXCHG (r4, @r8, r3, r2)
bf/s 8b
mov r2, r0
add #8, r15
lds.l @r15+, pr
mov.l @r15+, r8
mov.l @r15+, r9
mov.l @r15+, r12
rts
mov #0, r0
3:
neg r0, r0
6:
mov r0, r8
mova .Lgot2, r0
mov.l .Lgot2, r12
add r0, r12
#if USE___THREAD
mov.l .Lerrno2, r0
stc gbr, r1
mov.l @(r0, r12), r0
add r1, r0
mov.l r8, @r0
#else
mov.l .Lerrloc2, r1
bsrf r1
nop
.Lerrloc2b:
mov.l r8, @r0
#endif
add #8, r15
lds.l @r15+, pr
mov.l @r15+, r8
mov.l @r15+, r9
mov.l @r15+, r12
rts
mov #-1, r0
.L1k:
.word 1000
.align 2
.L1g:
.long 1000000000
.Lgot2:
.long _GLOBAL_OFFSET_TABLE_
#if USE___THREAD
.Lerrno2:
.long errno@GOTTPOFF
#else
.Lerrloc2:
.long __errno_location@PLT-(.Lerrloc2b+2-.)
#endif
.size sem_timedwait,.-sem_timedwait

View File

@ -0,0 +1,99 @@
/* Copyright (C) 2003 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 <shlib-compat.h>
#include "lowlevel-atomic.h"
#define SYS_gettimeofday __NR_gettimeofday
#define SYS_futex 240
#define FUTEX_WAIT 0
#define FUTEX_WAKE 1
#define EINTR 4
#define EAGAIN 11
#define EWOULDBLOCK EAGAIN
#define EINVAL 22
#define ETIMEDOUT 110
.text
.globl __new_sem_trywait
.type __new_sem_trywait,@function
.align 5
__new_sem_trywait:
mov.l r12, @-r15
mov.l r8, @-r15
sts.l pr, @-r15
mov r4, r8
mov.l @r8, r0
2:
tst r0, r0
bt 1f
mov r0, r3
mov r0, r4
add #-1, r3
CMPXCHG (r4, @r8, r3, r2)
bf/s 2b
mov r2, r0
lds.l @r15+, pr
mov.l @r15+, r8
mov.l @r15+, r12
rts
mov #0, r0
1:
mov #EAGAIN, r8
mova .Lgot1, r0
mov.l .Lgot1, r12
add r0, r12
#if USE___THREAD
mov.l .Lerrno1, r0
stc gbr, r1
mov.l @(r0, r12), r0
add r1, r0
mov.l r8, @r0
#else
mov.l .Lerrloc1, r1
bsrf r1
nop
.Lerrloc1b:
mov.l r8, @r0
#endif
lds.l @r15+, pr
mov.l @r15+, r8
mov.l @r15+, r12
rts
mov #-1, r0
.align 2
.Lgot1:
.long _GLOBAL_OFFSET_TABLE_
#if USE___THREAD
.Lerrno1:
.long errno@GOTTPOFF
#else
.Lerrloc1:
.long __errno_location@PLT-(.Lerrloc1b+2-.)
#endif
.size __new_sem_trywait,.-__new_sem_trywait
.symver __new_sem_trywait, sem_trywait@@GLIBC_2.2

View File

@ -0,0 +1,112 @@
/* Copyright (C) 2003 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 <shlib-compat.h>
#include "lowlevel-atomic.h"
#define SYS_gettimeofday __NR_gettimeofday
#define SYS_futex 240
#define FUTEX_WAIT 0
#define FUTEX_WAKE 1
#define EINTR 4
#define EAGAIN 11
#define EWOULDBLOCK EAGAIN
#define EINVAL 22
#define ETIMEDOUT 110
.text
.globl __new_sem_wait
.type __new_sem_wait,@function
.align 5
__new_sem_wait:
mov.l r12, @-r15
mov.l r8, @-r15
sts.l pr, @-r15
mov r4, r8
3:
mov.l @r8, r0
2:
tst r0, r0
bt 1f
mov r0, r3
mov r0, r4
add #-1, r3
CMPXCHG (r4, @r8, r3, r2)
bf 2b
lds.l @r15+, pr
mov.l @r15+, r8
mov.l @r15+, r12
rts
mov #0, r0
1:
mov r8, r4
mov #FUTEX_WAIT, r5
mov #0, r6
mov #0, r7
mov #SYS_futex, r3
extu.b r3, r3
trapa #0x14
SYSCALL_INST_PAD
tst r0, r0
bt 3b
cmp/eq #-EWOULDBLOCK, r0
bt 3b
neg r0, r0
mov r0, r8
mova .Lgot0, r0
mov.l .Lgot0, r12
add r0, r12
#if USE___THREAD
mov.l .Lerrno0, r0
stc gbr, r1
mov.l @(r0, r12), r0
add r1, r0
mov.l r8, @r0
#else
mov.l .Lerrloc0, r1
bsrf r1
nop
.Lerrloc0b:
mov.l r8, @r0
#endif
lds.l @r15+, pr
mov.l @r15+, r8
mov.l @r15+, r12
rts
mov #-1, r0
.align 2
.Lgot0:
.long _GLOBAL_OFFSET_TABLE_
#if USE___THREAD
.Lerrno0:
.long errno@GOTTPOFF
#else
.Lerrloc0:
.long __errno_location@PLT-(.Lerrloc0b+2-.)
#endif
.size __new_sem_wait,.-__new_sem_wait
.symver __new_sem_wait, sem_wait@@GLIBC_2.2

View File

@ -0,0 +1,140 @@
/* Copyright (C) 2003 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 <tls.h>
#ifndef __ASSEMBLER__
# include <nptl/pthreadP.h>
#endif
#if !defined NOT_IN_libc || defined IS_IN_libpthread
# define _IMM12 #-12
# define _IMM16 #-16
# define _IMP16 #16
# undef PSEUDO
# define PSEUDO(name, syscall_name, args) \
.text; \
ENTRY (name); \
SINGLE_THREAD_P; \
bf .Lpseudo_cancel; \
DO_CALL (syscall_name, args); \
mov r0,r1; \
mov _IMM12,r2; \
shad r2,r1; \
not r1,r1; \
tst r1,r1; \
bt .Lsyscall_error; \
bra .Lpseudo_end; \
nop; \
.Lpseudo_cancel: \
sts.l pr,@-r15; \
add _IMM16,r15; \
SAVE_ARGS_##args; \
CENABLE; \
LOAD_ARGS_##args; \
add _IMP16,r15; \
lds.l @r15+,pr; \
DO_CALL(syscall_name, args); \
SYSCALL_INST_PAD; \
sts.l pr,@-r15; \
mov.l r0,@-r15; \
CDISABLE; \
mov.l @r15+,r0; \
lds.l @r15+,pr; \
mov r0,r1; \
mov _IMM12,r2; \
shad r2,r1; \
not r1,r1; \
tst r1,r1; \
bf .Lpseudo_end; \
.Lsyscall_error: \
SYSCALL_ERROR_HANDLER; \
.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_5 SAVE_ARGS_4
# define SAVE_ARGS_6 SAVE_ARGS_5
# define LOAD_ARGS_0 /* Nothing. */
# define LOAD_ARGS_1 LOAD_ARGS_0; mov.l @(0,r15),r4
# define LOAD_ARGS_2 LOAD_ARGS_1; mov.l @(4,r15),r5
# define LOAD_ARGS_3 LOAD_ARGS_2; mov.l @(8,r15),r6
# define LOAD_ARGS_4 LOAD_ARGS_3; mov.l @(12,r15),r7
# define LOAD_ARGS_5 LOAD_ARGS_4
# define LOAD_ARGS_6 LOAD_ARGS_5
# ifdef IS_IN_libpthread
# define __local_enable_asynccancel __pthread_enable_asynccancel
# define __local_disable_asynccancel __pthread_disable_asynccancel
# else
# define __local_enable_asynccancel __libc_enable_asynccancel
# define __local_disable_asynccancel __libc_disable_asynccancel
# endif
# define CENABLE \
mov.l 1f,r0; \
bsrf r0; \
nop; \
0: bra 2f; \
nop; \
.align 2; \
1: .long __local_enable_asynccancel - 0b; \
2:
# define CDISABLE \
mov.l 1f,r0; \
bsrf r0; \
nop; \
0: bra 2f; \
nop; \
.align 2; \
1: .long __local_disable_asynccancel - 0b; \
2:
# ifndef __ASSEMBLER__
# define SINGLE_THREAD_P \
__builtin_expect (THREAD_GETMEM (THREAD_SELF, \
header.data.multiple_threads) == 0, 1)
# else
# define SINGLE_THREAD_P \
stc gbr,r0; \
mov.w 0f,r1; \
sub r1,r0; \
mov.l @(MULTIPLE_THREADS_OFFSET,r0),r0; \
bra 1f; \
tst r0,r0; \
0: .word TLS_PRE_TCB_SIZE; \
1:
# endif
#elif !defined __ASSEMBLER__
/* This code should never be used but we define it anyhow. */
# define SINGLE_THREAD_P (1)
#endif