aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBoris Kolpackov <boris@codesynthesis.com>2022-06-23 06:36:20 +0200
committerBoris Kolpackov <boris@codesynthesis.com>2022-06-23 06:36:20 +0200
commite872913956c05c6fe1826ff3f2a3e67953e31064 (patch)
treea39163fa82d7fa3fffaf093a85f9c84d2818d639
parent735927b150d2262a317a99b563af57a97e8dd67c (diff)
Minor enhancements to algorithms
-rw-r--r--libbuild2/algorithm.cxx59
-rw-r--r--libbuild2/algorithm.hxx28
-rw-r--r--libbuild2/algorithm.ixx15
3 files changed, 82 insertions, 20 deletions
diff --git a/libbuild2/algorithm.cxx b/libbuild2/algorithm.cxx
index 564105c..843808d 100644
--- a/libbuild2/algorithm.cxx
+++ b/libbuild2/algorithm.cxx
@@ -1217,9 +1217,8 @@ namespace build2
match_prerequisite_range (a, t, group_prerequisite_members (a, t), msm, s);
}
- template <typename T>
void
- match_members (action a, target& t, T const* ts, size_t n)
+ match_members (action a, target& t, const target* const* ts, size_t n)
{
// Pretty much identical to match_prerequisite_range() except we don't
// search.
@@ -1251,15 +1250,45 @@ namespace build2
}
}
- // Instantiate only for what we need.
- //
- template LIBBUILD2_SYMEXPORT void
- match_members<const target*> (action, target&,
- const target* const*, size_t);
+ void
+ match_members (action a,
+ target& t,
+ prerequisite_targets& ts,
+ size_t s,
+ pair<uintptr_t, uintptr_t> imv)
+ {
+ size_t n (ts.size ());
+
+ wait_guard wg (t.ctx, t.ctx.count_busy (), t[a].task_count, true);
- template LIBBUILD2_SYMEXPORT void
- match_members<prerequisite_target> (action, target&,
- prerequisite_target const*, size_t);
+ for (size_t i (s); i != n; ++i)
+ {
+ const prerequisite_target& pt (ts[i]);
+ const target* m (pt.target);
+
+ if (m == nullptr ||
+ marked (m) ||
+ (imv.first != 0 && (pt.include & imv.first) != imv.second))
+ continue;
+
+ match_async (a, *m, t.ctx.count_busy (), t[a].task_count);
+ }
+
+ wg.wait ();
+
+ for (size_t i (s); i != n; ++i)
+ {
+ const prerequisite_target& pt (ts[i]);
+ const target* m (pt.target);
+
+ if (m == nullptr ||
+ marked (m) ||
+ (imv.first != 0 && (pt.include & imv.first) != imv.second))
+ continue;
+
+ match_complete (a, *m);
+ }
+ }
const fsdir*
inject_fsdir (action a, target& t, bool parent)
@@ -2313,6 +2342,16 @@ namespace build2
if (n == 0)
return false;
+ // Provide additional information on what's going on.
+ //
+ auto df = make_diag_frame (
+ [&t](const diag_record& dr)
+ {
+ if (verb != 0)
+ dr << info << "while updating during match prerequisites of "
+ << "target " << t;
+ });
+
context& ctx (t.ctx);
phase_switch ps (ctx, run_phase::execute);
diff --git a/libbuild2/algorithm.hxx b/libbuild2/algorithm.hxx
index 75976bf..db3e93d 100644
--- a/libbuild2/algorithm.hxx
+++ b/libbuild2/algorithm.hxx
@@ -145,6 +145,15 @@ namespace build2
const string* ext = nullptr,
const scope* = nullptr);
+ template <typename T>
+ const T*
+ search_existing (context&,
+ const dir_path& dir,
+ const dir_path& out,
+ const string& name,
+ const string* ext = nullptr,
+ const scope* = nullptr);
+
// Search for a target identified by the name. The semantics is "as if" we
// first created a prerequisite based on this name in exactly the same way
// as the parser would and then searched based on this prerequisite. If the
@@ -471,11 +480,8 @@ namespace build2
// dependencies. Similar in semantics to match_prerequisites(). Any marked
// target pointers are skipped.
//
- // T can only be const target* or prerequisite_target.
- //
- template <typename T>
- void
- match_members (action, target&, T const*, size_t);
+ LIBBUILD2_SYMEXPORT void
+ match_members (action, target&, const target* const*, size_t);
template <size_t N>
inline void
@@ -484,14 +490,16 @@ namespace build2
match_members (a, t, ts, N);
}
- inline void
+ // As above plus if the include mask (first) and value (second) are
+ // specified, then only match prerequisites that satisfy the
+ // ((prerequisite_target::include & mask) == value) condition.
+ //
+ LIBBUILD2_SYMEXPORT void
match_members (action a,
target& t,
prerequisite_targets& ts,
- size_t start = 0)
- {
- match_members (a, t, ts.data () + start, ts.size () - start);
- }
+ size_t start = 0,
+ pair<uintptr_t, uintptr_t> include = {0, 0});
// Unless already known, match, and, if necessary, execute the group in
// order to resolve its members list. Note that even after that the member's
diff --git a/libbuild2/algorithm.ixx b/libbuild2/algorithm.ixx
index 10ed754..ea4241e 100644
--- a/libbuild2/algorithm.ixx
+++ b/libbuild2/algorithm.ixx
@@ -187,6 +187,21 @@ namespace build2
t, T::static_type, dir, out, name, ext, scope).template as<T> ();
}
+ template <typename T>
+ inline const T*
+ search_existing (context& ctx,
+ const dir_path& dir,
+ const dir_path& out,
+ const string& name,
+ const string* ext,
+ const scope* scope)
+ {
+ const target* r (
+ search_existing (
+ ctx, T::static_type, dir, out, name, ext, scope));
+ return r != nullptr ? &r->template as<T> () : nullptr;
+ }
+
LIBBUILD2_SYMEXPORT target_lock
lock_impl (action, const target&, optional<scheduler::work_queue>);