blob: 5f11d3e2c04aa1db0f5c43fb27b878e5de7efeaf [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
10 Copyright (C) 2000-2005 Julian Seward
11 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 */
70 VgSrc_ExitSyscall, /* client called exit(). This is the normal
71 route out. */
72 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 */
124 Int exitcode; // in the case of exitgroup, set by someone else
125 Int fatalsig; // fatal signal
126 }
127 ThreadOSstate;
njnc7561b92005-06-19 01:24:32 +0000128
129
sewardja4068de2006-04-05 23:06:31 +0000130/* Overall thread state */
njnc7561b92005-06-19 01:24:32 +0000131typedef struct {
132 /* ThreadId == 0 (and hence vg_threads[0]) is NEVER USED.
133 The thread identity is simply the index in vg_threads[].
134 ThreadId == 1 is the root thread and has the special property
135 that we don't try and allocate or deallocate its stack. For
136 convenience of generating error message, we also put the
137 ThreadId in this tid field, but be aware that it should
138 ALWAYS == the index in vg_threads[]. */
139 ThreadId tid;
140
141 /* Current scheduling status. */
142 ThreadStatus status;
143
144 /* This is set if the thread is in the process of exiting for any
145 reason. The precise details of the exit are in the OS-specific
146 state. */
147 VgSchedReturnCode exitreason;
148
149 /* Architecture-specific thread state. */
150 ThreadArchState arch;
151
152 /* This thread's blocked-signals mask. Semantics is that for a
153 signal to be delivered to this thread, the signal must not be
154 blocked by this signal mask. If more than one thread accepts a
155 signal, then it will be delivered to one at random. If all
156 threads block the signal, it will remain pending until either a
157 thread unblocks it or someone uses sigwaitsig/sigtimedwait. */
158 vki_sigset_t sig_mask;
159
160 /* tmp_sig_mask is usually the same as sig_mask, and is kept in
161 sync whenever sig_mask is changed. The only time they have
162 different values is during the execution of a sigsuspend, where
163 tmp_sig_mask is the temporary mask which sigsuspend installs.
164 It is only consulted to compute the signal mask applied to a
165 signal handler. */
166 vki_sigset_t tmp_sig_mask;
167
168 /* A little signal queue for signals we can't get the kernel to
169 queue for us. This is only allocated as needed, since it should
170 be rare. */
171 struct SigQueue *sig_queue;
172
173 /* Client stacks. When a thread slot is freed, we don't deallocate its
174 stack; we just leave it lying around for the next use of the
175 slot. If the next use of the slot requires a larger stack,
176 only then is the old one deallocated and a new one
177 allocated.
178
sewardja4068de2006-04-05 23:06:31 +0000179 For the main thread (threadid == 1), this mechanism doesn't
njnc7561b92005-06-19 01:24:32 +0000180 apply. We don't know the size of the stack since we didn't
181 allocate it, and furthermore we never reallocate it. */
182
183 /* The allocated size of this thread's stack (permanently zero
sewardja4068de2006-04-05 23:06:31 +0000184 if this is ThreadId == 1, since we didn't allocate its stack) */
njnc7561b92005-06-19 01:24:32 +0000185 SizeT client_stack_szB;
186
187 /* Address of the highest legitimate word in this stack. This is
188 used for error messages only -- not critical for execution
189 correctness. Is is set for all stacks, specifically including
sewardja4068de2006-04-05 23:06:31 +0000190 ThreadId == 1 (the main thread). */
njnc7561b92005-06-19 01:24:32 +0000191 Addr client_stack_highest_word;
192
193 /* Alternate signal stack */
194 vki_stack_t altstack;
195
196 /* OS-specific thread state */
sewardja4068de2006-04-05 23:06:31 +0000197 ThreadOSstate os_state;
njnc7561b92005-06-19 01:24:32 +0000198
njnc7561b92005-06-19 01:24:32 +0000199 /* Per-thread jmp_buf to resume scheduler after a signal */
200 Bool sched_jmpbuf_valid;
201 jmp_buf sched_jmpbuf;
202}
203ThreadState;
204
205
206/*------------------------------------------------------------*/
207/*--- The thread table. ---*/
208/*------------------------------------------------------------*/
209
210/* A statically allocated array of threads. NOTE: [0] is
211 never used, to simplify the simulation of initialisers for
212 LinuxThreads. */
213extern ThreadState VG_(threads)[VG_N_THREADS];
214
215// The running thread. m_scheduler should be the only other module
216// to write to this.
217extern ThreadId VG_(running_tid);
218
219/*------------------------------------------------------------*/
220/*--- Basic operations on the thread table. ---*/
221/*------------------------------------------------------------*/
222
223// Convert a ThreadStatus to a string.
224const HChar* VG_(name_of_ThreadStatus) ( ThreadStatus status );
225
226/* Get the ThreadState for a particular thread */
227extern ThreadState *VG_(get_ThreadState) ( ThreadId tid );
228
229/* Check that tid is in range and denotes a non-Empty thread. */
230extern Bool VG_(is_valid_tid) ( ThreadId tid );
231
232/* Returns true if a thread is currently running (ie, has the CPU lock) */
233extern Bool VG_(is_running_thread)(ThreadId tid);
234
235/* Returns true if the thread is in the process of exiting */
236extern Bool VG_(is_exiting)(ThreadId tid);
237
238/* Return the number of non-dead Threads */
239extern Int VG_(count_living_threads)(void);
240
241/* Given an LWP id (ie, real kernel thread id), find the corresponding
242 ThreadId */
243extern ThreadId VG_(get_lwp_tid)(Int lwpid);
244
245#endif // __PUB_CORE_THREADSTATE_H
246
247/*--------------------------------------------------------------------*/
248/*--- end ---*/
249/*--------------------------------------------------------------------*/