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-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