[project @ 1999-12-01 14:34:38 by simonmar]
[ghc-hetmet.git] / ghc / includes / TSO.h
1 /* -----------------------------------------------------------------------------
2  * $Id: TSO.h,v 1.9 1999/12/01 14:34:49 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(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  * Threads may be blocked for several reasons.  A blocked thread will
75  * have the reason in the why_blocked field of the TSO, and some
76  * further info (such as the closure the thread is blocked on, or the
77  * file descriptor if the thread is waiting on I/O) in the block_info
78  * field.
79  */
80
81 typedef enum {
82   NotBlocked,
83   BlockedOnMVar,
84   BlockedOnBlackHole,
85   BlockedOnException,
86   BlockedOnRead,
87   BlockedOnWrite,
88   BlockedOnDelay
89 } StgTSOBlockReason;
90
91 typedef union {
92   StgClosure *closure;
93   struct StgTSO_ *tso;
94   int fd;
95   unsigned int delay;
96 } StgTSOBlockInfo;
97
98 /*
99  * TSOs live on the heap, and therefore look just like heap objects.
100  * Large TSOs will live in their own "block group" allocated by the
101  * storage manager, and won't be copied during garbage collection.
102  */
103
104 typedef struct StgTSO_ {
105   StgHeader          header;
106   struct StgTSO_*    link;
107   StgMutClosure *    mut_link;  /* TSO's are mutable of course! */
108   StgTSOWhatNext     whatNext;
109   StgTSOBlockReason  why_blocked;
110   StgTSOBlockInfo    block_info;
111   struct StgTSO_*    blocked_exceptions;
112   StgThreadID        id;
113   StgTSOTickyInfo    ticky; 
114   StgTSOProfInfo     prof;
115   StgTSOParInfo      par;
116   /* GranSim Info? */
117
118   /* The thread stack... */
119   StgWord            stack_size;     /* stack size in *words* */
120   StgWord            max_stack_size; /* maximum stack size in *words* */
121   StgPtr             sp;
122   StgUpdateFrame*    su;
123   StgPtr             splim;
124   
125   StgWord            stack[0];
126 } StgTSO;
127
128 /* -----------------------------------------------------------------------------
129    Invariants:
130
131    An active thread has the following properties:
132
133       tso->stack < tso->sp < tso->stack+tso->stack_size
134       tso->stack_size <= tso->max_stack_size
135       tso->splim == tso->stack + RESERVED_STACK_WORDS;
136       
137       RESERVED_STACK_WORDS is large enough for any heap-check or
138       stack-check failure.
139
140       The size of the TSO struct plus the stack is either
141         (a) smaller than a block, or
142         (b) a multiple of BLOCK_SIZE
143
144         tso->block_reason      tso->block_info      location
145         ----------------------------------------------------------------------
146         NotBlocked             NULL                 runnable_queue, or running
147         
148         BlockedOnBlackHole     the BLACKHOLE_BQ     the BLACKHOLE_BQ's queue
149         
150         BlockedOnMVar          the MVAR             the MVAR's queue
151         
152         BlockedOnException     the TSO              TSO->blocked_exception
153
154         BlockedOnRead          NULL                 blocked_queue
155         BlockedOnWrite         NULL                 blocked_queue
156         BlockedOnDelay         NULL                 blocked_queue
157
158       tso->link == END_TSO_QUEUE, if the thread is currently running.
159
160    A zombie thread has the following properties:
161       
162       tso->whatNext == ThreadComplete or ThreadKilled
163       tso->link     ==  (could be on some queue somewhere)
164       tso->su       ==  tso->stack + tso->stack_size
165       tso->sp       ==  tso->stack + tso->stack_size - 1 (i.e. top stack word)
166       tso->sp[0]    ==  return value of thread, if whatNext == ThreadComplete,
167                         exception             , if whatNext == ThreadKilled
168
169       (tso->sp is left pointing at the top word on the stack so that
170       the return value or exception will be retained by a GC).
171
172    tso->blocked_exceptions is either:
173
174       NULL             if async exceptions are unblocked.
175
176       END_TSO_QUEUE    if async exceptions are blocked, but no threads
177                        are currently waiting to deliver.
178
179       (StgTSO *)tso    if threads are currently awaiting delivery of
180                        exceptions to this thread.
181
182  ---------------------------------------------------------------------------- */
183
184 /* Workaround for a bug/quirk in gcc on certain architectures.
185  * symptom is that (&tso->stack - &tso->header) /=  sizeof(StgTSO)
186  * in other words, gcc pads the structure at the end.
187  */
188
189 extern StgTSO dummy_tso;
190
191 #define TSO_STRUCT_SIZE \
192    ((int)&(dummy_tso).stack - (int)&(dummy_tso).header)
193
194 #define TSO_STRUCT_SIZEW (TSO_STRUCT_SIZE / sizeof(W_))
195
196 #endif /* TSO_H */