blob: e7bde55c562fd5bf4ec1f918586aa711c73888ea [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
njn99778ee2009-05-19 05:01:27 +0000117/* OS-specific thread state. IMPORTANT: if you add fields to this,
118 you _must_ add code to os_state_clear() to initialise those
119 fields. */
sewardja4068de2006-04-05 23:06:31 +0000120typedef
121 struct {
122 /* who we are */
123 Int lwpid; // PID of kernel task
124 Int threadgroup; // thread group id
njnc7561b92005-06-19 01:24:32 +0000125
sewardja4068de2006-04-05 23:06:31 +0000126 ThreadId parent; // parent tid (if any)
njnc7561b92005-06-19 01:24:32 +0000127
sewardja4068de2006-04-05 23:06:31 +0000128 /* runtime details */
129 Addr valgrind_stack_base; // Valgrind's stack (VgStack*)
130 Addr valgrind_stack_init_SP; // starting value for SP
njnc7561b92005-06-19 01:24:32 +0000131
sewardja4068de2006-04-05 23:06:31 +0000132 /* exit details */
sewardjd8a725e2006-10-17 02:01:12 +0000133 Word exitcode; // in the case of exitgroup, set by someone else
134 Int fatalsig; // fatal signal
135
136# if defined(VGO_aix5)
137 /* AIX specific fields to make thread cancellation sort-of work */
138 /* What is this thread's current cancellation state a la
139 POSIX (deferred vs async, enable vs disabled) ? */
140 Bool cancel_async; // current cancel mode (async vs deferred)
141 Bool cancel_disabled; // cancellation disabled?
142 /* What's happened so far? */
143 enum { Canc_NoRequest=0, // no cancellation requested
144 Canc_Requested=1, // requested but not actioned
145 Canc_Actioned=2 } // requested and actioned
146 cancel_progress;
147 /* Initial state is False, False, Canc_Normal. */
148# endif
sewardja4068de2006-04-05 23:06:31 +0000149 }
150 ThreadOSstate;
njnc7561b92005-06-19 01:24:32 +0000151
152
sewardja4068de2006-04-05 23:06:31 +0000153/* Overall thread state */
njnc7561b92005-06-19 01:24:32 +0000154typedef struct {
155 /* ThreadId == 0 (and hence vg_threads[0]) is NEVER USED.
156 The thread identity is simply the index in vg_threads[].
157 ThreadId == 1 is the root thread and has the special property
158 that we don't try and allocate or deallocate its stack. For
159 convenience of generating error message, we also put the
160 ThreadId in this tid field, but be aware that it should
161 ALWAYS == the index in vg_threads[]. */
162 ThreadId tid;
163
164 /* Current scheduling status. */
165 ThreadStatus status;
166
167 /* This is set if the thread is in the process of exiting for any
168 reason. The precise details of the exit are in the OS-specific
169 state. */
170 VgSchedReturnCode exitreason;
171
172 /* Architecture-specific thread state. */
173 ThreadArchState arch;
174
175 /* This thread's blocked-signals mask. Semantics is that for a
176 signal to be delivered to this thread, the signal must not be
177 blocked by this signal mask. If more than one thread accepts a
178 signal, then it will be delivered to one at random. If all
179 threads block the signal, it will remain pending until either a
180 thread unblocks it or someone uses sigwaitsig/sigtimedwait. */
181 vki_sigset_t sig_mask;
182
183 /* tmp_sig_mask is usually the same as sig_mask, and is kept in
184 sync whenever sig_mask is changed. The only time they have
185 different values is during the execution of a sigsuspend, where
186 tmp_sig_mask is the temporary mask which sigsuspend installs.
187 It is only consulted to compute the signal mask applied to a
188 signal handler. */
189 vki_sigset_t tmp_sig_mask;
190
191 /* A little signal queue for signals we can't get the kernel to
192 queue for us. This is only allocated as needed, since it should
193 be rare. */
194 struct SigQueue *sig_queue;
195
196 /* Client stacks. When a thread slot is freed, we don't deallocate its
197 stack; we just leave it lying around for the next use of the
198 slot. If the next use of the slot requires a larger stack,
199 only then is the old one deallocated and a new one
200 allocated.
201
sewardja4068de2006-04-05 23:06:31 +0000202 For the main thread (threadid == 1), this mechanism doesn't
njnc7561b92005-06-19 01:24:32 +0000203 apply. We don't know the size of the stack since we didn't
204 allocate it, and furthermore we never reallocate it. */
205
bart96a0de32008-03-29 09:25:11 +0000206 /* The allocated size of this thread's stack */
njnc7561b92005-06-19 01:24:32 +0000207 SizeT client_stack_szB;
208
209 /* Address of the highest legitimate word in this stack. This is
210 used for error messages only -- not critical for execution
211 correctness. Is is set for all stacks, specifically including
sewardja4068de2006-04-05 23:06:31 +0000212 ThreadId == 1 (the main thread). */
njnc7561b92005-06-19 01:24:32 +0000213 Addr client_stack_highest_word;
214
215 /* Alternate signal stack */
216 vki_stack_t altstack;
217
218 /* OS-specific thread state */
sewardja4068de2006-04-05 23:06:31 +0000219 ThreadOSstate os_state;
njnc7561b92005-06-19 01:24:32 +0000220
njnc7561b92005-06-19 01:24:32 +0000221 /* Per-thread jmp_buf to resume scheduler after a signal */
222 Bool sched_jmpbuf_valid;
223 jmp_buf sched_jmpbuf;
224}
225ThreadState;
226
227
228/*------------------------------------------------------------*/
229/*--- The thread table. ---*/
230/*------------------------------------------------------------*/
231
232/* A statically allocated array of threads. NOTE: [0] is
233 never used, to simplify the simulation of initialisers for
234 LinuxThreads. */
235extern ThreadState VG_(threads)[VG_N_THREADS];
236
237// The running thread. m_scheduler should be the only other module
238// to write to this.
239extern ThreadId VG_(running_tid);
240
241/*------------------------------------------------------------*/
242/*--- Basic operations on the thread table. ---*/
243/*------------------------------------------------------------*/
244
245// Convert a ThreadStatus to a string.
246const HChar* VG_(name_of_ThreadStatus) ( ThreadStatus status );
247
248/* Get the ThreadState for a particular thread */
249extern ThreadState *VG_(get_ThreadState) ( ThreadId tid );
250
251/* Check that tid is in range and denotes a non-Empty thread. */
252extern Bool VG_(is_valid_tid) ( ThreadId tid );
253
254/* Returns true if a thread is currently running (ie, has the CPU lock) */
255extern Bool VG_(is_running_thread)(ThreadId tid);
256
257/* Returns true if the thread is in the process of exiting */
258extern Bool VG_(is_exiting)(ThreadId tid);
259
260/* Return the number of non-dead Threads */
261extern Int VG_(count_living_threads)(void);
262
sewardjd8a725e2006-10-17 02:01:12 +0000263/* Return the number of threads in VgTs_Runnable state */
264extern Int VG_(count_runnable_threads)(void);
265
njnc7561b92005-06-19 01:24:32 +0000266/* Given an LWP id (ie, real kernel thread id), find the corresponding
267 ThreadId */
sewardj42781722006-12-17 19:36:06 +0000268extern ThreadId VG_(lwpid_to_vgtid)(Int lwpid);
njnc7561b92005-06-19 01:24:32 +0000269
270#endif // __PUB_CORE_THREADSTATE_H
271
272/*--------------------------------------------------------------------*/
273/*--- end ---*/
274/*--------------------------------------------------------------------*/