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