From b37f1aa6398065be806e6605a023189685669885 Mon Sep 17 00:00:00 2001 From: Boris Kolpackov Date: Wed, 15 Feb 2017 03:55:15 +0200 Subject: Implement parallel match --- build2/test/script/parser.cxx | 37 ++++++++++++++++++++----------------- build2/test/script/script.cxx | 10 +++++----- 2 files changed, 25 insertions(+), 22 deletions(-) (limited to 'build2/test/script') diff --git a/build2/test/script/parser.cxx b/build2/test/script/parser.cxx index 2ea42b5..4e6759f 100644 --- a/build2/test/script/parser.cxx +++ b/build2/test/script/parser.cxx @@ -6,8 +6,7 @@ #include -#include // keep_going -#include +#include // sched, keep_going #include #include @@ -2838,16 +2837,14 @@ namespace build2 { exec_lines (g->setup_.begin (), g->setup_.end (), li, false); - scheduler::atomic_count task_count (0); + atomic_count task_count (0); + wait_guard wg (task_count); // Start asynchronous execution of inner scopes keeping track of how // many we have handled. // - auto i (g->scopes.begin ()); - for (auto e (g->scopes.end ()); i != e; ++i) + for (unique_ptr& chain: g->scopes) { - unique_ptr& chain (*i); - // Check if this scope is ignored (e.g., via config.test). // if (!runner_->test (*chain)) @@ -2932,12 +2929,18 @@ namespace build2 // exec_scope_body (); // scope_ = os; + // Pass our diagnostics stack (this is safe since we are going + // to wait for completion before unwinding the diag stack). + // // If the scope was executed synchronously, check the status and // bail out if we weren't asked to keep going. // if (!sched.async (task_count, - [] (scope& s, script& scr, runner& r) + [] (scope& s, script& scr, runner& r, + const diag_frame* ds) { + diag_frame df (ds); + try { parser p; @@ -2951,24 +2954,24 @@ namespace build2 }, ref (*chain), ref (*script_), - ref (*runner_))) + ref (*runner_), + diag_frame::stack)) { + // Bail out if the scope has failed and we weren't instructed + // to keep going. + // if (chain->state == scope_state::failed && !keep_going) - { - ++i; - break; - } + throw failed (); } } } - sched.wait (task_count); + + wg.wait (); // Re-examine the scopes we have executed collecting their state. // - for (auto j (g->scopes.begin ()); j != i; ++j) + for (const unique_ptr& chain: g->scopes) { - const unique_ptr& chain (*j); - if (chain == nullptr) continue; diff --git a/build2/test/script/script.cxx b/build2/test/script/script.cxx index 0586377..c2b13ca 100644 --- a/build2/test/script/script.cxx +++ b/build2/test/script/script.cxx @@ -567,17 +567,17 @@ namespace build2 // if (t != nullptr) { - if (auto* p = t->is_a ()) + if (auto* pt = t->is_a ()) { // Do some sanity checks: the target better be up-to-date with // an assigned path. // - if (p->path ().empty ()) - fail << "target " << *p << " specified in the test variable " + v = pt->path (); + + if (v.empty ()) + fail << "target " << *pt << " specified in the test variable " << "is out of date" << info << "consider specifying it as a prerequisite of " << tt; - - v = p->path (); } else if (t->is_a ()) v = path (t->dir); -- cgit v1.1