From a54e8d33d17f6197ac629ac86e3381643b802bec Mon Sep 17 00:00:00 2001 From: Ulrich Drepper Date: Mon, 10 Feb 2003 09:24:12 +0000 Subject: Update. 2003-02-08 kaz Kojima * 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. --- nptl/sysdeps/sh/bits/atomic.h | 405 +++++++++++++++++++++++++++++++++ nptl/sysdeps/sh/pthread_spin_init.c | 20 ++ nptl/sysdeps/sh/pthread_spin_lock.c | 35 +++ nptl/sysdeps/sh/pthread_spin_trylock.S | 32 +++ nptl/sysdeps/sh/pthread_spin_unlock.S | 30 +++ nptl/sysdeps/sh/pthreaddef.h | 52 +++++ nptl/sysdeps/sh/tcb-offsets.sym | 5 + nptl/sysdeps/sh/td_ta_map_lwp2thr.c | 44 ++++ nptl/sysdeps/sh/tls.h | 135 +++++++++++ 9 files changed, 758 insertions(+) create mode 100644 nptl/sysdeps/sh/bits/atomic.h create mode 100644 nptl/sysdeps/sh/pthread_spin_init.c create mode 100644 nptl/sysdeps/sh/pthread_spin_lock.c create mode 100644 nptl/sysdeps/sh/pthread_spin_trylock.S create mode 100644 nptl/sysdeps/sh/pthread_spin_unlock.S create mode 100644 nptl/sysdeps/sh/pthreaddef.h create mode 100644 nptl/sysdeps/sh/tcb-offsets.sym create mode 100644 nptl/sysdeps/sh/td_ta_map_lwp2thr.c create mode 100644 nptl/sysdeps/sh/tls.h (limited to 'nptl/sysdeps/sh') diff --git a/nptl/sysdeps/sh/bits/atomic.h b/nptl/sysdeps/sh/bits/atomic.h new file mode 100644 index 0000000..de176ca --- /dev/null +++ b/nptl/sysdeps/sh/bits/atomic.h @@ -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 + + +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; }) diff --git a/nptl/sysdeps/sh/pthread_spin_init.c b/nptl/sysdeps/sh/pthread_spin_init.c new file mode 100644 index 0000000..0a47981 --- /dev/null +++ b/nptl/sysdeps/sh/pthread_spin_init.c @@ -0,0 +1,20 @@ +/* Copyright (C) 2002 Free Software Foundation, Inc. + This file is part of the GNU C Library. + Contributed by Ulrich Drepper , 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. */ diff --git a/nptl/sysdeps/sh/pthread_spin_lock.c b/nptl/sysdeps/sh/pthread_spin_lock.c new file mode 100644 index 0000000..e732641 --- /dev/null +++ b/nptl/sysdeps/sh/pthread_spin_lock.c @@ -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; +} diff --git a/nptl/sysdeps/sh/pthread_spin_trylock.S b/nptl/sysdeps/sh/pthread_spin_trylock.S new file mode 100644 index 0000000..63ae4d3 --- /dev/null +++ b/nptl/sysdeps/sh/pthread_spin_trylock.S @@ -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 diff --git a/nptl/sysdeps/sh/pthread_spin_unlock.S b/nptl/sysdeps/sh/pthread_spin_unlock.S new file mode 100644 index 0000000..c77acaf --- /dev/null +++ b/nptl/sysdeps/sh/pthread_spin_unlock.S @@ -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 diff --git a/nptl/sysdeps/sh/pthreaddef.h b/nptl/sysdeps/sh/pthreaddef.h new file mode 100644 index 0000000..c66e838 --- /dev/null +++ b/nptl/sysdeps/sh/pthreaddef.h @@ -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 + +/* 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)); \ + } diff --git a/nptl/sysdeps/sh/tcb-offsets.sym b/nptl/sysdeps/sh/tcb-offsets.sym new file mode 100644 index 0000000..ae14fa0 --- /dev/null +++ b/nptl/sysdeps/sh/tcb-offsets.sym @@ -0,0 +1,5 @@ +#include +#include + +MULTIPLE_THREADS_OFFSET offsetof (struct pthread, header.data.multiple_threads) +TLS_PRE_TCB_SIZE sizeof (struct pthread) diff --git a/nptl/sysdeps/sh/td_ta_map_lwp2thr.c b/nptl/sysdeps/sh/td_ta_map_lwp2thr.c new file mode 100644 index 0000000..7585300 --- /dev/null +++ b/nptl/sysdeps/sh/td_ta_map_lwp2thr.c @@ -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 +#include + + +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; +} diff --git a/nptl/sysdeps/sh/tls.h b/nptl/sysdeps/sh/tls.h new file mode 100644 index 0000000..b92b0b8 --- /dev/null +++ b/nptl/sysdeps/sh/tls.h @@ -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 + +#ifndef __ASSEMBLER__ +# include +# include + +/* 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 +#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 + +/* Get the thread descriptor definition. */ +# include + +/* 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 */ -- cgit v1.1