cf51598e0b23892460bbd23c202cb27b37f8ed8e
[ghc-hetmet.git] / ghc / includes / TSO.h
1 /* -----------------------------------------------------------------------------
2  * $Id: TSO.h,v 1.36 2004/08/13 13:57:06 simonmar 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(GRAN) || defined(PAR)
14
15 #if DEBUG
16 #define TSO_MAGIC 4321
17 #endif
18
19 typedef struct {
20   StgInt   pri;
21   StgInt   magic;
22   StgInt   sparkname;
23   rtsTime  startedat;
24   rtsBool  exported;
25   StgInt   basicblocks;
26   StgInt   allocs;
27   rtsTime  exectime;
28   rtsTime  fetchtime;
29   rtsTime  fetchcount;
30   rtsTime  blocktime;
31   StgInt   blockcount;
32   rtsTime  blockedat;
33   StgInt   globalsparks;
34   StgInt   localsparks;
35   rtsTime  clock;
36 } StgTSOStatBuf;
37 #endif
38
39 /*
40  * PROFILING info in a TSO
41  */
42 typedef struct {
43   CostCentreStack *CCCS;        /* thread's current CCS */
44 } StgTSOProfInfo;
45
46 /*
47  * PAR info in a TSO
48  */
49 #ifdef PAR
50 typedef StgTSOStatBuf StgTSOParInfo;
51 #else
52 #ifdef SUPPORTS_EMPTY_STRUCTS
53 typedef struct {
54         /* empty */
55 } StgTSOParInfo;
56 #endif
57 #endif
58
59 /*
60  * DIST info in a TSO
61  */
62 #ifdef DIST
63 typedef struct {
64   StgThreadPriority  priority;   
65   StgInt             revalTid;   /* ToDo: merge both into 1 word */
66   StgInt             revalSlot;
67 } StgTSODistInfo;
68 #else
69 #ifdef SUPPORTS_EMPTY_STRUCTS
70 typedef struct {
71         /* empty */
72 } StgTSODistInfo;
73 #endif
74 #endif
75
76 /*
77  * GRAN info in a TSO
78  */
79 #ifdef GRAN
80 typedef StgTSOStatBuf StgTSOGranInfo;
81 #else
82 #ifdef SUPPORTS_EMPTY_STRUCTS
83 typedef struct {
84         /* empty */
85 } StgTSOGranInfo;
86 #endif
87 #endif
88
89 /*
90  * TICKY_TICKY info in a TSO
91  */
92 #ifdef SUPPORTS_EMPTY_STRUCTS
93 typedef struct {
94     /* empty */
95 } StgTSOTickyInfo;
96 #endif
97
98 /*
99  * Thread IDs are 32 bits.
100  */
101 typedef StgWord32 StgThreadID;
102
103 /*
104  * Type returned after running a thread.  Values of this type
105  * include HeapOverflow, StackOverflow etc.  See Constants.h for the
106  * full list.
107  */
108 typedef unsigned int StgThreadReturnCode;
109
110 /*
111  * We distinguish between the various classes of threads in the system.
112  */
113
114 typedef enum {
115   AdvisoryPriority,
116   MandatoryPriority,
117   RevalPriority
118 } StgThreadPriority;
119
120 #if defined(mingw32_TARGET_OS)
121 /* results from an async I/O request + it's ID. */
122 typedef struct {
123   unsigned int reqID;
124   int          len;
125   int          errCode;
126 } StgAsyncIOResult;
127 #endif
128
129 typedef union {
130   StgClosure *closure;
131   struct StgTSO_ *tso;
132   int fd;
133 #if defined(mingw32_TARGET_OS)
134   StgAsyncIOResult* async_result;
135 #endif
136   unsigned int target;
137 } StgTSOBlockInfo;
138
139 /*
140  * TSOs live on the heap, and therefore look just like heap objects.
141  * Large TSOs will live in their own "block group" allocated by the
142  * storage manager, and won't be copied during garbage collection.
143  */
144
145 /* 
146  * Threads may be blocked for several reasons.  A blocked thread will
147  * have the reason in the why_blocked field of the TSO, and some
148  * further info (such as the closure the thread is blocked on, or the
149  * file descriptor if the thread is waiting on I/O) in the block_info
150  * field.
151  */
152
153 /* 
154  * ToDo: make this structure sensible on a non-32-bit arch.
155  */
156
157 typedef struct StgTSO_ {
158   StgHeader          header;
159
160   struct StgTSO_*    link;           // Links threads onto blocking queues */
161   StgMutClosure *    mut_link;       // TSO's are mutable of course! */
162   struct StgTSO_*    global_link;    // Links all threads together */
163   
164   StgWord16           what_next;  // Values defined in Constants.h
165   StgWord16           why_blocked;  // Values defined in Constants.h
166   StgTSOBlockInfo    block_info;
167   struct StgTSO_*    blocked_exceptions;
168   StgThreadID        id;
169   int                saved_errno;
170   struct StgMainThread_* main;
171   
172 #ifdef TICKY_TICKY
173   MAYBE_EMPTY_STRUCT(StgTSOTickyInfo,ticky)
174 #endif
175 #ifdef PROFILING
176    StgTSOProfInfo prof;
177 #endif
178
179    MAYBE_EMPTY_STRUCT(StgTSOParInfo,par);
180    MAYBE_EMPTY_STRUCT(StgTSOGranInfo,gran);
181    MAYBE_EMPTY_STRUCT(StgTSODistInfo,dist);
182
183   /* The thread stack... */
184   StgWord            stack_size;     /* stack size in *words* */
185   StgWord            max_stack_size; /* maximum stack size in *words* */
186   StgPtr             sp;
187   
188   StgWord            stack[FLEXIBLE_ARRAY];
189 } StgTSO;
190
191 /* -----------------------------------------------------------------------------
192    Invariants:
193
194    An active thread has the following properties:
195
196       tso->stack < tso->sp < tso->stack+tso->stack_size
197       tso->stack_size <= tso->max_stack_size
198       
199       RESERVED_STACK_WORDS is large enough for any heap-check or
200       stack-check failure.
201
202       The size of the TSO struct plus the stack is either
203         (a) smaller than a block, or
204         (b) a multiple of BLOCK_SIZE
205
206         tso->why_blocked       tso->block_info      location
207         ----------------------------------------------------------------------
208         NotBlocked             NULL                 runnable_queue, or running
209         
210         BlockedOnBlackHole     the BLACKHOLE_BQ     the BLACKHOLE_BQ's queue
211         
212         BlockedOnMVar          the MVAR             the MVAR's queue
213         
214         BlockedOnException     the TSO              TSO->blocked_exception
215
216         BlockedOnRead          NULL                 blocked_queue
217         BlockedOnWrite         NULL                 blocked_queue
218         BlockedOnDelay         NULL                 blocked_queue
219         BlockedOnGA            closure TSO blocks on   BQ of that closure
220         BlockedOnGA_NoSend     closure TSO blocks on   BQ of that closure
221
222       tso->link == END_TSO_QUEUE, if the thread is currently running.
223
224    A zombie thread has the following properties:
225       
226       tso->what_next == ThreadComplete or ThreadKilled
227       tso->link     ==  (could be on some queue somewhere)
228       tso->su       ==  tso->stack + tso->stack_size
229       tso->sp       ==  tso->stack + tso->stack_size - 1 (i.e. top stack word)
230       tso->sp[0]    ==  return value of thread, if what_next == ThreadComplete,
231                         exception             , if what_next == ThreadKilled
232
233       (tso->sp is left pointing at the top word on the stack so that
234       the return value or exception will be retained by a GC).
235
236    tso->blocked_exceptions is either:
237
238       NULL             if async exceptions are unblocked.
239
240       END_TSO_QUEUE    if async exceptions are blocked, but no threads
241                        are currently waiting to deliver.
242
243       (StgTSO *)tso    if threads are currently awaiting delivery of
244                        exceptions to this thread.
245
246    The 2 cases BlockedOnGA and BlockedOnGA_NoSend are needed in a GUM
247    setup only. They mark a TSO that has entered a FETCH_ME or
248    FETCH_ME_BQ closure, respectively; only the first TSO hitting the 
249    closure will send a Fetch message.
250    Currently we have no separate code for blocking on an RBH; we use the
251    BlockedOnBlackHole case for that.   -- HWL
252
253  ---------------------------------------------------------------------------- */
254
255 /* Workaround for a bug/quirk in gcc on certain architectures.
256  * symptom is that (&tso->stack - &tso->header) /=  sizeof(StgTSO)
257  * in other words, gcc pads the structure at the end.
258  */
259
260 extern StgTSO dummy_tso;
261
262 #define TSO_STRUCT_SIZE \
263    ((char *)&dummy_tso.stack - (char *)&dummy_tso.header)
264
265 #define TSO_STRUCT_SIZEW (TSO_STRUCT_SIZE / sizeof(W_))
266
267
268 /* this is the NIL ptr for a TSO queue (e.g. runnable queue) */
269 #define END_TSO_QUEUE  ((StgTSO *)(void*)&stg_END_TSO_QUEUE_closure)
270
271 #if defined(PAR) || defined(GRAN)
272 /* this is the NIL ptr for a blocking queue */
273 # define END_BQ_QUEUE  ((StgBlockingQueueElement *)(void*)&stg_END_TSO_QUEUE_closure)
274 /* this is the NIL ptr for a blocked fetch queue (as in PendingFetches in GUM) */
275 # define END_BF_QUEUE  ((StgBlockedFetch *)(void*)&stg_END_TSO_QUEUE_closure)
276 #endif
277 /* ToDo?: different name for end of sleeping queue ? -- HWL */
278
279 #endif /* TSO_H */