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