blob: e6a551d7ae2e6b7ecae9a45f9601cd8619ab1969 (
plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
|
/*
* Wait/check for external events. Periodically, the
* Scheduler checks for the completion of external operations,
* like the expiration of timers, completion of I/O requests
* issued by Haskell threads.
*
* If the Scheduler is otherwise out of work, it'll block
* herein waiting for external events to occur.
*
* This file mirrors the select()-based functionality
* for POSIX / Unix platforms in rts/Select.c, but for
* Win32.
*
*/
#include "Rts.h"
#include "Schedule.h"
#include <windows.h>
#include "win32/AsyncIO.h"
void
awaitEvent(rtsBool wait)
{
RELEASE_LOCK(&sched_mutex);
do {
/* Try to de-queue completed IO requests */
if (!awaitRequests(wait)) {
return;
}
ACQUIRE_LOCK(&sched_mutex);
/* we were interrupted, return to the scheduler immediately.
*/
if (interrupted) {
return; /* still hold the lock */
}
/* If new runnable threads have arrived, stop waiting for
* I/O and run them.
*/
if (run_queue_hd != END_TSO_QUEUE) {
return; /* still hold the lock */
}
#ifdef RTS_SUPPORTS_THREADS
/* If another worker thread wants to take over,
* return to the scheduler
*/
if (needToYieldToReturningWorker()) {
return; /* still hold the lock */
}
#endif
RELEASE_LOCK(&sched_mutex);
} while (wait && !interrupted && run_queue_hd == END_TSO_QUEUE);
}
#ifdef RTS_SUPPORTS_THREADS
void
wakeBlockedWorkerThread()
{
abandonRequestWait();
}
#endif
|