[project @ 2000-11-13 14:40:36 by simonmar]
[ghc-hetmet.git] / ghc / rts / Schedule.h
1 /* -----------------------------------------------------------------------------
2  * $Id: Schedule.h,v 1.20 2000/11/13 14:40:37 simonmar Exp $
3  *
4  * (c) The GHC Team 1998-1999
5  *
6  * Prototypes for functions in Schedule.c 
7  * (RTS internal scheduler interface)
8  *
9  * -------------------------------------------------------------------------*/
10
11 //@menu
12 //* Scheduler Functions::       
13 //* Scheduler Vars and Data Types::  
14 //* Some convenient macros::    
15 //* Index::                     
16 //@end menu
17
18 //@node Scheduler Functions, Scheduler Vars and Data Types
19 //@subsection Scheduler Functions
20
21 //@cindex initScheduler
22 //@cindex exitScheduler
23 //@cindex startTasks
24 /* initScheduler(), exitScheduler(), startTasks()
25  * 
26  * Called from STG :  no
27  * Locks assumed   :  none
28  */
29 void initScheduler( void );
30 void exitScheduler( void );
31 #ifdef SMP
32 void startTasks( void );
33 #endif
34
35
36 //@cindex awakenBlockedQueue
37 /* awakenBlockedQueue()
38  *
39  * Takes a pointer to the beginning of a blocked TSO queue, and
40  * wakes up the entire queue.
41  *
42  * Called from STG :  yes
43  * Locks assumed   :  none
44  */
45 #if defined(GRAN)
46 void awakenBlockedQueue(StgBlockingQueueElement *q, StgClosure *node);
47 #elif defined(PAR)
48 void awakenBlockedQueue(StgBlockingQueueElement *q, StgClosure *node);
49 #else
50 void awakenBlockedQueue(StgTSO *tso);
51 #endif
52
53 //@cindex unblockOne
54 /* unblockOne()
55  *
56  * Takes a pointer to the beginning of a blocked TSO queue, and
57  * removes the first thread, placing it on the runnable queue.
58  *
59  * Called from STG : yes
60  * Locks assumed   : none
61  */
62 #if defined(GRAN) || defined(PAR)
63 StgBlockingQueueElement *unblockOne(StgBlockingQueueElement *bqe, StgClosure *node);
64 #else
65 StgTSO *unblockOne(StgTSO *tso);
66 #endif
67
68 //@cindex raiseAsync
69 /* raiseAsync()
70  *
71  * Raises an exception asynchronously in the specified thread.
72  *
73  * Called from STG :  yes
74  * Locks assumed   :  none
75  */
76 void raiseAsync(StgTSO *tso, StgClosure *exception);
77
78 //@cindex awaitEvent
79 /* awaitEvent()
80  *
81  * Raises an exception asynchronously in the specified thread.
82  *
83  * Called from STG :  NO
84  * Locks assumed   :  sched_mutex
85  */
86 void awaitEvent(rtsBool wait);  /* In Select.c */
87
88 /* wakeUpSleepingThreads(nat ticks)
89  *
90  * Wakes up any sleeping threads whose timers have expired.
91  *
92  * Called from STG :  NO
93  * Locks assumed   :  sched_mutex
94  */
95 rtsBool wakeUpSleepingThreads(nat);  /* In Select.c */
96
97 // ToDo: check whether all fcts below are used in the SMP version, too
98 //@cindex awaken_blocked_queue
99 #if defined(GRAN)
100 void    awaken_blocked_queue(StgBlockingQueueElement *q, StgClosure *node);
101 void    unlink_from_bq(StgTSO* tso, StgClosure* node);
102 void    initThread(StgTSO *tso, nat stack_size, StgInt pri);
103 #elif defined(PAR)
104 nat     run_queue_len(void);
105 void    awaken_blocked_queue(StgBlockingQueueElement *q, StgClosure *node);
106 void    initThread(StgTSO *tso, nat stack_size);
107 #else
108 char   *info_type(StgClosure *closure);    // dummy
109 char   *info_type_by_ip(StgInfoTable *ip); // dummy
110 void    awaken_blocked_queue(StgTSO *q);
111 void    initThread(StgTSO *tso, nat stack_size);
112 #endif
113
114 //@node Scheduler Vars and Data Types, Some convenient macros, Scheduler Functions
115 //@subsection Scheduler Vars and Data Types
116
117 //@cindex context_switch
118 /* Context switch flag.
119  * Locks required  : sched_mutex
120  */
121 extern nat context_switch;
122 extern rtsBool interrupted;
123
124 /* In Select.c */
125 extern nat timestamp;
126 extern nat ticks_since_timestamp;
127
128 //@cindex Capability
129 /* Capability type
130  */
131 typedef StgRegTable Capability;
132
133 /* Free capability list.
134  * Locks required: sched_mutex.
135  */
136 #ifdef SMP
137 extern Capability *free_capabilities;
138 extern nat n_free_capabilities;
139 #else
140 extern Capability MainRegTable;
141 #endif
142
143 /* Thread queues.
144  * Locks required  : sched_mutex
145  *
146  * In GranSim we have one run/blocked_queue per PE.
147  */
148 #if defined(GRAN)
149 // run_queue_hds defined in GranSim.h
150 #else
151 extern  StgTSO *run_queue_hd, *run_queue_tl;
152 extern  StgTSO *blocked_queue_hd, *blocked_queue_tl;
153 extern  StgTSO *sleeping_queue;
154 #endif
155 /* Linked list of all threads. */
156 extern  StgTSO *all_threads;
157
158 #ifdef SMP
159 //@cindex sched_mutex
160 //@cindex thread_ready_cond
161 //@cindex gc_pending_cond
162 extern pthread_mutex_t sched_mutex;
163 extern pthread_cond_t  thread_ready_cond;
164 extern pthread_cond_t  gc_pending_cond;
165 #endif
166
167 //@cindex task_info
168 #ifdef SMP
169 typedef struct {
170   pthread_t id;
171   double    elapsedtimestart;
172   double    mut_time;
173   double    mut_etime;
174   double    gc_time;
175   double    gc_etime;
176 } task_info;
177
178 extern task_info *task_ids;
179 #endif
180
181 /* Needed by Hugs.
182  */
183 void interruptStgRts ( void );
184
185 void raiseAsync(StgTSO *tso, StgClosure *exception);
186 nat  run_queue_len(void);
187
188 void resurrectThreads( StgTSO * );
189
190 //@node Some convenient macros, Index, Scheduler Vars and Data Types
191 //@subsection Some convenient macros
192
193 /* debugging only 
194  */
195 #ifdef DEBUG
196 void printThreadBlockage(StgTSO *tso);
197 void printThreadStatus(StgTSO *tso);
198 void printAllThreads(void);
199 #endif
200 void print_bq (StgClosure *node);
201
202 /* -----------------------------------------------------------------------------
203  * Some convenient macros...
204  */
205
206 /* this is the NIL ptr for a TSO queue (e.g. runnable queue) */
207 #define END_TSO_QUEUE  ((StgTSO *)(void*)&stg_END_TSO_QUEUE_closure)
208 /* this is the NIL ptr for a list CAFs */
209 #define END_ECAF_LIST   ((StgCAF *)(void*)&stg_END_TSO_QUEUE_closure)
210
211 //@cindex APPEND_TO_RUN_QUEUE
212 /* Add a thread to the end of the run queue.
213  * NOTE: tso->link should be END_TSO_QUEUE before calling this macro.
214  */
215 #define APPEND_TO_RUN_QUEUE(tso)                \
216     ASSERT(tso->link == END_TSO_QUEUE);         \
217     if (run_queue_hd == END_TSO_QUEUE) {        \
218       run_queue_hd = tso;                       \
219     } else {                                    \
220       run_queue_tl->link = tso;                 \
221     }                                           \
222     run_queue_tl = tso;
223
224 //@cindex PUSH_ON_RUN_QUEUE
225 /* Push a thread on the beginning of the run queue.  Used for
226  * newly awakened threads, so they get run as soon as possible.
227  */
228 #define PUSH_ON_RUN_QUEUE(tso)                  \
229     tso->link = run_queue_hd;                   \
230       run_queue_hd = tso;                       \
231     if (run_queue_tl == END_TSO_QUEUE) {        \
232       run_queue_tl = tso;                       \
233     }
234
235 //@cindex POP_RUN_QUEUE
236 /* Pop the first thread off the runnable queue.
237  */
238 #define POP_RUN_QUEUE()                         \
239   ({ StgTSO *t = run_queue_hd;                  \
240     if (t != END_TSO_QUEUE) {                   \
241       run_queue_hd = t->link;                   \
242       t->link = END_TSO_QUEUE;                  \
243       if (run_queue_hd == END_TSO_QUEUE) {      \
244         run_queue_tl = END_TSO_QUEUE;           \
245       }                                         \
246     }                                           \
247     t;                                          \
248   })
249
250 //@cindex APPEND_TO_BLOCKED_QUEUE
251 /* Add a thread to the end of the blocked queue.
252  */
253 #define APPEND_TO_BLOCKED_QUEUE(tso)            \
254     ASSERT(tso->link == END_TSO_QUEUE);         \
255     if (blocked_queue_hd == END_TSO_QUEUE) {    \
256       blocked_queue_hd = tso;                   \
257     } else {                                    \
258       blocked_queue_tl->link = tso;             \
259     }                                           \
260     blocked_queue_tl = tso;
261
262 //@cindex THREAD_RUNNABLE
263 /* Signal that a runnable thread has become available, in
264  * case there are any waiting tasks to execute it.
265  */
266 #ifdef SMP
267 #define THREAD_RUNNABLE()                       \
268   if (free_capabilities != NULL) {              \
269      pthread_cond_signal(&thread_ready_cond);   \
270   }                                             \
271   context_switch = 1;
272 #else
273 #define THREAD_RUNNABLE()  /* nothing */
274 #endif
275
276 //@node Index,  , Some convenient macros
277 //@subsection Index
278
279 //@index
280 //* APPEND_TO_BLOCKED_QUEUE::  @cindex\s-+APPEND_TO_BLOCKED_QUEUE
281 //* APPEND_TO_RUN_QUEUE::  @cindex\s-+APPEND_TO_RUN_QUEUE
282 //* Capability::  @cindex\s-+Capability
283 //* POP_RUN_QUEUE    ::  @cindex\s-+POP_RUN_QUEUE    
284 //* PUSH_ON_RUN_QUEUE::  @cindex\s-+PUSH_ON_RUN_QUEUE
285 //* THREAD_RUNNABLE::  @cindex\s-+THREAD_RUNNABLE
286 //* awaitEvent::  @cindex\s-+awaitEvent
287 //* awakenBlockedQueue::  @cindex\s-+awakenBlockedQueue
288 //* awaken_blocked_queue::  @cindex\s-+awaken_blocked_queue
289 //* context_switch::  @cindex\s-+context_switch
290 //* exitScheduler::  @cindex\s-+exitScheduler
291 //* gc_pending_cond::  @cindex\s-+gc_pending_cond
292 //* initScheduler::  @cindex\s-+initScheduler
293 //* raiseAsync::  @cindex\s-+raiseAsync
294 //* sched_mutex::  @cindex\s-+sched_mutex
295 //* startTasks::  @cindex\s-+startTasks
296 //* task_info::  @cindex\s-+task_info
297 //* thread_ready_cond::  @cindex\s-+thread_ready_cond
298 //* unblockOne::  @cindex\s-+unblockOne
299 //@end index