blob: 148d18e093c2ae5ea4dc1ad5cdb87d0498334779 [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;
82#elif defined(VGA_arm)
83 typedef VexGuestARMState VexGuestArchState;
84#else
85# error Unknown architecture
86#endif
87
88
89typedef
90 struct {
91 /* --- BEGIN vex-mandated guest state --- */
92
93 /* Saved machine context. */
94 VexGuestArchState vex;
95
96 /* Saved shadow context. */
97 VexGuestArchState vex_shadow;
98
99 /* Spill area. */
100 UChar vex_spill[LibVEX_N_SPILL_BYTES];
101
102 /* --- END vex-mandated guest state --- */
103 }
104 ThreadArchState;
105
106/* OS-specific thread state */
107typedef struct {
108 /* who we are */
109 Int lwpid; // PID of kernel task
110 Int threadgroup; // thread group id
111
112 ThreadId parent; // parent tid (if any)
113
114 /* runtime details */
115 Addr valgrind_stack_base; // Valgrind's stack base
116 SizeT valgrind_stack_szB; // stack size in bytes
117
118 /* exit details */
119 Int exitcode; // in the case of exitgroup, set by someone else
120 Int fatalsig; // fatal signal
121} os_thread_t;
122
123
124typedef struct {
125 /* ThreadId == 0 (and hence vg_threads[0]) is NEVER USED.
126 The thread identity is simply the index in vg_threads[].
127 ThreadId == 1 is the root thread and has the special property
128 that we don't try and allocate or deallocate its stack. For
129 convenience of generating error message, we also put the
130 ThreadId in this tid field, but be aware that it should
131 ALWAYS == the index in vg_threads[]. */
132 ThreadId tid;
133
134 /* Current scheduling status. */
135 ThreadStatus status;
136
137 /* This is set if the thread is in the process of exiting for any
138 reason. The precise details of the exit are in the OS-specific
139 state. */
140 VgSchedReturnCode exitreason;
141
142 /* Architecture-specific thread state. */
143 ThreadArchState arch;
144
145 /* This thread's blocked-signals mask. Semantics is that for a
146 signal to be delivered to this thread, the signal must not be
147 blocked by this signal mask. If more than one thread accepts a
148 signal, then it will be delivered to one at random. If all
149 threads block the signal, it will remain pending until either a
150 thread unblocks it or someone uses sigwaitsig/sigtimedwait. */
151 vki_sigset_t sig_mask;
152
153 /* tmp_sig_mask is usually the same as sig_mask, and is kept in
154 sync whenever sig_mask is changed. The only time they have
155 different values is during the execution of a sigsuspend, where
156 tmp_sig_mask is the temporary mask which sigsuspend installs.
157 It is only consulted to compute the signal mask applied to a
158 signal handler. */
159 vki_sigset_t tmp_sig_mask;
160
161 /* A little signal queue for signals we can't get the kernel to
162 queue for us. This is only allocated as needed, since it should
163 be rare. */
164 struct SigQueue *sig_queue;
165
166 /* Client stacks. When a thread slot is freed, we don't deallocate its
167 stack; we just leave it lying around for the next use of the
168 slot. If the next use of the slot requires a larger stack,
169 only then is the old one deallocated and a new one
170 allocated.
171
172 For the main thread (threadid == 0), this mechanism doesn't
173 apply. We don't know the size of the stack since we didn't
174 allocate it, and furthermore we never reallocate it. */
175
176 /* The allocated size of this thread's stack (permanently zero
177 if this is ThreadId == 0, since we didn't allocate its stack) */
178 SizeT client_stack_szB;
179
180 /* Address of the highest legitimate word in this stack. This is
181 used for error messages only -- not critical for execution
182 correctness. Is is set for all stacks, specifically including
183 ThreadId == 0 (the main thread). */
184 Addr client_stack_highest_word;
185
186 /* Alternate signal stack */
187 vki_stack_t altstack;
188
189 /* OS-specific thread state */
190 os_thread_t os_state;
191
192 /* Used in the syscall handlers. Set to True to indicate that the
193 PRE routine for a syscall has set the syscall result already and
194 so the syscall does not need to be handed to the kernel. */
195 Bool syscall_result_set;
196
197 /* Per-thread jmp_buf to resume scheduler after a signal */
198 Bool sched_jmpbuf_valid;
199 jmp_buf sched_jmpbuf;
200}
201ThreadState;
202
203
204/*------------------------------------------------------------*/
205/*--- The thread table. ---*/
206/*------------------------------------------------------------*/
207
208/* A statically allocated array of threads. NOTE: [0] is
209 never used, to simplify the simulation of initialisers for
210 LinuxThreads. */
211extern ThreadState VG_(threads)[VG_N_THREADS];
212
213// The running thread. m_scheduler should be the only other module
214// to write to this.
215extern ThreadId VG_(running_tid);
216
217/*------------------------------------------------------------*/
218/*--- Basic operations on the thread table. ---*/
219/*------------------------------------------------------------*/
220
221// Convert a ThreadStatus to a string.
222const HChar* VG_(name_of_ThreadStatus) ( ThreadStatus status );
223
224/* Get the ThreadState for a particular thread */
225extern ThreadState *VG_(get_ThreadState) ( ThreadId tid );
226
227/* Check that tid is in range and denotes a non-Empty thread. */
228extern Bool VG_(is_valid_tid) ( ThreadId tid );
229
230/* Returns true if a thread is currently running (ie, has the CPU lock) */
231extern Bool VG_(is_running_thread)(ThreadId tid);
232
233/* Returns true if the thread is in the process of exiting */
234extern Bool VG_(is_exiting)(ThreadId tid);
235
236/* Return the number of non-dead Threads */
237extern Int VG_(count_living_threads)(void);
238
239/* Given an LWP id (ie, real kernel thread id), find the corresponding
240 ThreadId */
241extern ThreadId VG_(get_lwp_tid)(Int lwpid);
242
243#endif // __PUB_CORE_THREADSTATE_H
244
245/*--------------------------------------------------------------------*/
246/*--- end ---*/
247/*--------------------------------------------------------------------*/