[project @ 1999-11-09 15:46:49 by simonmar]
[ghc-hetmet.git] / ghc / rts / Schedule.h
1 /* -----------------------------------------------------------------------------
2  * $Id: Schedule.h,v 1.10 1999/11/09 15:46:55 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
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 /* -----------------------------------------------------------------------------
111  * Some convenient macros...
112  */
113
114 #define END_TSO_QUEUE  ((StgTSO *)(void*)&END_TSO_QUEUE_closure)
115 #define END_CAF_LIST   ((StgCAF *)(void*)&END_TSO_QUEUE_closure)
116
117 /* Add a thread to the end of the run queue.
118  * NOTE: tso->link should be END_TSO_QUEUE before calling this macro.
119  */
120 #define APPEND_TO_RUN_QUEUE(tso)                \
121     ASSERT(tso->link == END_TSO_QUEUE);         \
122     if (run_queue_hd == END_TSO_QUEUE) {        \
123       run_queue_hd = tso;                       \
124     } else {                                    \
125       run_queue_tl->link = tso;                 \
126     }                                           \
127     run_queue_tl = tso;
128
129 /* Push a thread on the beginning of the run queue.  Used for
130  * newly awakened threads, so they get run as soon as possible.
131  */
132 #define PUSH_ON_RUN_QUEUE(tso)                  \
133     tso->link = run_queue_hd;                   \
134       run_queue_hd = tso;                       \
135     if (run_queue_tl == END_TSO_QUEUE) {        \
136       run_queue_tl = tso;                       \
137     }
138     
139 /* Pop the first thread off the runnable queue.
140  */
141 #define POP_RUN_QUEUE()                         \
142   ({ StgTSO *t = run_queue_hd;                  \
143     if (t != END_TSO_QUEUE) {                   \
144       run_queue_hd = t->link;                   \
145       t->link = END_TSO_QUEUE;                  \
146       if (run_queue_hd == END_TSO_QUEUE) {      \
147         run_queue_tl = END_TSO_QUEUE;           \
148       }                                         \
149     }                                           \
150     t;                                          \
151   })
152
153 /* Add a thread to the end of the blocked queue.
154  */
155 #define APPEND_TO_BLOCKED_QUEUE(tso)            \
156     ASSERT(tso->link == END_TSO_QUEUE);         \
157     if (blocked_queue_hd == END_TSO_QUEUE) {    \
158       blocked_queue_hd = tso;                   \
159     } else {                                    \
160       blocked_queue_tl->link = tso;             \
161     }                                           \
162     blocked_queue_tl = tso;
163
164 /* Signal that a runnable thread has become available, in
165  * case there are any waiting tasks to execute it.
166  */
167 #ifdef SMP
168 #define THREAD_RUNNABLE()                       \
169   if (free_capabilities != NULL) {              \
170      pthread_cond_signal(&thread_ready_cond);   \
171   }                                             \
172   context_switch = 1;
173 #else
174 #define THREAD_RUNNABLE()  /* nothing */
175 #endif
176