Back to index

glibc  2.9
tls.h
Go to the documentation of this file.
00001 /* Definitions for thread-local data handling.  linuxthreads/MIPS version.
00002    Copyright (C) 2005 Free Software Foundation, Inc.
00003    This file is part of the GNU C Library.
00004 
00005    The GNU C Library is free software; you can redistribute it and/or
00006    modify it under the terms of the GNU Lesser General Public
00007    License as published by the Free Software Foundation; either
00008    version 2.1 of the License, or (at your option) any later version.
00009 
00010    The GNU C Library is distributed in the hope that it will be useful,
00011    but WITHOUT ANY WARRANTY; without even the implied warranty of
00012    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00013    Lesser General Public License for more details.
00014 
00015    You should have received a copy of the GNU Lesser General Public
00016    License along with the GNU C Library; if not, write to the Free
00017    Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
00018    02111-1307 USA.  */
00019 
00020 #ifndef _TLS_H
00021 #define _TLS_H
00022 
00023 #ifndef __ASSEMBLER__
00024 
00025 # include <stdbool.h>
00026 # include <pt-machine.h>
00027 # include <stddef.h>
00028 
00029 /* Type for the dtv.  */
00030 typedef union dtv
00031 {
00032   size_t counter;
00033   struct
00034   {
00035     void *val;
00036     bool is_static;
00037   } pointer;
00038 } dtv_t;
00039 
00040 # define READ_THREAD_POINTER() \
00041     ({ void *__result;                                                      \
00042        asm volatile (".set\tpush\n\t.set\tmips32r2\n\t"                     \
00043                    "rdhwr\t%0, $29\n\t.set\tpop" : "=v" (__result));        \
00044        __result; })
00045 
00046 #else /* __ASSEMBLER__ */
00047 # include <tcb-offsets.h>
00048 
00049 /* Note: rd must be $v1 to be ABI-conformant.  */
00050 # define READ_THREAD_POINTER(rd) \
00051        .set   push;                                                  \
00052        .set   mips32r2;                                              \
00053        rdhwr  rd, $29;                                               \
00054        .set   pop
00055 #endif /* __ASSEMBLER__ */
00056 
00057 /* LinuxThreads can only use TLS if both floating stacks (in the MIPS case,
00058    that means support for "rdhwr") and support from the tools are available.
00059 
00060    We have to define USE_TLS consistently, or ldsodefs.h will lay out types
00061    differently between an NPTL build and a LinuxThreads build.  It can be set
00062    for libc.so and not libpthread.so, but only if we provide appropriate padding
00063    in the _pthread_descr_struct.
00064 
00065    Currently nothing defines FLOATING_STACKS.  We could assume this based on
00066    kernel version once the TLS patches are available in kernel.org, but
00067    it hardly seems worth it.  Use NPTL if you can.
00068 
00069    To avoid bothering with the TLS support code at all, use configure
00070    --without-tls.  */
00071 
00072 #if defined HAVE_TLS_SUPPORT \
00073     && (defined FLOATING_STACKS || !defined IS_IN_libpthread)
00074 
00075 /* Signal that TLS support is available.  */
00076 # define USE_TLS     1
00077 
00078 /* Include padding in _pthread_descr_struct so that libc can find p_errno,
00079    if libpthread will only include the padding because of the !IS_IN_libpthread
00080    check.  */
00081 #ifndef FLOATING_STACKS
00082 # define INCLUDE_TLS_PADDING       1
00083 #endif
00084 
00085 # ifndef __ASSEMBLER__
00086 
00087 /* This layout is actually wholly private and not affected by the ABI.
00088    Nor does it overlap the pthread data structure, so we need nothing
00089    extra here at all.  */
00090 typedef struct
00091 {
00092   dtv_t *dtv;
00093   void *private;
00094 } tcbhead_t;
00095 
00096 /* This is the size of the initial TCB.  */
00097 #  define TLS_INIT_TCB_SIZE 0
00098 
00099 /* Alignment requirements for the initial TCB.  */
00100 #  define TLS_INIT_TCB_ALIGN       __alignof__ (struct _pthread_descr_struct)
00101 
00102 /* This is the size of the TCB.  */
00103 #  define TLS_TCB_SIZE             0
00104 
00105 /* Alignment requirements for the TCB.  */
00106 #  define TLS_TCB_ALIGN            __alignof__ (struct _pthread_descr_struct)
00107 
00108 /* This is the size we need before TCB.  */
00109 #  define TLS_PRE_TCB_SIZE \
00110   (sizeof (struct _pthread_descr_struct)                             \
00111    + ((sizeof (tcbhead_t) + TLS_TCB_ALIGN - 1) & ~(TLS_TCB_ALIGN - 1)))
00112 
00113 /* The thread pointer (in hardware register $29) points to the end of
00114    the TCB + 0x7000, as for PowerPC.  The pthread_descr structure is
00115    immediately in front of the TCB.  */
00116 #define TLS_TCB_OFFSET             0x7000
00117 
00118 /* The DTV is allocated at the TP; the TCB is placed elsewhere.  */
00119 /* This is not really true for powerpc64.  We are following alpha
00120    where the DTV pointer is first doubleword in the TCB.  */
00121 #  define TLS_DTV_AT_TP 1
00122 
00123 /* Install the dtv pointer.  The pointer passed is to the element with
00124    index -1 which contain the length.  */
00125 #  define INSTALL_DTV(TCBP, DTVP) \
00126   (((tcbhead_t *) (TCBP))[-1].dtv = (DTVP) + 1)
00127 
00128 /* Install new dtv for current thread.  */
00129 #  define INSTALL_NEW_DTV(DTV) (THREAD_DTV() = (DTV))
00130 
00131 /* Return dtv of given thread descriptor.  */
00132 #  define GET_DTV(TCBP)     (((tcbhead_t *) (TCBP))[-1].dtv)
00133 
00134 /* Get system call information.  */
00135 #  include <sysdep.h>
00136 
00137 /* Code to initially initialize the thread pointer.  This might need
00138    special attention since 'errno' is not yet available and if the
00139    operation can cause a failure 'errno' must not be touched.  */
00140 # define TLS_INIT_TP(tcbp, secondcall) \
00141   ({ INTERNAL_SYSCALL_DECL (err);                              \
00142      long result_var;                                                 \
00143      result_var = INTERNAL_SYSCALL (set_thread_area, err, 1,          \
00144                                 (char *) (tcbp) + TLS_TCB_OFFSET);    \
00145      INTERNAL_SYSCALL_ERROR_P (result_var, err)                       \
00146        ? "unknown error" : NULL; })
00147 
00148 /* Return the address of the dtv for the current thread.  */
00149 # define THREAD_DTV() \
00150   (((tcbhead_t *) (READ_THREAD_POINTER () - TLS_TCB_OFFSET))[-1].dtv)
00151 
00152 /* Return the thread descriptor for the current thread.  */
00153 #  undef THREAD_SELF
00154 #  define THREAD_SELF \
00155     ((pthread_descr) (READ_THREAD_POINTER () \
00156                     - TLS_TCB_OFFSET - TLS_PRE_TCB_SIZE))
00157 
00158 /* Get the thread descriptor definition.  */
00159 #  include <linuxthreads/descr.h>
00160 
00161 /* l_tls_offset == 0 is perfectly valid on MIPS, so we have to use some
00162    different value to mean unset l_tls_offset.  */
00163 #  define NO_TLS_OFFSET     -1
00164 
00165 /* Initializing the thread pointer requires a syscall which may not be
00166    available, so don't do it if we don't need to.  */
00167 #  define TLS_INIT_TP_EXPENSIVE 1
00168 
00169 # endif /* __ASSEMBLER__ */
00170 
00171 #endif /* HAVE_TLS_SUPPORT */
00172 
00173 #endif /* tls.h */