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