blob: 5b7b5e62cfd53e40e305a47900624233e3917cf2 [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
sewardj9ebd6e02007-01-08 06:01:59 +000010 Copyright (C) 2000-2007 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
96 /* Saved machine context. */
97 VexGuestArchState vex;
98
99 /* Saved shadow context. */
100 VexGuestArchState vex_shadow;
101
102 /* Spill area. */
103 UChar vex_spill[LibVEX_N_SPILL_BYTES];
104
105 /* --- END vex-mandated guest state --- */
106 }
107 ThreadArchState;
108
sewardja4068de2006-04-05 23:06:31 +0000109
njnc7561b92005-06-19 01:24:32 +0000110/* OS-specific thread state */
sewardja4068de2006-04-05 23:06:31 +0000111typedef
112 struct {
113 /* who we are */
114 Int lwpid; // PID of kernel task
115 Int threadgroup; // thread group id
njnc7561b92005-06-19 01:24:32 +0000116
sewardja4068de2006-04-05 23:06:31 +0000117 ThreadId parent; // parent tid (if any)
njnc7561b92005-06-19 01:24:32 +0000118
sewardja4068de2006-04-05 23:06:31 +0000119 /* runtime details */
120 Addr valgrind_stack_base; // Valgrind's stack (VgStack*)
121 Addr valgrind_stack_init_SP; // starting value for SP
njnc7561b92005-06-19 01:24:32 +0000122
sewardja4068de2006-04-05 23:06:31 +0000123 /* exit details */
sewardjd8a725e2006-10-17 02:01:12 +0000124 Word exitcode; // in the case of exitgroup, set by someone else
125 Int fatalsig; // fatal signal
126
127# if defined(VGO_aix5)
128 /* AIX specific fields to make thread cancellation sort-of work */
129 /* What is this thread's current cancellation state a la
130 POSIX (deferred vs async, enable vs disabled) ? */
131 Bool cancel_async; // current cancel mode (async vs deferred)
132 Bool cancel_disabled; // cancellation disabled?
133 /* What's happened so far? */
134 enum { Canc_NoRequest=0, // no cancellation requested
135 Canc_Requested=1, // requested but not actioned
136 Canc_Actioned=2 } // requested and actioned
137 cancel_progress;
138 /* Initial state is False, False, Canc_Normal. */
139# endif
sewardja4068de2006-04-05 23:06:31 +0000140 }
141 ThreadOSstate;
njnc7561b92005-06-19 01:24:32 +0000142
143
sewardja4068de2006-04-05 23:06:31 +0000144/* Overall thread state */
njnc7561b92005-06-19 01:24:32 +0000145typedef struct {
146 /* ThreadId == 0 (and hence vg_threads[0]) is NEVER USED.
147 The thread identity is simply the index in vg_threads[].
148 ThreadId == 1 is the root thread and has the special property
149 that we don't try and allocate or deallocate its stack. For
150 convenience of generating error message, we also put the
151 ThreadId in this tid field, but be aware that it should
152 ALWAYS == the index in vg_threads[]. */
153 ThreadId tid;
154
155 /* Current scheduling status. */
156 ThreadStatus status;
157
158 /* This is set if the thread is in the process of exiting for any
159 reason. The precise details of the exit are in the OS-specific
160 state. */
161 VgSchedReturnCode exitreason;
162
163 /* Architecture-specific thread state. */
164 ThreadArchState arch;
165
166 /* This thread's blocked-signals mask. Semantics is that for a
167 signal to be delivered to this thread, the signal must not be
168 blocked by this signal mask. If more than one thread accepts a
169 signal, then it will be delivered to one at random. If all
170 threads block the signal, it will remain pending until either a
171 thread unblocks it or someone uses sigwaitsig/sigtimedwait. */
172 vki_sigset_t sig_mask;
173
174 /* tmp_sig_mask is usually the same as sig_mask, and is kept in
175 sync whenever sig_mask is changed. The only time they have
176 different values is during the execution of a sigsuspend, where
177 tmp_sig_mask is the temporary mask which sigsuspend installs.
178 It is only consulted to compute the signal mask applied to a
179 signal handler. */
180 vki_sigset_t tmp_sig_mask;
181
182 /* A little signal queue for signals we can't get the kernel to
183 queue for us. This is only allocated as needed, since it should
184 be rare. */
185 struct SigQueue *sig_queue;
186
187 /* Client stacks. When a thread slot is freed, we don't deallocate its
188 stack; we just leave it lying around for the next use of the
189 slot. If the next use of the slot requires a larger stack,
190 only then is the old one deallocated and a new one
191 allocated.
192
sewardja4068de2006-04-05 23:06:31 +0000193 For the main thread (threadid == 1), this mechanism doesn't
njnc7561b92005-06-19 01:24:32 +0000194 apply. We don't know the size of the stack since we didn't
195 allocate it, and furthermore we never reallocate it. */
196
197 /* The allocated size of this thread's stack (permanently zero
sewardja4068de2006-04-05 23:06:31 +0000198 if this is ThreadId == 1, since we didn't allocate its stack) */
njnc7561b92005-06-19 01:24:32 +0000199 SizeT client_stack_szB;
200
201 /* Address of the highest legitimate word in this stack. This is
202 used for error messages only -- not critical for execution
203 correctness. Is is set for all stacks, specifically including
sewardja4068de2006-04-05 23:06:31 +0000204 ThreadId == 1 (the main thread). */
njnc7561b92005-06-19 01:24:32 +0000205 Addr client_stack_highest_word;
206
207 /* Alternate signal stack */
208 vki_stack_t altstack;
209
210 /* OS-specific thread state */
sewardja4068de2006-04-05 23:06:31 +0000211 ThreadOSstate os_state;
njnc7561b92005-06-19 01:24:32 +0000212
njnc7561b92005-06-19 01:24:32 +0000213 /* Per-thread jmp_buf to resume scheduler after a signal */
214 Bool sched_jmpbuf_valid;
215 jmp_buf sched_jmpbuf;
216}
217ThreadState;
218
219
220/*------------------------------------------------------------*/
221/*--- The thread table. ---*/
222/*------------------------------------------------------------*/
223
224/* A statically allocated array of threads. NOTE: [0] is
225 never used, to simplify the simulation of initialisers for
226 LinuxThreads. */
227extern ThreadState VG_(threads)[VG_N_THREADS];
228
229// The running thread. m_scheduler should be the only other module
230// to write to this.
231extern ThreadId VG_(running_tid);
232
233/*------------------------------------------------------------*/
234/*--- Basic operations on the thread table. ---*/
235/*------------------------------------------------------------*/
236
237// Convert a ThreadStatus to a string.
238const HChar* VG_(name_of_ThreadStatus) ( ThreadStatus status );
239
240/* Get the ThreadState for a particular thread */
241extern ThreadState *VG_(get_ThreadState) ( ThreadId tid );
242
243/* Check that tid is in range and denotes a non-Empty thread. */
244extern Bool VG_(is_valid_tid) ( ThreadId tid );
245
246/* Returns true if a thread is currently running (ie, has the CPU lock) */
247extern Bool VG_(is_running_thread)(ThreadId tid);
248
249/* Returns true if the thread is in the process of exiting */
250extern Bool VG_(is_exiting)(ThreadId tid);
251
252/* Return the number of non-dead Threads */
253extern Int VG_(count_living_threads)(void);
254
sewardjd8a725e2006-10-17 02:01:12 +0000255/* Return the number of threads in VgTs_Runnable state */
256extern Int VG_(count_runnable_threads)(void);
257
njnc7561b92005-06-19 01:24:32 +0000258/* Given an LWP id (ie, real kernel thread id), find the corresponding
259 ThreadId */
sewardj42781722006-12-17 19:36:06 +0000260extern ThreadId VG_(lwpid_to_vgtid)(Int lwpid);
njnc7561b92005-06-19 01:24:32 +0000261
262#endif // __PUB_CORE_THREADSTATE_H
263
264/*--------------------------------------------------------------------*/
265/*--- end ---*/
266/*--------------------------------------------------------------------*/