blob: caae07003408bd8a0855fc1697d4c2a15a07f562 [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;
cerion85665ca2005-06-20 15:51:07 +000084#elif defined(VGA_ppc32)
85 typedef VexGuestPPC32State VexGuestArchState;
njnc7561b92005-06-19 01:24:32 +000086#else
87# error Unknown architecture
88#endif
89
90
91typedef
92 struct {
93 /* --- BEGIN vex-mandated guest state --- */
94
95 /* Saved machine context. */
96 VexGuestArchState vex;
97
98 /* Saved shadow context. */
99 VexGuestArchState vex_shadow;
100
101 /* Spill area. */
102 UChar vex_spill[LibVEX_N_SPILL_BYTES];
103
104 /* --- END vex-mandated guest state --- */
105 }
106 ThreadArchState;
107
108/* OS-specific thread state */
109typedef struct {
110 /* who we are */
111 Int lwpid; // PID of kernel task
112 Int threadgroup; // thread group id
113
114 ThreadId parent; // parent tid (if any)
115
116 /* runtime details */
117 Addr valgrind_stack_base; // Valgrind's stack base
118 SizeT valgrind_stack_szB; // stack size in bytes
119
120 /* exit details */
121 Int exitcode; // in the case of exitgroup, set by someone else
122 Int fatalsig; // fatal signal
123} os_thread_t;
124
125
126typedef struct {
127 /* ThreadId == 0 (and hence vg_threads[0]) is NEVER USED.
128 The thread identity is simply the index in vg_threads[].
129 ThreadId == 1 is the root thread and has the special property
130 that we don't try and allocate or deallocate its stack. For
131 convenience of generating error message, we also put the
132 ThreadId in this tid field, but be aware that it should
133 ALWAYS == the index in vg_threads[]. */
134 ThreadId tid;
135
136 /* Current scheduling status. */
137 ThreadStatus status;
138
139 /* This is set if the thread is in the process of exiting for any
140 reason. The precise details of the exit are in the OS-specific
141 state. */
142 VgSchedReturnCode exitreason;
143
144 /* Architecture-specific thread state. */
145 ThreadArchState arch;
146
147 /* This thread's blocked-signals mask. Semantics is that for a
148 signal to be delivered to this thread, the signal must not be
149 blocked by this signal mask. If more than one thread accepts a
150 signal, then it will be delivered to one at random. If all
151 threads block the signal, it will remain pending until either a
152 thread unblocks it or someone uses sigwaitsig/sigtimedwait. */
153 vki_sigset_t sig_mask;
154
155 /* tmp_sig_mask is usually the same as sig_mask, and is kept in
156 sync whenever sig_mask is changed. The only time they have
157 different values is during the execution of a sigsuspend, where
158 tmp_sig_mask is the temporary mask which sigsuspend installs.
159 It is only consulted to compute the signal mask applied to a
160 signal handler. */
161 vki_sigset_t tmp_sig_mask;
162
163 /* A little signal queue for signals we can't get the kernel to
164 queue for us. This is only allocated as needed, since it should
165 be rare. */
166 struct SigQueue *sig_queue;
167
168 /* Client stacks. When a thread slot is freed, we don't deallocate its
169 stack; we just leave it lying around for the next use of the
170 slot. If the next use of the slot requires a larger stack,
171 only then is the old one deallocated and a new one
172 allocated.
173
174 For the main thread (threadid == 0), this mechanism doesn't
175 apply. We don't know the size of the stack since we didn't
176 allocate it, and furthermore we never reallocate it. */
177
178 /* The allocated size of this thread's stack (permanently zero
179 if this is ThreadId == 0, since we didn't allocate its stack) */
180 SizeT client_stack_szB;
181
182 /* Address of the highest legitimate word in this stack. This is
183 used for error messages only -- not critical for execution
184 correctness. Is is set for all stacks, specifically including
185 ThreadId == 0 (the main thread). */
186 Addr client_stack_highest_word;
187
188 /* Alternate signal stack */
189 vki_stack_t altstack;
190
191 /* OS-specific thread state */
192 os_thread_t os_state;
193
194 /* Used in the syscall handlers. Set to True to indicate that the
195 PRE routine for a syscall has set the syscall result already and
196 so the syscall does not need to be handed to the kernel. */
197 Bool syscall_result_set;
198
199 /* 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/*--------------------------------------------------------------------*/