2 /*--------------------------------------------------------------------*/
3 /*--- The thread state. pub_core_threadstate.h ---*/
4 /*--------------------------------------------------------------------*/
7 This file is part of Valgrind, a dynamic binary instrumentation
10 Copyright (C) 2000-2010 Julian Seward
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.
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.
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
28 The GNU General Public License is contained in the file COPYING.
31 #ifndef __PUB_CORE_THREADSTATE_H
32 #define __PUB_CORE_THREADSTATE_H
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
40 //--------------------------------------------------------------------
42 #include "pub_tool_threadstate.h"
44 #include <l4/sys/types.h>
45 #include <l4/sys/utcb.h>
46 #include <l4re_helper.h>
47 #include <l4/sys/thread.h>
49 #include "pub_l4re_consts.h"
52 /*------------------------------------------------------------*/
54 /*------------------------------------------------------------*/
59 Empty -> Init -> Runnable <=> WaitSys/Yielding
65 VgTs_Empty, /* this slot is not in use */
66 VgTs_Init, /* just allocated */
67 VgTs_Runnable, /* ready to run */
68 VgTs_WaitSys, /* waiting for a syscall to complete */
69 VgTs_Yielding, /* temporarily yielding the CPU */
70 VgTs_Zombie, /* transient state just before exiting */
74 /* Return codes from the scheduler. */
77 VgSrc_None, /* not exiting yet */
78 VgSrc_ExitThread, /* just this thread is exiting */
79 VgSrc_ExitProcess, /* entire process is exiting */
80 VgSrc_FatalSig /* Killed by the default action of a fatal
87 typedef VexGuestX86State VexGuestArchState;
88 #elif defined(VGA_amd64)
89 typedef VexGuestAMD64State VexGuestArchState;
90 #elif defined(VGA_ppc32)
91 typedef VexGuestPPC32State VexGuestArchState;
92 #elif defined(VGA_ppc64)
93 typedef VexGuestPPC64State VexGuestArchState;
94 #elif defined(VGA_arm)
95 typedef VexGuestARMState VexGuestArchState;
96 #elif defined(VGA_s390x)
97 typedef VexGuestS390XState VexGuestArchState;
99 # error Unknown architecture
102 /* Forward declarations */
103 struct SyscallStatus;
106 /* Architecture-specific thread state */
109 /* --- BEGIN vex-mandated guest state --- */
111 /* Note that for code generation reasons, we require that the
112 guest state area, its two shadows, and the spill area, are
113 16-aligned and have 16-aligned sizes, and there are no holes
114 in between. This is checked by do_pre_run_checks() in
117 /* Saved machine context. */
118 VexGuestArchState vex __attribute__((aligned(16)));
120 /* Saved shadow context (2 copies). */
121 VexGuestArchState vex_shadow1 __attribute__((aligned(16)));
122 VexGuestArchState vex_shadow2 __attribute__((aligned(16)));
125 UChar vex_spill[LibVEX_N_SPILL_BYTES] __attribute__((aligned(16)));
127 /* --- END vex-mandated guest state --- */
132 /* OS-specific thread state. IMPORTANT: if you add fields to this,
133 you _must_ add code to os_state_clear() to initialise those
138 Int lwpid; // PID of kernel task (Darwin: Mach thread)
139 Int threadgroup; // thread group id
141 ThreadId parent; // parent tid (if any)
143 /* runtime details */
144 Addr valgrind_stack_base; // Valgrind's stack (VgStack*)
145 Addr valgrind_stack_init_SP; // starting value for SP
148 Word exitcode; // in the case of exitgroup, set by someone else
149 Int fatalsig; // fatal signal
151 # if defined(VGO_aix5)
152 /* AIX specific fields to make thread cancellation sort-of work */
153 /* What is this thread's current cancellation state a la
154 POSIX (deferred vs async, enable vs disabled) ? */
155 Bool cancel_async; // current cancel mode (async vs deferred)
156 Bool cancel_disabled; // cancellation disabled?
157 /* What's happened so far? */
158 enum { Canc_NoRequest=0, // no cancellation requested
159 Canc_Requested=1, // requested but not actioned
160 Canc_Actioned=2 } // requested and actioned
162 /* Initial state is False, False, Canc_Normal. */
165 # if defined(VGO_darwin)
166 // Mach trap POST handler as chosen by PRE
167 void (*post_mach_trap_fn)(ThreadId tid,
168 struct SyscallArgs *, struct SyscallStatus *);
170 // This thread's pthread
173 // Argument passed when thread started
176 // Synchronization between child thread and parent thread's POST wrapper
177 semaphore_t child_go;
178 semaphore_t child_done;
180 // Workqueue re-entry
181 // (setjmp in PRE(workq_ops), longjmp in wqthread_hijack)
182 // DDD: JRS fixme: this comment is no longer correct; wq_jmpbuf is
183 // never used, and there is no such setjmp or longjmp pair.
184 // I guess we could leave wq_jmpbuf_valid in place though, since
185 // it does allow for an assertion in ML_(wqthread_continue_NORETURN).
186 Bool wq_jmpbuf_valid;
189 // Values saved from transient Mach RPC messages
190 Addr remote_port; // destination for original message
191 Int msgh_id; // outgoing message id
198 } mach_port_allocate;
203 } mach_port_mod_refs;
208 } mach_port_insert_right;
226 UWord new_protection;
256 } mach_vm_deallocate;
261 unsigned int new_protection;
274 } io_connect_unmap_memory;
277 } task_get_special_port;
283 } WindowServer_29828;
286 } WindowServer_29831;
289 } io_registry_entry_from_path;
293 #if defined(VGO_l4re)
294 char utcb_store[L4RE_UTCB_SIZE]; // XXX rename utcb_copy ?
300 SYS_ENTER_KDEBUG = 0x25,
301 SYS_LINUX_INT80 = 0x26,
303 SYS_ARTIFICIAL = 0x28,
309 /* Overall thread state */
311 /* ThreadId == 0 (and hence vg_threads[0]) is NEVER USED.
312 The thread identity is simply the index in vg_threads[].
313 ThreadId == 1 is the root thread and has the special property
314 that we don't try and allocate or deallocate its stack. For
315 convenience of generating error message, we also put the
316 ThreadId in this tid field, but be aware that it should
317 ALWAYS == the index in vg_threads[]. */
320 /* Current scheduling status. */
323 /* This is set if the thread is in the process of exiting for any
324 reason. The precise details of the exit are in the OS-specific
326 VgSchedReturnCode exitreason;
328 /* Architecture-specific thread state. */
329 ThreadArchState arch;
331 /* This thread's blocked-signals mask. Semantics is that for a
332 signal to be delivered to this thread, the signal must not be
333 blocked by this signal mask. If more than one thread accepts a
334 signal, then it will be delivered to one at random. If all
335 threads block the signal, it will remain pending until either a
336 thread unblocks it or someone uses sigwaitsig/sigtimedwait. */
337 vki_sigset_t sig_mask;
339 /* tmp_sig_mask is usually the same as sig_mask, and is kept in
340 sync whenever sig_mask is changed. The only time they have
341 different values is during the execution of a sigsuspend, where
342 tmp_sig_mask is the temporary mask which sigsuspend installs.
343 It is only consulted to compute the signal mask applied to a
345 vki_sigset_t tmp_sig_mask;
347 /* A little signal queue for signals we can't get the kernel to
348 queue for us. This is only allocated as needed, since it should
350 struct SigQueue *sig_queue;
352 /* Client stacks. When a thread slot is freed, we don't deallocate its
353 stack; we just leave it lying around for the next use of the
354 slot. If the next use of the slot requires a larger stack,
355 only then is the old one deallocated and a new one
358 For the main thread (threadid == 1), this mechanism doesn't
359 apply. We don't know the size of the stack since we didn't
360 allocate it, and furthermore we never reallocate it. */
362 /* The allocated size of this thread's stack */
363 SizeT client_stack_szB;
365 /* Address of the highest legitimate word in this stack. This is
366 used for error messages only -- not critical for execution
367 correctness. Is is set for all stacks, specifically including
368 ThreadId == 1 (the main thread). */
369 Addr client_stack_highest_word;
371 /* Alternate signal stack */
372 vki_stack_t altstack;
374 /* OS-specific thread state */
375 ThreadOSstate os_state;
377 /* Per-thread jmp_buf to resume scheduler after a signal */
378 Bool sched_jmpbuf_valid;
379 VG_MINIMAL_JMP_BUF(sched_jmpbuf);
384 #if defined(VGO_l4re)
387 * L4Re redirections that trap into Valgrind even though they are not
390 * _dl_open, _dl_close, _dl_mmap
401 unsigned int redir_type;
426 /*------------------------------------------------------------*/
427 /*--- L4Re OS state accessor functions ---*/
428 /*------------------------------------------------------------*/
429 static inline char *ts_utcb_copy(ThreadState *ts)
430 { return ts->os_state.utcb_store; }
432 static inline l4_utcb_t *ts_utcb(ThreadState *ts)
433 { return ts->os_state.utcb; }
437 /*------------------------------------------------------------*/
438 /*--- The thread table. ---*/
439 /*------------------------------------------------------------*/
441 /* A statically allocated array of threads. NOTE: [0] is
442 never used, to simplify the simulation of initialisers for
444 extern ThreadState VG_(threads)[VG_N_THREADS];
446 // The running thread. m_scheduler should be the only other module
448 extern ThreadId VG_(running_tid);
451 /*------------------------------------------------------------*/
452 /*--- Basic operations on the thread table. ---*/
453 /*------------------------------------------------------------*/
455 // Convert a ThreadStatus to a string.
456 const HChar* VG_(name_of_ThreadStatus) ( ThreadStatus status );
458 /* Get the ThreadState for a particular thread */
459 extern ThreadState *VG_(get_ThreadState) ( ThreadId tid );
461 /* Check that tid is in range and denotes a non-Empty thread. */
462 extern Bool VG_(is_valid_tid) ( ThreadId tid );
464 /* Returns true if a thread is currently running (ie, has the CPU lock) */
465 extern Bool VG_(is_running_thread)(ThreadId tid);
467 /* Returns true if the thread is in the process of exiting */
468 extern Bool VG_(is_exiting)(ThreadId tid);
470 /* Return the number of non-dead Threads */
471 extern Int VG_(count_living_threads)(void);
473 /* Return the number of threads in VgTs_Runnable state */
474 extern Int VG_(count_runnable_threads)(void);
476 /* Given an LWP id (ie, real kernel thread id), find the corresponding
478 extern ThreadId VG_(lwpid_to_vgtid)(Int lwpid);
480 #endif // __PUB_CORE_THREADSTATE_H
482 /*--------------------------------------------------------------------*/
484 /*--------------------------------------------------------------------*/