Schedule.h 4.22 KB
Newer Older
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
7
8
9
10
 *
 * Prototypes for functions in Schedule.c 
 * (RTS internal scheduler interface)
 *
 * ---------------------------------------------------------------------------*/

11
12
13
14
/* initScheduler(), exitScheduler(), startTasks()
 * 
 * Called from STG :  no
 * Locks assumed   :  none
15
 */
16
17
18
19
20
void initScheduler( void );
void exitScheduler( void );
#ifdef SMP
void startTasks( void );
#endif
21

22
23
24
25
26
27
28
/* awakenBlockedQueue()
 *
 * Takes a pointer to the beginning of a blocked TSO queue, and
 * wakes up the entire queue.
 *
 * Called from STG :  yes
 * Locks assumed   :  none
29
 */
30
void awakenBlockedQueue(StgTSO *tso);
31

32
33
34
35
36
37
38
39
/* unblockOne()
 *
 * Takes a pointer to the beginning of a blocked TSO queue, and
 * removes the first thread, placing it on the runnable queue.
 *
 * Called from STG : yes
 * Locks assumed   : none
 */
40
StgTSO *unblockOne(StgTSO *tso);
41

42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
/* raiseAsync()
 *
 * Raises an exception asynchronously in the specified thread.
 *
 * Called from STG :  yes
 * Locks assumed   :  none
 */
void raiseAsync(StgTSO *tso, StgClosure *exception);

/* awaitEvent()
 *
 * Raises an exception asynchronously in the specified thread.
 *
 * Called from STG :  NO
 * Locks assumed   :  sched_mutex
 */
void awaitEvent(rtsBool wait);  /* In Select.c */

/* Context switch flag.
 * Locks required  : sched_mutex
 */
extern nat context_switch;

extern  nat ticks_since_select;
66

67
68
69
70
71
72
73
74
75
76
77
78
79
/* Capability type
 */
typedef StgRegTable Capability;

/* Free capability list.
 * Locks required: sched_mutex.
 */
#ifdef SMP
extern Capability *free_capabilities;
extern nat n_free_capabilities;
#else
extern Capability MainRegTable;
#endif
80

81
82
83
/* Thread queues.
 * Locks required  : sched_mutex
 */
84
85
86
extern  StgTSO *run_queue_hd, *run_queue_tl;
extern  StgTSO *blocked_queue_hd, *blocked_queue_tl;

87
88
89
90
#ifdef DEBUG
extern void printThreadBlockage(StgTSO *tso);
#endif

91
92
93
94
95
96
97
98
99
#ifdef SMP
extern pthread_mutex_t sched_mutex;
extern pthread_cond_t  thread_ready_cond;
extern pthread_cond_t  gc_pending_cond;
#endif

#ifdef SMP
typedef struct {
  pthread_t id;
100
  double    elapsedtimestart;
101
  double    mut_time;
102
  double    mut_etime;
103
104
105
106
107
  double    gc_time;
  double    gc_etime;
} task_info;

extern task_info *task_ids;
sof's avatar
sof committed
108
#endif
109

110
111
112
113
/* Needed by Hugs.
 */
void interruptStgRts ( void );

114
115
116
117
/* -----------------------------------------------------------------------------
 * Some convenient macros...
 */

118
#define END_TSO_QUEUE  ((StgTSO *)(void*)&END_TSO_QUEUE_closure)
119
#define END_CAF_LIST   ((StgCAF *)(void*)&END_TSO_QUEUE_closure)
120

121
122
123
/* Add a thread to the end of the run queue.
 * NOTE: tso->link should be END_TSO_QUEUE before calling this macro.
 */
124
#define APPEND_TO_RUN_QUEUE(tso)		\
125
126
    ASSERT(tso->link == END_TSO_QUEUE);		\
    if (run_queue_hd == END_TSO_QUEUE) {	\
127
128
129
130
131
132
      run_queue_hd = tso;			\
    } else {					\
      run_queue_tl->link = tso;			\
    }						\
    run_queue_tl = tso;

133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
/* Push a thread on the beginning of the run queue.  Used for
 * newly awakened threads, so they get run as soon as possible.
 */
#define PUSH_ON_RUN_QUEUE(tso)			\
    tso->link = run_queue_hd;			\
      run_queue_hd = tso;			\
    if (run_queue_tl == END_TSO_QUEUE) {	\
      run_queue_tl = tso;			\
    }
    
/* Pop the first thread off the runnable queue.
 */
#define POP_RUN_QUEUE()				\
  ({ StgTSO *t = run_queue_hd;			\
    if (t != END_TSO_QUEUE) {			\
      run_queue_hd = t->link;			\
      t->link = END_TSO_QUEUE;			\
      if (run_queue_hd == END_TSO_QUEUE) {	\
        run_queue_tl = END_TSO_QUEUE;		\
      }						\
    }						\
    t;						\
  })

/* Add a thread to the end of the blocked queue.
 */
#define APPEND_TO_BLOCKED_QUEUE(tso)		\
160
    ASSERT(tso->link == END_TSO_QUEUE);		\
161
162
163
164
165
166
167
    if (blocked_queue_hd == END_TSO_QUEUE) {    \
      blocked_queue_hd = tso;			\
    } else {					\
      blocked_queue_tl->link = tso;		\
    }						\
    blocked_queue_tl = tso;

168
169
170
171
172
173
174
175
176
177
178
179
180
/* Signal that a runnable thread has become available, in
 * case there are any waiting tasks to execute it.
 */
#ifdef SMP
#define THREAD_RUNNABLE()			\
  if (free_capabilities != NULL) {		\
     pthread_cond_signal(&thread_ready_cond);	\
  }						\
  context_switch = 1;
#else
#define THREAD_RUNNABLE()  /* nothing */
#endif