[project @ 2000-01-12 15:15:17 by simonmar]
[ghc-hetmet.git] / ghc / rts / Schedule.h
1 /* -----------------------------------------------------------------------------
2  * $Id: Schedule.h,v 1.12 2000/01/12 15:15:18 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 /* initScheduler(), exitScheduler(), startTasks()
12  * 
13  * Called from STG :  no
14  * Locks assumed   :  none
15  */
16 void initScheduler( void );
17 void exitScheduler( void );
18 #ifdef SMP
19 void startTasks( void );
20 #endif
21
22 /* awakenBlockedQueue()
23  *
24  * Takes a pointer to the beginning of a blocked TSO queue, and
25  * wakes up the entire queue.
26  *
27  * Called from STG :  yes
28  * Locks assumed   :  none
29  */
30 void awakenBlockedQueue(StgTSO *tso);
31
32 /* unblockOne()
33  *
34  * Takes a pointer to the beginning of a blocked TSO queue, and
35  * removes the first thread, placing it on the runnable queue.
36  *
37  * Called from STG : yes
38  * Locks assumed   : none
39  */
40 StgTSO *unblockOne(StgTSO *tso);
41
42 /* raiseAsync()
43  *
44  * Raises an exception asynchronously in the specified thread.
45  *
46  * Called from STG :  yes
47  * Locks assumed   :  none
48  */
49 void raiseAsync(StgTSO *tso, StgClosure *exception);
50
51 /* awaitEvent()
52  *
53  * Raises an exception asynchronously in the specified thread.
54  *
55  * Called from STG :  NO
56  * Locks assumed   :  sched_mutex
57  */
58 void awaitEvent(rtsBool wait);  /* In Select.c */
59
60 /* Context switch flag.
61  * Locks required  : sched_mutex
62  */
63 extern nat context_switch;
64 extern rtsBool interrupted;
65
66 extern  nat ticks_since_select;
67
68 /* Capability type
69  */
70 typedef StgRegTable Capability;
71
72 /* Free capability list.
73  * Locks required: sched_mutex.
74  */
75 #ifdef SMP
76 extern Capability *free_capabilities;
77 extern nat n_free_capabilities;
78 #else
79 extern Capability MainRegTable;
80 #endif
81
82 /* Thread queues.
83  * Locks required  : sched_mutex
84  */
85 extern  StgTSO *run_queue_hd, *run_queue_tl;
86 extern  StgTSO *blocked_queue_hd, *blocked_queue_tl;
87
88 #ifdef DEBUG
89 extern void printThreadBlockage(StgTSO *tso);
90 #endif
91
92 #ifdef SMP
93 extern pthread_mutex_t sched_mutex;
94 extern pthread_cond_t  thread_ready_cond;
95 extern pthread_cond_t  gc_pending_cond;
96 #endif
97
98 #ifdef SMP
99 typedef struct {
100   pthread_t id;
101   double    elapsedtimestart;
102   double    mut_time;
103   double    mut_etime;
104   double    gc_time;
105   double    gc_etime;
106 } task_info;
107
108 extern task_info *task_ids;
109 #endif
110
111 /* Needed by Hugs.
112  */
113 void interruptStgRts ( void );
114
115 /* -----------------------------------------------------------------------------
116  * Some convenient macros...
117  */
118
119 #define END_TSO_QUEUE  ((StgTSO *)(void*)&END_TSO_QUEUE_closure)
120 #define END_CAF_LIST   ((StgCAF *)(void*)&END_TSO_QUEUE_closure)
121
122 /* Add a thread to the end of the run queue.
123  * NOTE: tso->link should be END_TSO_QUEUE before calling this macro.
124  */
125 #define APPEND_TO_RUN_QUEUE(tso)                \
126     ASSERT(tso->link == END_TSO_QUEUE);         \
127     if (run_queue_hd == END_TSO_QUEUE) {        \
128       run_queue_hd = tso;                       \
129     } else {                                    \
130       run_queue_tl->link = tso;                 \
131     }                                           \
132     run_queue_tl = tso;
133
134 /* Push a thread on the beginning of the run queue.  Used for
135  * newly awakened threads, so they get run as soon as possible.
136  */
137 #define PUSH_ON_RUN_QUEUE(tso)                  \
138     tso->link = run_queue_hd;                   \
139       run_queue_hd = tso;                       \
140     if (run_queue_tl == END_TSO_QUEUE) {        \
141       run_queue_tl = tso;                       \
142     }
143     
144 /* Pop the first thread off the runnable queue.
145  */
146 #define POP_RUN_QUEUE()                         \
147   ({ StgTSO *t = run_queue_hd;                  \
148     if (t != END_TSO_QUEUE) {                   \
149       run_queue_hd = t->link;                   \
150       t->link = END_TSO_QUEUE;                  \
151       if (run_queue_hd == END_TSO_QUEUE) {      \
152         run_queue_tl = END_TSO_QUEUE;           \
153       }                                         \
154     }                                           \
155     t;                                          \
156   })
157
158 /* Add a thread to the end of the blocked queue.
159  */
160 #define APPEND_TO_BLOCKED_QUEUE(tso)            \
161     ASSERT(tso->link == END_TSO_QUEUE);         \
162     if (blocked_queue_hd == END_TSO_QUEUE) {    \
163       blocked_queue_hd = tso;                   \
164     } else {                                    \
165       blocked_queue_tl->link = tso;             \
166     }                                           \
167     blocked_queue_tl = tso;
168
169 /* Signal that a runnable thread has become available, in
170  * case there are any waiting tasks to execute it.
171  */
172 #ifdef SMP
173 #define THREAD_RUNNABLE()                       \
174   if (free_capabilities != NULL) {              \
175      pthread_cond_signal(&thread_ready_cond);   \
176   }                                             \
177   context_switch = 1;
178 #else
179 #define THREAD_RUNNABLE()  /* nothing */
180 #endif
181