blob: 694dddcf6bde9d8cca1c38d0f044f681947d22ed [file] [log] [blame]
njnc7561b92005-06-19 01:24:32 +00001
2/*--------------------------------------------------------------------*/
3/*--- The thread state. pub_core_threadstate.h ---*/
4/*--------------------------------------------------------------------*/
5
6/*
7 This file is part of Valgrind, a dynamic binary instrumentation
8 framework.
9
sewardj0f157dd2013-10-18 14:27:36 +000010 Copyright (C) 2000-2013 Julian Seward
njnc7561b92005-06-19 01:24:32 +000011 jseward@acm.org
12
13 This program is free software; you can redistribute it and/or
14 modify it under the terms of the GNU General Public License as
15 published by the Free Software Foundation; either version 2 of the
16 License, or (at your option) any later version.
17
18 This program is distributed in the hope that it will be useful, but
19 WITHOUT ANY WARRANTY; without even the implied warranty of
20 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
21 General Public License for more details.
22
23 You should have received a copy of the GNU General Public License
24 along with this program; if not, write to the Free Software
25 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
26 02111-1307, USA.
27
28 The GNU General Public License is contained in the file COPYING.
29*/
30
31#ifndef __PUB_CORE_THREADSTATE_H
32#define __PUB_CORE_THREADSTATE_H
33
34//--------------------------------------------------------------------
35// PURPOSE: This module defines the ThreadState type and the
36// VG_(threads)[] data structure which holds all the important thread
37// state. It also defines some simple operations on the data structure
38// that don't require any external help. (m_scheduler does the complex
39// stuff).
40//--------------------------------------------------------------------
41
42#include "pub_tool_threadstate.h"
florianc91f5842013-09-15 10:42:26 +000043#include "pub_core_libcsetjmp.h" // VG_MINIMAL_JMP_BUF
florian535fb1b2013-09-15 13:54:34 +000044#include "pub_core_vki.h" // vki_sigset_t
njnc7561b92005-06-19 01:24:32 +000045
46/*------------------------------------------------------------*/
47/*--- Types ---*/
48/*------------------------------------------------------------*/
49
50/*
51 Thread state machine:
52
53 Empty -> Init -> Runnable <=> WaitSys/Yielding
54 ^ |
55 \---- Zombie -----/
56 */
57typedef
58 enum ThreadStatus {
59 VgTs_Empty, /* this slot is not in use */
60 VgTs_Init, /* just allocated */
61 VgTs_Runnable, /* ready to run */
62 VgTs_WaitSys, /* waiting for a syscall to complete */
63 VgTs_Yielding, /* temporarily yielding the CPU */
64 VgTs_Zombie, /* transient state just before exiting */
65 }
66 ThreadStatus;
67
68/* Return codes from the scheduler. */
69typedef
70 enum {
71 VgSrc_None, /* not exiting yet */
sewardjd8a725e2006-10-17 02:01:12 +000072 VgSrc_ExitThread, /* just this thread is exiting */
philippeb8ba0312013-10-21 19:57:08 +000073 VgSrc_ExitProcess, /* this thread is exiting due to another thread
74 calling exit() */
njnc7561b92005-06-19 01:24:32 +000075 VgSrc_FatalSig /* Killed by the default action of a fatal
76 signal */
77 }
78 VgSchedReturnCode;
79
80
81#if defined(VGA_x86)
82 typedef VexGuestX86State VexGuestArchState;
83#elif defined(VGA_amd64)
84 typedef VexGuestAMD64State VexGuestArchState;
cerion85665ca2005-06-20 15:51:07 +000085#elif defined(VGA_ppc32)
86 typedef VexGuestPPC32State VexGuestArchState;
sewardj2c48c7b2005-11-29 13:05:56 +000087#elif defined(VGA_ppc64)
88 typedef VexGuestPPC64State VexGuestArchState;
sewardj59570ff2010-01-01 11:59:33 +000089#elif defined(VGA_arm)
90 typedef VexGuestARMState VexGuestArchState;
sewardjf0c12502014-01-12 12:54:00 +000091#elif defined(VGA_arm64)
92 typedef VexGuestARM64State VexGuestArchState;
sewardjb5b87402011-03-07 16:05:35 +000093#elif defined(VGA_s390x)
94 typedef VexGuestS390XState VexGuestArchState;
sewardj5db15402012-06-07 09:13:21 +000095#elif defined(VGA_mips32)
96 typedef VexGuestMIPS32State VexGuestArchState;
petarj4df0bfc2013-02-27 23:17:33 +000097#elif defined(VGA_mips64)
98 typedef VexGuestMIPS64State VexGuestArchState;
njnc7561b92005-06-19 01:24:32 +000099#else
100# error Unknown architecture
101#endif
102
njnf76d27a2009-05-28 01:53:07 +0000103/* Forward declarations */
104struct SyscallStatus;
105struct SyscallArgs;
njnc7561b92005-06-19 01:24:32 +0000106
sewardja4068de2006-04-05 23:06:31 +0000107/* Architecture-specific thread state */
njnc7561b92005-06-19 01:24:32 +0000108typedef
109 struct {
110 /* --- BEGIN vex-mandated guest state --- */
111
sewardj7cf4e6b2008-05-01 20:24:26 +0000112 /* Note that for code generation reasons, we require that the
113 guest state area, its two shadows, and the spill area, are
sewardj02e97e92012-08-02 22:08:53 +0000114 16-aligned and have 16-aligned sizes, and there are no holes
sewardj7cf4e6b2008-05-01 20:24:26 +0000115 in between. This is checked by do_pre_run_checks() in
116 scheduler.c. */
njnc7561b92005-06-19 01:24:32 +0000117
sewardj7cf4e6b2008-05-01 20:24:26 +0000118 /* Saved machine context. */
sewardj02e97e92012-08-02 22:08:53 +0000119 VexGuestArchState vex __attribute__((aligned(16)));
sewardj7cf4e6b2008-05-01 20:24:26 +0000120
121 /* Saved shadow context (2 copies). */
sewardj02e97e92012-08-02 22:08:53 +0000122 VexGuestArchState vex_shadow1 __attribute__((aligned(16)));
123 VexGuestArchState vex_shadow2 __attribute__((aligned(16)));
njnc7561b92005-06-19 01:24:32 +0000124
125 /* Spill area. */
sewardj02e97e92012-08-02 22:08:53 +0000126 UChar vex_spill[LibVEX_N_SPILL_BYTES] __attribute__((aligned(16)));
njnc7561b92005-06-19 01:24:32 +0000127
128 /* --- END vex-mandated guest state --- */
129 }
130 ThreadArchState;
131
sewardja4068de2006-04-05 23:06:31 +0000132
njn99778ee2009-05-19 05:01:27 +0000133/* OS-specific thread state. IMPORTANT: if you add fields to this,
134 you _must_ add code to os_state_clear() to initialise those
135 fields. */
sewardja4068de2006-04-05 23:06:31 +0000136typedef
137 struct {
138 /* who we are */
njnf76d27a2009-05-28 01:53:07 +0000139 Int lwpid; // PID of kernel task (Darwin: Mach thread)
sewardja4068de2006-04-05 23:06:31 +0000140 Int threadgroup; // thread group id
njnc7561b92005-06-19 01:24:32 +0000141
sewardja4068de2006-04-05 23:06:31 +0000142 ThreadId parent; // parent tid (if any)
njnc7561b92005-06-19 01:24:32 +0000143
sewardja4068de2006-04-05 23:06:31 +0000144 /* runtime details */
145 Addr valgrind_stack_base; // Valgrind's stack (VgStack*)
146 Addr valgrind_stack_init_SP; // starting value for SP
njnc7561b92005-06-19 01:24:32 +0000147
sewardja4068de2006-04-05 23:06:31 +0000148 /* exit details */
sewardjd8a725e2006-10-17 02:01:12 +0000149 Word exitcode; // in the case of exitgroup, set by someone else
150 Int fatalsig; // fatal signal
151
njnf76d27a2009-05-28 01:53:07 +0000152# if defined(VGO_darwin)
153 // Mach trap POST handler as chosen by PRE
154 void (*post_mach_trap_fn)(ThreadId tid,
155 struct SyscallArgs *, struct SyscallStatus *);
156
157 // This thread's pthread
158 Addr pthread;
159
160 // Argument passed when thread started
161 Addr func_arg;
162
163 // Synchronization between child thread and parent thread's POST wrapper
164 semaphore_t child_go;
165 semaphore_t child_done;
166
167 // Workqueue re-entry
168 // (setjmp in PRE(workq_ops), longjmp in wqthread_hijack)
169 // DDD: JRS fixme: this comment is no longer correct; wq_jmpbuf is
170 // never used, and there is no such setjmp or longjmp pair.
171 // I guess we could leave wq_jmpbuf_valid in place though, since
172 // it does allow for an assertion in ML_(wqthread_continue_NORETURN).
173 Bool wq_jmpbuf_valid;
174 //jmp_buf wq_jmpbuf;
175
176 // Values saved from transient Mach RPC messages
177 Addr remote_port; // destination for original message
178 Int msgh_id; // outgoing message id
179 union {
180 struct {
181 Addr port;
182 } mach_port;
183 struct {
184 Int right;
185 } mach_port_allocate;
186 struct {
187 Addr port;
188 Int right;
189 Int delta;
190 } mach_port_mod_refs;
191 struct {
192 Addr task;
193 Addr name;
194 Int disposition;
195 } mach_port_insert_right;
196 struct {
197 Addr size;
198 int flags;
199 } vm_allocate;
200 struct {
201 Addr address;
202 Addr size;
203 } vm_deallocate;
204 struct {
205 Addr src;
206 Addr dst;
207 Addr size;
208 } vm_copy;
209 struct {
210 Addr address;
211 Addr size;
212 int set_maximum;
213 UWord new_protection;
214 } vm_protect;
215 struct {
216 Addr addr;
217 SizeT size;
218 } vm_read;
219 struct {
220 ULong addr;
221 ULong size;
222 } mach_vm_read;
223 struct {
224 Addr addr;
225 SizeT size;
226 Addr data;
227 } vm_read_overwrite;
228 struct {
229 Addr size;
230 int copy;
231 UWord protection;
232 } vm_map;
233 struct {
234 Addr size;
235 } vm_remap;
236 struct {
237 ULong size;
238 int flags;
239 } mach_vm_allocate;
240 struct {
241 ULong address;
242 ULong size;
243 } mach_vm_deallocate;
244 struct {
245 ULong address;
246 ULong size;
247 int set_maximum;
248 unsigned int new_protection;
249 } mach_vm_protect;
250 struct {
251 ULong size;
252 int copy;
253 UWord protection;
254 } mach_vm_map;
255 struct {
256 Addr thread;
257 UWord flavor;
258 } thread_get_state;
259 struct {
260 Addr address;
261 } io_connect_unmap_memory;
262 struct {
263 int which_port;
264 } task_get_special_port;
265 struct {
266 char *service_name;
267 } bootstrap_look_up;
268 struct {
269 vki_size_t size;
270 } WindowServer_29828;
271 struct {
272 Int access_rights;
273 } WindowServer_29831;
274 struct {
275 char *path;
276 } io_registry_entry_from_path;
277 } mach_args;
278# endif
279
sewardja4068de2006-04-05 23:06:31 +0000280 }
281 ThreadOSstate;
njnc7561b92005-06-19 01:24:32 +0000282
283
sewardja4068de2006-04-05 23:06:31 +0000284/* Overall thread state */
njnc7561b92005-06-19 01:24:32 +0000285typedef struct {
286 /* ThreadId == 0 (and hence vg_threads[0]) is NEVER USED.
287 The thread identity is simply the index in vg_threads[].
288 ThreadId == 1 is the root thread and has the special property
289 that we don't try and allocate or deallocate its stack. For
290 convenience of generating error message, we also put the
291 ThreadId in this tid field, but be aware that it should
292 ALWAYS == the index in vg_threads[]. */
293 ThreadId tid;
294
295 /* Current scheduling status. */
296 ThreadStatus status;
297
298 /* This is set if the thread is in the process of exiting for any
299 reason. The precise details of the exit are in the OS-specific
300 state. */
301 VgSchedReturnCode exitreason;
302
303 /* Architecture-specific thread state. */
304 ThreadArchState arch;
305
306 /* This thread's blocked-signals mask. Semantics is that for a
307 signal to be delivered to this thread, the signal must not be
308 blocked by this signal mask. If more than one thread accepts a
309 signal, then it will be delivered to one at random. If all
310 threads block the signal, it will remain pending until either a
311 thread unblocks it or someone uses sigwaitsig/sigtimedwait. */
312 vki_sigset_t sig_mask;
313
314 /* tmp_sig_mask is usually the same as sig_mask, and is kept in
315 sync whenever sig_mask is changed. The only time they have
316 different values is during the execution of a sigsuspend, where
317 tmp_sig_mask is the temporary mask which sigsuspend installs.
318 It is only consulted to compute the signal mask applied to a
319 signal handler. */
320 vki_sigset_t tmp_sig_mask;
321
322 /* A little signal queue for signals we can't get the kernel to
323 queue for us. This is only allocated as needed, since it should
324 be rare. */
325 struct SigQueue *sig_queue;
326
327 /* Client stacks. When a thread slot is freed, we don't deallocate its
328 stack; we just leave it lying around for the next use of the
329 slot. If the next use of the slot requires a larger stack,
330 only then is the old one deallocated and a new one
331 allocated.
332
sewardja4068de2006-04-05 23:06:31 +0000333 For the main thread (threadid == 1), this mechanism doesn't
njnc7561b92005-06-19 01:24:32 +0000334 apply. We don't know the size of the stack since we didn't
335 allocate it, and furthermore we never reallocate it. */
336
bart96a0de32008-03-29 09:25:11 +0000337 /* The allocated size of this thread's stack */
njnc7561b92005-06-19 01:24:32 +0000338 SizeT client_stack_szB;
339
340 /* Address of the highest legitimate word in this stack. This is
341 used for error messages only -- not critical for execution
342 correctness. Is is set for all stacks, specifically including
sewardja4068de2006-04-05 23:06:31 +0000343 ThreadId == 1 (the main thread). */
njnc7561b92005-06-19 01:24:32 +0000344 Addr client_stack_highest_word;
345
346 /* Alternate signal stack */
347 vki_stack_t altstack;
348
349 /* OS-specific thread state */
sewardja4068de2006-04-05 23:06:31 +0000350 ThreadOSstate os_state;
njnc7561b92005-06-19 01:24:32 +0000351
sewardjdc873c02011-07-24 16:02:33 +0000352 /* Error disablement level. A counter which allows selectively
353 disabling error reporting in threads. When zero, reporting is
354 enabled. When nonzero, it is disabled. This is controlled by
355 the client request 'VG_USERREQ__CHANGE_ERR_DISABLEMENT'. New
356 threads are always created with this as zero (errors
357 enabled). */
358 UInt err_disablement_level;
359
njnc7561b92005-06-19 01:24:32 +0000360 /* Per-thread jmp_buf to resume scheduler after a signal */
sewardj6c591e12011-04-11 16:17:51 +0000361 Bool sched_jmpbuf_valid;
sewardj97d3ebb2011-04-11 18:36:34 +0000362 VG_MINIMAL_JMP_BUF(sched_jmpbuf);
florian49789512013-09-16 17:08:50 +0000363
364 /* This thread's name. NULL, if no name. */
365 HChar *thread_name;
njnc7561b92005-06-19 01:24:32 +0000366}
367ThreadState;
368
369
370/*------------------------------------------------------------*/
371/*--- The thread table. ---*/
372/*------------------------------------------------------------*/
373
374/* A statically allocated array of threads. NOTE: [0] is
375 never used, to simplify the simulation of initialisers for
376 LinuxThreads. */
377extern ThreadState VG_(threads)[VG_N_THREADS];
378
379// The running thread. m_scheduler should be the only other module
380// to write to this.
381extern ThreadId VG_(running_tid);
382
njnf76d27a2009-05-28 01:53:07 +0000383
njnc7561b92005-06-19 01:24:32 +0000384/*------------------------------------------------------------*/
385/*--- Basic operations on the thread table. ---*/
386/*------------------------------------------------------------*/
387
bart27233e92012-03-08 14:59:25 +0000388/* Initialize the m_threadstate module. */
389void VG_(init_Threads)(void);
390
njnc7561b92005-06-19 01:24:32 +0000391// Convert a ThreadStatus to a string.
392const HChar* VG_(name_of_ThreadStatus) ( ThreadStatus status );
393
philippeb8ba0312013-10-21 19:57:08 +0000394// Convert a VgSchedReturnCode to a string.
395const HChar* VG_(name_of_VgSchedReturnCode) ( VgSchedReturnCode retcode );
396
njnc7561b92005-06-19 01:24:32 +0000397/* Get the ThreadState for a particular thread */
398extern ThreadState *VG_(get_ThreadState) ( ThreadId tid );
399
400/* Check that tid is in range and denotes a non-Empty thread. */
401extern Bool VG_(is_valid_tid) ( ThreadId tid );
402
403/* Returns true if a thread is currently running (ie, has the CPU lock) */
404extern Bool VG_(is_running_thread)(ThreadId tid);
405
406/* Returns true if the thread is in the process of exiting */
407extern Bool VG_(is_exiting)(ThreadId tid);
408
409/* Return the number of non-dead Threads */
410extern Int VG_(count_living_threads)(void);
411
sewardjd8a725e2006-10-17 02:01:12 +0000412/* Return the number of threads in VgTs_Runnable state */
413extern Int VG_(count_runnable_threads)(void);
414
njnc7561b92005-06-19 01:24:32 +0000415/* Given an LWP id (ie, real kernel thread id), find the corresponding
416 ThreadId */
sewardj42781722006-12-17 19:36:06 +0000417extern ThreadId VG_(lwpid_to_vgtid)(Int lwpid);
njnc7561b92005-06-19 01:24:32 +0000418
419#endif // __PUB_CORE_THREADSTATE_H
420
421/*--------------------------------------------------------------------*/
422/*--- end ---*/
423/*--------------------------------------------------------------------*/