diff options
Diffstat (limited to 'linuxthreads')
-rw-r--r-- | linuxthreads/ChangeLog | 26 | ||||
-rw-r--r-- | linuxthreads/sysdeps/sh/Makefile | 3 | ||||
-rw-r--r-- | linuxthreads/sysdeps/sh/tcb-offsets.sym | 10 | ||||
-rw-r--r-- | linuxthreads/sysdeps/sh/tls.h | 123 | ||||
-rw-r--r-- | linuxthreads/sysdeps/unix/sysv/linux/sh/pt-initfini.c | 8 | ||||
-rw-r--r-- | linuxthreads/sysdeps/unix/sysv/linux/sh/sysdep-cancel.h | 13 | ||||
-rw-r--r-- | linuxthreads/sysdeps/unix/sysv/linux/sh/vfork.S | 18 |
7 files changed, 139 insertions, 62 deletions
diff --git a/linuxthreads/ChangeLog b/linuxthreads/ChangeLog index 4cb52a1c9b..fe06a451bd 100644 --- a/linuxthreads/ChangeLog +++ b/linuxthreads/ChangeLog @@ -1,3 +1,29 @@ +2003-02-07 Kaz Kojima <kkojima@rr.iij4u.or.jp> + + * sysdeps/sh/Makefile: New file. + * sysdeps/sh/tcb-offsets.sym: Likewise. + * sysdeps/sh/tls.h: Don't include sysdep.h. Move include + of linuxthreads/descr.h after the definition of THREAD_SELF. + (tcbhead_t): Use IA64 type tcbhead_t for TLS case. + (TLS_TCB_SIZE): Set size of tcbhead_t. + (TLS_PRE_TCB_SIZE): Define. + (INSTALL_NEW_DTV): Set dtv of tcbhead_t structure instead of + a member of thread structure. + (THREAD_DTV): Likewise. + (TLS_INIT_TP_EXPENSIVE): Remove. + (TLS_INIT_TP): Set gbr register only. + (THREAD_SELF): New. + (INIT_THREAD_SELF): Likewise. + (NONTLS_INIT_TP): New. + * sysdeps/unix/sysv/linux/sh/pt-initfini.c (__fpscr_values): + Remove. + * sysdeps/unix/sysv/linux/sh/sysdep-cancel.h (PSEUDO): Add + SYSCALL_INST_PAD macro after DO_CALL. + (SINGLE_THREAD_P): Fix non-PIC and TLS case so to read the + correct variable. + * sysdeps/unix/sysv/linux/sh/vfork.S (__vfork): Branch to __fork + whenever libpthread.so is loaded. + 2003-02-08 Andreas Schwab <schwab@suse.de> * sysdeps/unix/sysv/linux/m68k/vfork.S: Branch to __fork whenever diff --git a/linuxthreads/sysdeps/sh/Makefile b/linuxthreads/sysdeps/sh/Makefile new file mode 100644 index 0000000000..81bddf688c --- /dev/null +++ b/linuxthreads/sysdeps/sh/Makefile @@ -0,0 +1,3 @@ +ifeq ($(subdir),csu) +gen-as-const-headers += tcb-offsets.sym +endif diff --git a/linuxthreads/sysdeps/sh/tcb-offsets.sym b/linuxthreads/sysdeps/sh/tcb-offsets.sym new file mode 100644 index 0000000000..d74292b1c2 --- /dev/null +++ b/linuxthreads/sysdeps/sh/tcb-offsets.sym @@ -0,0 +1,10 @@ +#include <sysdep.h> +#include <tls.h> + +-- +#ifdef USE_TLS +MULTIPLE_THREADS_OFFSET offsetof (struct _pthread_descr_struct, p_header.data.multiple_threads) +TLS_PRE_TCB_SIZE sizeof (struct _pthread_descr_struct) +#else +MULTIPLE_THREADS_OFFSET offsetof (tcbhead_t, multiple_threads) +#endif diff --git a/linuxthreads/sysdeps/sh/tls.h b/linuxthreads/sysdeps/sh/tls.h index de79aaed0a..af67a8eded 100644 --- a/linuxthreads/sysdeps/sh/tls.h +++ b/linuxthreads/sysdeps/sh/tls.h @@ -34,15 +34,6 @@ typedef union dtv void *pointer; } dtv_t; - -typedef struct -{ - void *tcb; /* Pointer to the TCB. Not necessary the - thread descriptor used by libpthread. */ - dtv_t *dtv; - void *self; /* Pointer to the thread descriptor. */ - int multiple_threads; -} tcbhead_t; #else /* __ASSEMBLER__ */ # include <tcb-offsets.h> #endif /* __ASSEMBLER__ */ @@ -55,73 +46,101 @@ typedef struct /* Signal that TLS support is available. */ # define USE_TLS 1 -#ifndef __ASSEMBLER__ - -/* Get system call information. */ -# include <sysdep.h> +# ifndef __ASSEMBLER__ -/* Get the thread descriptor definition. */ -# include <linuxthreads/descr.h> +typedef struct +{ + dtv_t *dtv; + void *private; +} tcbhead_t; /* This is the size of the initial TCB. */ -# define TLS_INIT_TCB_SIZE sizeof (tcbhead_t) +# define TLS_INIT_TCB_SIZE sizeof (tcbhead_t) /* Alignment requirements for the initial TCB. */ -# define TLS_INIT_TCB_ALIGN __alignof__ (tcbhead_t) +# define TLS_INIT_TCB_ALIGN __alignof__ (tcbhead_t) /* This is the size of the TCB. */ -# define TLS_TCB_SIZE sizeof (struct _pthread_descr_struct) +# define TLS_TCB_SIZE sizeof (tcbhead_t) + +/* This is the size we need before TCB. */ +# define TLS_PRE_TCB_SIZE sizeof (struct _pthread_descr_struct) /* Alignment requirements for the TCB. */ -# define TLS_TCB_ALIGN __alignof__ (struct _pthread_descr_struct) +# define TLS_TCB_ALIGN __alignof__ (struct _pthread_descr_struct) /* The TLS blocks start right after the TCB. */ -# define TLS_DTV_AT_TP 1 - +# 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(descr, dtvp) \ - ((tcbhead_t *) (descr))->dtv = dtvp + 1 +# define INSTALL_DTV(tcbp, dtvp) \ + ((tcbhead_t *) (tcbp))->dtv = dtvp + 1 /* Install new dtv for current thread. */ -# define INSTALL_NEW_DTV(dtv) \ - ({ struct _pthread_descr_struct *__descr; \ - THREAD_SETMEM (__descr, p_header.data.dtvp, (dtv)); }) +# 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(descr) \ - (((tcbhead_t *) (descr))->dtv) +# 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(descr, secondcall) \ - ({ \ - void *_descr = (descr); \ - int result; \ - tcbhead_t *head = _descr; \ - \ - head->tcb = _descr; \ - /* For now the thread descriptor is at the same address. */ \ - head->self = _descr; \ - \ - asm ("ldc %0,gbr" : : "r" (_descr)); \ - \ - 0; \ - }) - -/* Indicate that dynamic linker shouldn't try to initialize TLS even - when no PT_TLS segments are found in the program and libraries - it is linked against. */ -# define TLS_INIT_TP_EXPENSIVE 1 +# 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() \ - ({ struct _pthread_descr_struct *__descr; \ - THREAD_GETMEM (__descr, p_header.data.dtvp); }) +# define THREAD_DTV() \ + ({ tcbhead_t *__tcbp; \ + __asm __volatile ("stc gbr,%0" : "=r" (__tcbp)); \ + __tcbp->dtv;}) -# endif /* HAVE_TLS_SUPPORT && (FLOATING_STACKS || !IS_IN_libpthread) */ -#endif /* __ASSEMBLER__ */ +/* Return the thread descriptor for the current thread. */ +# undef THREAD_SELF +# define THREAD_SELF \ + ({ struct _pthread_descr_struct *__self; \ + __asm ("stc gbr,%0" : "=r" (__self)); \ + __self - 1;}) + +# undef INIT_THREAD_SELF +# define INIT_THREAD_SELF(descr, nr) \ + ({ struct _pthread_descr_struct *__self = (void *) descr; \ + __asm __volatile ("ldc %0,gbr" : : "r" (__self + 1)); \ + 0; }) + +/* Get the thread descriptor definition. This must be after the + the definition of THREAD_SELF for TLS. */ +# include <linuxthreads/descr.h> + +# endif /* __ASSEMBLER__ */ + +#else + +# ifndef __ASSEMBLER__ + +typedef struct +{ + void *tcb; + dtv_t *dtv; + void *self; + int multiple_threads; +} tcbhead_t; + +/* Get the thread descriptor definition. */ +# include <linuxthreads/descr.h> + +# define NONTLS_INIT_TP \ + do { \ + static const tcbhead_t nontls_init_tp = { .multiple_threads = 0 }; \ + __asm __volatile ("ldc %0,gbr" : : "r" (&nontls_init_tp)); \ + } while (0) + +# endif /* __ASSEMBLER__ */ + +#endif /* HAVE_TLS_SUPPORT && (FLOATING_STACKS || !IS_IN_libpthread) */ #endif /* tls.h */ diff --git a/linuxthreads/sysdeps/unix/sysv/linux/sh/pt-initfini.c b/linuxthreads/sysdeps/unix/sysv/linux/sh/pt-initfini.c index 1cf51a8e09..1cdb98f0f7 100644 --- a/linuxthreads/sysdeps/unix/sysv/linux/sh/pt-initfini.c +++ b/linuxthreads/sysdeps/unix/sysv/linux/sh/pt-initfini.c @@ -1,5 +1,5 @@ /* Special .init and .fini section support for SH. Linuxthread version. - Copyright (C) 2000, 2001 Free Software Foundation, Inc. + Copyright (C) 2000, 2001, 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 @@ -77,12 +77,6 @@ _init:\n\ .long __gmon_start__@PLT\n\ .L24:\n\ .long __pthread_initialize_minimal@PLT\n\ - .data\n\ - .global __fpscr_values\n\ -__fpscr_values:\n\ - .long 0\n\ - .long 0x80000\n\ - .previous\n\ 1:\n\ ALIGN\n\ END_INIT\n\ diff --git a/linuxthreads/sysdeps/unix/sysv/linux/sh/sysdep-cancel.h b/linuxthreads/sysdeps/unix/sysv/linux/sh/sysdep-cancel.h index b357eb4e88..57db351735 100644 --- a/linuxthreads/sysdeps/unix/sysv/linux/sh/sysdep-cancel.h +++ b/linuxthreads/sysdeps/unix/sysv/linux/sh/sysdep-cancel.h @@ -52,6 +52,7 @@ add _IMP16,r15; \ lds.l @r15+,pr; \ DO_CALL(syscall_name, args); \ + SYSCALL_INST_PAD; \ sts.l pr,@-r15; \ mov.l r0,@-r15; \ CDISABLE; \ @@ -106,6 +107,7 @@ .align 2; \ 1: .long __local_enable_asynccancel - 0b; \ 2: + # define CDISABLE \ mov.l 1f,r0; \ bsrf r0; \ @@ -129,6 +131,7 @@ extern int __local_multiple_threads attribute_hidden; # if !defined PIC # define SINGLE_THREAD_P \ mov.l 1f,r0; \ + mov.l @r0,r0; \ bra 2f; \ tst r0,r0; \ .align 2; \ @@ -136,7 +139,15 @@ extern int __local_multiple_threads attribute_hidden; 2: # elif defined FLOATING_STACKS && USE___THREAD # define SINGLE_THREAD_P \ - mov.l @(MULTIPLE_THREADS_OFFSET,gbr),r0; tst r0,r0 + 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: + # else # define SINGLE_THREAD_P \ mov r12,r2; \ diff --git a/linuxthreads/sysdeps/unix/sysv/linux/sh/vfork.S b/linuxthreads/sysdeps/unix/sysv/linux/sh/vfork.S index f796e31088..b118ca34d7 100644 --- a/linuxthreads/sysdeps/unix/sysv/linux/sh/vfork.S +++ b/linuxthreads/sysdeps/unix/sysv/linux/sh/vfork.S @@ -26,8 +26,14 @@ and the process ID of the new process to the old process. */ ENTRY (__vfork) - SINGLE_THREAD_P - bf .Lhidden_fork +#ifdef SHARED + mov.l .Lpthread_func, r0 + mov.l @(r0,r12), r0 +#else + mov.l .Lpthread_fork, r0 +#endif + tst r0, r0 + bf .Lhidden_fork mov.w .L1, r3 trapa #0x10 @@ -42,6 +48,14 @@ ENTRY (__vfork) rts nop .L1: .word __NR_vfork + .align 2 +#ifdef SHARED +.Lpthread_func: + .long __libc_pthread_functions@GOTOFF +#else +.Lpthread_fork: + .long __pthread_fork +#endif .Lhidden_fork: mov.l .L2, r1 |