blob: 2e80f87bf07dacb14ac8c823d538f94f66b342af [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
sewardjec062e82011-10-23 07:32:08 +000010 Copyright (C) 2000-2011 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"
43
44/*------------------------------------------------------------*/
45/*--- Types ---*/
46/*------------------------------------------------------------*/
47
48/*
49 Thread state machine:
50
51 Empty -> Init -> Runnable <=> WaitSys/Yielding
52 ^ |
53 \---- Zombie -----/
54 */
55typedef
56 enum ThreadStatus {
57 VgTs_Empty, /* this slot is not in use */
58 VgTs_Init, /* just allocated */
59 VgTs_Runnable, /* ready to run */
60 VgTs_WaitSys, /* waiting for a syscall to complete */
61 VgTs_Yielding, /* temporarily yielding the CPU */
62 VgTs_Zombie, /* transient state just before exiting */
63 }
64 ThreadStatus;
65
66/* Return codes from the scheduler. */
67typedef
68 enum {
69 VgSrc_None, /* not exiting yet */
sewardjd8a725e2006-10-17 02:01:12 +000070 VgSrc_ExitThread, /* just this thread is exiting */
71 VgSrc_ExitProcess, /* entire process is exiting */
njnc7561b92005-06-19 01:24:32 +000072 VgSrc_FatalSig /* Killed by the default action of a fatal
73 signal */
74 }
75 VgSchedReturnCode;
76
77
78#if defined(VGA_x86)
79 typedef VexGuestX86State VexGuestArchState;
80#elif defined(VGA_amd64)
81 typedef VexGuestAMD64State VexGuestArchState;
cerion85665ca2005-06-20 15:51:07 +000082#elif defined(VGA_ppc32)
83 typedef VexGuestPPC32State VexGuestArchState;
sewardj2c48c7b2005-11-29 13:05:56 +000084#elif defined(VGA_ppc64)
85 typedef VexGuestPPC64State VexGuestArchState;
sewardj59570ff2010-01-01 11:59:33 +000086#elif defined(VGA_arm)
87 typedef VexGuestARMState VexGuestArchState;
sewardjb5b87402011-03-07 16:05:35 +000088#elif defined(VGA_s390x)
89 typedef VexGuestS390XState VexGuestArchState;
sewardj5db15402012-06-07 09:13:21 +000090#elif defined(VGA_mips32)
91 typedef VexGuestMIPS32State VexGuestArchState;
njnc7561b92005-06-19 01:24:32 +000092#else
93# error Unknown architecture
94#endif
95
njnf76d27a2009-05-28 01:53:07 +000096/* Forward declarations */
97struct SyscallStatus;
98struct SyscallArgs;
njnc7561b92005-06-19 01:24:32 +000099
sewardja4068de2006-04-05 23:06:31 +0000100/* Architecture-specific thread state */
njnc7561b92005-06-19 01:24:32 +0000101typedef
102 struct {
103 /* --- BEGIN vex-mandated guest state --- */
104
sewardj7cf4e6b2008-05-01 20:24:26 +0000105 /* Note that for code generation reasons, we require that the
106 guest state area, its two shadows, and the spill area, are
sewardj45fa9f42012-05-21 10:18:10 +0000107 32-aligned and have 32-aligned sizes, and there are no holes
sewardj7cf4e6b2008-05-01 20:24:26 +0000108 in between. This is checked by do_pre_run_checks() in
109 scheduler.c. */
njnc7561b92005-06-19 01:24:32 +0000110
sewardj7cf4e6b2008-05-01 20:24:26 +0000111 /* Saved machine context. */
sewardj45fa9f42012-05-21 10:18:10 +0000112 VexGuestArchState vex __attribute__((aligned(32)));
sewardj7cf4e6b2008-05-01 20:24:26 +0000113
114 /* Saved shadow context (2 copies). */
sewardj45fa9f42012-05-21 10:18:10 +0000115 VexGuestArchState vex_shadow1 __attribute__((aligned(32)));
116 VexGuestArchState vex_shadow2 __attribute__((aligned(32)));
njnc7561b92005-06-19 01:24:32 +0000117
118 /* Spill area. */
sewardj45fa9f42012-05-21 10:18:10 +0000119 UChar vex_spill[LibVEX_N_SPILL_BYTES] __attribute__((aligned(32)));
njnc7561b92005-06-19 01:24:32 +0000120
121 /* --- END vex-mandated guest state --- */
122 }
123 ThreadArchState;
124
sewardja4068de2006-04-05 23:06:31 +0000125
njn99778ee2009-05-19 05:01:27 +0000126/* OS-specific thread state. IMPORTANT: if you add fields to this,
127 you _must_ add code to os_state_clear() to initialise those
128 fields. */
sewardja4068de2006-04-05 23:06:31 +0000129typedef
130 struct {
131 /* who we are */
njnf76d27a2009-05-28 01:53:07 +0000132 Int lwpid; // PID of kernel task (Darwin: Mach thread)
sewardja4068de2006-04-05 23:06:31 +0000133 Int threadgroup; // thread group id
njnc7561b92005-06-19 01:24:32 +0000134
sewardja4068de2006-04-05 23:06:31 +0000135 ThreadId parent; // parent tid (if any)
njnc7561b92005-06-19 01:24:32 +0000136
sewardja4068de2006-04-05 23:06:31 +0000137 /* runtime details */
138 Addr valgrind_stack_base; // Valgrind's stack (VgStack*)
139 Addr valgrind_stack_init_SP; // starting value for SP
njnc7561b92005-06-19 01:24:32 +0000140
sewardja4068de2006-04-05 23:06:31 +0000141 /* exit details */
sewardjd8a725e2006-10-17 02:01:12 +0000142 Word exitcode; // in the case of exitgroup, set by someone else
143 Int fatalsig; // fatal signal
144
njnf76d27a2009-05-28 01:53:07 +0000145# if defined(VGO_darwin)
146 // Mach trap POST handler as chosen by PRE
147 void (*post_mach_trap_fn)(ThreadId tid,
148 struct SyscallArgs *, struct SyscallStatus *);
149
150 // This thread's pthread
151 Addr pthread;
152
153 // Argument passed when thread started
154 Addr func_arg;
155
156 // Synchronization between child thread and parent thread's POST wrapper
157 semaphore_t child_go;
158 semaphore_t child_done;
159
160 // Workqueue re-entry
161 // (setjmp in PRE(workq_ops), longjmp in wqthread_hijack)
162 // DDD: JRS fixme: this comment is no longer correct; wq_jmpbuf is
163 // never used, and there is no such setjmp or longjmp pair.
164 // I guess we could leave wq_jmpbuf_valid in place though, since
165 // it does allow for an assertion in ML_(wqthread_continue_NORETURN).
166 Bool wq_jmpbuf_valid;
167 //jmp_buf wq_jmpbuf;
168
169 // Values saved from transient Mach RPC messages
170 Addr remote_port; // destination for original message
171 Int msgh_id; // outgoing message id
172 union {
173 struct {
174 Addr port;
175 } mach_port;
176 struct {
177 Int right;
178 } mach_port_allocate;
179 struct {
180 Addr port;
181 Int right;
182 Int delta;
183 } mach_port_mod_refs;
184 struct {
185 Addr task;
186 Addr name;
187 Int disposition;
188 } mach_port_insert_right;
189 struct {
190 Addr size;
191 int flags;
192 } vm_allocate;
193 struct {
194 Addr address;
195 Addr size;
196 } vm_deallocate;
197 struct {
198 Addr src;
199 Addr dst;
200 Addr size;
201 } vm_copy;
202 struct {
203 Addr address;
204 Addr size;
205 int set_maximum;
206 UWord new_protection;
207 } vm_protect;
208 struct {
209 Addr addr;
210 SizeT size;
211 } vm_read;
212 struct {
213 ULong addr;
214 ULong size;
215 } mach_vm_read;
216 struct {
217 Addr addr;
218 SizeT size;
219 Addr data;
220 } vm_read_overwrite;
221 struct {
222 Addr size;
223 int copy;
224 UWord protection;
225 } vm_map;
226 struct {
227 Addr size;
228 } vm_remap;
229 struct {
230 ULong size;
231 int flags;
232 } mach_vm_allocate;
233 struct {
234 ULong address;
235 ULong size;
236 } mach_vm_deallocate;
237 struct {
238 ULong address;
239 ULong size;
240 int set_maximum;
241 unsigned int new_protection;
242 } mach_vm_protect;
243 struct {
244 ULong size;
245 int copy;
246 UWord protection;
247 } mach_vm_map;
248 struct {
249 Addr thread;
250 UWord flavor;
251 } thread_get_state;
252 struct {
253 Addr address;
254 } io_connect_unmap_memory;
255 struct {
256 int which_port;
257 } task_get_special_port;
258 struct {
259 char *service_name;
260 } bootstrap_look_up;
261 struct {
262 vki_size_t size;
263 } WindowServer_29828;
264 struct {
265 Int access_rights;
266 } WindowServer_29831;
267 struct {
268 char *path;
269 } io_registry_entry_from_path;
270 } mach_args;
271# endif
272
sewardja4068de2006-04-05 23:06:31 +0000273 }
274 ThreadOSstate;
njnc7561b92005-06-19 01:24:32 +0000275
276
sewardja4068de2006-04-05 23:06:31 +0000277/* Overall thread state */
njnc7561b92005-06-19 01:24:32 +0000278typedef struct {
279 /* ThreadId == 0 (and hence vg_threads[0]) is NEVER USED.
280 The thread identity is simply the index in vg_threads[].
281 ThreadId == 1 is the root thread and has the special property
282 that we don't try and allocate or deallocate its stack. For
283 convenience of generating error message, we also put the
284 ThreadId in this tid field, but be aware that it should
285 ALWAYS == the index in vg_threads[]. */
286 ThreadId tid;
287
288 /* Current scheduling status. */
289 ThreadStatus status;
290
291 /* This is set if the thread is in the process of exiting for any
292 reason. The precise details of the exit are in the OS-specific
293 state. */
294 VgSchedReturnCode exitreason;
295
296 /* Architecture-specific thread state. */
297 ThreadArchState arch;
298
299 /* This thread's blocked-signals mask. Semantics is that for a
300 signal to be delivered to this thread, the signal must not be
301 blocked by this signal mask. If more than one thread accepts a
302 signal, then it will be delivered to one at random. If all
303 threads block the signal, it will remain pending until either a
304 thread unblocks it or someone uses sigwaitsig/sigtimedwait. */
305 vki_sigset_t sig_mask;
306
307 /* tmp_sig_mask is usually the same as sig_mask, and is kept in
308 sync whenever sig_mask is changed. The only time they have
309 different values is during the execution of a sigsuspend, where
310 tmp_sig_mask is the temporary mask which sigsuspend installs.
311 It is only consulted to compute the signal mask applied to a
312 signal handler. */
313 vki_sigset_t tmp_sig_mask;
314
315 /* A little signal queue for signals we can't get the kernel to
316 queue for us. This is only allocated as needed, since it should
317 be rare. */
318 struct SigQueue *sig_queue;
319
320 /* Client stacks. When a thread slot is freed, we don't deallocate its
321 stack; we just leave it lying around for the next use of the
322 slot. If the next use of the slot requires a larger stack,
323 only then is the old one deallocated and a new one
324 allocated.
325
sewardja4068de2006-04-05 23:06:31 +0000326 For the main thread (threadid == 1), this mechanism doesn't
njnc7561b92005-06-19 01:24:32 +0000327 apply. We don't know the size of the stack since we didn't
328 allocate it, and furthermore we never reallocate it. */
329
bart96a0de32008-03-29 09:25:11 +0000330 /* The allocated size of this thread's stack */
njnc7561b92005-06-19 01:24:32 +0000331 SizeT client_stack_szB;
332
333 /* Address of the highest legitimate word in this stack. This is
334 used for error messages only -- not critical for execution
335 correctness. Is is set for all stacks, specifically including
sewardja4068de2006-04-05 23:06:31 +0000336 ThreadId == 1 (the main thread). */
njnc7561b92005-06-19 01:24:32 +0000337 Addr client_stack_highest_word;
338
339 /* Alternate signal stack */
340 vki_stack_t altstack;
341
342 /* OS-specific thread state */
sewardja4068de2006-04-05 23:06:31 +0000343 ThreadOSstate os_state;
njnc7561b92005-06-19 01:24:32 +0000344
sewardjdc873c02011-07-24 16:02:33 +0000345 /* Error disablement level. A counter which allows selectively
346 disabling error reporting in threads. When zero, reporting is
347 enabled. When nonzero, it is disabled. This is controlled by
348 the client request 'VG_USERREQ__CHANGE_ERR_DISABLEMENT'. New
349 threads are always created with this as zero (errors
350 enabled). */
351 UInt err_disablement_level;
352
njnc7561b92005-06-19 01:24:32 +0000353 /* Per-thread jmp_buf to resume scheduler after a signal */
sewardj6c591e12011-04-11 16:17:51 +0000354 Bool sched_jmpbuf_valid;
sewardj97d3ebb2011-04-11 18:36:34 +0000355 VG_MINIMAL_JMP_BUF(sched_jmpbuf);
njnc7561b92005-06-19 01:24:32 +0000356}
357ThreadState;
358
359
360/*------------------------------------------------------------*/
361/*--- The thread table. ---*/
362/*------------------------------------------------------------*/
363
364/* A statically allocated array of threads. NOTE: [0] is
365 never used, to simplify the simulation of initialisers for
366 LinuxThreads. */
367extern ThreadState VG_(threads)[VG_N_THREADS];
368
369// The running thread. m_scheduler should be the only other module
370// to write to this.
371extern ThreadId VG_(running_tid);
372
njnf76d27a2009-05-28 01:53:07 +0000373
njnc7561b92005-06-19 01:24:32 +0000374/*------------------------------------------------------------*/
375/*--- Basic operations on the thread table. ---*/
376/*------------------------------------------------------------*/
377
bart27233e92012-03-08 14:59:25 +0000378/* Initialize the m_threadstate module. */
379void VG_(init_Threads)(void);
380
njnc7561b92005-06-19 01:24:32 +0000381// Convert a ThreadStatus to a string.
382const HChar* VG_(name_of_ThreadStatus) ( ThreadStatus status );
383
384/* Get the ThreadState for a particular thread */
385extern ThreadState *VG_(get_ThreadState) ( ThreadId tid );
386
387/* Check that tid is in range and denotes a non-Empty thread. */
388extern Bool VG_(is_valid_tid) ( ThreadId tid );
389
390/* Returns true if a thread is currently running (ie, has the CPU lock) */
391extern Bool VG_(is_running_thread)(ThreadId tid);
392
393/* Returns true if the thread is in the process of exiting */
394extern Bool VG_(is_exiting)(ThreadId tid);
395
396/* Return the number of non-dead Threads */
397extern Int VG_(count_living_threads)(void);
398
sewardjd8a725e2006-10-17 02:01:12 +0000399/* Return the number of threads in VgTs_Runnable state */
400extern Int VG_(count_runnable_threads)(void);
401
njnc7561b92005-06-19 01:24:32 +0000402/* Given an LWP id (ie, real kernel thread id), find the corresponding
403 ThreadId */
sewardj42781722006-12-17 19:36:06 +0000404extern ThreadId VG_(lwpid_to_vgtid)(Int lwpid);
njnc7561b92005-06-19 01:24:32 +0000405
406#endif // __PUB_CORE_THREADSTATE_H
407
408/*--------------------------------------------------------------------*/
409/*--- end ---*/
410/*--------------------------------------------------------------------*/