From 5393589ec2d898a02c52adf9125a592d3d7ff829 Mon Sep 17 00:00:00 2001 From: Boris Kolpackov Date: Fri, 26 May 2023 12:15:24 +0200 Subject: Disable counts verification if matched but not executed in resolve_members() --- libbuild2/adhoc-rule-regex-pattern.cxx | 1 + libbuild2/algorithm.cxx | 7 ++++++ libbuild2/context.cxx | 1 + libbuild2/context.hxx | 4 +++- libbuild2/operation.cxx | 42 +++++++++++++++++++++++----------- 5 files changed, 41 insertions(+), 14 deletions(-) (limited to 'libbuild2') diff --git a/libbuild2/adhoc-rule-regex-pattern.cxx b/libbuild2/adhoc-rule-regex-pattern.cxx index c4b4cab..3f207dc 100644 --- a/libbuild2/adhoc-rule-regex-pattern.cxx +++ b/libbuild2/adhoc-rule-regex-pattern.cxx @@ -433,6 +433,7 @@ namespace build2 else { // @@ TODO: currently this uses type as the ad hoc member identity. + // Use inject_adhoc_group_member() variant? // add_adhoc_member ( t, diff --git a/libbuild2/algorithm.cxx b/libbuild2/algorithm.cxx index 966c7a8..cf972e7 100644 --- a/libbuild2/algorithm.cxx +++ b/libbuild2/algorithm.cxx @@ -1283,7 +1283,10 @@ namespace build2 throw failed (); if ((r = g.group_members (a)).members != nullptr) + { + g.ctx.resolve_count.fetch_add (1, memory_order_relaxed); break; + } // Unlock and to execute ... // @@ -1300,6 +1303,10 @@ namespace build2 // we would have already known the members list) and we really do need // to execute it now. // + // Note that while it might be tempting to decrement resolve_count + // here, there is no guarantee that we were the ones who have matched + // this target. + // { phase_switch ps (g.ctx, run_phase::execute); execute_direct_sync (a, g); diff --git a/libbuild2/context.cxx b/libbuild2/context.cxx index ecf34fc..c0442f0 100644 --- a/libbuild2/context.cxx +++ b/libbuild2/context.cxx @@ -850,6 +850,7 @@ namespace build2 dependency_count.store (0, memory_order_relaxed); target_count.store (0, memory_order_relaxed); skip_count.store (0, memory_order_relaxed); + resolve_count.store (0, memory_order_relaxed); // Clear accumulated targets with post hoc prerequisites. // diff --git a/libbuild2/context.hxx b/libbuild2/context.hxx index 7574787..a54d010 100644 --- a/libbuild2/context.hxx +++ b/libbuild2/context.hxx @@ -405,11 +405,13 @@ namespace build2 // decremented after such recipe has been executed. If such a recipe has // skipped executing the operation, then it should increment the skip // count. These two counters are used for progress monitoring and - // diagnostics. + // diagnostics. The resolve count keeps track of the number of targets + // matched but not executed as a result of the resolve_members() calls. // atomic_count dependency_count; atomic_count target_count; atomic_count skip_count; + atomic_count resolve_count; // Build state (scopes, targets, variables, etc). // diff --git a/libbuild2/operation.cxx b/libbuild2/operation.cxx index e57caa5..f199827 100644 --- a/libbuild2/operation.cxx +++ b/libbuild2/operation.cxx @@ -761,26 +761,42 @@ namespace build2 if (fail) throw failed (); - // We should have executed every target that we matched, provided we - // haven't failed (in which case we could have bailed out early). - // - assert (ctx.target_count.load (memory_order_relaxed) == 0); - #ifndef NDEBUG - if (ctx.dependency_count.load (memory_order_relaxed) != 0) + // For now we disable these checks if we've performed any group member + // resolutions that required a match (with apply()) but not execute. + // + if (ctx.resolve_count.load (memory_order_relaxed) == 0) { - diag_record dr; - dr << info << "detected unexecuted matched targets:"; + // We should have executed every target that we matched, provided we + // haven't failed (in which case we could have bailed out early). + // + assert (ctx.target_count.load (memory_order_relaxed) == 0); - for (const auto& pt: ctx.targets) + if (ctx.dependency_count.load (memory_order_relaxed) != 0) { - const target& t (*pt); - if (size_t n = t[a].dependents.load (memory_order_relaxed)) - dr << text << t << ' ' << n; + diag_record dr; + dr << info << "detected unexecuted matched targets:"; + + for (const auto& pt: ctx.targets) + { + const target& t (*pt); + + if (size_t n = t[a].dependents.load (memory_order_relaxed)) + dr << text << t << ' ' << n; + + if (a.outer ()) + { + action ia (a.inner_action ()); + + if (size_t n = t[ia].dependents.load (memory_order_relaxed)) + dr << text << t << ' ' << n; + } + } } + + assert (ctx.dependency_count.load (memory_order_relaxed) == 0); } #endif - assert (ctx.dependency_count.load (memory_order_relaxed) == 0); } const meta_operation_info mo_perform { -- cgit v1.1