Back to index

glibc  2.9
tls.h
Go to the documentation of this file.
00001 /* Definitions for thread-local data handling.  linuxthreads/x86-64 version.
00002    Copyright (C) 2002, 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 
00042 typedef struct
00043 {
00044   void *tcb;         /* Pointer to the TCB.  Not necessary the
00045                         thread descriptor used by libpthread.  */
00046   dtv_t *dtv;
00047   void *self;        /* Pointer to the thread descriptor.  */
00048   int multiple_threads;
00049   uintptr_t sysinfo;
00050   uintptr_t stack_guard;
00051   uintptr_t pointer_guard;
00052 } tcbhead_t;
00053 
00054 #else /* __ASSEMBLER__ */
00055 # include <tcb-offsets.h>
00056 #endif
00057 
00058 
00059 #ifdef HAVE_TLS_SUPPORT
00060 
00061 /* Signal that TLS support is available.  */
00062 # define USE_TLS     1
00063 
00064 # ifndef __ASSEMBLER__
00065 /* Get system call information.  */
00066 #  include <sysdep.h>
00067 
00068 /* Get the thread descriptor definition.  */
00069 #  include <linuxthreads/descr.h>
00070 
00071 /* This is the size of the initial TCB.  */
00072 #  define TLS_INIT_TCB_SIZE sizeof (tcbhead_t)
00073 
00074 /* Alignment requirements for the initial TCB.  */
00075 #  define TLS_INIT_TCB_ALIGN __alignof__ (tcbhead_t)
00076 
00077 /* This is the size of the TCB.  */
00078 #  define TLS_TCB_SIZE sizeof (struct _pthread_descr_struct)
00079 
00080 /* Alignment requirements for the TCB.  */
00081 #  define TLS_TCB_ALIGN __alignof__ (struct _pthread_descr_struct)
00082 
00083 /* The TCB can have any size and the memory following the address the
00084    thread pointer points to is unspecified.  Allocate the TCB there.  */
00085 #  define TLS_TCB_AT_TP     1
00086 
00087 
00088 /* Install the dtv pointer.  The pointer passed is to the element with
00089    index -1 which contain the length.  */
00090 #  define INSTALL_DTV(descr, dtvp) \
00091   ((tcbhead_t *) (descr))->dtv = (dtvp) + 1
00092 
00093 /* Install new dtv for current thread.  */
00094 #  define INSTALL_NEW_DTV(dtv) \
00095   ({ struct _pthread_descr_struct *__descr;                                 \
00096      THREAD_SETMEM (__descr, p_header.data.dtvp, (dtv)); })
00097 
00098 /* Return dtv of given thread descriptor.  */
00099 #  define GET_DTV(descr) \
00100   (((tcbhead_t *) (descr))->dtv)
00101 
00102 /* Code to initially initialize the thread pointer.  This might need
00103    special attention since 'errno' is not yet available and if the
00104    operation can cause a failure 'errno' must not be touched.  */
00105 # define TLS_INIT_TP(descr, secondcall)                                     \
00106   ({                                                                 \
00107     void *_descr = (descr);                                          \
00108     tcbhead_t *head = _descr;                                               \
00109     long int _result;                                                       \
00110                                                                      \
00111     head->tcb = _descr;                                                     \
00112     /* For now the thread descriptor is at the same address.  */            \
00113     head->self = _descr;                                             \
00114                                                                      \
00115     asm volatile ("syscall"                                          \
00116                 : "=a" (_result)                                     \
00117                 : "0" ((unsigned long int) __NR_arch_prctl),                \
00118                   "D" ((unsigned long int) ARCH_SET_FS),                    \
00119                   "S" (_descr)                                       \
00120                 : "memory", "cc", "r11", "cx");                      \
00121                                                                      \
00122     _result ? "cannot set %fs base address for thread-local storage" : 0;     \
00123   })
00124 
00125 /* Indicate that dynamic linker shouldn't try to initialize TLS even
00126    when no PT_TLS segments are found in the program and libraries
00127    it is linked against.  */
00128 #  define TLS_INIT_TP_EXPENSIVE 1
00129 
00130 /* Return the address of the dtv for the current thread.  */
00131 #  define THREAD_DTV() \
00132   ({ struct _pthread_descr_struct *__descr;                                 \
00133      THREAD_GETMEM (__descr, p_header.data.dtvp); })
00134 
00135 /* Set the stack guard field in TCB head.  */
00136 # define THREAD_SET_STACK_GUARD(value) \
00137     THREAD_SETMEM (THREAD_SELF, p_header.data.stack_guard, value)
00138 # define THREAD_COPY_STACK_GUARD(descr) \
00139     ((descr)->p_header.data.stack_guard                              \
00140      = THREAD_GETMEM (THREAD_SELF, p_header.data.stack_guard))
00141 
00142 
00143 /* Set the pointer guard field in the TCB head.  */
00144 #define THREAD_SET_POINTER_GUARD(value) \
00145   THREAD_SETMEM (THREAD_SELF, p_header.data.pointer_guard, value)
00146 #define THREAD_COPY_POINTER_GUARD(descr) \
00147   ((descr)->p_header.data.pointer_guard                              \
00148    = THREAD_GETMEM (THREAD_SELF, p_header.data.pointer_guard))
00149 
00150 # endif       /* HAVE_TLS_SUPPORT */
00151 #endif /* __ASSEMBLER__ */
00152 
00153 #endif /* tls.h */