blob: 1ae0b60ff12d1dc2f6203a40746b6fa332ceccfd [file] [log] [blame]
yuezonghe824eb0c2024-06-27 02:32:26 -07001/* 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.
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#ifndef __ASSEMBLER__
24
25# include <pt-machine.h>
26# include <stdbool.h>
27# include <stddef.h>
28
29/* Type for the dtv. */
30typedef union dtv
31{
32 size_t counter;
33 struct
34 {
35 void *val;
36 bool is_static;
37 } pointer;
38} dtv_t;
39
40#else /* __ASSEMBLER__ */
41# include <tcb-offsets.h>
42#endif /* __ASSEMBLER__ */
43
44#ifdef HAVE_TLS_SUPPORT
45
46/* Signal that TLS support is available. */
47# define USE_TLS 1
48
49# ifndef __ASSEMBLER__
50
51/* This layout is actually wholly private and not affected by the ABI.
52 Nor does it overlap the pthread data structure, so we need nothing
53 extra here at all. */
54typedef struct
55{
56 dtv_t *dtv;
57} tcbhead_t;
58
59/* This is the size of the initial TCB. */
60# define TLS_INIT_TCB_SIZE 0
61
62/* Alignment requirements for the initial TCB. */
63# define TLS_INIT_TCB_ALIGN __alignof__ (struct _pthread_descr_struct)
64
65/* This is the size of the TCB. */
66# define TLS_TCB_SIZE 0
67
68/* Alignment requirements for the TCB. */
69# define TLS_TCB_ALIGN __alignof__ (struct _pthread_descr_struct)
70
71/* This is the size we need before TCB. */
72# define TLS_PRE_TCB_SIZE \
73 (sizeof (struct _pthread_descr_struct) \
74 + ((sizeof (tcbhead_t) + TLS_TCB_ALIGN - 1) & ~(TLS_TCB_ALIGN - 1)))
75
76/* The following assumes that TP (R2 or R13) is points to the end of the
77 TCB + 0x7000 (per the ABI). This implies that TCB address is
78 TP - 0x7000. As we define TLS_DTV_AT_TP we can
79 assume that the pthread_descr is allocated immediately ahead of the
80 TCB. This implies that the pthread_descr address is
81 TP - (TLS_PRE_TCB_SIZE + 0x7000). */
82#define TLS_TCB_OFFSET 0x7000
83
84/* The DTV is allocated at the TP; the TCB is placed elsewhere. */
85/* This is not really true for powerpc64. We are following alpha
86 where the DTV pointer is first doubleword in the TCB. */
87# define TLS_DTV_AT_TP 1
88
89/* Install the dtv pointer. The pointer passed is to the element with
90 index -1 which contain the length. */
91# define INSTALL_DTV(TCBP, DTVP) \
92 (((tcbhead_t *) (TCBP))[-1].dtv = (DTVP) + 1)
93
94/* Install new dtv for current thread. */
95# define INSTALL_NEW_DTV(DTV) (THREAD_DTV() = (DTV))
96
97/* Return dtv of given thread descriptor. */
98# define GET_DTV(TCBP) (((tcbhead_t *) (TCBP))[-1].dtv)
99
100/* We still need this define so that tcb-offsets.sym can override it and
101 use THREAD_SELF to generate MULTIPLE_THREADS_OFFSET. */
102# define __thread_register ((void *) __thread_self)
103
104/* Code to initially initialize the thread pointer. This might need
105 special attention since 'errno' is not yet available and if the
106 operation can cause a failure 'errno' must not be touched.
107
108 The global register variable is declared in pt-machine.h with the
109 wrong type, so we need some extra casts to get the desired result.
110 This avoids a lvalue cast that gcc-3.4 does not like. */
111# define TLS_INIT_TP(TCBP, SECONDCALL) \
112 (__thread_self = (struct _pthread_descr_struct *) \
113 ((void *) (TCBP) + TLS_TCB_OFFSET), NULL)
114
115/* Return the address of the dtv for the current thread. */
116# define THREAD_DTV() \
117 (((tcbhead_t *) ((void *) __thread_self - TLS_TCB_OFFSET))[-1].dtv)
118
119/* Return the thread descriptor for the current thread. */
120# undef THREAD_SELF
121# define THREAD_SELF \
122 ((pthread_descr) (__thread_register \
123 - TLS_TCB_OFFSET - TLS_PRE_TCB_SIZE))
124
125# undef INIT_THREAD_SELF
126# define INIT_THREAD_SELF(DESCR, NR) \
127 (__thread_self = (struct _pthread_descr_struct *)((void *) (DESCR) \
128 + TLS_TCB_OFFSET + TLS_PRE_TCB_SIZE))
129
130/* Make sure we have the p_multiple_threads member in the thread structure.
131 See below. */
132# define TLS_MULTIPLE_THREADS_IN_TCB 1
133
134/* Get the thread descriptor definition. */
135# include <linuxthreads/descr.h>
136
137/* l_tls_offset == 0 is perfectly valid on PPC, so we have to use some
138 different value to mean unset l_tls_offset. */
139# define NO_TLS_OFFSET -1
140
141# endif /* __ASSEMBLER__ */
142
143#elif !defined __ASSEMBLER__
144
145/* This overlaps the start of the pthread_descr. System calls
146 and such use this to find the multiple_threads flag and need
147 to use the same offset relative to the thread register in both
148 single-threaded and multi-threaded code. */
149typedef struct
150{
151 void *tcb; /* Never used. */
152 dtv_t *dtv; /* Never used. */
153 void *self; /* Used only if multithreaded, and rarely. */
154 int multiple_threads; /* Only this member is really used. */
155} tcbhead_t;
156
157#define NONTLS_INIT_TP \
158 do { \
159 static const tcbhead_t nontls_init_tp = { .multiple_threads = 0 }; \
160 __thread_self = (__typeof (__thread_self)) &nontls_init_tp; \
161 } while (0)
162
163#endif /* HAVE_TLS_SUPPORT */
164
165#endif /* tls.h */