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