blob: 51b4adf94b856f72662f1e3792c08767cf61ef41 [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
njn9f207462009-03-10 22:02:09 +000010 Copyright (C) 2000-2009 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;
njnc7561b92005-06-19 01:24:32 +000086#else
87# error Unknown architecture
88#endif
89
njnf76d27a2009-05-28 01:53:07 +000090/* Forward declarations */
91struct SyscallStatus;
92struct SyscallArgs;
njnc7561b92005-06-19 01:24:32 +000093
sewardja4068de2006-04-05 23:06:31 +000094/* Architecture-specific thread state */
njnc7561b92005-06-19 01:24:32 +000095typedef
96 struct {
97 /* --- BEGIN vex-mandated guest state --- */
98
sewardj7cf4e6b2008-05-01 20:24:26 +000099 /* Note that for code generation reasons, we require that the
100 guest state area, its two shadows, and the spill area, are
101 16-aligned and have 16-aligned sizes, and there are no holes
102 in between. This is checked by do_pre_run_checks() in
103 scheduler.c. */
njnc7561b92005-06-19 01:24:32 +0000104
sewardj7cf4e6b2008-05-01 20:24:26 +0000105 /* Saved machine context. */
106 VexGuestArchState vex __attribute__((aligned(16)));
107
108 /* Saved shadow context (2 copies). */
109 VexGuestArchState vex_shadow1 __attribute__((aligned(16)));
110 VexGuestArchState vex_shadow2 __attribute__((aligned(16)));
njnc7561b92005-06-19 01:24:32 +0000111
112 /* Spill area. */
sewardj7cf4e6b2008-05-01 20:24:26 +0000113 UChar vex_spill[LibVEX_N_SPILL_BYTES] __attribute__((aligned(16)));
njnc7561b92005-06-19 01:24:32 +0000114
115 /* --- END vex-mandated guest state --- */
116 }
117 ThreadArchState;
118
sewardja4068de2006-04-05 23:06:31 +0000119
njn99778ee2009-05-19 05:01:27 +0000120/* OS-specific thread state. IMPORTANT: if you add fields to this,
121 you _must_ add code to os_state_clear() to initialise those
122 fields. */
sewardja4068de2006-04-05 23:06:31 +0000123typedef
124 struct {
125 /* who we are */
njnf76d27a2009-05-28 01:53:07 +0000126 Int lwpid; // PID of kernel task (Darwin: Mach thread)
sewardja4068de2006-04-05 23:06:31 +0000127 Int threadgroup; // thread group id
njnc7561b92005-06-19 01:24:32 +0000128
sewardja4068de2006-04-05 23:06:31 +0000129 ThreadId parent; // parent tid (if any)
njnc7561b92005-06-19 01:24:32 +0000130
sewardja4068de2006-04-05 23:06:31 +0000131 /* runtime details */
132 Addr valgrind_stack_base; // Valgrind's stack (VgStack*)
133 Addr valgrind_stack_init_SP; // starting value for SP
njnc7561b92005-06-19 01:24:32 +0000134
sewardja4068de2006-04-05 23:06:31 +0000135 /* exit details */
sewardjd8a725e2006-10-17 02:01:12 +0000136 Word exitcode; // in the case of exitgroup, set by someone else
137 Int fatalsig; // fatal signal
138
139# if defined(VGO_aix5)
140 /* AIX specific fields to make thread cancellation sort-of work */
141 /* What is this thread's current cancellation state a la
142 POSIX (deferred vs async, enable vs disabled) ? */
143 Bool cancel_async; // current cancel mode (async vs deferred)
144 Bool cancel_disabled; // cancellation disabled?
145 /* What's happened so far? */
146 enum { Canc_NoRequest=0, // no cancellation requested
147 Canc_Requested=1, // requested but not actioned
148 Canc_Actioned=2 } // requested and actioned
149 cancel_progress;
150 /* Initial state is False, False, Canc_Normal. */
151# endif
njnf76d27a2009-05-28 01:53:07 +0000152
153# if defined(VGO_darwin)
154 // Mach trap POST handler as chosen by PRE
155 void (*post_mach_trap_fn)(ThreadId tid,
156 struct SyscallArgs *, struct SyscallStatus *);
157
158 // This thread's pthread
159 Addr pthread;
160
161 // Argument passed when thread started
162 Addr func_arg;
163
164 // Synchronization between child thread and parent thread's POST wrapper
165 semaphore_t child_go;
166 semaphore_t child_done;
167
168 // Workqueue re-entry
169 // (setjmp in PRE(workq_ops), longjmp in wqthread_hijack)
170 // DDD: JRS fixme: this comment is no longer correct; wq_jmpbuf is
171 // never used, and there is no such setjmp or longjmp pair.
172 // I guess we could leave wq_jmpbuf_valid in place though, since
173 // it does allow for an assertion in ML_(wqthread_continue_NORETURN).
174 Bool wq_jmpbuf_valid;
175 //jmp_buf wq_jmpbuf;
176
177 // Values saved from transient Mach RPC messages
178 Addr remote_port; // destination for original message
179 Int msgh_id; // outgoing message id
180 union {
181 struct {
182 Addr port;
183 } mach_port;
184 struct {
185 Int right;
186 } mach_port_allocate;
187 struct {
188 Addr port;
189 Int right;
190 Int delta;
191 } mach_port_mod_refs;
192 struct {
193 Addr task;
194 Addr name;
195 Int disposition;
196 } mach_port_insert_right;
197 struct {
198 Addr size;
199 int flags;
200 } vm_allocate;
201 struct {
202 Addr address;
203 Addr size;
204 } vm_deallocate;
205 struct {
206 Addr src;
207 Addr dst;
208 Addr size;
209 } vm_copy;
210 struct {
211 Addr address;
212 Addr size;
213 int set_maximum;
214 UWord new_protection;
215 } vm_protect;
216 struct {
217 Addr addr;
218 SizeT size;
219 } vm_read;
220 struct {
221 ULong addr;
222 ULong size;
223 } mach_vm_read;
224 struct {
225 Addr addr;
226 SizeT size;
227 Addr data;
228 } vm_read_overwrite;
229 struct {
230 Addr size;
231 int copy;
232 UWord protection;
233 } vm_map;
234 struct {
235 Addr size;
236 } vm_remap;
237 struct {
238 ULong size;
239 int flags;
240 } mach_vm_allocate;
241 struct {
242 ULong address;
243 ULong size;
244 } mach_vm_deallocate;
245 struct {
246 ULong address;
247 ULong size;
248 int set_maximum;
249 unsigned int new_protection;
250 } mach_vm_protect;
251 struct {
252 ULong size;
253 int copy;
254 UWord protection;
255 } mach_vm_map;
256 struct {
257 Addr thread;
258 UWord flavor;
259 } thread_get_state;
260 struct {
261 Addr address;
262 } io_connect_unmap_memory;
263 struct {
264 int which_port;
265 } task_get_special_port;
266 struct {
267 char *service_name;
268 } bootstrap_look_up;
269 struct {
270 vki_size_t size;
271 } WindowServer_29828;
272 struct {
273 Int access_rights;
274 } WindowServer_29831;
275 struct {
276 char *path;
277 } io_registry_entry_from_path;
278 } mach_args;
279# endif
280
sewardja4068de2006-04-05 23:06:31 +0000281 }
282 ThreadOSstate;
njnc7561b92005-06-19 01:24:32 +0000283
284
sewardja4068de2006-04-05 23:06:31 +0000285/* Overall thread state */
njnc7561b92005-06-19 01:24:32 +0000286typedef struct {
287 /* ThreadId == 0 (and hence vg_threads[0]) is NEVER USED.
288 The thread identity is simply the index in vg_threads[].
289 ThreadId == 1 is the root thread and has the special property
290 that we don't try and allocate or deallocate its stack. For
291 convenience of generating error message, we also put the
292 ThreadId in this tid field, but be aware that it should
293 ALWAYS == the index in vg_threads[]. */
294 ThreadId tid;
295
296 /* Current scheduling status. */
297 ThreadStatus status;
298
299 /* This is set if the thread is in the process of exiting for any
300 reason. The precise details of the exit are in the OS-specific
301 state. */
302 VgSchedReturnCode exitreason;
303
304 /* Architecture-specific thread state. */
305 ThreadArchState arch;
306
307 /* This thread's blocked-signals mask. Semantics is that for a
308 signal to be delivered to this thread, the signal must not be
309 blocked by this signal mask. If more than one thread accepts a
310 signal, then it will be delivered to one at random. If all
311 threads block the signal, it will remain pending until either a
312 thread unblocks it or someone uses sigwaitsig/sigtimedwait. */
313 vki_sigset_t sig_mask;
314
315 /* tmp_sig_mask is usually the same as sig_mask, and is kept in
316 sync whenever sig_mask is changed. The only time they have
317 different values is during the execution of a sigsuspend, where
318 tmp_sig_mask is the temporary mask which sigsuspend installs.
319 It is only consulted to compute the signal mask applied to a
320 signal handler. */
321 vki_sigset_t tmp_sig_mask;
322
323 /* A little signal queue for signals we can't get the kernel to
324 queue for us. This is only allocated as needed, since it should
325 be rare. */
326 struct SigQueue *sig_queue;
327
328 /* Client stacks. When a thread slot is freed, we don't deallocate its
329 stack; we just leave it lying around for the next use of the
330 slot. If the next use of the slot requires a larger stack,
331 only then is the old one deallocated and a new one
332 allocated.
333
sewardja4068de2006-04-05 23:06:31 +0000334 For the main thread (threadid == 1), this mechanism doesn't
njnc7561b92005-06-19 01:24:32 +0000335 apply. We don't know the size of the stack since we didn't
336 allocate it, and furthermore we never reallocate it. */
337
bart96a0de32008-03-29 09:25:11 +0000338 /* The allocated size of this thread's stack */
njnc7561b92005-06-19 01:24:32 +0000339 SizeT client_stack_szB;
340
341 /* Address of the highest legitimate word in this stack. This is
342 used for error messages only -- not critical for execution
343 correctness. Is is set for all stacks, specifically including
sewardja4068de2006-04-05 23:06:31 +0000344 ThreadId == 1 (the main thread). */
njnc7561b92005-06-19 01:24:32 +0000345 Addr client_stack_highest_word;
346
347 /* Alternate signal stack */
348 vki_stack_t altstack;
349
350 /* OS-specific thread state */
sewardja4068de2006-04-05 23:06:31 +0000351 ThreadOSstate os_state;
njnc7561b92005-06-19 01:24:32 +0000352
njnc7561b92005-06-19 01:24:32 +0000353 /* Per-thread jmp_buf to resume scheduler after a signal */
354 Bool sched_jmpbuf_valid;
355 jmp_buf sched_jmpbuf;
356}
357ThreadState;
358
359
360/*------------------------------------------------------------*/
361/*--- The thread table. ---*/
362/*------------------------------------------------------------*/
363
364/* A statically allocated array of threads. NOTE: [0] is
365 never used, to simplify the simulation of initialisers for
366 LinuxThreads. */
367extern ThreadState VG_(threads)[VG_N_THREADS];
368
369// The running thread. m_scheduler should be the only other module
370// to write to this.
371extern ThreadId VG_(running_tid);
372
njnf76d27a2009-05-28 01:53:07 +0000373
njnc7561b92005-06-19 01:24:32 +0000374/*------------------------------------------------------------*/
375/*--- Basic operations on the thread table. ---*/
376/*------------------------------------------------------------*/
377
378// Convert a ThreadStatus to a string.
379const HChar* VG_(name_of_ThreadStatus) ( ThreadStatus status );
380
381/* Get the ThreadState for a particular thread */
382extern ThreadState *VG_(get_ThreadState) ( ThreadId tid );
383
384/* Check that tid is in range and denotes a non-Empty thread. */
385extern Bool VG_(is_valid_tid) ( ThreadId tid );
386
387/* Returns true if a thread is currently running (ie, has the CPU lock) */
388extern Bool VG_(is_running_thread)(ThreadId tid);
389
390/* Returns true if the thread is in the process of exiting */
391extern Bool VG_(is_exiting)(ThreadId tid);
392
393/* Return the number of non-dead Threads */
394extern Int VG_(count_living_threads)(void);
395
sewardjd8a725e2006-10-17 02:01:12 +0000396/* Return the number of threads in VgTs_Runnable state */
397extern Int VG_(count_runnable_threads)(void);
398
njnc7561b92005-06-19 01:24:32 +0000399/* Given an LWP id (ie, real kernel thread id), find the corresponding
400 ThreadId */
sewardj42781722006-12-17 19:36:06 +0000401extern ThreadId VG_(lwpid_to_vgtid)(Int lwpid);
njnc7561b92005-06-19 01:24:32 +0000402
403#endif // __PUB_CORE_THREADSTATE_H
404
405/*--------------------------------------------------------------------*/
406/*--- end ---*/
407/*--------------------------------------------------------------------*/