diff options
Diffstat (limited to 'linuxthreads/sysdeps')
5 files changed, 100 insertions, 7 deletions
diff --git a/linuxthreads/sysdeps/s390/s390-32/pt-machine.h b/linuxthreads/sysdeps/s390/s390-32/pt-machine.h index 18b5919544..ee35320059 100644 --- a/linuxthreads/sysdeps/s390/s390-32/pt-machine.h +++ b/linuxthreads/sysdeps/s390/s390-32/pt-machine.h @@ -58,6 +58,13 @@ testandset (int *spinlock) #define CURRENT_STACK_FRAME stack_pointer register char * stack_pointer __asm__ ("15"); +#ifdef USE_TLS +/* Return the thread descriptor for the current thread. */ +# define THREAD_SELF ((pthread_descr) __builtin_thread_pointer ()) + +/* Initialize the thread-unique value. */ +#define INIT_THREAD_SELF(descr, nr) __builtin_set_thread_pointer (descr) +#else /* Return the thread descriptor for the current thread. S/390 registers uses access register 0 as "thread register". */ #define THREAD_SELF ({ \ @@ -70,6 +77,7 @@ register char * stack_pointer __asm__ ("15"); #define INIT_THREAD_SELF(descr, nr) ({ \ __asm__ ("sar %%a0,%0" : : "d" (descr) ); \ }) +#endif /* Access to data in the thread descriptor is easy. */ #define THREAD_GETMEM(descr, member) THREAD_SELF->member diff --git a/linuxthreads/sysdeps/s390/s390-64/pt-machine.h b/linuxthreads/sysdeps/s390/s390-64/pt-machine.h index 92ebe1ecc4..c0f30789c2 100644 --- a/linuxthreads/sysdeps/s390/s390-64/pt-machine.h +++ b/linuxthreads/sysdeps/s390/s390-64/pt-machine.h @@ -58,6 +58,13 @@ testandset (int *spinlock) #define CURRENT_STACK_FRAME stack_pointer register char * stack_pointer __asm__ ("15"); +#ifdef USE_TLS +/* Return the thread descriptor for the current thread. */ +# define THREAD_SELF ((pthread_descr) __builtin_thread_pointer ()) + +/* Initialize the thread-unique value. */ +#define INIT_THREAD_SELF(descr, nr) __builtin_set_thread_pointer (descr) +#else /* Return the thread descriptor for the current thread. 64 bit S/390 uses access register 0 and 1 as "thread register". */ #define THREAD_SELF ({ \ @@ -76,6 +83,7 @@ register char * stack_pointer __asm__ ("15"); " sar %%a0,0\n" \ : : "d" (descr) : "0" ); \ }) +#endif /* Access to data in the thread descriptor is easy. */ #define THREAD_GETMEM(descr, member) THREAD_SELF->member diff --git a/linuxthreads/sysdeps/s390/tls.h b/linuxthreads/sysdeps/s390/tls.h index d872bb7553..11f31ba88a 100644 --- a/linuxthreads/sysdeps/s390/tls.h +++ b/linuxthreads/sysdeps/s390/tls.h @@ -45,19 +45,96 @@ typedef struct # include <tcb-offsets.h> #endif /* __ASSEMBLER__ */ -#undef USE_TLS +/* TLS is always supported if the tools support it. There are no + kernel dependencies. To avoid bothering with the TLS support code + at all, use configure --without-tls. -#if USE_TLS + We need USE_TLS to be consistently defined, for ldsodefs.h + conditionals. */ -#else +#ifdef HAVE_TLS_SUPPORT -#define NONTLS_INIT_TP \ +/* 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 <linuxthreads/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 (struct _pthread_descr_struct) + +/* Alignment requirements for the TCB. */ +# define TLS_TCB_ALIGN __alignof__ (struct _pthread_descr_struct) + +/* The TCB can have any size and the memory following the address the + thread pointer points to is unspecified. Allocate the TCB there. */ +# define TLS_TCB_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 + +/* Install new dtv for current thread. */ +# define INSTALL_NEW_DTV(dtv) \ + (((tcbhead_t *) __builtin_thread_pointer ())->dtv = (dtv)) + +/* Return dtv of given thread descriptor. */ +# define GET_DTV(descr) \ + (((tcbhead_t *) (descr))->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. + + The value of this macro is null if successful, or an error string. */ +# define TLS_INIT_TP(descr, secondcall) \ + ({ \ + void *_descr = (descr); \ + tcbhead_t *head = _descr; \ + \ + head->tcb = _descr; \ + /* For now the thread descriptor is at the same address. */ \ + head->self = _descr; \ + \ + __builtin_set_thread_pointer (_descr); \ + 0; \ + }) + +/* Return the address of the dtv for the current thread. */ +# define THREAD_DTV() \ + (((tcbhead_t *) __builtin_thread_pointer ())->dtv) + +# endif /* __ASSEMBLER__ */ + +#else /* HAVE_TLS_SUPPORT && (FLOATING_STACKS || !IS_IN_libpthread) */ + +# ifndef __ASSEMBLER__ + +/* Get the thread descriptor definition. */ +# include <linuxthreads/descr.h> + +# define NONTLS_INIT_TP \ do { \ static const tcbhead_t nontls_init_tp \ = { .multiple_threads = 0 }; \ INIT_THREAD_SELF (&nontls_init_tp, 0); \ } while (0) -#endif /* USE_TLS */ +# endif /* __ASSEMBLER__ */ + +#endif /* HAVE_TLS_SUPPORT && (FLOATING_STACKS || !IS_IN_libpthread) */ #endif /* tls.h */ diff --git a/linuxthreads/sysdeps/unix/sysv/linux/s390/s390-64/sysdep-cancel.h b/linuxthreads/sysdeps/unix/sysv/linux/s390/s390-64/sysdep-cancel.h index ce4afb1d7b..4e54e550c2 100644 --- a/linuxthreads/sysdeps/unix/sysv/linux/s390/s390-64/sysdep-cancel.h +++ b/linuxthreads/sysdeps/unix/sysv/linux/s390/s390-64/sysdep-cancel.h @@ -51,7 +51,7 @@ ENTRY(name) \ L(pseudo_check): \ lghi %r4,-4095; \ clgr %r2,%r4; \ - jnl SYSCALL_ERROR_LABEL; \ + jgnl SYSCALL_ERROR_LABEL; \ L(pseudo_end): # ifdef IS_IN_libpthread diff --git a/linuxthreads/sysdeps/unix/sysv/linux/s390/s390-64/vfork.S b/linuxthreads/sysdeps/unix/sysv/linux/s390/s390-64/vfork.S index e01d4389d3..efc9710d7b 100644 --- a/linuxthreads/sysdeps/unix/sysv/linux/s390/s390-64/vfork.S +++ b/linuxthreads/sysdeps/unix/sysv/linux/s390/s390-64/vfork.S @@ -36,7 +36,7 @@ ENTRY (__vfork) /* Check for error. */ lghi %r4,-4095 clgr %r2,%r4 - jnl SYSCALL_ERROR_LABEL + jgnl SYSCALL_ERROR_LABEL /* Normal return. */ br %r14 |