f56b9d9a0c62bfdb4633a86362b29993de76e83b
[ghc-hetmet.git] / ghc / rts / Schedule.h
1 /* -----------------------------------------------------------------------------
2  * $Id: Schedule.h,v 1.11 1999/11/11 17:24:49 sewardj 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
65 extern  nat ticks_since_select;
66
67 /* Capability type
68  */
69 typedef StgRegTable Capability;
70
71 /* Free capability list.
72  * Locks required: sched_mutex.
73  */
74 #ifdef SMP
75 extern Capability *free_capabilities;
76 extern nat n_free_capabilities;
77 #else
78 extern Capability MainRegTable;
79 #endif
80
81 /* Thread queues.
82  * Locks required  : sched_mutex
83  */
84 extern  StgTSO *run_queue_hd, *run_queue_tl;
85 extern  StgTSO *blocked_queue_hd, *blocked_queue_tl;
86
87 #ifdef DEBUG
88 extern void printThreadBlockage(StgTSO *tso);
89 #endif
90
91 #ifdef SMP
92 extern pthread_mutex_t sched_mutex;
93 extern pthread_cond_t  thread_ready_cond;
94 extern pthread_cond_t  gc_pending_cond;
95 #endif
96
97 #ifdef SMP
98 typedef struct {
99   pthread_t id;
100   double    elapsedtimestart;
101   double    mut_time;
102   double    mut_etime;
103   double    gc_time;
104   double    gc_etime;
105 } task_info;
106
107 extern task_info *task_ids;
108 #endif
109
110 /* Needed by Hugs.
111  */
112 void interruptStgRts ( void );
113
114 /* -----------------------------------------------------------------------------
115  * Some convenient macros...
116  */
117
118 #define END_TSO_QUEUE  ((StgTSO *)(void*)&END_TSO_QUEUE_closure)
119 #define END_CAF_LIST   ((StgCAF *)(void*)&END_TSO_QUEUE_closure)
120
121 /* Add a thread to the end of the run queue.
122  * NOTE: tso->link should be END_TSO_QUEUE before calling this macro.
123  */
124 #define APPEND_TO_RUN_QUEUE(tso)                \
125     ASSERT(tso->link == END_TSO_QUEUE);         \
126     if (run_queue_hd == END_TSO_QUEUE) {        \
127       run_queue_hd = tso;                       \
128     } else {                                    \
129       run_queue_tl->link = tso;                 \
130     }                                           \
131     run_queue_tl = tso;
132
133 /* Push a thread on the beginning of the run queue.  Used for
134  * newly awakened threads, so they get run as soon as possible.
135  */
136 #define PUSH_ON_RUN_QUEUE(tso)                  \
137     tso->link = run_queue_hd;                   \
138       run_queue_hd = tso;                       \
139     if (run_queue_tl == END_TSO_QUEUE) {        \
140       run_queue_tl = tso;                       \
141     }
142     
143 /* Pop the first thread off the runnable queue.
144  */
145 #define POP_RUN_QUEUE()                         \
146   ({ StgTSO *t = run_queue_hd;                  \
147     if (t != END_TSO_QUEUE) {                   \
148       run_queue_hd = t->link;                   \
149       t->link = END_TSO_QUEUE;                  \
150       if (run_queue_hd == END_TSO_QUEUE) {      \
151         run_queue_tl = END_TSO_QUEUE;           \
152       }                                         \
153     }                                           \
154     t;                                          \
155   })
156
157 /* Add a thread to the end of the blocked queue.
158  */
159 #define APPEND_TO_BLOCKED_QUEUE(tso)            \
160     ASSERT(tso->link == END_TSO_QUEUE);         \
161     if (blocked_queue_hd == END_TSO_QUEUE) {    \
162       blocked_queue_hd = tso;                   \
163     } else {                                    \
164       blocked_queue_tl->link = tso;             \
165     }                                           \
166     blocked_queue_tl = tso;
167
168 /* Signal that a runnable thread has become available, in
169  * case there are any waiting tasks to execute it.
170  */
171 #ifdef SMP
172 #define THREAD_RUNNABLE()                       \
173   if (free_capabilities != NULL) {              \
174      pthread_cond_signal(&thread_ready_cond);   \
175   }                                             \
176   context_switch = 1;
177 #else
178 #define THREAD_RUNNABLE()  /* nothing */
179 #endif
180