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