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