blob: 639ef73afcf4649f9456e20938269e007cc18ee7 [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
sewardj9eecbbb2010-05-03 21:37:12 +000010 Copyright (C) 2000-2010 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
143# if defined(VGO_aix5)
144 /* AIX specific fields to make thread cancellation sort-of work */
145 /* What is this thread's current cancellation state a la
146 POSIX (deferred vs async, enable vs disabled) ? */
147 Bool cancel_async; // current cancel mode (async vs deferred)
148 Bool cancel_disabled; // cancellation disabled?
149 /* What's happened so far? */
150 enum { Canc_NoRequest=0, // no cancellation requested
151 Canc_Requested=1, // requested but not actioned
152 Canc_Actioned=2 } // requested and actioned
153 cancel_progress;
154 /* Initial state is False, False, Canc_Normal. */
155# endif
njnf76d27a2009-05-28 01:53:07 +0000156
157# if defined(VGO_darwin)
158 // Mach trap POST handler as chosen by PRE
159 void (*post_mach_trap_fn)(ThreadId tid,
160 struct SyscallArgs *, struct SyscallStatus *);
161
162 // This thread's pthread
163 Addr pthread;
164
165 // Argument passed when thread started
166 Addr func_arg;
167
168 // Synchronization between child thread and parent thread's POST wrapper
169 semaphore_t child_go;
170 semaphore_t child_done;
171
172 // Workqueue re-entry
173 // (setjmp in PRE(workq_ops), longjmp in wqthread_hijack)
174 // DDD: JRS fixme: this comment is no longer correct; wq_jmpbuf is
175 // never used, and there is no such setjmp or longjmp pair.
176 // I guess we could leave wq_jmpbuf_valid in place though, since
177 // it does allow for an assertion in ML_(wqthread_continue_NORETURN).
178 Bool wq_jmpbuf_valid;
179 //jmp_buf wq_jmpbuf;
180
181 // Values saved from transient Mach RPC messages
182 Addr remote_port; // destination for original message
183 Int msgh_id; // outgoing message id
184 union {
185 struct {
186 Addr port;
187 } mach_port;
188 struct {
189 Int right;
190 } mach_port_allocate;
191 struct {
192 Addr port;
193 Int right;
194 Int delta;
195 } mach_port_mod_refs;
196 struct {
197 Addr task;
198 Addr name;
199 Int disposition;
200 } mach_port_insert_right;
201 struct {
202 Addr size;
203 int flags;
204 } vm_allocate;
205 struct {
206 Addr address;
207 Addr size;
208 } vm_deallocate;
209 struct {
210 Addr src;
211 Addr dst;
212 Addr size;
213 } vm_copy;
214 struct {
215 Addr address;
216 Addr size;
217 int set_maximum;
218 UWord new_protection;
219 } vm_protect;
220 struct {
221 Addr addr;
222 SizeT size;
223 } vm_read;
224 struct {
225 ULong addr;
226 ULong size;
227 } mach_vm_read;
228 struct {
229 Addr addr;
230 SizeT size;
231 Addr data;
232 } vm_read_overwrite;
233 struct {
234 Addr size;
235 int copy;
236 UWord protection;
237 } vm_map;
238 struct {
239 Addr size;
240 } vm_remap;
241 struct {
242 ULong size;
243 int flags;
244 } mach_vm_allocate;
245 struct {
246 ULong address;
247 ULong size;
248 } mach_vm_deallocate;
249 struct {
250 ULong address;
251 ULong size;
252 int set_maximum;
253 unsigned int new_protection;
254 } mach_vm_protect;
255 struct {
256 ULong size;
257 int copy;
258 UWord protection;
259 } mach_vm_map;
260 struct {
261 Addr thread;
262 UWord flavor;
263 } thread_get_state;
264 struct {
265 Addr address;
266 } io_connect_unmap_memory;
267 struct {
268 int which_port;
269 } task_get_special_port;
270 struct {
271 char *service_name;
272 } bootstrap_look_up;
273 struct {
274 vki_size_t size;
275 } WindowServer_29828;
276 struct {
277 Int access_rights;
278 } WindowServer_29831;
279 struct {
280 char *path;
281 } io_registry_entry_from_path;
282 } mach_args;
283# endif
284
sewardja4068de2006-04-05 23:06:31 +0000285 }
286 ThreadOSstate;
njnc7561b92005-06-19 01:24:32 +0000287
288
sewardja4068de2006-04-05 23:06:31 +0000289/* Overall thread state */
njnc7561b92005-06-19 01:24:32 +0000290typedef struct {
291 /* ThreadId == 0 (and hence vg_threads[0]) is NEVER USED.
292 The thread identity is simply the index in vg_threads[].
293 ThreadId == 1 is the root thread and has the special property
294 that we don't try and allocate or deallocate its stack. For
295 convenience of generating error message, we also put the
296 ThreadId in this tid field, but be aware that it should
297 ALWAYS == the index in vg_threads[]. */
298 ThreadId tid;
299
300 /* Current scheduling status. */
301 ThreadStatus status;
302
303 /* This is set if the thread is in the process of exiting for any
304 reason. The precise details of the exit are in the OS-specific
305 state. */
306 VgSchedReturnCode exitreason;
307
308 /* Architecture-specific thread state. */
309 ThreadArchState arch;
310
311 /* This thread's blocked-signals mask. Semantics is that for a
312 signal to be delivered to this thread, the signal must not be
313 blocked by this signal mask. If more than one thread accepts a
314 signal, then it will be delivered to one at random. If all
315 threads block the signal, it will remain pending until either a
316 thread unblocks it or someone uses sigwaitsig/sigtimedwait. */
317 vki_sigset_t sig_mask;
318
319 /* tmp_sig_mask is usually the same as sig_mask, and is kept in
320 sync whenever sig_mask is changed. The only time they have
321 different values is during the execution of a sigsuspend, where
322 tmp_sig_mask is the temporary mask which sigsuspend installs.
323 It is only consulted to compute the signal mask applied to a
324 signal handler. */
325 vki_sigset_t tmp_sig_mask;
326
327 /* A little signal queue for signals we can't get the kernel to
328 queue for us. This is only allocated as needed, since it should
329 be rare. */
330 struct SigQueue *sig_queue;
331
332 /* Client stacks. When a thread slot is freed, we don't deallocate its
333 stack; we just leave it lying around for the next use of the
334 slot. If the next use of the slot requires a larger stack,
335 only then is the old one deallocated and a new one
336 allocated.
337
sewardja4068de2006-04-05 23:06:31 +0000338 For the main thread (threadid == 1), this mechanism doesn't
njnc7561b92005-06-19 01:24:32 +0000339 apply. We don't know the size of the stack since we didn't
340 allocate it, and furthermore we never reallocate it. */
341
bart96a0de32008-03-29 09:25:11 +0000342 /* The allocated size of this thread's stack */
njnc7561b92005-06-19 01:24:32 +0000343 SizeT client_stack_szB;
344
345 /* Address of the highest legitimate word in this stack. This is
346 used for error messages only -- not critical for execution
347 correctness. Is is set for all stacks, specifically including
sewardja4068de2006-04-05 23:06:31 +0000348 ThreadId == 1 (the main thread). */
njnc7561b92005-06-19 01:24:32 +0000349 Addr client_stack_highest_word;
350
351 /* Alternate signal stack */
352 vki_stack_t altstack;
353
354 /* OS-specific thread state */
sewardja4068de2006-04-05 23:06:31 +0000355 ThreadOSstate os_state;
njnc7561b92005-06-19 01:24:32 +0000356
njnc7561b92005-06-19 01:24:32 +0000357 /* Per-thread jmp_buf to resume scheduler after a signal */
sewardj6c591e12011-04-11 16:17:51 +0000358 Bool sched_jmpbuf_valid;
359 VG_MINIMAL_JMP_BUF sched_jmpbuf;
njnc7561b92005-06-19 01:24:32 +0000360}
361ThreadState;
362
363
364/*------------------------------------------------------------*/
365/*--- The thread table. ---*/
366/*------------------------------------------------------------*/
367
368/* A statically allocated array of threads. NOTE: [0] is
369 never used, to simplify the simulation of initialisers for
370 LinuxThreads. */
371extern ThreadState VG_(threads)[VG_N_THREADS];
372
373// The running thread. m_scheduler should be the only other module
374// to write to this.
375extern ThreadId VG_(running_tid);
376
njnf76d27a2009-05-28 01:53:07 +0000377
njnc7561b92005-06-19 01:24:32 +0000378/*------------------------------------------------------------*/
379/*--- Basic operations on the thread table. ---*/
380/*------------------------------------------------------------*/
381
382// Convert a ThreadStatus to a string.
383const HChar* VG_(name_of_ThreadStatus) ( ThreadStatus status );
384
385/* Get the ThreadState for a particular thread */
386extern ThreadState *VG_(get_ThreadState) ( ThreadId tid );
387
388/* Check that tid is in range and denotes a non-Empty thread. */
389extern Bool VG_(is_valid_tid) ( ThreadId tid );
390
391/* Returns true if a thread is currently running (ie, has the CPU lock) */
392extern Bool VG_(is_running_thread)(ThreadId tid);
393
394/* Returns true if the thread is in the process of exiting */
395extern Bool VG_(is_exiting)(ThreadId tid);
396
397/* Return the number of non-dead Threads */
398extern Int VG_(count_living_threads)(void);
399
sewardjd8a725e2006-10-17 02:01:12 +0000400/* Return the number of threads in VgTs_Runnable state */
401extern Int VG_(count_runnable_threads)(void);
402
njnc7561b92005-06-19 01:24:32 +0000403/* Given an LWP id (ie, real kernel thread id), find the corresponding
404 ThreadId */
sewardj42781722006-12-17 19:36:06 +0000405extern ThreadId VG_(lwpid_to_vgtid)(Int lwpid);
njnc7561b92005-06-19 01:24:32 +0000406
407#endif // __PUB_CORE_THREADSTATE_H
408
409/*--------------------------------------------------------------------*/
410/*--- end ---*/
411/*--------------------------------------------------------------------*/