blob: bcba985c52ec4d3503d6f790197540385566e071 [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
90
sewardja4068de2006-04-05 23:06:31 +000091/* Architecture-specific thread state */
njnc7561b92005-06-19 01:24:32 +000092typedef
93 struct {
94 /* --- BEGIN vex-mandated guest state --- */
95
sewardj7cf4e6b2008-05-01 20:24:26 +000096 /* Note that for code generation reasons, we require that the
97 guest state area, its two shadows, and the spill area, are
98 16-aligned and have 16-aligned sizes, and there are no holes
99 in between. This is checked by do_pre_run_checks() in
100 scheduler.c. */
njnc7561b92005-06-19 01:24:32 +0000101
sewardj7cf4e6b2008-05-01 20:24:26 +0000102 /* Saved machine context. */
103 VexGuestArchState vex __attribute__((aligned(16)));
104
105 /* Saved shadow context (2 copies). */
106 VexGuestArchState vex_shadow1 __attribute__((aligned(16)));
107 VexGuestArchState vex_shadow2 __attribute__((aligned(16)));
njnc7561b92005-06-19 01:24:32 +0000108
109 /* Spill area. */
sewardj7cf4e6b2008-05-01 20:24:26 +0000110 UChar vex_spill[LibVEX_N_SPILL_BYTES] __attribute__((aligned(16)));
njnc7561b92005-06-19 01:24:32 +0000111
112 /* --- END vex-mandated guest state --- */
113 }
114 ThreadArchState;
115
sewardja4068de2006-04-05 23:06:31 +0000116
njnc7561b92005-06-19 01:24:32 +0000117/* OS-specific thread state */
sewardja4068de2006-04-05 23:06:31 +0000118typedef
119 struct {
120 /* who we are */
121 Int lwpid; // PID of kernel task
122 Int threadgroup; // thread group id
njnc7561b92005-06-19 01:24:32 +0000123
sewardja4068de2006-04-05 23:06:31 +0000124 ThreadId parent; // parent tid (if any)
njnc7561b92005-06-19 01:24:32 +0000125
sewardja4068de2006-04-05 23:06:31 +0000126 /* runtime details */
127 Addr valgrind_stack_base; // Valgrind's stack (VgStack*)
128 Addr valgrind_stack_init_SP; // starting value for SP
njnc7561b92005-06-19 01:24:32 +0000129
sewardja4068de2006-04-05 23:06:31 +0000130 /* exit details */
sewardjd8a725e2006-10-17 02:01:12 +0000131 Word exitcode; // in the case of exitgroup, set by someone else
132 Int fatalsig; // fatal signal
133
134# if defined(VGO_aix5)
135 /* AIX specific fields to make thread cancellation sort-of work */
136 /* What is this thread's current cancellation state a la
137 POSIX (deferred vs async, enable vs disabled) ? */
138 Bool cancel_async; // current cancel mode (async vs deferred)
139 Bool cancel_disabled; // cancellation disabled?
140 /* What's happened so far? */
141 enum { Canc_NoRequest=0, // no cancellation requested
142 Canc_Requested=1, // requested but not actioned
143 Canc_Actioned=2 } // requested and actioned
144 cancel_progress;
145 /* Initial state is False, False, Canc_Normal. */
146# endif
sewardja4068de2006-04-05 23:06:31 +0000147 }
148 ThreadOSstate;
njnc7561b92005-06-19 01:24:32 +0000149
150
sewardja4068de2006-04-05 23:06:31 +0000151/* Overall thread state */
njnc7561b92005-06-19 01:24:32 +0000152typedef struct {
153 /* ThreadId == 0 (and hence vg_threads[0]) is NEVER USED.
154 The thread identity is simply the index in vg_threads[].
155 ThreadId == 1 is the root thread and has the special property
156 that we don't try and allocate or deallocate its stack. For
157 convenience of generating error message, we also put the
158 ThreadId in this tid field, but be aware that it should
159 ALWAYS == the index in vg_threads[]. */
160 ThreadId tid;
161
162 /* Current scheduling status. */
163 ThreadStatus status;
164
165 /* This is set if the thread is in the process of exiting for any
166 reason. The precise details of the exit are in the OS-specific
167 state. */
168 VgSchedReturnCode exitreason;
169
170 /* Architecture-specific thread state. */
171 ThreadArchState arch;
172
173 /* This thread's blocked-signals mask. Semantics is that for a
174 signal to be delivered to this thread, the signal must not be
175 blocked by this signal mask. If more than one thread accepts a
176 signal, then it will be delivered to one at random. If all
177 threads block the signal, it will remain pending until either a
178 thread unblocks it or someone uses sigwaitsig/sigtimedwait. */
179 vki_sigset_t sig_mask;
180
181 /* tmp_sig_mask is usually the same as sig_mask, and is kept in
182 sync whenever sig_mask is changed. The only time they have
183 different values is during the execution of a sigsuspend, where
184 tmp_sig_mask is the temporary mask which sigsuspend installs.
185 It is only consulted to compute the signal mask applied to a
186 signal handler. */
187 vki_sigset_t tmp_sig_mask;
188
189 /* A little signal queue for signals we can't get the kernel to
190 queue for us. This is only allocated as needed, since it should
191 be rare. */
192 struct SigQueue *sig_queue;
193
194 /* Client stacks. When a thread slot is freed, we don't deallocate its
195 stack; we just leave it lying around for the next use of the
196 slot. If the next use of the slot requires a larger stack,
197 only then is the old one deallocated and a new one
198 allocated.
199
sewardja4068de2006-04-05 23:06:31 +0000200 For the main thread (threadid == 1), this mechanism doesn't
njnc7561b92005-06-19 01:24:32 +0000201 apply. We don't know the size of the stack since we didn't
202 allocate it, and furthermore we never reallocate it. */
203
bart96a0de32008-03-29 09:25:11 +0000204 /* The allocated size of this thread's stack */
njnc7561b92005-06-19 01:24:32 +0000205 SizeT client_stack_szB;
206
207 /* Address of the highest legitimate word in this stack. This is
208 used for error messages only -- not critical for execution
209 correctness. Is is set for all stacks, specifically including
sewardja4068de2006-04-05 23:06:31 +0000210 ThreadId == 1 (the main thread). */
njnc7561b92005-06-19 01:24:32 +0000211 Addr client_stack_highest_word;
212
213 /* Alternate signal stack */
214 vki_stack_t altstack;
215
216 /* OS-specific thread state */
sewardja4068de2006-04-05 23:06:31 +0000217 ThreadOSstate os_state;
njnc7561b92005-06-19 01:24:32 +0000218
njnc7561b92005-06-19 01:24:32 +0000219 /* Per-thread jmp_buf to resume scheduler after a signal */
220 Bool sched_jmpbuf_valid;
221 jmp_buf sched_jmpbuf;
222}
223ThreadState;
224
225
226/*------------------------------------------------------------*/
227/*--- The thread table. ---*/
228/*------------------------------------------------------------*/
229
230/* A statically allocated array of threads. NOTE: [0] is
231 never used, to simplify the simulation of initialisers for
232 LinuxThreads. */
233extern ThreadState VG_(threads)[VG_N_THREADS];
234
235// The running thread. m_scheduler should be the only other module
236// to write to this.
237extern ThreadId VG_(running_tid);
238
239/*------------------------------------------------------------*/
240/*--- Basic operations on the thread table. ---*/
241/*------------------------------------------------------------*/
242
243// Convert a ThreadStatus to a string.
244const HChar* VG_(name_of_ThreadStatus) ( ThreadStatus status );
245
246/* Get the ThreadState for a particular thread */
247extern ThreadState *VG_(get_ThreadState) ( ThreadId tid );
248
249/* Check that tid is in range and denotes a non-Empty thread. */
250extern Bool VG_(is_valid_tid) ( ThreadId tid );
251
252/* Returns true if a thread is currently running (ie, has the CPU lock) */
253extern Bool VG_(is_running_thread)(ThreadId tid);
254
255/* Returns true if the thread is in the process of exiting */
256extern Bool VG_(is_exiting)(ThreadId tid);
257
258/* Return the number of non-dead Threads */
259extern Int VG_(count_living_threads)(void);
260
sewardjd8a725e2006-10-17 02:01:12 +0000261/* Return the number of threads in VgTs_Runnable state */
262extern Int VG_(count_runnable_threads)(void);
263
njnc7561b92005-06-19 01:24:32 +0000264/* Given an LWP id (ie, real kernel thread id), find the corresponding
265 ThreadId */
sewardj42781722006-12-17 19:36:06 +0000266extern ThreadId VG_(lwpid_to_vgtid)(Int lwpid);
njnc7561b92005-06-19 01:24:32 +0000267
268#endif // __PUB_CORE_THREADSTATE_H
269
270/*--------------------------------------------------------------------*/
271/*--- end ---*/
272/*--------------------------------------------------------------------*/