1 /* Definitions for thread-local data handling. linuxthreads/PPC version.
2 Copyright (C) 2003, 2005 Free Software Foundation, Inc.
3 This file is part of the GNU C Library.
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.
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.
15 You should have received a copy of the GNU Lesser General Public
16 License along with the GNU C Library; if not, see
17 <http://www.gnu.org/licenses/>. */
24 # include <pt-machine.h>
28 /* Type for the dtv. */
39 #else /* __ASSEMBLER__ */
40 # include <tcb-offsets.h>
41 #endif /* __ASSEMBLER__ */
43 #ifdef HAVE_TLS_SUPPORT
45 /* Signal that TLS support is available. */
48 # ifndef __ASSEMBLER__
50 /* This layout is actually wholly private and not affected by the ABI.
51 Nor does it overlap the pthread data structure, so we need nothing
58 /* This is the size of the initial TCB. */
59 # define TLS_INIT_TCB_SIZE 0
61 /* Alignment requirements for the initial TCB. */
62 # define TLS_INIT_TCB_ALIGN __alignof__ (struct _pthread_descr_struct)
64 /* This is the size of the TCB. */
65 # define TLS_TCB_SIZE 0
67 /* Alignment requirements for the TCB. */
68 # define TLS_TCB_ALIGN __alignof__ (struct _pthread_descr_struct)
70 /* This is the size we need before TCB. */
71 # define TLS_PRE_TCB_SIZE \
72 (sizeof (struct _pthread_descr_struct) \
73 + ((sizeof (tcbhead_t) + TLS_TCB_ALIGN - 1) & ~(TLS_TCB_ALIGN - 1)))
75 /* The following assumes that TP (R2 or R13) is points to the end of the
76 TCB + 0x7000 (per the ABI). This implies that TCB address is
77 TP - 0x7000. As we define TLS_DTV_AT_TP we can
78 assume that the pthread_descr is allocated immediately ahead of the
79 TCB. This implies that the pthread_descr address is
80 TP - (TLS_PRE_TCB_SIZE + 0x7000). */
81 #define TLS_TCB_OFFSET 0x7000
83 /* The DTV is allocated at the TP; the TCB is placed elsewhere. */
84 /* This is not really true for powerpc64. We are following alpha
85 where the DTV pointer is first doubleword in the TCB. */
86 # define TLS_DTV_AT_TP 1
88 /* Install the dtv pointer. The pointer passed is to the element with
89 index -1 which contain the length. */
90 # define INSTALL_DTV(TCBP, DTVP) \
91 (((tcbhead_t *) (TCBP))[-1].dtv = (DTVP) + 1)
93 /* Install new dtv for current thread. */
94 # define INSTALL_NEW_DTV(DTV) (THREAD_DTV() = (DTV))
96 /* Return dtv of given thread descriptor. */
97 # define GET_DTV(TCBP) (((tcbhead_t *) (TCBP))[-1].dtv)
99 /* We still need this define so that tcb-offsets.sym can override it and
100 use THREAD_SELF to generate MULTIPLE_THREADS_OFFSET. */
101 # define __thread_register ((void *) __thread_self)
103 /* Code to initially initialize the thread pointer. This might need
104 special attention since 'errno' is not yet available and if the
105 operation can cause a failure 'errno' must not be touched.
107 The global register variable is declared in pt-machine.h with the
108 wrong type, so we need some extra casts to get the desired result.
109 This avoids a lvalue cast that gcc-3.4 does not like. */
110 # define TLS_INIT_TP(TCBP, SECONDCALL) \
111 (__thread_self = (struct _pthread_descr_struct *) \
112 ((void *) (TCBP) + TLS_TCB_OFFSET), NULL)
114 /* Return the address of the dtv for the current thread. */
115 # define THREAD_DTV() \
116 (((tcbhead_t *) ((void *) __thread_self - TLS_TCB_OFFSET))[-1].dtv)
118 /* Return the thread descriptor for the current thread. */
120 # define THREAD_SELF \
121 ((pthread_descr) (__thread_register \
122 - TLS_TCB_OFFSET - TLS_PRE_TCB_SIZE))
124 # undef INIT_THREAD_SELF
125 # define INIT_THREAD_SELF(DESCR, NR) \
126 (__thread_self = (struct _pthread_descr_struct *)((void *) (DESCR) \
127 + TLS_TCB_OFFSET + TLS_PRE_TCB_SIZE))
129 /* Make sure we have the p_multiple_threads member in the thread structure.
131 # define TLS_MULTIPLE_THREADS_IN_TCB 1
133 /* Get the thread descriptor definition. */
134 # include <linuxthreads/descr.h>
136 /* l_tls_offset == 0 is perfectly valid on PPC, so we have to use some
137 different value to mean unset l_tls_offset. */
138 # define NO_TLS_OFFSET -1
140 # endif /* __ASSEMBLER__ */
142 #elif !defined __ASSEMBLER__
144 /* This overlaps the start of the pthread_descr. System calls
145 and such use this to find the multiple_threads flag and need
146 to use the same offset relative to the thread register in both
147 single-threaded and multi-threaded code. */
150 void *tcb; /* Never used. */
151 dtv_t *dtv; /* Never used. */
152 void *self; /* Used only if multithreaded, and rarely. */
153 int multiple_threads; /* Only this member is really used. */
156 #define NONTLS_INIT_TP \
158 static const tcbhead_t nontls_init_tp = { .multiple_threads = 0 }; \
159 __thread_self = (__typeof (__thread_self)) &nontls_init_tp; \
162 #endif /* HAVE_TLS_SUPPORT */