[project @ 1999-08-25 16:11:43 by simonmar]
[ghc-hetmet.git] / ghc / includes / TSO.h
1 /* -----------------------------------------------------------------------------
2  * $Id: TSO.h,v 1.8 1999/08/25 16:11:44 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   BlockedOnRead,
86   BlockedOnWrite,
87   BlockedOnDelay
88 } StgTSOBlockReason;
89
90 typedef union {
91   StgClosure *closure;
92   int fd;
93   unsigned int delay;
94 } StgTSOBlockInfo;
95
96 /*
97  * TSOs live on the heap, and therefore look just like heap objects.
98  * Large TSOs will live in their own "block group" allocated by the
99  * storage manager, and won't be copied during garbage collection.
100  */
101
102 typedef struct StgTSO_ {
103   StgHeader          header;
104   struct StgTSO_*    link;
105   StgMutClosure *    mut_link;  /* TSO's are mutable of course! */
106   StgTSOWhatNext     whatNext;
107   StgTSOBlockReason  why_blocked;
108   StgTSOBlockInfo    block_info;
109   StgThreadID        id;
110   StgTSOTickyInfo    ticky; 
111   StgTSOProfInfo     prof;
112   StgTSOParInfo      par;
113   /* GranSim Info? */
114
115   /* The thread stack... */
116   StgWord            stack_size;     /* stack size in *words* */
117   StgWord            max_stack_size; /* maximum stack size in *words* */
118   StgPtr             sp;
119   StgUpdateFrame*    su;
120   StgPtr             splim;
121   
122   StgWord            stack[0];
123 } StgTSO;
124
125 extern DLL_IMPORT_RTS StgTSO      *CurrentTSO;
126
127 /* -----------------------------------------------------------------------------
128    Invariants:
129
130    An active thread has the following properties:
131
132       tso->stack < tso->sp < tso->stack+tso->stack_size
133       tso->stack_size <= tso->max_stack_size
134       tso->splim == tso->stack + RESERVED_STACK_WORDS;
135       
136       RESERVED_STACK_WORDS is large enough for any heap-check or
137       stack-check failure.
138
139       The size of the TSO struct plus the stack is either
140         (a) smaller than a block, or
141         (b) a multiple of BLOCK_SIZE
142
143       tso->link
144           == END_TSO_QUEUE  , iff the thread is currently running.
145           == (StgTSO *)     , otherwise, and it is linked onto either:
146
147           - the runnable_queue       tso->blocked_on == END_TSO_QUEUE
148           - the blocked_queue        tso->blocked_on == END_TSO_QUEUE
149           - a BLACKHOLE_BQ,          tso->blocked_on == the BLACKHOLE_BQ
150           - an MVAR,                 tso->blocked_on == the MVAR
151                                 
152    A zombie thread has the following properties:
153       
154       tso->whatNext == ThreadComplete or ThreadKilled
155       tso->link     ==  (could be on some queue somewhere)
156       tso->su       ==  tso->stack + tso->stack_size
157       tso->sp       ==  tso->stack + tso->stack_size - 1 (i.e. top stack word)
158       tso->sp[0]    ==  return value of thread, if whatNext == ThreadComplete,
159                         exception             , if whatNext == ThreadKilled
160
161       (tso->sp is left pointing at the top word on the stack so that
162       the return value or exception will be retained by a GC).
163
164    ---------------------------------------------------------------------------- */
165
166 /* Workaround for a bug/quirk in gcc on certain architectures.
167  * symptom is that (&tso->stack - &tso->header) /=  sizeof(StgTSO)
168  * in other words, gcc pads the structure at the end.
169  */
170
171 extern StgTSO dummy_tso;
172
173 #define TSO_STRUCT_SIZE \
174    ((int)&(dummy_tso).stack - (int)&(dummy_tso).header)
175
176 #define TSO_STRUCT_SIZEW (TSO_STRUCT_SIZE / sizeof(W_))
177
178 #endif /* TSO_H */