forked from JuliaLang/julia
-
Notifications
You must be signed in to change notification settings - Fork 0
/
task.jl
66 lines (58 loc) · 1.26 KB
/
task.jl
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
63
64
65
66
show(io, t::Task) = print(io, "Task")
current_task() = ccall(:jl_get_current_task, Task, ())
istaskdone(t::Task) = t.done
# task-local storage
function tls()
t = current_task()
if is(t.tls, nothing)
t.tls = ObjectIdDict()
end
(t.tls)::ObjectIdDict
end
function tls(key)
tls()[key]
end
function tls(key, val)
tls()[key] = val
end
function produce(v)
ct = current_task()
q = ct.consumers
if !is(q,nothing)
Q = q::Array{Any,1}
if !isempty(Q)
# make a task waiting for us runnable again
enq_work(pop(Q))
end
end
yieldto(ct.last, v)
ct.parent = ct.last # always exit to last consumer
nothing
end
function consume(P::Task)
while !(P.runnable || P.done)
yield(WaitFor(:consume, P))
end
ct = current_task()
prev = ct.last
ct.runnable = false
v = yieldto(P)
ct.last = prev
ct.runnable = true
if P.done
q = P.consumers
if !is(q, nothing)
Q = q::Array{Any,1}
while !isempty(Q)
enq_work(pop(Q))
end
end
end
v
end
start(t::Task) = consume(t)
done(t::Task, val) = istaskdone(t)
next(t::Task, val) = (val, consume(t))
macro task(ex)
:(Task(()->$(esc(ex))))
end