blob: 2f322597db19be46fb79512e738a7ab0431bff6b [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
floriande6ffbd2014-10-06 16:41:14 +000045#include "pub_core_guest.h" // VexGuestAMD64State etc.
46#include "libvex.h" // LibVEX_N_SPILL_BYTES
47
njnc7561b92005-06-19 01:24:32 +000048
49/*------------------------------------------------------------*/
50/*--- Types ---*/
51/*------------------------------------------------------------*/
52
53/*
54 Thread state machine:
55
56 Empty -> Init -> Runnable <=> WaitSys/Yielding
57 ^ |
58 \---- Zombie -----/
59 */
60typedef
61 enum ThreadStatus {
62 VgTs_Empty, /* this slot is not in use */
63 VgTs_Init, /* just allocated */
64 VgTs_Runnable, /* ready to run */
65 VgTs_WaitSys, /* waiting for a syscall to complete */
66 VgTs_Yielding, /* temporarily yielding the CPU */
67 VgTs_Zombie, /* transient state just before exiting */
68 }
69 ThreadStatus;
70
71/* Return codes from the scheduler. */
72typedef
73 enum {
74 VgSrc_None, /* not exiting yet */
sewardjd8a725e2006-10-17 02:01:12 +000075 VgSrc_ExitThread, /* just this thread is exiting */
philippeb8ba0312013-10-21 19:57:08 +000076 VgSrc_ExitProcess, /* this thread is exiting due to another thread
77 calling exit() */
njnc7561b92005-06-19 01:24:32 +000078 VgSrc_FatalSig /* Killed by the default action of a fatal
79 signal */
80 }
81 VgSchedReturnCode;
82
83
njnf76d27a2009-05-28 01:53:07 +000084/* Forward declarations */
85struct SyscallStatus;
86struct SyscallArgs;
njnc7561b92005-06-19 01:24:32 +000087
sewardja4068de2006-04-05 23:06:31 +000088/* Architecture-specific thread state */
njnc7561b92005-06-19 01:24:32 +000089typedef
90 struct {
91 /* --- BEGIN vex-mandated guest state --- */
92
sewardj7cf4e6b2008-05-01 20:24:26 +000093 /* Note that for code generation reasons, we require that the
94 guest state area, its two shadows, and the spill area, are
sewardj02e97e92012-08-02 22:08:53 +000095 16-aligned and have 16-aligned sizes, and there are no holes
sewardj7cf4e6b2008-05-01 20:24:26 +000096 in between. This is checked by do_pre_run_checks() in
97 scheduler.c. */
njnc7561b92005-06-19 01:24:32 +000098
sewardj7cf4e6b2008-05-01 20:24:26 +000099 /* Saved machine context. */
sewardj02e97e92012-08-02 22:08:53 +0000100 VexGuestArchState vex __attribute__((aligned(16)));
sewardj7cf4e6b2008-05-01 20:24:26 +0000101
102 /* Saved shadow context (2 copies). */
sewardj02e97e92012-08-02 22:08:53 +0000103 VexGuestArchState vex_shadow1 __attribute__((aligned(16)));
104 VexGuestArchState vex_shadow2 __attribute__((aligned(16)));
njnc7561b92005-06-19 01:24:32 +0000105
106 /* Spill area. */
sewardj02e97e92012-08-02 22:08:53 +0000107 UChar vex_spill[LibVEX_N_SPILL_BYTES] __attribute__((aligned(16)));
njnc7561b92005-06-19 01:24:32 +0000108
109 /* --- END vex-mandated guest state --- */
110 }
111 ThreadArchState;
112
sewardja4068de2006-04-05 23:06:31 +0000113
njn99778ee2009-05-19 05:01:27 +0000114/* OS-specific thread state. IMPORTANT: if you add fields to this,
115 you _must_ add code to os_state_clear() to initialise those
116 fields. */
sewardja4068de2006-04-05 23:06:31 +0000117typedef
118 struct {
119 /* who we are */
njnf76d27a2009-05-28 01:53:07 +0000120 Int lwpid; // PID of kernel task (Darwin: Mach thread)
sewardja4068de2006-04-05 23:06:31 +0000121 Int threadgroup; // thread group id
njnc7561b92005-06-19 01:24:32 +0000122
sewardja4068de2006-04-05 23:06:31 +0000123 ThreadId parent; // parent tid (if any)
njnc7561b92005-06-19 01:24:32 +0000124
sewardja4068de2006-04-05 23:06:31 +0000125 /* runtime details */
126 Addr valgrind_stack_base; // Valgrind's stack (VgStack*)
127 Addr valgrind_stack_init_SP; // starting value for SP
njnc7561b92005-06-19 01:24:32 +0000128
sewardja4068de2006-04-05 23:06:31 +0000129 /* exit details */
sewardjd8a725e2006-10-17 02:01:12 +0000130 Word exitcode; // in the case of exitgroup, set by someone else
131 Int fatalsig; // fatal signal
132
njnf76d27a2009-05-28 01:53:07 +0000133# if defined(VGO_darwin)
134 // Mach trap POST handler as chosen by PRE
135 void (*post_mach_trap_fn)(ThreadId tid,
136 struct SyscallArgs *, struct SyscallStatus *);
137
138 // This thread's pthread
139 Addr pthread;
140
141 // Argument passed when thread started
142 Addr func_arg;
143
144 // Synchronization between child thread and parent thread's POST wrapper
145 semaphore_t child_go;
146 semaphore_t child_done;
147
148 // Workqueue re-entry
149 // (setjmp in PRE(workq_ops), longjmp in wqthread_hijack)
150 // DDD: JRS fixme: this comment is no longer correct; wq_jmpbuf is
151 // never used, and there is no such setjmp or longjmp pair.
152 // I guess we could leave wq_jmpbuf_valid in place though, since
153 // it does allow for an assertion in ML_(wqthread_continue_NORETURN).
154 Bool wq_jmpbuf_valid;
155 //jmp_buf wq_jmpbuf;
156
157 // Values saved from transient Mach RPC messages
158 Addr remote_port; // destination for original message
159 Int msgh_id; // outgoing message id
160 union {
161 struct {
162 Addr port;
163 } mach_port;
164 struct {
165 Int right;
166 } mach_port_allocate;
167 struct {
168 Addr port;
169 Int right;
170 Int delta;
171 } mach_port_mod_refs;
172 struct {
173 Addr task;
174 Addr name;
175 Int disposition;
176 } mach_port_insert_right;
177 struct {
178 Addr size;
179 int flags;
180 } vm_allocate;
181 struct {
182 Addr address;
183 Addr size;
184 } vm_deallocate;
185 struct {
186 Addr src;
187 Addr dst;
188 Addr size;
189 } vm_copy;
190 struct {
191 Addr address;
192 Addr size;
193 int set_maximum;
194 UWord new_protection;
195 } vm_protect;
196 struct {
197 Addr addr;
198 SizeT size;
199 } vm_read;
200 struct {
201 ULong addr;
202 ULong size;
203 } mach_vm_read;
204 struct {
205 Addr addr;
206 SizeT size;
207 Addr data;
208 } vm_read_overwrite;
209 struct {
210 Addr size;
211 int copy;
212 UWord protection;
213 } vm_map;
214 struct {
215 Addr size;
216 } vm_remap;
217 struct {
218 ULong size;
219 int flags;
220 } mach_vm_allocate;
221 struct {
222 ULong address;
223 ULong size;
224 } mach_vm_deallocate;
225 struct {
226 ULong address;
227 ULong size;
228 int set_maximum;
229 unsigned int new_protection;
230 } mach_vm_protect;
231 struct {
232 ULong size;
233 int copy;
234 UWord protection;
235 } mach_vm_map;
236 struct {
sewardj5d75d532014-06-20 12:35:00 +0000237 ULong size;
238 int copy;
239 } mach_vm_remap;
240 struct {
njnf76d27a2009-05-28 01:53:07 +0000241 Addr thread;
242 UWord flavor;
243 } thread_get_state;
244 struct {
245 Addr address;
246 } io_connect_unmap_memory;
247 struct {
248 int which_port;
249 } task_get_special_port;
250 struct {
251 char *service_name;
252 } bootstrap_look_up;
253 struct {
254 vki_size_t size;
255 } WindowServer_29828;
256 struct {
257 Int access_rights;
258 } WindowServer_29831;
259 struct {
260 char *path;
261 } io_registry_entry_from_path;
262 } mach_args;
263# endif
264
sewardja4068de2006-04-05 23:06:31 +0000265 }
266 ThreadOSstate;
njnc7561b92005-06-19 01:24:32 +0000267
268
sewardja4068de2006-04-05 23:06:31 +0000269/* Overall thread state */
njnc7561b92005-06-19 01:24:32 +0000270typedef struct {
271 /* ThreadId == 0 (and hence vg_threads[0]) is NEVER USED.
272 The thread identity is simply the index in vg_threads[].
273 ThreadId == 1 is the root thread and has the special property
274 that we don't try and allocate or deallocate its stack. For
275 convenience of generating error message, we also put the
276 ThreadId in this tid field, but be aware that it should
277 ALWAYS == the index in vg_threads[]. */
278 ThreadId tid;
279
280 /* Current scheduling status. */
281 ThreadStatus status;
282
283 /* This is set if the thread is in the process of exiting for any
284 reason. The precise details of the exit are in the OS-specific
285 state. */
286 VgSchedReturnCode exitreason;
287
288 /* Architecture-specific thread state. */
289 ThreadArchState arch;
290
291 /* This thread's blocked-signals mask. Semantics is that for a
292 signal to be delivered to this thread, the signal must not be
293 blocked by this signal mask. If more than one thread accepts a
294 signal, then it will be delivered to one at random. If all
295 threads block the signal, it will remain pending until either a
296 thread unblocks it or someone uses sigwaitsig/sigtimedwait. */
297 vki_sigset_t sig_mask;
298
299 /* tmp_sig_mask is usually the same as sig_mask, and is kept in
300 sync whenever sig_mask is changed. The only time they have
301 different values is during the execution of a sigsuspend, where
302 tmp_sig_mask is the temporary mask which sigsuspend installs.
303 It is only consulted to compute the signal mask applied to a
304 signal handler. */
305 vki_sigset_t tmp_sig_mask;
306
307 /* A little signal queue for signals we can't get the kernel to
308 queue for us. This is only allocated as needed, since it should
309 be rare. */
310 struct SigQueue *sig_queue;
311
312 /* Client stacks. When a thread slot is freed, we don't deallocate its
313 stack; we just leave it lying around for the next use of the
314 slot. If the next use of the slot requires a larger stack,
315 only then is the old one deallocated and a new one
316 allocated.
317
sewardja4068de2006-04-05 23:06:31 +0000318 For the main thread (threadid == 1), this mechanism doesn't
njnc7561b92005-06-19 01:24:32 +0000319 apply. We don't know the size of the stack since we didn't
320 allocate it, and furthermore we never reallocate it. */
321
bart96a0de32008-03-29 09:25:11 +0000322 /* The allocated size of this thread's stack */
njnc7561b92005-06-19 01:24:32 +0000323 SizeT client_stack_szB;
324
philippe38a74d22014-08-29 22:53:19 +0000325 /* Address of the highest legitimate byte in this stack. This is
njnc7561b92005-06-19 01:24:32 +0000326 used for error messages only -- not critical for execution
327 correctness. Is is set for all stacks, specifically including
sewardja4068de2006-04-05 23:06:31 +0000328 ThreadId == 1 (the main thread). */
philippe38a74d22014-08-29 22:53:19 +0000329 Addr client_stack_highest_byte;
njnc7561b92005-06-19 01:24:32 +0000330
331 /* Alternate signal stack */
332 vki_stack_t altstack;
333
334 /* OS-specific thread state */
sewardja4068de2006-04-05 23:06:31 +0000335 ThreadOSstate os_state;
njnc7561b92005-06-19 01:24:32 +0000336
sewardjdc873c02011-07-24 16:02:33 +0000337 /* Error disablement level. A counter which allows selectively
338 disabling error reporting in threads. When zero, reporting is
339 enabled. When nonzero, it is disabled. This is controlled by
340 the client request 'VG_USERREQ__CHANGE_ERR_DISABLEMENT'. New
341 threads are always created with this as zero (errors
342 enabled). */
343 UInt err_disablement_level;
344
njnc7561b92005-06-19 01:24:32 +0000345 /* Per-thread jmp_buf to resume scheduler after a signal */
sewardj6c591e12011-04-11 16:17:51 +0000346 Bool sched_jmpbuf_valid;
sewardj97d3ebb2011-04-11 18:36:34 +0000347 VG_MINIMAL_JMP_BUF(sched_jmpbuf);
florian49789512013-09-16 17:08:50 +0000348
349 /* This thread's name. NULL, if no name. */
350 HChar *thread_name;
njnc7561b92005-06-19 01:24:32 +0000351}
352ThreadState;
353
354
355/*------------------------------------------------------------*/
356/*--- The thread table. ---*/
357/*------------------------------------------------------------*/
358
359/* A statically allocated array of threads. NOTE: [0] is
360 never used, to simplify the simulation of initialisers for
361 LinuxThreads. */
362extern ThreadState VG_(threads)[VG_N_THREADS];
363
364// The running thread. m_scheduler should be the only other module
365// to write to this.
366extern ThreadId VG_(running_tid);
367
njnf76d27a2009-05-28 01:53:07 +0000368
njnc7561b92005-06-19 01:24:32 +0000369/*------------------------------------------------------------*/
370/*--- Basic operations on the thread table. ---*/
371/*------------------------------------------------------------*/
372
bart27233e92012-03-08 14:59:25 +0000373/* Initialize the m_threadstate module. */
374void VG_(init_Threads)(void);
375
njnc7561b92005-06-19 01:24:32 +0000376// Convert a ThreadStatus to a string.
377const HChar* VG_(name_of_ThreadStatus) ( ThreadStatus status );
378
philippeb8ba0312013-10-21 19:57:08 +0000379// Convert a VgSchedReturnCode to a string.
380const HChar* VG_(name_of_VgSchedReturnCode) ( VgSchedReturnCode retcode );
381
njnc7561b92005-06-19 01:24:32 +0000382/* 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/*--------------------------------------------------------------------*/