3 |
* "futures", but much less powerful). |
* "futures", but much less powerful). |
4 |
* - uses no preemption |
* - uses no preemption |
5 |
* - thread gives up control by waiting on a condition |
* - thread gives up control by waiting on a condition |
6 |
* - conditions can signal thread termination and available input on some |
* - conditions can signal thread termination, available input on some |
7 |
* text stream |
* text stream, or on some explicitly signalled "unit" condition |
8 |
* - gives total priority to "local" computations |
* - gives total priority to "local" computations |
9 |
* (meaning that all threads must get stuck before I/O is even checked) |
* (meaning that all threads must get stuck before I/O is even checked) |
10 |
* (This is just here to utilize some external concurrency, i.e., OS |
* (This is just here to utilize some external concurrency, i.e., OS |
65 |
val dl = map #2 il |
val dl = map #2 il |
66 |
(* since nothing else is there to do we can afford to wait *) |
(* since nothing else is there to do we can afford to wait *) |
67 |
val pil = OS.IO.poll (dl, NONE) |
val pil = OS.IO.poll (dl, NONE) |
68 |
fun wakeup_ready (pi, (c, pd), il') = |
fun isReady (_, pd) = let |
69 |
if OS.IO.isIn pi then (wakeup (c, ()); il') |
val pd_iod = OS.IO.pollToIODesc pd |
70 |
else (c, pd) :: il' |
fun sameIod pi = |
71 |
val il' = ListPair.foldl wakeup_ready [] (pil, il) |
OS.IO.compare (pd_iod, |
72 |
|
OS.IO.pollToIODesc |
73 |
|
(OS.IO.infoToPollDesc pi)) = EQUAL |
74 |
in |
in |
75 |
inputs := il'; |
List.exists sameIod pil |
76 |
|
end |
77 |
|
val (ready, notready) = List.partition isReady il |
78 |
|
in |
79 |
|
inputs := notready; |
80 |
|
app (fn (c, _) => wakeup (c, ())) ready; |
81 |
(* try to schedule again; if this fails it's bad *) |
(* try to schedule again; if this fails it's bad *) |
82 |
case dequeue runable of |
case dequeue runable of |
83 |
NONE => |
NONE => |