blob: 7e7fa874db919b24969fdfa89165094f9d3b6ef2 [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
sewardj03f8d3f2012-08-05 15:46:46 +000010 Copyright (C) 2000-2012 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;
petarj4df0bfc2013-02-27 23:17:33 +000092#elif defined(VGA_mips64)
93 typedef VexGuestMIPS64State VexGuestArchState;
njnc7561b92005-06-19 01:24:32 +000094#else
95# error Unknown architecture
96#endif
97
njnf76d27a2009-05-28 01:53:07 +000098/* Forward declarations */
99struct SyscallStatus;
100struct SyscallArgs;
njnc7561b92005-06-19 01:24:32 +0000101
sewardja4068de2006-04-05 23:06:31 +0000102/* Architecture-specific thread state */
njnc7561b92005-06-19 01:24:32 +0000103typedef
104 struct {
105 /* --- BEGIN vex-mandated guest state --- */
106
sewardj7cf4e6b2008-05-01 20:24:26 +0000107 /* Note that for code generation reasons, we require that the
108 guest state area, its two shadows, and the spill area, are
sewardj02e97e92012-08-02 22:08:53 +0000109 16-aligned and have 16-aligned sizes, and there are no holes
sewardj7cf4e6b2008-05-01 20:24:26 +0000110 in between. This is checked by do_pre_run_checks() in
111 scheduler.c. */
njnc7561b92005-06-19 01:24:32 +0000112
sewardj7cf4e6b2008-05-01 20:24:26 +0000113 /* Saved machine context. */
sewardj02e97e92012-08-02 22:08:53 +0000114 VexGuestArchState vex __attribute__((aligned(16)));
sewardj7cf4e6b2008-05-01 20:24:26 +0000115
116 /* Saved shadow context (2 copies). */
sewardj02e97e92012-08-02 22:08:53 +0000117 VexGuestArchState vex_shadow1 __attribute__((aligned(16)));
118 VexGuestArchState vex_shadow2 __attribute__((aligned(16)));
njnc7561b92005-06-19 01:24:32 +0000119
120 /* Spill area. */
sewardj02e97e92012-08-02 22:08:53 +0000121 UChar vex_spill[LibVEX_N_SPILL_BYTES] __attribute__((aligned(16)));
njnc7561b92005-06-19 01:24:32 +0000122
123 /* --- END vex-mandated guest state --- */
124 }
125 ThreadArchState;
126
sewardja4068de2006-04-05 23:06:31 +0000127
njn99778ee2009-05-19 05:01:27 +0000128/* OS-specific thread state. IMPORTANT: if you add fields to this,
129 you _must_ add code to os_state_clear() to initialise those
130 fields. */
sewardja4068de2006-04-05 23:06:31 +0000131typedef
132 struct {
133 /* who we are */
njnf76d27a2009-05-28 01:53:07 +0000134 Int lwpid; // PID of kernel task (Darwin: Mach thread)
sewardja4068de2006-04-05 23:06:31 +0000135 Int threadgroup; // thread group id
njnc7561b92005-06-19 01:24:32 +0000136
sewardja4068de2006-04-05 23:06:31 +0000137 ThreadId parent; // parent tid (if any)
njnc7561b92005-06-19 01:24:32 +0000138
sewardja4068de2006-04-05 23:06:31 +0000139 /* runtime details */
140 Addr valgrind_stack_base; // Valgrind's stack (VgStack*)
141 Addr valgrind_stack_init_SP; // starting value for SP
njnc7561b92005-06-19 01:24:32 +0000142
sewardja4068de2006-04-05 23:06:31 +0000143 /* exit details */
sewardjd8a725e2006-10-17 02:01:12 +0000144 Word exitcode; // in the case of exitgroup, set by someone else
145 Int fatalsig; // fatal signal
146
njnf76d27a2009-05-28 01:53:07 +0000147# if defined(VGO_darwin)
148 // Mach trap POST handler as chosen by PRE
149 void (*post_mach_trap_fn)(ThreadId tid,
150 struct SyscallArgs *, struct SyscallStatus *);
151
152 // This thread's pthread
153 Addr pthread;
154
155 // Argument passed when thread started
156 Addr func_arg;
157
158 // Synchronization between child thread and parent thread's POST wrapper
159 semaphore_t child_go;
160 semaphore_t child_done;
161
162 // Workqueue re-entry
163 // (setjmp in PRE(workq_ops), longjmp in wqthread_hijack)
164 // DDD: JRS fixme: this comment is no longer correct; wq_jmpbuf is
165 // never used, and there is no such setjmp or longjmp pair.
166 // I guess we could leave wq_jmpbuf_valid in place though, since
167 // it does allow for an assertion in ML_(wqthread_continue_NORETURN).
168 Bool wq_jmpbuf_valid;
169 //jmp_buf wq_jmpbuf;
170
171 // Values saved from transient Mach RPC messages
172 Addr remote_port; // destination for original message
173 Int msgh_id; // outgoing message id
174 union {
175 struct {
176 Addr port;
177 } mach_port;
178 struct {
179 Int right;
180 } mach_port_allocate;
181 struct {
182 Addr port;
183 Int right;
184 Int delta;
185 } mach_port_mod_refs;
186 struct {
187 Addr task;
188 Addr name;
189 Int disposition;
190 } mach_port_insert_right;
191 struct {
192 Addr size;
193 int flags;
194 } vm_allocate;
195 struct {
196 Addr address;
197 Addr size;
198 } vm_deallocate;
199 struct {
200 Addr src;
201 Addr dst;
202 Addr size;
203 } vm_copy;
204 struct {
205 Addr address;
206 Addr size;
207 int set_maximum;
208 UWord new_protection;
209 } vm_protect;
210 struct {
211 Addr addr;
212 SizeT size;
213 } vm_read;
214 struct {
215 ULong addr;
216 ULong size;
217 } mach_vm_read;
218 struct {
219 Addr addr;
220 SizeT size;
221 Addr data;
222 } vm_read_overwrite;
223 struct {
224 Addr size;
225 int copy;
226 UWord protection;
227 } vm_map;
228 struct {
229 Addr size;
230 } vm_remap;
231 struct {
232 ULong size;
233 int flags;
234 } mach_vm_allocate;
235 struct {
236 ULong address;
237 ULong size;
238 } mach_vm_deallocate;
239 struct {
240 ULong address;
241 ULong size;
242 int set_maximum;
243 unsigned int new_protection;
244 } mach_vm_protect;
245 struct {
246 ULong size;
247 int copy;
248 UWord protection;
249 } mach_vm_map;
250 struct {
251 Addr thread;
252 UWord flavor;
253 } thread_get_state;
254 struct {
255 Addr address;
256 } io_connect_unmap_memory;
257 struct {
258 int which_port;
259 } task_get_special_port;
260 struct {
261 char *service_name;
262 } bootstrap_look_up;
263 struct {
264 vki_size_t size;
265 } WindowServer_29828;
266 struct {
267 Int access_rights;
268 } WindowServer_29831;
269 struct {
270 char *path;
271 } io_registry_entry_from_path;
272 } mach_args;
273# endif
274
sewardja4068de2006-04-05 23:06:31 +0000275 }
276 ThreadOSstate;
njnc7561b92005-06-19 01:24:32 +0000277
278
sewardja4068de2006-04-05 23:06:31 +0000279/* Overall thread state */
njnc7561b92005-06-19 01:24:32 +0000280typedef struct {
281 /* ThreadId == 0 (and hence vg_threads[0]) is NEVER USED.
282 The thread identity is simply the index in vg_threads[].
283 ThreadId == 1 is the root thread and has the special property
284 that we don't try and allocate or deallocate its stack. For
285 convenience of generating error message, we also put the
286 ThreadId in this tid field, but be aware that it should
287 ALWAYS == the index in vg_threads[]. */
288 ThreadId tid;
289
290 /* Current scheduling status. */
291 ThreadStatus status;
292
293 /* This is set if the thread is in the process of exiting for any
294 reason. The precise details of the exit are in the OS-specific
295 state. */
296 VgSchedReturnCode exitreason;
297
298 /* Architecture-specific thread state. */
299 ThreadArchState arch;
300
301 /* This thread's blocked-signals mask. Semantics is that for a
302 signal to be delivered to this thread, the signal must not be
303 blocked by this signal mask. If more than one thread accepts a
304 signal, then it will be delivered to one at random. If all
305 threads block the signal, it will remain pending until either a
306 thread unblocks it or someone uses sigwaitsig/sigtimedwait. */
307 vki_sigset_t sig_mask;
308
309 /* tmp_sig_mask is usually the same as sig_mask, and is kept in
310 sync whenever sig_mask is changed. The only time they have
311 different values is during the execution of a sigsuspend, where
312 tmp_sig_mask is the temporary mask which sigsuspend installs.
313 It is only consulted to compute the signal mask applied to a
314 signal handler. */
315 vki_sigset_t tmp_sig_mask;
316
317 /* A little signal queue for signals we can't get the kernel to
318 queue for us. This is only allocated as needed, since it should
319 be rare. */
320 struct SigQueue *sig_queue;
321
322 /* Client stacks. When a thread slot is freed, we don't deallocate its
323 stack; we just leave it lying around for the next use of the
324 slot. If the next use of the slot requires a larger stack,
325 only then is the old one deallocated and a new one
326 allocated.
327
sewardja4068de2006-04-05 23:06:31 +0000328 For the main thread (threadid == 1), this mechanism doesn't
njnc7561b92005-06-19 01:24:32 +0000329 apply. We don't know the size of the stack since we didn't
330 allocate it, and furthermore we never reallocate it. */
331
bart96a0de32008-03-29 09:25:11 +0000332 /* The allocated size of this thread's stack */
njnc7561b92005-06-19 01:24:32 +0000333 SizeT client_stack_szB;
334
335 /* Address of the highest legitimate word in this stack. This is
336 used for error messages only -- not critical for execution
337 correctness. Is is set for all stacks, specifically including
sewardja4068de2006-04-05 23:06:31 +0000338 ThreadId == 1 (the main thread). */
njnc7561b92005-06-19 01:24:32 +0000339 Addr client_stack_highest_word;
340
341 /* Alternate signal stack */
342 vki_stack_t altstack;
343
344 /* OS-specific thread state */
sewardja4068de2006-04-05 23:06:31 +0000345 ThreadOSstate os_state;
njnc7561b92005-06-19 01:24:32 +0000346
sewardjdc873c02011-07-24 16:02:33 +0000347 /* Error disablement level. A counter which allows selectively
348 disabling error reporting in threads. When zero, reporting is
349 enabled. When nonzero, it is disabled. This is controlled by
350 the client request 'VG_USERREQ__CHANGE_ERR_DISABLEMENT'. New
351 threads are always created with this as zero (errors
352 enabled). */
353 UInt err_disablement_level;
354
njnc7561b92005-06-19 01:24:32 +0000355 /* Per-thread jmp_buf to resume scheduler after a signal */
sewardj6c591e12011-04-11 16:17:51 +0000356 Bool sched_jmpbuf_valid;
sewardj97d3ebb2011-04-11 18:36:34 +0000357 VG_MINIMAL_JMP_BUF(sched_jmpbuf);
njnc7561b92005-06-19 01:24:32 +0000358}
359ThreadState;
360
361
362/*------------------------------------------------------------*/
363/*--- The thread table. ---*/
364/*------------------------------------------------------------*/
365
366/* A statically allocated array of threads. NOTE: [0] is
367 never used, to simplify the simulation of initialisers for
368 LinuxThreads. */
369extern ThreadState VG_(threads)[VG_N_THREADS];
370
371// The running thread. m_scheduler should be the only other module
372// to write to this.
373extern ThreadId VG_(running_tid);
374
njnf76d27a2009-05-28 01:53:07 +0000375
njnc7561b92005-06-19 01:24:32 +0000376/*------------------------------------------------------------*/
377/*--- Basic operations on the thread table. ---*/
378/*------------------------------------------------------------*/
379
bart27233e92012-03-08 14:59:25 +0000380/* Initialize the m_threadstate module. */
381void VG_(init_Threads)(void);
382
njnc7561b92005-06-19 01:24:32 +0000383// Convert a ThreadStatus to a string.
384const HChar* VG_(name_of_ThreadStatus) ( ThreadStatus status );
385
386/* Get the ThreadState for a particular thread */
387extern ThreadState *VG_(get_ThreadState) ( ThreadId tid );
388
389/* Check that tid is in range and denotes a non-Empty thread. */
390extern Bool VG_(is_valid_tid) ( ThreadId tid );
391
392/* Returns true if a thread is currently running (ie, has the CPU lock) */
393extern Bool VG_(is_running_thread)(ThreadId tid);
394
395/* Returns true if the thread is in the process of exiting */
396extern Bool VG_(is_exiting)(ThreadId tid);
397
398/* Return the number of non-dead Threads */
399extern Int VG_(count_living_threads)(void);
400
sewardjd8a725e2006-10-17 02:01:12 +0000401/* Return the number of threads in VgTs_Runnable state */
402extern Int VG_(count_runnable_threads)(void);
403
njnc7561b92005-06-19 01:24:32 +0000404/* Given an LWP id (ie, real kernel thread id), find the corresponding
405 ThreadId */
sewardj42781722006-12-17 19:36:06 +0000406extern ThreadId VG_(lwpid_to_vgtid)(Int lwpid);
njnc7561b92005-06-19 01:24:32 +0000407
408#endif // __PUB_CORE_THREADSTATE_H
409
410/*--------------------------------------------------------------------*/
411/*--- end ---*/
412/*--------------------------------------------------------------------*/