chiark / gitweb /
eglibc (2.11.3-4+deb6u3) squeeze-lts; urgency=medium
[eglibc.git] / linuxthreads / sysdeps / sh / tls.h
1 /* Definition for thread-local data handling.  linuxthreads/SH version.
2    Copyright (C) 2002, 2003, 2005 Free Software Foundation, Inc.
3    This file is part of the GNU C Library.
4
5    The GNU C Library is free software; you can redistribute it and/or
6    modify it under the terms of the GNU Lesser General Public
7    License as published by the Free Software Foundation; either
8    version 2.1 of the License, or (at your option) any later version.
9
10    The GNU C Library is distributed in the hope that it will be useful,
11    but WITHOUT ANY WARRANTY; without even the implied warranty of
12    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13    Lesser General Public License for more details.
14
15    You should have received a copy of the GNU Lesser General Public
16    License along with the GNU C Library; if not, write to the Free
17    Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
18    02111-1307 USA.  */
19
20 #ifndef _TLS_H
21 #define _TLS_H
22
23 # include <dl-sysdep.h>
24 # include <pt-machine.h>
25
26 #ifndef __ASSEMBLER__
27 # include <stdbool.h>
28 # include <stddef.h>
29 # include <stdint.h>
30
31 /* Type for the dtv.  */
32 typedef union dtv
33 {
34   size_t counter;
35   struct
36   {
37     void *val;
38     bool is_static;
39   } pointer;
40 } dtv_t;
41
42 #else /* __ASSEMBLER__ */
43 # include <tcb-offsets.h>
44 #endif /* __ASSEMBLER__ */
45
46
47 /* We can support TLS only if the floating-stack support is available.  */
48 #if defined HAVE_TLS_SUPPORT \
49     && (defined FLOATING_STACKS || !defined IS_IN_libpthread)
50
51 /* Signal that TLS support is available.  */
52 # define USE_TLS        1
53
54 /* Include padding in _pthread_descr_struct so that libc can find p_errno,
55    if libpthread will only include the padding because of the !IS_IN_libpthread
56    check.  */
57 #ifndef FLOATING_STACKS
58 # define INCLUDE_TLS_PADDING    1
59 #endif
60
61 # ifndef __ASSEMBLER__
62
63 typedef struct
64 {
65   dtv_t *dtv;
66   uintptr_t pointer_guard;
67 } tcbhead_t;
68
69 /* This is the size of the initial TCB.  */
70 #  define TLS_INIT_TCB_SIZE sizeof (tcbhead_t)
71
72 /* Alignment requirements for the initial TCB.  */
73 #  define TLS_INIT_TCB_ALIGN __alignof__ (tcbhead_t)
74
75 /* This is the size of the TCB.  */
76 #  define TLS_TCB_SIZE sizeof (tcbhead_t)
77
78 /* This is the size we need before TCB.  */
79 #  define TLS_PRE_TCB_SIZE sizeof (struct _pthread_descr_struct)
80
81 /* Alignment requirements for the TCB.  */
82 #  define TLS_TCB_ALIGN __alignof__ (struct _pthread_descr_struct)
83
84 /* The TLS blocks start right after the TCB.  */
85 #  define TLS_DTV_AT_TP 1
86
87 /* Install the dtv pointer.  The pointer passed is to the element with
88    index -1 which contain the length.  */
89 #  define INSTALL_DTV(tcbp, dtvp) \
90   ((tcbhead_t *) (tcbp))->dtv = dtvp + 1
91
92 /* Install new dtv for current thread.  */
93 #  define INSTALL_NEW_DTV(dtv) \
94   ({ tcbhead_t *__tcbp;                                                       \
95      __asm __volatile ("stc gbr,%0" : "=r" (__tcbp));                         \
96      __tcbp->dtv = (dtv);})
97
98 /* Return dtv of given thread descriptor.  */
99 #  define GET_DTV(tcbp) \
100   (((tcbhead_t *) (tcbp))->dtv)
101
102 /* Code to initially initialize the thread pointer.  This might need
103    special attention since 'errno' is not yet available and if the
104    operation can cause a failure 'errno' must not be touched.  */
105 #  define TLS_INIT_TP(tcbp, secondcall) \
106   ({ __asm __volatile ("ldc %0,gbr" : : "r" (tcbp)); 0; })
107
108 /* Return the address of the dtv for the current thread.  */
109 #  define THREAD_DTV() \
110   ({ tcbhead_t *__tcbp;                                                       \
111      __asm __volatile ("stc gbr,%0" : "=r" (__tcbp));                         \
112      __tcbp->dtv;})
113
114 /* Return the thread descriptor for the current thread.  */
115 #  undef THREAD_SELF
116 #  define THREAD_SELF \
117   ({ struct _pthread_descr_struct *__self;                                    \
118      __asm ("stc gbr,%0" : "=r" (__self));                                    \
119      __self - 1;})
120
121 #  undef INIT_THREAD_SELF
122 #  define INIT_THREAD_SELF(descr, nr) \
123   ({ struct _pthread_descr_struct *__self = (void *) descr;                   \
124      __asm __volatile ("ldc %0,gbr" : : "r" (__self + 1));                    \
125      0; })
126
127 # define TLS_MULTIPLE_THREADS_IN_TCB 1
128
129 #define THREAD_GET_POINTER_GUARD() \
130   ({ tcbhead_t *__tcbp;                                                       \
131      __asm __volatile ("stc gbr,%0" : "=r" (__tcbp));                         \
132      __tcbp->pointer_guard;})
133  #define THREAD_SET_POINTER_GUARD(value) \
134   ({ tcbhead_t *__tcbp;                                                       \
135      __asm __volatile ("stc gbr,%0" : "=r" (__tcbp));                         \
136      __tcbp->pointer_guard = (value);})
137 #define THREAD_COPY_POINTER_GUARD(descr) \
138   ({ tcbhead_t *__tcbp;                                                       \
139      __asm __volatile ("stc gbr,%0" : "=r" (__tcbp));                         \
140      ((tcbhead_t *) (descr + 1))->pointer_guard = __tcbp->pointer_guard;})
141
142 /* Get the thread descriptor definition.  This must be after the
143    the definition of THREAD_SELF for TLS.  */
144 #  include <linuxthreads/descr.h>
145
146 # endif /* __ASSEMBLER__ */
147
148 #else
149
150 # ifndef __ASSEMBLER__
151
152 typedef struct
153 {
154   void *tcb;
155   dtv_t *dtv;
156   void *self;
157   int multiple_threads;
158 } tcbhead_t;
159
160 /* Get the thread descriptor definition.  */
161 #  include <linuxthreads/descr.h>
162
163 #  define NONTLS_INIT_TP \
164   do {                                                                  \
165     static const tcbhead_t nontls_init_tp = { .multiple_threads = 0 };  \
166     __asm __volatile ("ldc %0,gbr" : : "r" (&nontls_init_tp));          \
167   } while (0)
168
169 # endif /* __ASSEMBLER__ */
170
171 #endif  /* HAVE_TLS_SUPPORT && (FLOATING_STACKS || !IS_IN_libpthread) */
172
173 #endif  /* tls.h */