Home | History | Annotate | Download | only in coregrind
      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