1 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-2010 Julian Seward 11 jseward (at) 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 */ 55 typedef 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. */ 67 typedef 68 enum { 69 VgSrc_None, /* not exiting yet */ 70 VgSrc_ExitThread, /* just this thread is exiting */ 71 VgSrc_ExitProcess, /* entire process is exiting */ 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_ppc32) 83 typedef VexGuestPPC32State VexGuestArchState; 84 #elif defined(VGA_ppc64) 85 typedef VexGuestPPC64State VexGuestArchState; 86 #elif defined(VGA_arm) 87 typedef VexGuestARMState VexGuestArchState; 88 #else 89 # error Unknown architecture 90 #endif 91 92 /* Forward declarations */ 93 struct SyscallStatus; 94 struct SyscallArgs; 95 96 /* Architecture-specific thread state */ 97 typedef 98 struct { 99 /* --- BEGIN vex-mandated guest state --- */ 100 101 /* Note that for code generation reasons, we require that the 102 guest state area, its two shadows, and the spill area, are 103 16-aligned and have 16-aligned sizes, and there are no holes 104 in between. This is checked by do_pre_run_checks() in 105 scheduler.c. */ 106 107 /* Saved machine context. */ 108 VexGuestArchState vex __attribute__((aligned(16))); 109 110 /* Saved shadow context (2 copies). */ 111 VexGuestArchState vex_shadow1 __attribute__((aligned(16))); 112 VexGuestArchState vex_shadow2 __attribute__((aligned(16))); 113 114 /* Spill area. */ 115 UChar vex_spill[LibVEX_N_SPILL_BYTES] __attribute__((aligned(16))); 116 117 /* --- END vex-mandated guest state --- */ 118 } 119 ThreadArchState; 120 121 122 /* OS-specific thread state. IMPORTANT: if you add fields to this, 123 you _must_ add code to os_state_clear() to initialise those 124 fields. */ 125 typedef 126 struct { 127 /* who we are */ 128 Int lwpid; // PID of kernel task (Darwin: Mach thread) 129 Int threadgroup; // thread group id 130 131 ThreadId parent; // parent tid (if any) 132 133 /* runtime details */ 134 Addr valgrind_stack_base; // Valgrind's stack (VgStack*) 135 Addr valgrind_stack_init_SP; // starting value for SP 136 137 /* exit details */ 138 Word exitcode; // in the case of exitgroup, set by someone else 139 Int fatalsig; // fatal signal 140 141 # if defined(VGO_aix5) 142 /* AIX specific fields to make thread cancellation sort-of work */ 143 /* What is this thread's current cancellation state a la 144 POSIX (deferred vs async, enable vs disabled) ? */ 145 Bool cancel_async; // current cancel mode (async vs deferred) 146 Bool cancel_disabled; // cancellation disabled? 147 /* What's happened so far? */ 148 enum { Canc_NoRequest=0, // no cancellation requested 149 Canc_Requested=1, // requested but not actioned 150 Canc_Actioned=2 } // requested and actioned 151 cancel_progress; 152 /* Initial state is False, False, Canc_Normal. */ 153 # endif 154 155 # if defined(VGO_darwin) 156 // Mach trap POST handler as chosen by PRE 157 void (*post_mach_trap_fn)(ThreadId tid, 158 struct SyscallArgs *, struct SyscallStatus *); 159 160 // This thread's pthread 161 Addr pthread; 162 163 // Argument passed when thread started 164 Addr func_arg; 165 166 // Synchronization between child thread and parent thread's POST wrapper 167 semaphore_t child_go; 168 semaphore_t child_done; 169 170 // Workqueue re-entry 171 // (setjmp in PRE(workq_ops), longjmp in wqthread_hijack) 172 // DDD: JRS fixme: this comment is no longer correct; wq_jmpbuf is 173 // never used, and there is no such setjmp or longjmp pair. 174 // I guess we could leave wq_jmpbuf_valid in place though, since 175 // it does allow for an assertion in ML_(wqthread_continue_NORETURN). 176 Bool wq_jmpbuf_valid; 177 //jmp_buf wq_jmpbuf; 178 179 // Values saved from transient Mach RPC messages 180 Addr remote_port; // destination for original message 181 Int msgh_id; // outgoing message id 182 union { 183 struct { 184 Addr port; 185 } mach_port; 186 struct { 187 Int right; 188 } mach_port_allocate; 189 struct { 190 Addr port; 191 Int right; 192 Int delta; 193 } mach_port_mod_refs; 194 struct { 195 Addr task; 196 Addr name; 197 Int disposition; 198 } mach_port_insert_right; 199 struct { 200 Addr size; 201 int flags; 202 } vm_allocate; 203 struct { 204 Addr address; 205 Addr size; 206 } vm_deallocate; 207 struct { 208 Addr src; 209 Addr dst; 210 Addr size; 211 } vm_copy; 212 struct { 213 Addr address; 214 Addr size; 215 int set_maximum; 216 UWord new_protection; 217 } vm_protect; 218 struct { 219 Addr addr; 220 SizeT size; 221 } vm_read; 222 struct { 223 ULong addr; 224 ULong size; 225 } mach_vm_read; 226 struct { 227 Addr addr; 228 SizeT size; 229 Addr data; 230 } vm_read_overwrite; 231 struct { 232 Addr size; 233 int copy; 234 UWord protection; 235 } vm_map; 236 struct { 237 Addr size; 238 } vm_remap; 239 struct { 240 ULong size; 241 int flags; 242 } mach_vm_allocate; 243 struct { 244 ULong address; 245 ULong size; 246 } mach_vm_deallocate; 247 struct { 248 ULong address; 249 ULong size; 250 int set_maximum; 251 unsigned int new_protection; 252 } mach_vm_protect; 253 struct { 254 ULong size; 255 int copy; 256 UWord protection; 257 } mach_vm_map; 258 struct { 259 Addr thread; 260 UWord flavor; 261 } thread_get_state; 262 struct { 263 Addr address; 264 } io_connect_unmap_memory; 265 struct { 266 int which_port; 267 } task_get_special_port; 268 struct { 269 char *service_name; 270 } bootstrap_look_up; 271 struct { 272 vki_size_t size; 273 } WindowServer_29828; 274 struct { 275 Int access_rights; 276 } WindowServer_29831; 277 struct { 278 char *path; 279 } io_registry_entry_from_path; 280 } mach_args; 281 # endif 282 283 } 284 ThreadOSstate; 285 286 287 /* Overall thread state */ 288 typedef struct { 289 /* ThreadId == 0 (and hence vg_threads[0]) is NEVER USED. 290 The thread identity is simply the index in vg_threads[]. 291 ThreadId == 1 is the root thread and has the special property 292 that we don't try and allocate or deallocate its stack. For 293 convenience of generating error message, we also put the 294 ThreadId in this tid field, but be aware that it should 295 ALWAYS == the index in vg_threads[]. */ 296 ThreadId tid; 297 298 /* Current scheduling status. */ 299 ThreadStatus status; 300 301 /* This is set if the thread is in the process of exiting for any 302 reason. The precise details of the exit are in the OS-specific 303 state. */ 304 VgSchedReturnCode exitreason; 305 306 /* Architecture-specific thread state. */ 307 ThreadArchState arch; 308 309 /* This thread's blocked-signals mask. Semantics is that for a 310 signal to be delivered to this thread, the signal must not be 311 blocked by this signal mask. If more than one thread accepts a 312 signal, then it will be delivered to one at random. If all 313 threads block the signal, it will remain pending until either a 314 thread unblocks it or someone uses sigwaitsig/sigtimedwait. */ 315 vki_sigset_t sig_mask; 316 317 /* tmp_sig_mask is usually the same as sig_mask, and is kept in 318 sync whenever sig_mask is changed. The only time they have 319 different values is during the execution of a sigsuspend, where 320 tmp_sig_mask is the temporary mask which sigsuspend installs. 321 It is only consulted to compute the signal mask applied to a 322 signal handler. */ 323 vki_sigset_t tmp_sig_mask; 324 325 /* A little signal queue for signals we can't get the kernel to 326 queue for us. This is only allocated as needed, since it should 327 be rare. */ 328 struct SigQueue *sig_queue; 329 330 /* Client stacks. When a thread slot is freed, we don't deallocate its 331 stack; we just leave it lying around for the next use of the 332 slot. If the next use of the slot requires a larger stack, 333 only then is the old one deallocated and a new one 334 allocated. 335 336 For the main thread (threadid == 1), this mechanism doesn't 337 apply. We don't know the size of the stack since we didn't 338 allocate it, and furthermore we never reallocate it. */ 339 340 /* The allocated size of this thread's stack */ 341 SizeT client_stack_szB; 342 343 /* Address of the highest legitimate word in this stack. This is 344 used for error messages only -- not critical for execution 345 correctness. Is is set for all stacks, specifically including 346 ThreadId == 1 (the main thread). */ 347 Addr client_stack_highest_word; 348 349 /* Alternate signal stack */ 350 vki_stack_t altstack; 351 352 /* OS-specific thread state */ 353 ThreadOSstate os_state; 354 355 /* Per-thread jmp_buf to resume scheduler after a signal */ 356 Bool sched_jmpbuf_valid; 357 jmp_buf sched_jmpbuf; 358 } 359 ThreadState; 360 361 362 /*------------------------------------------------------------*/ 363 /*--- The thread table. ---*/ 364 /*------------------------------------------------------------*/ 365 366 /* A statically allocated array of threads. NOTE: [0] is 367 never used, to simplify the simulation of initialisers for 368 LinuxThreads. */ 369 extern ThreadState VG_(threads)[VG_N_THREADS]; 370 371 // The running thread. m_scheduler should be the only other module 372 // to write to this. 373 extern ThreadId VG_(running_tid); 374 375 376 /*------------------------------------------------------------*/ 377 /*--- Basic operations on the thread table. ---*/ 378 /*------------------------------------------------------------*/ 379 380 // Convert a ThreadStatus to a string. 381 const HChar* VG_(name_of_ThreadStatus) ( ThreadStatus status ); 382 383 /* Get the ThreadState for a particular thread */ 384 extern ThreadState *VG_(get_ThreadState) ( ThreadId tid ); 385 386 /* Check that tid is in range and denotes a non-Empty thread. */ 387 extern Bool VG_(is_valid_tid) ( ThreadId tid ); 388 389 /* Returns true if a thread is currently running (ie, has the CPU lock) */ 390 extern Bool VG_(is_running_thread)(ThreadId tid); 391 392 /* Returns true if the thread is in the process of exiting */ 393 extern Bool VG_(is_exiting)(ThreadId tid); 394 395 /* Return the number of non-dead Threads */ 396 extern Int VG_(count_living_threads)(void); 397 398 /* Return the number of threads in VgTs_Runnable state */ 399 extern Int VG_(count_runnable_threads)(void); 400 401 /* Given an LWP id (ie, real kernel thread id), find the corresponding 402 ThreadId */ 403 extern ThreadId VG_(lwpid_to_vgtid)(Int lwpid); 404 405 #endif // __PUB_CORE_THREADSTATE_H 406 407 /*--------------------------------------------------------------------*/ 408 /*--- end ---*/ 409 /*--------------------------------------------------------------------*/ 410