[project @ 1999-05-11 16:47:39 by keithw]
[ghc-hetmet.git] / ghc / includes / TSO.h
1 /* -----------------------------------------------------------------------------
2  * $Id: TSO.h,v 1.7 1999/05/11 16:47:42 keithw Exp $
3  *
4  * (c) The GHC Team, 1998-1999
5  *
6  * The definitions for Thread State Objects.
7  *
8  * ---------------------------------------------------------------------------*/
9
10 #ifndef TSO_H
11 #define TSO_H
12
13 #if defined(PROFILING)
14 typedef struct {
15   CostCentreStack *CCCS;        /* thread's current CCS */
16 } StgTSOProfInfo;
17 #else /* !PROFILING */
18 typedef struct {
19 } StgTSOProfInfo;
20 #endif /* PROFILING */
21
22 #if defined(PAR)
23 typedef struct {
24 } StgTSOParInfo;
25 #else /* !PAR */
26 typedef struct {
27 } StgTSOParInfo;
28 #endif /* PAR */
29
30 #if defined(TICKY_TICKY)
31 typedef struct {
32 } StgTSOTickyInfo;
33 #else /* !TICKY_TICKY */
34 typedef struct {
35 } StgTSOTickyInfo;
36 #endif /* TICKY_TICKY */
37
38 typedef enum {
39     tso_state_runnable,
40     tso_state_stopped
41 } StgTSOState;
42
43 typedef enum {
44   ThreadEnterGHC,
45   ThreadRunGHC,
46   ThreadEnterHugs,
47   ThreadKilled,
48   ThreadComplete
49 } StgTSOWhatNext;
50
51 /*
52  * We are completely paranoid and make thread IDs 64 bits to avoid
53  * having to worry about overflow.  A little calculation shows that
54  * even doing 10^6 forks per second would take 35 million years to
55  * overflow a 64 bit thread ID :-)
56  *
57  */
58 typedef StgWord32 StgThreadID;
59
60 /*
61  * This type is returned to the scheduler by a thread that has
62  * stopped for one reason or another.
63  */
64
65 typedef enum {
66   HeapOverflow,                 /* might also be StackOverflow */
67   StackOverflow,
68   ThreadYielding,
69   ThreadBlocked,
70   ThreadFinished
71 } StgThreadReturnCode;
72
73 /*
74  * TSOs live on the heap, and therefore look just like heap objects.
75  * Large TSOs will live in their own "block group" allocated by the
76  * storage manager, and won't be copied during garbage collection.
77  */
78
79 typedef struct StgTSO_ {
80   StgHeader          header;
81   struct StgTSO_*    link;
82   StgMutClosure *    mut_link;  /* TSO's are mutable of course! */
83   StgTSOWhatNext     whatNext;
84   StgClosure *       blocked_on;
85   StgThreadID        id;
86   StgTSOTickyInfo    ticky; 
87   StgTSOProfInfo     prof;
88   StgTSOParInfo      par;
89   /* GranSim Info? */
90
91   /* The thread stack... */
92   StgWord            stack_size;     /* stack size in *words* */
93   StgWord            max_stack_size; /* maximum stack size in *words* */
94   StgPtr             sp;
95   StgUpdateFrame*    su;
96   StgPtr             splim;
97   
98   StgWord            stack[0];
99 } StgTSO;
100
101 extern DLL_IMPORT_RTS StgTSO      *CurrentTSO;
102
103 /* -----------------------------------------------------------------------------
104    Invariants:
105
106    An active thread has the following properties:
107
108       tso->stack < tso->sp < tso->stack+tso->stack_size
109       tso->stack_size <= tso->max_stack_size
110       tso->splim == tso->stack + RESERVED_STACK_WORDS;
111       
112       RESERVED_STACK_WORDS is large enough for any heap-check or
113       stack-check failure.
114
115       The size of the TSO struct plus the stack is either
116         (a) smaller than a block, or
117         (b) a multiple of BLOCK_SIZE
118
119       tso->link
120           == END_TSO_QUEUE  , iff the thread is currently running.
121           == (StgTSO *)     , otherwise, and it is linked onto either:
122
123           - the runnable_queue       tso->blocked_on == END_TSO_QUEUE
124           - the blocked_queue        tso->blocked_on == END_TSO_QUEUE
125           - a BLACKHOLE_BQ,          tso->blocked_on == the BLACKHOLE_BQ
126           - an MVAR,                 tso->blocked_on == the MVAR
127                                 
128    A zombie thread has the following properties:
129       
130       tso->whatNext == ThreadComplete or ThreadKilled
131       tso->link     ==  (could be on some queue somewhere)
132       tso->su       ==  tso->stack + tso->stack_size
133       tso->sp       ==  tso->stack + tso->stack_size - 1 (i.e. top stack word)
134       tso->sp[0]    ==  return value of thread, if whatNext == ThreadComplete,
135                         exception             , if whatNext == ThreadKilled
136
137       (tso->sp is left pointing at the top word on the stack so that
138       the return value or exception will be retained by a GC).
139
140    ---------------------------------------------------------------------------- */
141
142 /* Workaround for a bug/quirk in gcc on certain architectures.
143  * symptom is that (&tso->stack - &tso->header) /=  sizeof(StgTSO)
144  * in other words, gcc pads the structure at the end.
145  */
146
147 extern StgTSO dummy_tso;
148
149 #define TSO_STRUCT_SIZE \
150    ((int)&(dummy_tso).stack - (int)&(dummy_tso).header)
151
152 #define TSO_STRUCT_SIZEW (TSO_STRUCT_SIZE / sizeof(W_))
153
154 #endif /* TSO_H */