add barriers - close #53
This commit is contained in:
parent
008fa4844d
commit
9bf4b8fa96
24
build_tests/simple/barrier.rb
Normal file
24
build_tests/simple/barrier.rb
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
class ThreadedTestBuilder < Rscons::Builder
|
||||||
|
def run(options)
|
||||||
|
if @command
|
||||||
|
puts "#{@target} finished"
|
||||||
|
true
|
||||||
|
else
|
||||||
|
@command = ["ruby", "-e", %[sleep #{@vars["delay"]}]]
|
||||||
|
register_command("ThreadedTestBuilder #{@target}", @command)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
build do
|
||||||
|
Environment.new do |env|
|
||||||
|
env.add_builder(ThreadedTestBuilder)
|
||||||
|
env.ThreadedTestBuilder("T3", [], "delay" => 3)
|
||||||
|
env.ThreadedTestBuilder("T2", [], "delay" => 1.0)
|
||||||
|
env.ThreadedTestBuilder("T1", [], "delay" => 0.5)
|
||||||
|
env.barrier
|
||||||
|
env.ThreadedTestBuilder("T6", [], "delay" => 1.5)
|
||||||
|
env.ThreadedTestBuilder("T5", [], "delay" => 1.0)
|
||||||
|
env.ThreadedTestBuilder("T4", [], "delay" => 0.5)
|
||||||
|
end
|
||||||
|
end
|
@ -70,7 +70,7 @@ module Rscons
|
|||||||
@threads = {}
|
@threads = {}
|
||||||
@registered_build_dependencies = {}
|
@registered_build_dependencies = {}
|
||||||
@side_effects = {}
|
@side_effects = {}
|
||||||
@builder_set = BuilderSet.new(@registered_build_dependencies, @side_effects)
|
@builder_sets = []
|
||||||
@build_targets = {}
|
@build_targets = {}
|
||||||
@user_deps = {}
|
@user_deps = {}
|
||||||
# Hash of builder name (String) => builder class (Class).
|
# Hash of builder name (String) => builder class (Class).
|
||||||
@ -265,12 +265,16 @@ module Rscons
|
|||||||
@process_builder_waits = {}
|
@process_builder_waits = {}
|
||||||
@process_builders_to_run = []
|
@process_builders_to_run = []
|
||||||
begin
|
begin
|
||||||
while @builder_set.size > 0 or @threads.size > 0 or @process_commands_waiting_to_run.size > 0
|
while @builder_sets.size > 0 or @threads.size > 0 or @process_commands_waiting_to_run.size > 0
|
||||||
process_step
|
process_step
|
||||||
|
if @builder_sets.size > 0 and @builder_sets.first.empty? and @threads.empty? and @process_commands_waiting_to_run.empty? and @process_builders_to_run.empty?
|
||||||
|
# Remove empty BuilderSet when all other operations have completed.
|
||||||
|
@builder_sets.slice!(0)
|
||||||
|
end
|
||||||
unless @process_failures.empty?
|
unless @process_failures.empty?
|
||||||
# On a build failure, do not start any more builders or commands,
|
# On a build failure, do not start any more builders or commands,
|
||||||
# but let the threads that have already been started complete.
|
# but let the threads that have already been started complete.
|
||||||
@builder_set.clear
|
@builder_sets.clear
|
||||||
@process_commands_waiting_to_run.clear
|
@process_commands_waiting_to_run.clear
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
@ -290,7 +294,7 @@ module Rscons
|
|||||||
#
|
#
|
||||||
# @return [void]
|
# @return [void]
|
||||||
def clear_targets
|
def clear_targets
|
||||||
@builder_set.clear
|
@builder_sets.clear
|
||||||
end
|
end
|
||||||
|
|
||||||
# Define a build target.
|
# Define a build target.
|
||||||
@ -319,7 +323,10 @@ module Rscons
|
|||||||
cache: Cache.instance,
|
cache: Cache.instance,
|
||||||
env: self,
|
env: self,
|
||||||
vars: vars)
|
vars: vars)
|
||||||
@builder_set << builder
|
if @builder_sets.empty?
|
||||||
|
@builder_sets << build_builder_set
|
||||||
|
end
|
||||||
|
@builder_sets.last << builder
|
||||||
@build_targets[target] = builder
|
@build_targets[target] = builder
|
||||||
builder
|
builder
|
||||||
else
|
else
|
||||||
@ -528,8 +535,26 @@ module Rscons
|
|||||||
@build_targets[target]
|
@build_targets[target]
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# Mark a "barrier" point.
|
||||||
|
#
|
||||||
|
# Rscons will wait for all build targets registered before the barrier to
|
||||||
|
# be built before beginning to build any build targets registered after
|
||||||
|
# the barrier. In other words, Rscons will not parallelize build operations
|
||||||
|
# across a barrier.
|
||||||
|
def barrier
|
||||||
|
@builder_sets << build_builder_set
|
||||||
|
end
|
||||||
|
|
||||||
private
|
private
|
||||||
|
|
||||||
|
# Build a BuilderSet.
|
||||||
|
#
|
||||||
|
# @return [BuilderSet]
|
||||||
|
# New {BuilderSet} object.
|
||||||
|
def build_builder_set
|
||||||
|
BuilderSet.new(@registered_build_dependencies, @side_effects)
|
||||||
|
end
|
||||||
|
|
||||||
# Run a builder and process its return value.
|
# Run a builder and process its return value.
|
||||||
#
|
#
|
||||||
# @param builder [Builder]
|
# @param builder [Builder]
|
||||||
@ -639,7 +664,9 @@ module Rscons
|
|||||||
targets_still_building = @threads.reduce([]) do |result, (thread, obj)|
|
targets_still_building = @threads.reduce([]) do |result, (thread, obj)|
|
||||||
result << builder_for_thread(thread).target
|
result << builder_for_thread(thread).target
|
||||||
end
|
end
|
||||||
builder = @builder_set.get_next_builder_to_run(targets_still_building)
|
if @builder_sets.size > 0
|
||||||
|
builder = @builder_sets[0].get_next_builder_to_run(targets_still_building)
|
||||||
|
end
|
||||||
|
|
||||||
if builder
|
if builder
|
||||||
builder.vars = @varset.merge(builder.vars)
|
builder.vars = @varset.merge(builder.vars)
|
||||||
|
@ -265,6 +265,27 @@ EOF
|
|||||||
]
|
]
|
||||||
end
|
end
|
||||||
|
|
||||||
|
it "supports barriers and prevents parallelizing builders across them" do
|
||||||
|
test_dir "simple"
|
||||||
|
result = run_rscons(rsconscript: "barrier.rb", rscons_args: %w[-j 3])
|
||||||
|
expect(result.stderr).to eq ""
|
||||||
|
slines = lines(result.stdout).select {|line| line =~ /T\d/}
|
||||||
|
expect(slines).to eq [
|
||||||
|
"ThreadedTestBuilder T3",
|
||||||
|
"ThreadedTestBuilder T2",
|
||||||
|
"ThreadedTestBuilder T1",
|
||||||
|
"T1 finished",
|
||||||
|
"T2 finished",
|
||||||
|
"T3 finished",
|
||||||
|
"ThreadedTestBuilder T6",
|
||||||
|
"ThreadedTestBuilder T5",
|
||||||
|
"ThreadedTestBuilder T4",
|
||||||
|
"T4 finished",
|
||||||
|
"T5 finished",
|
||||||
|
"T6 finished",
|
||||||
|
]
|
||||||
|
end
|
||||||
|
|
||||||
it "expands target and source paths starting with ^/ to be relative to the build root" do
|
it "expands target and source paths starting with ^/ to be relative to the build root" do
|
||||||
test_dir("typical")
|
test_dir("typical")
|
||||||
result = run_rscons(rsconscript: "carat.rb")
|
result = run_rscons(rsconscript: "carat.rb")
|
||||||
|
Loading…
x
Reference in New Issue
Block a user