1
1
module Internals
2
2
3
- import StableTasks: @spawn , @spawnat , StableTask
3
+ import StableTasks: @spawn , @spawnat , StableTask, AtomicRef
4
+
5
+ Base. getindex (r:: AtomicRef ) = @atomic r. x
6
+ Base. setindex! (r:: AtomicRef{T} , x) where {T} = @atomic r. x = convert (T, x)
4
7
5
8
function Base. fetch (t:: StableTask{T} ) where {T}
6
9
fetch (t. t)
@@ -25,32 +28,45 @@ Base.schedule(t::StableTask) = (schedule(t.t); t)
25
28
Base. schedule (t, val; error= false ) = (schedule (t. t, val; error); t)
26
29
27
30
28
- macro spawn (ex)
31
+ macro spawn (args... )
32
+ tp = QuoteNode (:default )
33
+ na = length (args)
34
+ if na == 2
35
+ ttype, ex = args
36
+ if ttype isa QuoteNode
37
+ ttype = ttype. value
38
+ if ttype != = :interactive && ttype != = :default
39
+ throw (ArgumentError (" unsupported threadpool in StableTasks.@spawn: $ttype " ))
40
+ end
41
+ tp = QuoteNode (ttype)
42
+ else
43
+ tp = ttype
44
+ end
45
+ elseif na == 1
46
+ ex = args[1 ]
47
+ else
48
+ throw (ArgumentError (" wrong number of arguments in @spawn" ))
49
+ end
29
50
letargs = _lift_one_interp! (ex)
30
51
31
52
thunk = replace_linenums! (:(() -> ($ (esc (ex)))), __source__)
32
53
var = esc (Base. sync_varname) # This is for the @sync macro which sets a local variable whose name is
33
54
# the symbol bound to Base.sync_varname
34
55
# I asked on slack and this is apparently safe to consider a public API
35
- set_pool = if VERSION < v " 1.9"
36
- nothing
37
- else
38
- :(Threads. _spawn_set_thrpool (task, :default ))
39
- end
40
56
quote
41
57
let $ (letargs... )
42
58
f = $ thunk
43
59
T = Core. Compiler. return_type (f, Tuple{})
44
- ref = Ref {T} ()
60
+ ref = AtomicRef {T} ()
45
61
f_wrap = () -> (ref[] = f (); nothing )
46
62
task = Task (f_wrap)
47
63
task. sticky = false
48
- $ set_pool
64
+ Threads . _spawn_set_thrpool (task, $ ( esc (tp)))
49
65
if $ (Expr (:islocal , var))
50
66
put! ($ var, task) # Sync will set up a Channel, and we want our task to be in there.
51
67
end
52
68
schedule (task)
53
- StableTask (task, ref)
69
+ StableTask {T} (task, ref)
54
70
end
55
71
end
56
72
end
@@ -75,7 +91,7 @@ macro spawnat(thrdid, ex)
75
91
let $ (letargs... )
76
92
thunk = $ thunk
77
93
RT = Core. Compiler. return_type (thunk, Tuple{})
78
- ret = Ref {RT} ()
94
+ ret = AtomicRef {RT} ()
79
95
thunk_wrap = () -> (ret[] = thunk (); nothing )
80
96
local task = Task (thunk_wrap)
81
97
task. sticky = true
0 commit comments