]>
Commit | Line | Data |
---|---|---|
f3c13160 RM |
1 | /* Definition for thread-local data handling. NPTL/PowerPC version. |
2 | Copyright (C) 2003 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 1 | |
22 | ||
23 | # include <dl-sysdep.h> | |
24 | ||
25 | #ifndef __ASSEMBLER__ | |
26 | # include <stddef.h> | |
27 | # include <stdint.h> | |
28 | ||
29 | /* Type for the dtv. */ | |
30 | typedef union dtv | |
31 | { | |
32 | size_t counter; | |
33 | void *pointer; | |
34 | } dtv_t; | |
35 | ||
36 | #else /* __ASSEMBLER__ */ | |
37 | # include <tcb-offsets.h> | |
38 | #endif /* __ASSEMBLER__ */ | |
39 | ||
40 | ||
41 | /* We require TLS support in the tools. */ | |
42 | #ifndef HAVE_TLS_SUPPORT | |
43 | # error "TLS support is required." | |
44 | #endif | |
45 | ||
46 | /* Signal that TLS support is available. */ | |
47 | # define USE_TLS 1 | |
48 | ||
49 | #ifndef __ASSEMBLER__ | |
50 | ||
51 | /* Get system call information. */ | |
52 | # include <sysdep.h> | |
53 | ||
54 | /* The TP points to the start of the thread blocks. */ | |
55 | # define TLS_DTV_AT_TP 1 | |
56 | ||
94659495 RM |
57 | /* We use the multiple_threads field in the pthread struct */ |
58 | #define TLS_MULTIPLE_THREADS_IN_TCB 1 | |
f3c13160 RM |
59 | |
60 | /* Get the thread descriptor definition. */ | |
61 | # include <nptl/descr.h> | |
62 | ||
63 | /* This layout is actually wholly private and not affected by the ABI. | |
64 | Nor does it overlap the pthread data structure, so we need nothing | |
65 | extra here at all. */ | |
66 | typedef struct | |
67 | { | |
68 | dtv_t *dtv; | |
69 | } tcbhead_t; | |
70 | ||
71 | /* This is the size of the initial TCB. */ | |
299601a1 | 72 | # define TLS_INIT_TCB_SIZE 0 |
f3c13160 RM |
73 | |
74 | /* Alignment requirements for the initial TCB. */ | |
299601a1 | 75 | # define TLS_INIT_TCB_ALIGN __alignof__ (struct pthread) |
f3c13160 RM |
76 | |
77 | /* This is the size of the TCB. */ | |
299601a1 | 78 | # define TLS_TCB_SIZE 0 |
f3c13160 RM |
79 | |
80 | /* Alignment requirements for the TCB. */ | |
299601a1 | 81 | # define TLS_TCB_ALIGN __alignof__ (struct pthread) |
f3c13160 RM |
82 | |
83 | /* This is the size we need before TCB. */ | |
299601a1 | 84 | # define TLS_PRE_TCB_SIZE (sizeof (struct pthread) + 32) |
f3c13160 RM |
85 | |
86 | # ifndef __powerpc64__ | |
87 | /* Register r2 (tp) is reserved by the ABI as "thread pointer". */ | |
88 | register void *__thread_register __asm__ ("r2"); | |
89 | # define PT_THREAD_POINTER PT_R2 | |
90 | # else | |
91 | /* Register r13 (tp) is reserved by the ABI as "thread pointer". */ | |
92 | register void *__thread_register __asm__ ("r13"); | |
93 | # define PT_THREAD_POINTER PT_R13 | |
94 | # endif | |
95 | ||
96 | /* The following assumes that TP (R2 or R13) points to the end of the | |
97 | TCB + 0x7000 (per the ABI). This implies that TCB address is | |
299601a1 | 98 | TP - 0x7000. As we define TLS_DTV_AT_TP we can |
f3c13160 RM |
99 | assume that the pthread struct is allocated immediately ahead of the |
100 | TCB. This implies that the pthread_descr address is | |
299601a1 | 101 | TP - (TLS_PRE_TCB_SIZE + 0x7000). */ |
f3c13160 RM |
102 | # define TLS_TCB_OFFSET 0x7000 |
103 | ||
104 | /* Install the dtv pointer. The pointer passed is to the element with | |
105 | index -1 which contain the length. */ | |
106 | # define INSTALL_DTV(tcbp, dtvp) \ | |
299601a1 | 107 | ((tcbhead_t *) (tcbp))[-1].dtv = dtvp + 1 |
f3c13160 RM |
108 | |
109 | /* Install new dtv for current thread. */ | |
110 | # define INSTALL_NEW_DTV(dtv) (THREAD_DTV() = (dtv)) | |
111 | ||
112 | /* Return dtv of given thread descriptor. */ | |
299601a1 | 113 | # define GET_DTV(tcbp) (((tcbhead_t *) (tcbp))[-1].dtv) |
f3c13160 RM |
114 | |
115 | /* Code to initially initialize the thread pointer. This might need | |
116 | special attention since 'errno' is not yet available and if the | |
117 | operation can cause a failure 'errno' must not be touched. */ | |
118 | # define TLS_INIT_TP(tcbp, secondcall) \ | |
299601a1 | 119 | (__thread_register = (void *) (tcbp) + TLS_TCB_OFFSET, NULL) |
f3c13160 RM |
120 | |
121 | /* Return the address of the dtv for the current thread. */ | |
122 | # define THREAD_DTV() \ | |
299601a1 | 123 | (((tcbhead_t *) (__thread_register - TLS_TCB_OFFSET))[-1].dtv) |
f3c13160 RM |
124 | |
125 | /* Return the thread descriptor for the current thread. */ | |
126 | # define THREAD_SELF \ | |
127 | ((struct pthread *) (__thread_register \ | |
299601a1 | 128 | - TLS_TCB_OFFSET - TLS_PRE_TCB_SIZE)) |
f3c13160 RM |
129 | |
130 | /* Read member of the thread descriptor directly. */ | |
131 | # define THREAD_GETMEM(descr, member) ((void)(descr), (THREAD_SELF)->member) | |
132 | ||
133 | /* Same as THREAD_GETMEM, but the member offset can be non-constant. */ | |
134 | # define THREAD_GETMEM_NC(descr, member, idx) \ | |
135 | ((void)(descr), (THREAD_SELF)->member[idx]) | |
136 | ||
137 | /* Set member of the thread descriptor directly. */ | |
138 | # define THREAD_SETMEM(descr, member, value) \ | |
139 | ((void)(descr), (THREAD_SELF)->member = (value)) | |
140 | ||
141 | /* Same as THREAD_SETMEM, but the member offset can be non-constant. */ | |
142 | # define THREAD_SETMEM_NC(descr, member, idx, value) \ | |
143 | ((void)(descr), (THREAD_SELF)->member[idx] = (value)) | |
144 | ||
299601a1 UD |
145 | /* l_tls_offset == 0 is perfectly valid on PPC, so we have to use some |
146 | different value to mean unset l_tls_offset. */ | |
147 | # define NO_TLS_OFFSET -1 | |
148 | ||
f3c13160 RM |
149 | #endif /* __ASSEMBLER__ */ |
150 | ||
151 | #endif /* tls.h */ |