1
+ export Context, addprocs!, rmprocs!
2
+
1
3
"""
2
4
Context(xs::Vector{OSProc}) -> Context
3
5
Context(xs::Vector{Int}) -> Context
@@ -15,21 +17,18 @@ Special fields include:
15
17
mutable struct Context
16
18
procs:: Vector{Processor}
17
19
proc_lock:: ReentrantLock
18
- proc_notify:: Threads.Condition
19
20
log_sink:: Any
20
21
profile:: Bool
21
22
options
22
23
end
23
24
24
25
function Context (procs:: Vector{P} = Processor[OSProc (w) for w in procs ()];
25
- proc_lock= ReentrantLock (), proc_notify= Threads. Condition (),
26
- log_sink= TimespanLogging. NoOpLog (), log_file= nothing , profile= false ,
27
- options= nothing ) where {P<: Processor }
26
+ proc_lock= ReentrantLock (), log_sink= TimespanLogging. NoOpLog (),
27
+ log_file= nothing , profile= false , options= nothing ) where {P<: Processor }
28
28
if log_file != = nothing
29
29
@warn " `log_file` is no longer supported\n Please instead load `GraphViz.jl` and use `render_logs(logs, :graphviz)`."
30
30
end
31
- Context (procs, proc_lock, proc_notify, log_sink,
32
- profile, options)
31
+ Context (procs, proc_lock, log_sink, profile, options)
33
32
end
34
33
Context (xs:: Vector{Int} ; kwargs... ) = Context (map (OSProc, xs); kwargs... )
35
34
Context (ctx:: Context , xs:: Vector = copy (procs (ctx))) = # make a copy
@@ -62,41 +61,90 @@ procs(ctx::Context) = lock(ctx) do
62
61
end
63
62
64
63
"""
65
- addprocs!(ctx::Context, xs)
64
+ addprocs!(xs) -> Processor[]
66
65
67
- Add new workers `xs` to `ctx`.
66
+ Add new workers `xs` to the eager scheduler and returns the ones that were
67
+ actually added.
68
68
69
69
Workers will typically be assigned new tasks in the next scheduling iteration
70
70
if scheduling is ongoing.
71
71
72
72
Workers can be either `Processor`s or the underlying process IDs as `Integer`s.
73
73
"""
74
- addprocs! (ctx:: Context , xs:: AbstractVector{<:Integer} ) = addprocs! (ctx, map (OSProc, xs))
75
- function addprocs! (ctx:: Context , xs:: AbstractVector{<:OSProc} )
76
- lock (ctx) do
77
- append! (ctx. procs, xs)
74
+ addprocs! (xs:: AbstractVector{<:Integer} ) = addprocs! (map (OSProc, xs))
75
+ function addprocs! (xs:: AbstractVector{<:Processor} )
76
+ Sch. init_eager ()
77
+
78
+ ctx = Sch. eager_context ()
79
+ state = Sch. EAGER_STATE[]
80
+
81
+ to_add = setdiff (xs, procs (ctx))
82
+
83
+ timespan_start (ctx, :addprocs! , nothing , nothing )
84
+
85
+ # Initialize new procs
86
+ for p in to_add
87
+ Sch. init_proc (state, p, ctx. log_sink)
88
+
89
+ # Empty the processor cache list and force reschedule
90
+ lock (state. lock) do
91
+ state. procs_cache_list[] = nothing
92
+ end
93
+ put! (state. chan, Sch. RescheduleSignal ())
78
94
end
79
- lock (ctx. proc_notify) do
80
- notify (ctx. proc_notify)
95
+
96
+ lock (ctx) do
97
+ append! (ctx. procs, to_add)
81
98
end
99
+ timespan_finish (ctx, :addprocs! , nothing , nothing )
100
+
101
+ return to_add
82
102
end
83
103
84
104
"""
85
- rmprocs!(ctx::Context, xs)
105
+ rmprocs!(xs) -> Processor[]
86
106
87
- Remove the specified workers `xs` from `ctx`.
107
+ Remove the specified workers `xs` from the eager scheduler and returns the ones
108
+ that were actuall added.
88
109
89
110
Workers will typically finish all their assigned tasks if scheduling is ongoing
90
111
but will not be assigned new tasks after removal.
91
112
92
113
Workers can be either `Processor`s or the underlying process IDs as `Integer`s.
93
114
"""
94
- rmprocs! (ctx:: Context , xs:: AbstractVector{<:Integer} ) = rmprocs! (ctx, map (OSProc, xs))
95
- function rmprocs! (ctx:: Context , xs:: AbstractVector{<:OSProc} )
96
- lock (ctx) do
97
- filter! (p -> (p ∉ xs), ctx. procs)
115
+ rmprocs! (xs:: AbstractVector{<:Integer} ) = rmprocs! (map (OSProc, xs))
116
+ function rmprocs! (xs:: AbstractVector{<:Processor} )
117
+ Sch. init_eager ()
118
+
119
+ ctx = Sch. eager_context ()
120
+ state = Sch. EAGER_STATE[]
121
+
122
+ _rmprocs! (ctx, state, xs; allow_empty= false )
123
+ end
124
+
125
+ function _rmprocs! (ctx:: Context , state, xs; allow_empty= true )
126
+
127
+ if ! allow_empty && Set (procs (ctx)) == Set (xs)
128
+ throw (ArgumentError (" Refusing to remove all processors from the Dagger.Context, at least one must be present." ))
129
+ end
130
+
131
+ to_remove = intersect (xs, procs (ctx))
132
+
133
+ timespan_start (ctx, :rmprocs! , nothing , nothing )
134
+
135
+ for p in to_remove
136
+ Sch. cleanup_proc (state, p, ctx. log_sink)
137
+
138
+ # Empty the processor cache list
139
+ lock (state. lock) do
140
+ state. procs_cache_list[] = nothing
141
+ end
98
142
end
99
- lock (ctx. proc_notify) do
100
- notify (ctx. proc_notify)
143
+
144
+ lock (ctx) do
145
+ filter! (p -> (p ∉ to_remove), ctx. procs)
101
146
end
147
+ timespan_finish (ctx, :rmprocs! , nothing , nothing )
148
+
149
+ return to_remove
102
150
end
0 commit comments