Back to index

glibc  2.9
tls.h
Go to the documentation of this file.
00001 /* Definitions for thread-local data handling.  linuxthreads/s390 version.
00002    Copyright (C) 2002, 2003, 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 <pt-machine.h>
00026 # include <stdbool.h>
00027 # include <stddef.h>
00028 # include <stdint.h>
00029 
00030 /* Type for the dtv.  */
00031 typedef union dtv
00032 {
00033   size_t counter;
00034   struct
00035   {
00036     void *val;
00037     bool is_static;
00038   } pointer;
00039 } dtv_t;
00040 
00041 typedef struct
00042 {
00043   void *tcb;         /* Pointer to the TCB.  Not necessary the
00044                         thread descriptor used by libpthread.  */
00045   dtv_t *dtv;
00046   void *self;        /* Pointer to the thread descriptor.  */
00047   int multiple_threads;
00048   uintptr_t sysinfo;
00049   uintptr_t stack_guard;
00050 } tcbhead_t;
00051 
00052 #else /* __ASSEMBLER__ */
00053 # include <tcb-offsets.h>
00054 #endif /* __ASSEMBLER__ */
00055 
00056 /* TLS is always supported if the tools support it.  There are no
00057    kernel dependencies.  To avoid bothering with the TLS support code
00058    at all, use configure --without-tls.
00059 
00060    We need USE_TLS to be consistently defined, for ldsodefs.h
00061    conditionals.  */
00062 
00063 #ifdef HAVE_TLS_SUPPORT
00064 
00065 /* Signal that TLS support is available.  */
00066 # define USE_TLS     1
00067 
00068 # ifndef __ASSEMBLER__
00069 /* Get system call information.  */
00070 #  include <sysdep.h>
00071 
00072 
00073 /* Get the thread descriptor definition.  */
00074 #  include <linuxthreads/descr.h>
00075 
00076 /* This is the size of the initial TCB.  */
00077 #  define TLS_INIT_TCB_SIZE sizeof (tcbhead_t)
00078 
00079 /* Alignment requirements for the initial TCB.  */
00080 #  define TLS_INIT_TCB_ALIGN __alignof__ (tcbhead_t)
00081 
00082 /* This is the size of the TCB.  */
00083 #  define TLS_TCB_SIZE sizeof (struct _pthread_descr_struct)
00084 
00085 /* Alignment requirements for the TCB.  */
00086 #  define TLS_TCB_ALIGN __alignof__ (struct _pthread_descr_struct)
00087 
00088 /* The TCB can have any size and the memory following the address the
00089    thread pointer points to is unspecified.  Allocate the TCB there.  */
00090 #  define TLS_TCB_AT_TP     1
00091 
00092 
00093 /* Install the dtv pointer.  The pointer passed is to the element with
00094    index -1 which contain the length.  */
00095 #  define INSTALL_DTV(descr, dtvp) \
00096   ((tcbhead_t *) (descr))->dtv = (dtvp) + 1
00097 
00098 /* Install new dtv for current thread.  */
00099 #  define INSTALL_NEW_DTV(dtv) \
00100   (((tcbhead_t *) __builtin_thread_pointer ())->dtv = (dtv))
00101 
00102 /* Return dtv of given thread descriptor.  */
00103 #  define GET_DTV(descr) \
00104   (((tcbhead_t *) (descr))->dtv)
00105 
00106 /* Code to initially initialize the thread pointer.  This might need
00107    special attention since 'errno' is not yet available and if the
00108    operation can cause a failure 'errno' must not be touched.
00109 
00110    The value of this macro is null if successful, or an error string.  */
00111 #  define TLS_INIT_TP(descr, secondcall)                             \
00112   ({                                                                 \
00113     void *_descr = (descr);                                          \
00114     tcbhead_t *head = _descr;                                               \
00115                                                                      \
00116     head->tcb = _descr;                                                     \
00117     /* For now the thread descriptor is at the same address.  */            \
00118     head->self = _descr;                                             \
00119                                                                      \
00120     __builtin_set_thread_pointer (_descr);                                  \
00121     NULL;                                                            \
00122   })
00123 
00124 /* Return the address of the dtv for the current thread.  */
00125 #  define THREAD_DTV() \
00126   (((tcbhead_t *) __builtin_thread_pointer ())->dtv)
00127 
00128 /* Set the stack guard field in TCB head.  */
00129 #define THREAD_SET_STACK_GUARD(value) \
00130   THREAD_SETMEM (THREAD_SELF, header.stack_guard, value)
00131 #define THREAD_COPY_STACK_GUARD(descr) \
00132   ((descr)->header.stack_guard                                              \
00133    = THREAD_GETMEM (THREAD_SELF, header.stack_guard))
00134 
00135 /* s390 doesn't have HP_TIMING_*, so for the time being
00136    use stack_guard as pointer_guard.  */
00137 #define THREAD_GET_POINTER_GUARD() \
00138   THREAD_GETMEM (THREAD_SELF, header.stack_guard)
00139 #define THREAD_SET_POINTER_GUARD(value)
00140 #define THREAD_COPY_POINTER_GUARD(descr)
00141 
00142 # endif /* __ASSEMBLER__ */
00143 
00144 #else  /* HAVE_TLS_SUPPORT && (FLOATING_STACKS || !IS_IN_libpthread) */
00145 
00146 # ifndef __ASSEMBLER__
00147 
00148 /* Get the thread descriptor definition.  */
00149 #  include <linuxthreads/descr.h>
00150 
00151 #  define NONTLS_INIT_TP \
00152   do {                                                         \
00153     static const tcbhead_t nontls_init_tp               \
00154       = { .multiple_threads = 0 };                      \
00155     INIT_THREAD_SELF (&nontls_init_tp, 0);                     \
00156   } while (0)
00157 
00158 # endif /* __ASSEMBLER__ */
00159 
00160 #endif /* HAVE_TLS_SUPPORT && (FLOATING_STACKS || !IS_IN_libpthread) */
00161 
00162 #endif /* tls.h */