[project @ 2004-08-13 13:04:50 by simonmar]
[ghc-hetmet.git] / ghc / includes / TSO.h
1 /* -----------------------------------------------------------------------------
2  * $Id: TSO.h,v 1.35 2004/08/13 13:09:40 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   
171 #ifdef TICKY_TICKY
172   MAYBE_EMPTY_STRUCT(StgTSOTickyInfo,ticky)
173 #endif
174 #ifdef PROFILING
175    StgTSOProfInfo prof;
176 #endif
177
178    MAYBE_EMPTY_STRUCT(StgTSOParInfo,par);
179    MAYBE_EMPTY_STRUCT(StgTSOGranInfo,gran);
180    MAYBE_EMPTY_STRUCT(StgTSODistInfo,dist);
181
182   /* The thread stack... */
183   StgWord            stack_size;     /* stack size in *words* */
184   StgWord            max_stack_size; /* maximum stack size in *words* */
185   StgPtr             sp;
186   
187   StgWord            stack[FLEXIBLE_ARRAY];
188 } StgTSO;
189
190 /* -----------------------------------------------------------------------------
191    Invariants:
192
193    An active thread has the following properties:
194
195       tso->stack < tso->sp < tso->stack+tso->stack_size
196       tso->stack_size <= tso->max_stack_size
197       
198       RESERVED_STACK_WORDS is large enough for any heap-check or
199       stack-check failure.
200
201       The size of the TSO struct plus the stack is either
202         (a) smaller than a block, or
203         (b) a multiple of BLOCK_SIZE
204
205         tso->why_blocked       tso->block_info      location
206         ----------------------------------------------------------------------
207         NotBlocked             NULL                 runnable_queue, or running
208         
209         BlockedOnBlackHole     the BLACKHOLE_BQ     the BLACKHOLE_BQ's queue
210         
211         BlockedOnMVar          the MVAR             the MVAR's queue
212         
213         BlockedOnException     the TSO              TSO->blocked_exception
214
215         BlockedOnRead          NULL                 blocked_queue
216         BlockedOnWrite         NULL                 blocked_queue
217         BlockedOnDelay         NULL                 blocked_queue
218         BlockedOnGA            closure TSO blocks on   BQ of that closure
219         BlockedOnGA_NoSend     closure TSO blocks on   BQ of that closure
220
221       tso->link == END_TSO_QUEUE, if the thread is currently running.
222
223    A zombie thread has the following properties:
224       
225       tso->what_next == ThreadComplete or ThreadKilled
226       tso->link     ==  (could be on some queue somewhere)
227       tso->su       ==  tso->stack + tso->stack_size
228       tso->sp       ==  tso->stack + tso->stack_size - 1 (i.e. top stack word)
229       tso->sp[0]    ==  return value of thread, if what_next == ThreadComplete,
230                         exception             , if what_next == ThreadKilled
231
232       (tso->sp is left pointing at the top word on the stack so that
233       the return value or exception will be retained by a GC).
234
235    tso->blocked_exceptions is either:
236
237       NULL             if async exceptions are unblocked.
238
239       END_TSO_QUEUE    if async exceptions are blocked, but no threads
240                        are currently waiting to deliver.
241
242       (StgTSO *)tso    if threads are currently awaiting delivery of
243                        exceptions to this thread.
244
245    The 2 cases BlockedOnGA and BlockedOnGA_NoSend are needed in a GUM
246    setup only. They mark a TSO that has entered a FETCH_ME or
247    FETCH_ME_BQ closure, respectively; only the first TSO hitting the 
248    closure will send a Fetch message.
249    Currently we have no separate code for blocking on an RBH; we use the
250    BlockedOnBlackHole case for that.   -- HWL
251
252  ---------------------------------------------------------------------------- */
253
254 /* Workaround for a bug/quirk in gcc on certain architectures.
255  * symptom is that (&tso->stack - &tso->header) /=  sizeof(StgTSO)
256  * in other words, gcc pads the structure at the end.
257  */
258
259 extern StgTSO dummy_tso;
260
261 #define TSO_STRUCT_SIZE \
262    ((char *)&dummy_tso.stack - (char *)&dummy_tso.header)
263
264 #define TSO_STRUCT_SIZEW (TSO_STRUCT_SIZE / sizeof(W_))
265
266
267 /* this is the NIL ptr for a TSO queue (e.g. runnable queue) */
268 #define END_TSO_QUEUE  ((StgTSO *)(void*)&stg_END_TSO_QUEUE_closure)
269
270 #if defined(PAR) || defined(GRAN)
271 /* this is the NIL ptr for a blocking queue */
272 # define END_BQ_QUEUE  ((StgBlockingQueueElement *)(void*)&stg_END_TSO_QUEUE_closure)
273 /* this is the NIL ptr for a blocked fetch queue (as in PendingFetches in GUM) */
274 # define END_BF_QUEUE  ((StgBlockedFetch *)(void*)&stg_END_TSO_QUEUE_closure)
275 #endif
276 /* ToDo?: different name for end of sleeping queue ? -- HWL */
277
278 #endif /* TSO_H */