diff options
Diffstat (limited to 'linuxthreads')
-rw-r--r-- | linuxthreads/Makefile | 12 | ||||
-rw-r--r-- | linuxthreads/descr.h | 4 | ||||
-rw-r--r-- | linuxthreads/libc_pthread_init.c | 3 | ||||
-rw-r--r-- | linuxthreads/sysdeps/i386/tls.h | 21 | ||||
-rw-r--r-- | linuxthreads/sysdeps/ia64/tls.h | 64 | ||||
-rw-r--r-- | linuxthreads/sysdeps/pthread/bits/libc-lock.h | 4 | ||||
-rw-r--r-- | linuxthreads/sysdeps/sparc/sparc32/tls.h | 61 | ||||
-rw-r--r-- | linuxthreads/sysdeps/sparc/sparc64/tls.h | 61 | ||||
-rw-r--r-- | linuxthreads/sysdeps/unix/sysv/linux/i386/dl-sysdep.h | 60 | ||||
-rw-r--r-- | linuxthreads/sysdeps/unix/sysv/linux/i386/sysdep-cancel.h | 2 | ||||
-rw-r--r-- | linuxthreads/sysdeps/unix/sysv/linux/ia64/Makefile | 3 | ||||
-rw-r--r-- | linuxthreads/sysdeps/unix/sysv/linux/ia64/sysdep-cancel.h | 118 | ||||
-rw-r--r-- | linuxthreads/sysdeps/unix/sysv/linux/sparc/sparc32/sysdep-cancel.h | 99 | ||||
-rw-r--r-- | linuxthreads/sysdeps/unix/sysv/linux/sparc/sparc64/sysdep-cancel.h | 98 | ||||
-rw-r--r-- | linuxthreads/sysdeps/x86_64/tls.h | 5 |
15 files changed, 609 insertions, 6 deletions
diff --git a/linuxthreads/Makefile b/linuxthreads/Makefile index e9cbf5e8b8..6425108389 100644 --- a/linuxthreads/Makefile +++ b/linuxthreads/Makefile @@ -74,8 +74,12 @@ endif librt-tests = ex10 ex11 tests = ex1 ex2 ex3 ex4 ex5 ex6 ex7 ex8 ex9 $(librt-tests) ex12 ex13 joinrace \ tststack $(tests-nodelete-$(have-z-nodelete)) ecmutex ex14 ex15 ex16 \ - ex17 ex18 tst-cancel tst-context bug-sleep + ex17 ex18 tst-cancel tst-context bug-sleep \ + tst-cancel1 tst-cancel2 tst-cancel3 tst-cancel4 tst-cancel5 \ + tst-cancel6 test-srcs = tst-signal +# These tests are linked with libc before libpthread +tests-reverse += tst-cancel5 ifeq ($(build-static),yes) tests += tststatic tst-static-locale @@ -149,8 +153,12 @@ $(objpfx)libpthread.so: $(libc-link.so) $(common-objpfx)libc_nonshared.a # Make sure we link with the thread library. ifeq ($(build-shared),yes) $(addprefix $(objpfx), \ - $(filter-out $(tests-static) unload, \ + $(filter-out $(tests-static) $(tests-reverse) unload, \ $(tests) $(test-srcs))): $(objpfx)libpthread.so +# $(objpfx)../libc.so is used instead of $(common-objpfx)libc.so, +# since otherwise libpthread.so comes before libc.so when linking. +$(addprefix $(objpfx), $(tests-reverse)): \ + $(objpfx)../libc.so $(objpfx)libpthread.so $(addprefix $(objpfx),$(librt-tests)): $(common-objpfx)rt/librt.so $(objpfx)unload: $(common-objpfx)dlfcn/libdl.so $(objpfx)unload.out: $(objpfx)libpthread.so diff --git a/linuxthreads/descr.h b/linuxthreads/descr.h index 94ad893979..74ef25e1f4 100644 --- a/linuxthreads/descr.h +++ b/linuxthreads/descr.h @@ -20,6 +20,7 @@ #include <sched.h> #include <setjmp.h> #include <signal.h> +#include <stdint.h> #include <sys/types.h> #include <hp-timing.h> #include <bits/libc-tsd.h> /* for _LIBC_TSD_KEY_N */ @@ -107,6 +108,9 @@ struct _pthread_descr_struct { union dtv *dtvp; pthread_descr self; /* Pointer to this structure */ int multiple_threads; +#ifdef NEED_DL_SYSINFO + uintptr_t sysinfo; +#endif } data; void *__padding[16]; } p_header; diff --git a/linuxthreads/libc_pthread_init.c b/linuxthreads/libc_pthread_init.c index 901d333fbf..c952b22d07 100644 --- a/linuxthreads/libc_pthread_init.c +++ b/linuxthreads/libc_pthread_init.c @@ -17,9 +17,10 @@ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. */ +#include <locale.h> +#include <stdlib.h> #include <string.h> #include <tls.h> -#include <locale.h> #include "internals.h" #include <sysdep-cancel.h> diff --git a/linuxthreads/sysdeps/i386/tls.h b/linuxthreads/sysdeps/i386/tls.h index c244801bf4..761a8ca943 100644 --- a/linuxthreads/sysdeps/i386/tls.h +++ b/linuxthreads/sysdeps/i386/tls.h @@ -20,10 +20,12 @@ #ifndef _TLS_H #define _TLS_H +# include <dl-sysdep.h> # include <pt-machine.h> #ifndef __ASSEMBLER__ # include <stddef.h> +# include <stdint.h> /* Type for the dtv. */ typedef union dtv @@ -39,9 +41,17 @@ typedef struct thread descriptor used by libpthread. */ dtv_t *dtv; void *self; /* Pointer to the thread descriptor. */ + int multiple_threads; +#ifdef NEED_DL_SYSINFO + uintptr_t sysinfo; +#endif } tcbhead_t; #endif +#ifdef NEED_DL_SYSINFO +/* Offset of the SYSINFO element in tcbhead_t. */ +# define SYSINFO_OFFSET 24 +#endif /* We can support TLS only if the floating-stack support is available. However, we want to compile in the support and test at runtime whether @@ -174,6 +184,12 @@ TLS_DO_MODIFY_LDT_KERNEL_CHECK( \ TLS_DO_MODIFY_LDT ((descr), 0) # endif +#if defined NEED_DL_SYSINFO && defined SHARED +# define INIT_SYSINFO \ + head->sysinfo = GL(dl_sysinfo) +#else +# define INIT_SYSINFO +#endif /* Code to initially initialize the thread pointer. This might need special attention since 'errno' is not yet available and if the @@ -189,9 +205,14 @@ TLS_DO_MODIFY_LDT_KERNEL_CHECK( \ /* For now the thread descriptor is at the same address. */ \ head->self = _descr; \ \ + INIT_SYSINFO; \ TLS_SETUP_GS_SEGMENT (_descr, secondcall); \ }) +/* 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 /* Return the address of the dtv for the current thread. */ # define THREAD_DTV() \ diff --git a/linuxthreads/sysdeps/ia64/tls.h b/linuxthreads/sysdeps/ia64/tls.h new file mode 100644 index 0000000000..c270795254 --- /dev/null +++ b/linuxthreads/sysdeps/ia64/tls.h @@ -0,0 +1,64 @@ +/* Definitions for thread-local data handling. linuxthreads/IA-64 version. + Copyright (C) 2002 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 + +#ifndef __ASSEMBLER__ + +# include <pt-machine.h> +# include <stddef.h> + +/* Type for the dtv. */ +typedef union dtv +{ + size_t counter; + void *pointer; +} dtv_t; + + +/* FIXME: Only temporary. When TLS is supported on IA-64, + pthread_descr struct needs to be immediately below r13 and + at r13 a struct { dtv_t *dtv; void *private; }. */ +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; +#endif /* __ASSEMBLER__ */ + +#undef USE_TLS + +#if USE_TLS + +#else + +#define NONTLS_INIT_TP \ + do { \ + static const tcbhead_t nontls_init_tp \ + = { .multiple_threads = 0 }; \ + __thread_self = (__typeof (__thread_self)) &nontls_init_tp; \ + } while (0) + +#endif /* USE_TLS */ + +#endif /* tls.h */ diff --git a/linuxthreads/sysdeps/pthread/bits/libc-lock.h b/linuxthreads/sysdeps/pthread/bits/libc-lock.h index 217b0be253..cb839fa42e 100644 --- a/linuxthreads/sysdeps/pthread/bits/libc-lock.h +++ b/linuxthreads/sysdeps/pthread/bits/libc-lock.h @@ -97,7 +97,7 @@ typedef pthread_key_t __libc_key_t; #if defined _LIBC && defined IS_IN_libpthread # define __libc_maybe_call(FUNC, ARGS, ELSE) FUNC ARGS #else -# ifdef __PIC__ +# if defined __PIC__ || (defined _LIBC && defined SHARED) # define __libc_maybe_call(FUNC, ARGS, ELSE) \ (__extension__ ({ __typeof (FUNC) *_fn = (FUNC); \ _fn != NULL ? (*_fn) ARGS : ELSE; })) @@ -106,7 +106,7 @@ typedef pthread_key_t __libc_key_t; (FUNC != NULL ? FUNC ARGS : ELSE) # endif #endif -#if defined _LIBC && !defined NOT_IN_libc && defined __PIC__ +#if defined _LIBC && !defined NOT_IN_libc && defined SHARED # define __libc_maybe_call2(FUNC, ARGS, ELSE) \ ({__libc_pthread_functions.ptr_##FUNC != NULL \ ? __libc_pthread_functions.ptr_##FUNC ARGS : ELSE; }) diff --git a/linuxthreads/sysdeps/sparc/sparc32/tls.h b/linuxthreads/sysdeps/sparc/sparc32/tls.h new file mode 100644 index 0000000000..1b316d0b33 --- /dev/null +++ b/linuxthreads/sysdeps/sparc/sparc32/tls.h @@ -0,0 +1,61 @@ +/* Definitions for thread-local data handling. linuxthreads/sparc32 version. + Copyright (C) 2002 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 + +#ifndef __ASSEMBLER__ + +# include <pt-machine.h> +# include <stddef.h> + +/* Type for the dtv. */ +typedef union dtv +{ + size_t counter; + 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; + +#endif /* __ASSEMBLER__ */ + +#undef USE_TLS + +#if USE_TLS + +#else + +#define NONTLS_INIT_TP \ + do { \ + static const tcbhead_t nontls_init_tp \ + = { .multiple_threads = 0 }; \ + __thread_self = (__typeof (__thread_self)) &nontls_init_tp; \ + } while (0) + +#endif /* USE_TLS */ + +#endif /* tls.h */ diff --git a/linuxthreads/sysdeps/sparc/sparc64/tls.h b/linuxthreads/sysdeps/sparc/sparc64/tls.h new file mode 100644 index 0000000000..039ad2bc48 --- /dev/null +++ b/linuxthreads/sysdeps/sparc/sparc64/tls.h @@ -0,0 +1,61 @@ +/* Definitions for thread-local data handling. linuxthreads/sparc64 version. + Copyright (C) 2002 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 + +#ifndef __ASSEMBLER__ + +# include <pt-machine.h> +# include <stddef.h> + +/* Type for the dtv. */ +typedef union dtv +{ + size_t counter; + 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; + +#endif /* __ASSEMBLER__ */ + +#undef USE_TLS + +#if USE_TLS + +#else + +#define NONTLS_INIT_TP \ + do { \ + static const tcbhead_t nontls_init_tp \ + = { .multiple_threads = 0 }; \ + __thread_self = (__typeof (__thread_self)) &nontls_init_tp; \ + } while (0) + +#endif /* USE_TLS */ + +#endif /* tls.h */ diff --git a/linuxthreads/sysdeps/unix/sysv/linux/i386/dl-sysdep.h b/linuxthreads/sysdeps/unix/sysv/linux/i386/dl-sysdep.h new file mode 100644 index 0000000000..ac19ac78a4 --- /dev/null +++ b/linuxthreads/sysdeps/unix/sysv/linux/i386/dl-sysdep.h @@ -0,0 +1,60 @@ +/* System-specific settings for dynamic linker code. IA-32 version. + Copyright (C) 2002 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 _DL_SYSDEP_H +#define _DL_SYSDEP_H 1 + +/* This macro must be defined to either 0 or 1. + + If 1, then an errno global variable hidden in ld.so will work right with + all the errno-using libc code compiled for ld.so, and there is never a + need to share the errno location with libc. This is appropriate only if + all the libc functions that ld.so uses are called without PLT and always + get the versions linked into ld.so rather than the libc ones. */ + +#ifdef IS_IN_rtld +# define RTLD_PRIVATE_ERRNO 1 +#else +# define RTLD_PRIVATE_ERRNO 0 +#endif + +/* Traditionally system calls have been made using int $0x80. A + second method was introduced which, if possible, will use the + sysenter/syscall instructions. To signal the presence and where to + find the code the kernel passes an AT_SYSINFO value in the + auxiliary vector to the application. + sysenter/syscall is not useful on i386 through i586, but the dynamic + linker and dl code in libc.a has to be able to load i686 compiled + libraries. */ +#define NEED_DL_SYSINFO 1 +#undef USE_DL_SYSINFO + +#if defined NEED_DL_SYSINFO && !defined __ASSEMBLER__ +extern void _dl_sysinfo_int80 (void) attribute_hidden; +# define DL_SYSINFO_DEFAULT (uintptr_t) _dl_sysinfo_int80 +# define DL_SYSINFO_IMPLEMENTATION \ + asm (".type _dl_sysinfo_int80,@function\n\t" \ + ".hidden _dl_sysinfo_int80\n" \ + "_dl_sysinfo_int80:\n\t" \ + "int $0x80;\n\t" \ + "ret;\n\t" \ + ".size _dl_sysinfo_int80,.-_dl_sysinfo_int80"); +#endif + +#endif /* dl-sysdep.h */ diff --git a/linuxthreads/sysdeps/unix/sysv/linux/i386/sysdep-cancel.h b/linuxthreads/sysdeps/unix/sysv/linux/i386/sysdep-cancel.h index 30be0b9c5f..d449527900 100644 --- a/linuxthreads/sysdeps/unix/sysv/linux/i386/sysdep-cancel.h +++ b/linuxthreads/sysdeps/unix/sysv/linux/i386/sysdep-cancel.h @@ -25,7 +25,7 @@ #endif #if defined FLOATING_STACKS && USE___THREAD -# define MULTIPLE_THREADS_OFFSET 12 +# define MULTIPLE_THREADS_OFFSET 20 #endif #if !defined NOT_IN_libc || defined IS_IN_libpthread diff --git a/linuxthreads/sysdeps/unix/sysv/linux/ia64/Makefile b/linuxthreads/sysdeps/unix/sysv/linux/ia64/Makefile new file mode 100644 index 0000000000..e03aee99fc --- /dev/null +++ b/linuxthreads/sysdeps/unix/sysv/linux/ia64/Makefile @@ -0,0 +1,3 @@ +ifeq ($(subdir),linuxthreads) +libpthread-routines += ptw-sysdep ptw-sigblock ptw-sigprocmask +endif diff --git a/linuxthreads/sysdeps/unix/sysv/linux/ia64/sysdep-cancel.h b/linuxthreads/sysdeps/unix/sysv/linux/ia64/sysdep-cancel.h new file mode 100644 index 0000000000..d74c044981 --- /dev/null +++ b/linuxthreads/sysdeps/unix/sysv/linux/ia64/sysdep-cancel.h @@ -0,0 +1,118 @@ +/* Copyright (C) 2002 Free Software Foundation, Inc. + This file is part of the GNU C Library. + Contributed by Jakub Jelinek <jakub@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. */ + +#include <sysdep.h> +#include <tls.h> +#ifndef ASSEMBLER +# include <linuxthreads/internals.h> +#endif + +#define MULTIPLE_THREADS_OFFSET 40 + +#if !defined NOT_IN_libc || defined IS_IN_libpthread + +# undef PSEUDO +# define PSEUDO(name, syscall_name, args) \ +.text; \ +ENTRY (name) \ + adds r14 = MULTIPLE_THREADS_OFFSET, r13;; \ + ld4 r14 = [r14]; \ + mov r15 = SYS_ify(syscall_name);; \ + cmp4.ne p6, p7 = 0, r14; \ +(p6) br.cond.spnt .Lpseudo_cancel;; \ + break __BREAK_SYSCALL;; \ + cmp.eq p6,p0=-1,r10; \ +(p6) br.cond.spnt.few __syscall_error; \ + ret;; \ +.Lpseudo_cancel: \ + .prologue; \ + .regstk args, 5, args, 0; \ + .save ar.pfs, loc0; \ + alloc loc0 = ar.pfs, args, 5, args, 0; \ + .save rp, loc1; \ + mov loc1 = rp;; \ + .body; \ + CENABLE;; \ + mov loc2 = r8; \ + COPY_ARGS_##args \ + mov r15 = SYS_ify(syscall_name); \ + break __BREAK_SYSCALL;; \ + mov loc3 = r8; \ + mov loc4 = r10; \ + mov out0 = loc2; \ + CDISABLE;; \ + cmp.eq p6,p0=-1,loc4; \ +(p6) br.cond.spnt.few __syscall_error_##args; \ + mov r8 = loc3; \ + mov rp = loc1; \ + mov ar.pfs = loc0; \ +.Lpseudo_end: \ + ret; \ + .endp name; \ +.section .gnu.linkonce.t.__syscall_error_##args, "ax"; \ + .align 32; \ + .proc __syscall_error_##args; \ + .global __syscall_error_##args; \ + .hidden __syscall_error_##args; \ +__syscall_error_##args: \ + .prologue; \ + .regstk args, 5, args, 0; \ + .save ar.pfs, loc0; \ + .save rp, loc1; \ + .body; \ + mov loc4 = r1;; \ + br.call.sptk.many b0 = __errno_location;; \ + st4 [r8] = loc3; \ + mov r1 = loc4; \ + mov rp = loc1; \ + mov r8 = -1; \ + mov ar.pfs = loc0 + +# ifdef IS_IN_libpthread +# define CENABLE br.call.sptk.many b0 = __pthread_enable_asynccancel +# define CDISABLE br.call.sptk.many b0 = __pthread_disable_asynccancel +# else +# define CENABLE br.call.sptk.many b0 = __libc_enable_asynccancel +# define CDISABLE br.call.sptk.many b0 = __libc_disable_asynccancel +# endif + +#define COPY_ARGS_0 /* Nothing */ +#define COPY_ARGS_1 COPY_ARGS_0 mov out0 = in0; +#define COPY_ARGS_2 COPY_ARGS_1 mov out1 = in1; +#define COPY_ARGS_3 COPY_ARGS_2 mov out2 = in2; +#define COPY_ARGS_4 COPY_ARGS_3 mov out3 = in3; +#define COPY_ARGS_5 COPY_ARGS_4 mov out4 = in4; +#define COPY_ARGS_6 COPY_ARGS_5 mov out5 = in5; +#define COPY_ARGS_7 COPY_ARGS_6 mov out6 = in6; + +# ifndef ASSEMBLER +# define SINGLE_THREAD_P \ + __builtin_expect (THREAD_GETMEM (THREAD_SELF, \ + p_header.data.multiple_threads) == 0, 1) +# else +# define SINGLE_THREAD_P \ + adds r14 = MULTIPLE_THREADS_OFFSET, r13 ;; ld4 r14 = [r14] ;; cmp4.ne p6, p7 = 0, r14 ;; +# endif + +#elif !defined ASSEMBLER + +/* This code should never be used but we define it anyhow. */ +# define SINGLE_THREAD_P (1) + +#endif diff --git a/linuxthreads/sysdeps/unix/sysv/linux/sparc/sparc32/sysdep-cancel.h b/linuxthreads/sysdeps/unix/sysv/linux/sparc/sparc32/sysdep-cancel.h new file mode 100644 index 0000000000..ff03f631e3 --- /dev/null +++ b/linuxthreads/sysdeps/unix/sysv/linux/sparc/sparc32/sysdep-cancel.h @@ -0,0 +1,99 @@ +/* Copyright (C) 2002 Free Software Foundation, Inc. + This file is part of the GNU C Library. + Contributed by Jakub Jelinek <jakub@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. */ + +#include <sysdep.h> +#include <tls.h> +#ifndef ASSEMBLER +# include <linuxthreads/internals.h> +#endif + +#define MULTIPLE_THREADS_OFFSET 20 + +#if !defined NOT_IN_libc || defined IS_IN_libpthread + +# undef PSEUDO +# define PSEUDO(name, syscall_name, args) \ + .text; \ +ENTRY(name) \ + ld [%g6 + MULTIPLE_THREADS_OFFSET], %g1; \ + cmp %g1, 0; \ + bne 1f; \ + mov SYS_ify(syscall_name), %g1; \ + ta 0x10; \ + bcs __syscall_error_handler; \ + nop; \ + .subsection 2; \ +1: save %sp, -96, %sp; \ + CENABLE; \ + nop; \ + mov %o0, %l0; \ + COPY_ARGS_##args \ + mov SYS_ify(syscall_name), %g1; \ + ta 0x10; \ + bcs __syscall_error_handler2; \ + mov %o0, %l1; \ + CDISABLE; \ + mov %l0, %o0; \ + jmpl %i7 + 8, %g0; \ + restore %g0, %l1, %o0; \ + .previous; \ + SYSCALL_ERROR_HANDLER \ + SYSCALL_ERROR_HANDLER2 + +#define SYSCALL_ERROR_HANDLER2 \ +SYSCALL_ERROR_HANDLER_ENTRY(__syscall_error_handler2) \ + .global __errno_location; \ + .type __errno_location,@function; \ + call __errno_location; \ + nop; \ + st %l1, [%o0]; \ + jmpl %i7 + 8, %g0; \ + restore %g0, -1, %o0; \ + .previous; + +# ifdef IS_IN_libpthread +# define CENABLE call __pthread_enable_asynccancel +# define CDISABLE call __pthread_disable_asynccancel +# else +# define CENABLE call __libc_enable_asynccancel +# define CDISABLE call __libc_disable_asynccancel +# endif + +#define COPY_ARGS_0 /* Nothing */ +#define COPY_ARGS_1 COPY_ARGS_0 mov %i0, %o0; +#define COPY_ARGS_2 COPY_ARGS_1 mov %i1, %o1; +#define COPY_ARGS_3 COPY_ARGS_2 mov %i2, %o2; +#define COPY_ARGS_4 COPY_ARGS_3 mov %i3, %o3; +#define COPY_ARGS_5 COPY_ARGS_4 mov %i4, %o4; +#define COPY_ARGS_6 COPY_ARGS_5 mov %i5, %o5; + +# ifndef ASSEMBLER +# define SINGLE_THREAD_P \ + __builtin_expect (THREAD_GETMEM (THREAD_SELF, \ + p_header.data.multiple_threads) == 0, 1) +# else +# define SINGLE_THREAD_P ld [%g6 + MULTIPLE_THREADS_OFFSET], %g1 +# endif + +#elif !defined ASSEMBLER + +/* This code should never be used but we define it anyhow. */ +# define SINGLE_THREAD_P (1) + +#endif diff --git a/linuxthreads/sysdeps/unix/sysv/linux/sparc/sparc64/sysdep-cancel.h b/linuxthreads/sysdeps/unix/sysv/linux/sparc/sparc64/sysdep-cancel.h new file mode 100644 index 0000000000..8b9585d2d7 --- /dev/null +++ b/linuxthreads/sysdeps/unix/sysv/linux/sparc/sparc64/sysdep-cancel.h @@ -0,0 +1,98 @@ +/* Copyright (C) 2002 Free Software Foundation, Inc. + This file is part of the GNU C Library. + Contributed by Jakub Jelinek <jakub@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. */ + +#include <sysdep.h> +#include <tls.h> +#ifndef ASSEMBLER +# include <linuxthreads/internals.h> +#endif + +#define MULTIPLE_THREADS_OFFSET 40 + +#if !defined NOT_IN_libc || defined IS_IN_libpthread + +# undef PSEUDO +# define PSEUDO(name, syscall_name, args) \ + .text; \ +ENTRY(name) \ + ld [%g6 + MULTIPLE_THREADS_OFFSET], %g1; \ + brz,pn %g1, 1f; \ + mov SYS_ify(syscall_name), %g1; \ + ta 0x6d; \ + bcs,pn %xcc, __syscall_error_handler; \ + nop; \ + .subsection 2; \ +1: save %sp, -192, %sp; \ + CENABLE; \ + nop; \ + mov %o0, %l0; \ + COPY_ARGS_##args \ + mov SYS_ify(syscall_name), %g1; \ + ta 0x6d; \ + bcs,pn %xcc, __syscall_error_handler2; \ + mov %o0, %l1; \ + CDISABLE; \ + mov %l0, %o0; \ + jmpl %i7 + 8, %g0; \ + restore %g0, %l1, %o0; \ + .previous; \ + SYSCALL_ERROR_HANDLER \ + SYSCALL_ERROR_HANDLER2 + +#define SYSCALL_ERROR_HANDLER2 \ +SYSCALL_ERROR_HANDLER_ENTRY(__syscall_error_handler2) \ + .global __errno_location; \ + .type __errno_location,@function; \ + call __errno_location; \ + nop; \ + st %l1, [%o0]; \ + jmpl %i7 + 8, %g0; \ + restore %g0, -1, %o0; \ + .previous; + +# ifdef IS_IN_libpthread +# define CENABLE call __pthread_enable_asynccancel +# define CDISABLE call __pthread_disable_asynccancel +# else +# define CENABLE call __libc_enable_asynccancel +# define CDISABLE call __libc_disable_asynccancel +# endif + +#define COPY_ARGS_0 /* Nothing */ +#define COPY_ARGS_1 COPY_ARGS_0 mov %i0, %o0; +#define COPY_ARGS_2 COPY_ARGS_1 mov %i1, %o1; +#define COPY_ARGS_3 COPY_ARGS_2 mov %i2, %o2; +#define COPY_ARGS_4 COPY_ARGS_3 mov %i3, %o3; +#define COPY_ARGS_5 COPY_ARGS_4 mov %i4, %o4; +#define COPY_ARGS_6 COPY_ARGS_5 mov %i5, %o5; + +# ifndef ASSEMBLER +# define SINGLE_THREAD_P \ + __builtin_expect (THREAD_GETMEM (THREAD_SELF, \ + p_header.data.multiple_threads) == 0, 1) +# else +# define SINGLE_THREAD_P ld [%g6 + MULTIPLE_THREADS_OFFSET], %g1 +# endif + +#elif !defined ASSEMBLER + +/* This code should never be used but we define it anyhow. */ +# define SINGLE_THREAD_P (1) + +#endif diff --git a/linuxthreads/sysdeps/x86_64/tls.h b/linuxthreads/sysdeps/x86_64/tls.h index a649898f3f..67e20b2ed9 100644 --- a/linuxthreads/sysdeps/x86_64/tls.h +++ b/linuxthreads/sysdeps/x86_64/tls.h @@ -109,6 +109,11 @@ typedef struct _result ? "cannot set %fs base address for thread-local storage" : 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 + /* Return the address of the dtv for the current thread. */ # define THREAD_DTV() \ ({ struct _pthread_descr_struct *__descr; \ |