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/cli/rule | 4 +-- build2/cli/rule.cxx | 93 +++++++++++++++++++++------------------------------ build2/cli/target | 17 +++++----- build2/cli/target.cxx | 18 ++-------- 4 files changed, 51 insertions(+), 81 deletions(-) (limited to 'build2/cli') diff --git a/build2/cli/rule b/build2/cli/rule index 03fd471..d783c20 100644 --- a/build2/cli/rule +++ b/build2/cli/rule @@ -22,10 +22,10 @@ namespace build2 compile () {} virtual match_result - match (slock&, action, target&, const string& hint) const override; + match (action, target&, const string&) const override; virtual recipe - apply (slock&, action, target&) const override; + apply (action, target&) const override; static target_state perform_update (action, const target&); diff --git a/build2/cli/rule.cxx b/build2/cli/rule.cxx index ba4963e..96eafbc 100644 --- a/build2/cli/rule.cxx +++ b/build2/cli/rule.cxx @@ -44,7 +44,7 @@ namespace build2 } match_result compile:: - match (slock& ml, action a, target& xt, const string&) const + match (action a, target& xt, const string&) const { tracer trace ("cli::compile::match"); @@ -57,7 +57,7 @@ namespace build2 // See if we have a .cli source file. // bool r (false); - for (prerequisite_member p: group_prerequisite_members (ml, a, t)) + for (prerequisite_member p: group_prerequisite_members (a, t)) { if (p.is_a ()) { @@ -81,25 +81,16 @@ namespace build2 return r; } - // If we still haven't figured out the member list, we can do - // that now. Specifically, at this stage, no further changes to - // cli.options are possible and we can determine whether the - // --suppress-inline option is present. + // Figure out the member list. // - if (t.h == nullptr) - { - t.h = &search (t.dir, t.out, t.name, nullptr, nullptr); - t.h->group = &t; - - t.c = &search (t.dir, t.out, t.name, nullptr, nullptr); - t.c->group = &t; - - if (!find_option ("--suppress-inline", t, "cli.options")) - { - t.i = &search (t.dir, t.out, t.name, nullptr, nullptr); - t.i->group = &t; - } - } + // At this stage, no further changes to cli.options are possible and + // we can determine whether the --suppress-inline option is present. + // + t.h = &search (t.dir, t.out, t.name); + t.c = &search (t.dir, t.out, t.name); + t.i = find_option ("--suppress-inline", t, "cli.options") + ? nullptr + : &search (t.dir, t.out, t.name); return r; } @@ -109,23 +100,17 @@ namespace build2 // target& t (xt); - // First see if we are already linked-up to the cli.cxx{} group. If - // it is some other group, then we are definitely not a match. - // - if (t.group != nullptr) - return t.group->is_a () != nullptr; - // Check if there is a corresponding cli.cxx{} group. // - cli_cxx* g (targets.find (t.dir, t.out, t.name)); + const cli_cxx* g (targets.find (t.dir, t.out, t.name)); // If not or if it has no prerequisites (happens when we use it to // set cli.options) and this target has a cli{} prerequisite, then - // synthesize the group. + // synthesize the dependency. // if (g == nullptr || !g->has_prerequisites ()) { - for (prerequisite_member p: group_prerequisite_members (ml, a, t)) + for (prerequisite_member p: prerequisite_members (a, t)) { if (p.is_a ()) { @@ -136,7 +121,7 @@ namespace build2 if (g == nullptr) g = &targets.insert (t.dir, t.out, t.name, trace); - g->prerequisites.push_back (p.as_prerequisite ()); + g->prerequisites (prerequisites {p.as_prerequisite ()}); } else l4 ([&]{trace << ".cli file stem '" << p.name () << "' " @@ -146,30 +131,23 @@ namespace build2 } } - if (g != nullptr) - { - // Resolve the group's members. This should link us up to the - // group. - // - resolve_group_members (ml, a, *g); - - // For ixx{}, verify it is part of the group. - // - if (t.is_a () && g->i == nullptr) - { - l4 ([&]{trace << "generation of inline file " << t - << " is disabled with --suppress-inline";}); - g = nullptr; - } - } + if (g == nullptr) + return false; - assert (t.group == g); - return g != nullptr; + // For ixx{}, verify it is part of the group (i.e., not disabled + // via --suppress-inline). + // + if (t.is_a () && + find_option ("--suppress-inline", *g, "cli.options")) + return false; + + t.group = g; + return true; } } recipe compile:: - apply (slock& ml, action a, target& xt) const + apply (action a, target& xt) const { if (cli_cxx* pt = xt.is_a ()) { @@ -184,11 +162,11 @@ namespace build2 // Inject dependency on the output directory. // - inject_fsdir (ml, a, t); + inject_fsdir (a, t); - // Search and match prerequisite members. + // Match prerequisite members. // - search_and_match_prerequisite_members (ml, a, t); + match_prerequisite_members (a, t); switch (a) { @@ -199,8 +177,8 @@ namespace build2 } else { - cli_cxx& g (xt.group->as ()); - build2::match (ml, a, g); + const cli_cxx& g (xt.group->as ()); + build2::match (a, g); return group_recipe; // Execute the group's recipe. } } @@ -239,7 +217,12 @@ namespace build2 // const cli* s; { - auto p (execute_prerequisites (a, t, t.mtime ())); + // The rule has been matched which means the members should be + // resolved and paths assigned. + // + auto p ( + execute_prerequisites ( + a, t, t.load_mtime (t.h->path ()))); if ((s = p.first) == nullptr) return p.second; diff --git a/build2/cli/target b/build2/cli/target index c10e4b8..5e51bb4 100644 --- a/build2/cli/target +++ b/build2/cli/target @@ -26,13 +26,13 @@ namespace build2 virtual const target_type& dynamic_type () const {return static_type;} }; - // Standard layout type compatible with target*[3]. + // Standard layout type compatible with group_view's const target*[3]. // struct cli_cxx_members { - const_ptr h = nullptr; - const_ptr c = nullptr; - const_ptr i = nullptr; + const cxx::hxx* h = nullptr; + const cxx::cxx* c = nullptr; + const cxx::ixx* i = nullptr; }; class cli_cxx: public mtime_target, public cli_cxx_members @@ -41,14 +41,13 @@ namespace build2 using mtime_target::mtime_target; virtual group_view - group_members (action_type); - - virtual timestamp - load_mtime () const; + group_members (action_type) const override; public: static const target_type static_type; - virtual const target_type& dynamic_type () const {return static_type;} + + virtual const target_type& + dynamic_type () const override {return static_type;} }; } } diff --git a/build2/cli/target.cxx b/build2/cli/target.cxx index 200f6f0..51f58aa 100644 --- a/build2/cli/target.cxx +++ b/build2/cli/target.cxx @@ -4,8 +4,6 @@ #include -#include // file_mtime() - using namespace std; using namespace butl; @@ -32,27 +30,17 @@ namespace build2 // cli.cxx // group_view cli_cxx:: - group_members (action_type) + group_members (action_type) const { - static_assert (offsetof (cli_cxx_members, i) - - offsetof (cli_cxx_members, h) == sizeof (target*) * 2, + static_assert (sizeof (cli_cxx_members) == sizeof (const target*) * 3, "member layout incompatible with array"); return h != nullptr - ? group_view {reinterpret_cast (&h), + ? group_view {reinterpret_cast (&h), (i != nullptr ? 3U : 2U)} : group_view {nullptr, 0}; } - timestamp cli_cxx:: - load_mtime () const - { - // The rule has been matched which means the members should - // be resolved and paths assigned. - // - return file_mtime (h->path ()); - } - static pair> cli_cxx_factory (const target_type&, dir_path d, -- cgit v1.1