]>
Commit | Line | Data |
---|---|---|
056a1eb7 SF |
1 | /* $Id: thread.h $ */ |
2 | /** @file | |
3 | * IPRT - Internal RTThread header. | |
4 | */ | |
5 | ||
6 | /* | |
6d209b23 | 7 | * Copyright (C) 2006-2017 Oracle Corporation |
056a1eb7 SF |
8 | * |
9 | * This file is part of VirtualBox Open Source Edition (OSE), as | |
10 | * available from http://www.virtualbox.org. This file is free software; | |
11 | * you can redistribute it and/or modify it under the terms of the GNU | |
12 | * General Public License (GPL) as published by the Free Software | |
13 | * Foundation, in version 2 as it comes in the "COPYING" file of the | |
14 | * VirtualBox OSE distribution. VirtualBox OSE is distributed in the | |
15 | * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind. | |
16 | * | |
17 | * The contents of this file may alternatively be used under the terms | |
18 | * of the Common Development and Distribution License Version 1.0 | |
19 | * (CDDL) only, as it comes in the "COPYING.CDDL" file of the | |
20 | * VirtualBox OSE distribution, in which case the provisions of the | |
21 | * CDDL are applicable instead of those of the GPL. | |
22 | * | |
23 | * You may elect to license modified versions of this file under the | |
24 | * terms and conditions of either the GPL or the CDDL or both. | |
25 | */ | |
26 | ||
27 | #ifndef ___thread_h | |
28 | #define ___thread_h | |
29 | ||
30 | #include <iprt/types.h> | |
31 | #include <iprt/thread.h> | |
32 | #include <iprt/avl.h> | |
33 | #ifdef IN_RING3 | |
34 | # include <iprt/process.h> | |
35 | # include <iprt/critsect.h> | |
36 | #endif | |
37 | #include "internal/lockvalidator.h" | |
38 | #include "internal/magics.h" | |
39 | #ifdef RT_WITH_ICONV_CACHE | |
40 | # include "internal/string.h" | |
41 | #endif | |
42 | ||
43 | RT_C_DECLS_BEGIN | |
44 | ||
45 | ||
46 | /** Max thread name length. */ | |
47 | #define RTTHREAD_NAME_LEN 16 | |
48 | #ifdef IPRT_WITH_GENERIC_TLS | |
49 | /** The number of TLS entries for the generic implementation. */ | |
50 | # define RTTHREAD_TLS_ENTRIES 64 | |
51 | #endif | |
52 | ||
53 | /** | |
54 | * Internal representation of a thread. | |
55 | */ | |
56 | typedef struct RTTHREADINT | |
57 | { | |
58 | /** Avl node core - the key is the native thread id. */ | |
59 | AVLPVNODECORE Core; | |
60 | /** Magic value (RTTHREADINT_MAGIC). */ | |
61 | uint32_t u32Magic; | |
62 | /** Reference counter. */ | |
63 | uint32_t volatile cRefs; | |
64 | /** The current thread state. */ | |
65 | RTTHREADSTATE volatile enmState; | |
66 | /** Set when really sleeping. */ | |
67 | bool volatile fReallySleeping; | |
68 | #if defined(RT_OS_WINDOWS) && defined(IN_RING3) | |
69 | /** The thread handle | |
70 | * This is not valid until the create function has returned! */ | |
71 | uintptr_t hThread; | |
72 | #endif | |
73 | #if defined(RT_OS_LINUX) && defined(IN_RING3) | |
74 | /** The thread ID. | |
75 | * This is not valid before rtThreadMain has been called by the new thread. */ | |
76 | pid_t tid; | |
77 | #endif | |
78 | #if defined(RT_OS_SOLARIS) && defined(IN_RING0) | |
79 | /** Debug thread ID needed for thread_join. */ | |
80 | uint64_t tid; | |
81 | #endif | |
82 | /** The user event semaphore. */ | |
83 | RTSEMEVENTMULTI EventUser; | |
84 | /** The terminated event semaphore. */ | |
85 | RTSEMEVENTMULTI EventTerminated; | |
86 | /** The thread type. */ | |
87 | RTTHREADTYPE enmType; | |
88 | /** The thread creation flags. (RTTHREADFLAGS) */ | |
89 | unsigned fFlags; | |
90 | /** Internal flags. (RTTHREADINT_FLAGS_ *) */ | |
91 | uint32_t fIntFlags; | |
92 | /** The result code. */ | |
93 | int rc; | |
94 | /** Thread function. */ | |
95 | PFNRTTHREAD pfnThread; | |
96 | /** Thread function argument. */ | |
97 | void *pvUser; | |
98 | /** Actual stack size. */ | |
99 | size_t cbStack; | |
100 | #ifdef IN_RING3 | |
101 | /** The lock validator data. */ | |
102 | RTLOCKVALPERTHREAD LockValidator; | |
103 | #endif /* IN_RING3 */ | |
104 | #ifdef RT_WITH_ICONV_CACHE | |
105 | /** Handle cache for iconv. | |
106 | * @remarks ASSUMES sizeof(void *) >= sizeof(iconv_t). */ | |
107 | void *ahIconvs[RTSTRICONV_END]; | |
108 | #endif | |
109 | #ifdef IPRT_WITH_GENERIC_TLS | |
110 | /** The TLS entries for this thread. */ | |
111 | void *apvTlsEntries[RTTHREAD_TLS_ENTRIES]; | |
112 | #endif | |
113 | /** Thread name. */ | |
114 | char szName[RTTHREAD_NAME_LEN]; | |
115 | } RTTHREADINT; | |
116 | /** Pointer to the internal representation of a thread. */ | |
117 | typedef RTTHREADINT *PRTTHREADINT; | |
118 | ||
119 | ||
120 | /** @name RTTHREADINT::fIntFlags Masks and Bits. | |
121 | * @{ */ | |
122 | /** Set if the thread is an alien thread. | |
123 | * Clear if the thread was created by IPRT. */ | |
124 | #define RTTHREADINT_FLAGS_ALIEN RT_BIT(0) | |
125 | /** Set if the thread has terminated. | |
126 | * Clear if the thread is running. */ | |
127 | #define RTTHREADINT_FLAGS_TERMINATED RT_BIT(1) | |
128 | /** This bit is set if the thread is in the AVL tree. */ | |
129 | #define RTTHREADINT_FLAG_IN_TREE_BIT 2 | |
130 | /** @copydoc RTTHREADINT_FLAG_IN_TREE_BIT */ | |
131 | #define RTTHREADINT_FLAG_IN_TREE RT_BIT(RTTHREADINT_FLAG_IN_TREE_BIT) | |
132 | /** Set if it's the main thread. */ | |
133 | #define RTTHREADINT_FLAGS_MAIN RT_BIT(3) | |
134 | /** @} */ | |
135 | ||
136 | ||
137 | /** | |
138 | * Initialize the native part of the thread management. | |
139 | * | |
140 | * Generally a TLS entry will be allocated at this point (Ring-3). | |
141 | * | |
142 | * @returns iprt status code. | |
143 | */ | |
144 | DECLHIDDEN(int) rtThreadNativeInit(void); | |
145 | ||
146 | #ifdef IN_RING3 | |
147 | /** | |
148 | * Called when IPRT was first initialized in unobtrusive mode and later changed | |
149 | * to obtrustive. | |
150 | * | |
151 | * This is only applicable in ring-3. | |
152 | */ | |
153 | DECLHIDDEN(void) rtThreadNativeReInitObtrusive(void); | |
154 | #endif | |
155 | ||
156 | /** | |
157 | * Create a native thread. | |
158 | * This creates the thread as described in pThreadInt and stores the thread id in *pThread. | |
159 | * | |
160 | * @returns iprt status code. | |
161 | * @param pThreadInt The thread data structure for the thread. | |
162 | * @param pNativeThread Where to store the native thread identifier. | |
163 | */ | |
164 | DECLHIDDEN(int) rtThreadNativeCreate(PRTTHREADINT pThreadInt, PRTNATIVETHREAD pNativeThread); | |
165 | ||
166 | /** | |
167 | * Adopts a thread, this is called immediately after allocating the | |
168 | * thread structure. | |
169 | * | |
170 | * @param pThread Pointer to the thread structure. | |
171 | */ | |
172 | DECLHIDDEN(int) rtThreadNativeAdopt(PRTTHREADINT pThread); | |
173 | ||
174 | /** | |
175 | * Called from rtThreadDestroy so that the TLS entry and any native data in the | |
176 | * thread structure can be cleared. | |
177 | * | |
178 | * @param pThread The thread structure. | |
179 | */ | |
180 | DECLHIDDEN(void) rtThreadNativeDestroy(PRTTHREADINT pThread); | |
181 | ||
6d209b23 SF |
182 | #ifdef IN_RING3 |
183 | /** | |
184 | * Called to check whether the thread is still alive or not before we start | |
185 | * waiting. | |
186 | * | |
187 | * This is a kludge to deal with windows threads being killed wholesale in | |
188 | * certain process termination scenarios and we don't want to hang the last | |
189 | * thread because it's waiting on the semaphore of a dead thread. | |
190 | * | |
191 | * @returns true if alive, false if not. | |
192 | * @param pThread The thread structure. | |
193 | */ | |
194 | DECLHIDDEN(bool) rtThreadNativeIsAliveKludge(PRTTHREADINT pThread); | |
195 | #endif | |
196 | ||
056a1eb7 SF |
197 | #ifdef IN_RING0 |
198 | /** | |
199 | * Called from rtThreadWait when the last thread has completed in order to make | |
200 | * sure it's all the way out of IPRT before RTR0Term is called. | |
201 | * | |
202 | * @param pThread The thread structure. | |
203 | */ | |
204 | DECLHIDDEN(void) rtThreadNativeWaitKludge(PRTTHREADINT pThread); | |
205 | #endif | |
206 | ||
207 | ||
208 | /** | |
209 | * Sets the priority of the thread according to the thread type | |
210 | * and current process priority. | |
211 | * | |
212 | * The RTTHREADINT::enmType member has not yet been updated and will be updated by | |
213 | * the caller on a successful return. | |
214 | * | |
215 | * @returns iprt status code. | |
216 | * @param pThread The thread in question. | |
217 | * @param enmType The thread type. | |
218 | * @remark Located in sched. | |
219 | */ | |
220 | DECLHIDDEN(int) rtThreadNativeSetPriority(PRTTHREADINT pThread, RTTHREADTYPE enmType); | |
221 | ||
222 | #ifdef IN_RING3 | |
223 | # ifdef RT_OS_WINDOWS | |
224 | /** | |
225 | * Callback for when a native thread is detaching. | |
226 | * | |
227 | * It give the Win32/64 backend a chance to terminate alien | |
228 | * threads properly. | |
229 | */ | |
230 | DECLHIDDEN(void) rtThreadNativeDetach(void); | |
231 | ||
232 | /** | |
233 | * Internal function for informing the debugger about a thread. | |
234 | * @param pThread The thread. May differ from the calling thread. | |
235 | */ | |
236 | DECLHIDDEN(void) rtThreadNativeInformDebugger(PRTTHREADINT pThread); | |
237 | # endif | |
238 | #endif /* IN_RING3 */ | |
239 | ||
240 | ||
241 | /* thread.cpp */ | |
242 | DECLCALLBACK(DECLHIDDEN(int)) rtThreadMain(PRTTHREADINT pThread, RTNATIVETHREAD NativeThread, const char *pszThreadName); | |
243 | DECLHIDDEN(uint32_t) rtThreadRelease(PRTTHREADINT pThread); | |
244 | DECLHIDDEN(void) rtThreadTerminate(PRTTHREADINT pThread, int rc); | |
245 | DECLHIDDEN(PRTTHREADINT) rtThreadGetByNative(RTNATIVETHREAD NativeThread); | |
246 | DECLHIDDEN(PRTTHREADINT) rtThreadGet(RTTHREAD Thread); | |
247 | DECLHIDDEN(int) rtThreadInit(void); | |
248 | #ifdef IN_RING3 | |
249 | DECLHIDDEN(void) rtThreadReInitObtrusive(void); | |
250 | #endif | |
251 | DECLHIDDEN(void) rtThreadTerm(void); | |
252 | DECLHIDDEN(void) rtThreadInsert(PRTTHREADINT pThread, RTNATIVETHREAD NativeThread); | |
253 | #ifdef IN_RING3 | |
254 | DECLHIDDEN(int) rtThreadDoSetProcPriority(RTPROCPRIORITY enmPriority); | |
255 | #endif /* !IN_RING0 */ | |
256 | #ifdef IPRT_WITH_GENERIC_TLS | |
257 | DECLHIDDEN(void) rtThreadClearTlsEntry(RTTLS iTls); | |
258 | DECLHIDDEN(void) rtThreadTlsDestruction(PRTTHREADINT pThread); /* in tls-generic.cpp */ | |
259 | #endif | |
260 | ||
261 | #ifdef ___iprt_asm_h | |
262 | ||
263 | /** | |
264 | * Gets the thread state. | |
265 | * | |
266 | * @returns The thread state. | |
267 | * @param pThread The thread. | |
268 | */ | |
269 | DECLINLINE(RTTHREADSTATE) rtThreadGetState(PRTTHREADINT pThread) | |
270 | { | |
271 | return pThread->enmState; | |
272 | } | |
273 | ||
274 | /** | |
275 | * Sets the thread state. | |
276 | * | |
277 | * @param pThread The thread. | |
278 | * @param enmNewState The new thread state. | |
279 | */ | |
280 | DECLINLINE(void) rtThreadSetState(PRTTHREADINT pThread, RTTHREADSTATE enmNewState) | |
281 | { | |
282 | AssertCompile(sizeof(pThread->enmState) == sizeof(uint32_t)); | |
283 | ASMAtomicWriteU32((uint32_t volatile *)&pThread->enmState, enmNewState); | |
284 | } | |
285 | ||
286 | #endif | |
287 | ||
288 | RT_C_DECLS_END | |
289 | ||
290 | #endif |