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