aboutsummaryrefslogtreecommitdiff
path: root/build2
diff options
context:
space:
mode:
authorBoris Kolpackov <boris@codesynthesis.com>2017-04-01 11:56:01 +0200
committerBoris Kolpackov <boris@codesynthesis.com>2017-04-01 11:56:01 +0200
commitc0059a3c0217ca6abea64cadff59b2174bdbf730 (patch)
tree50bacdaf53973b51ea818380ae44d72be8fd5b98 /build2
parentc4adc6d6aa772cb9b8e5dc294bbdc75b4e22f38d (diff)
Fix bug in task state/count logic
Diffstat (limited to 'build2')
-rw-r--r--build2/algorithm.cxx16
1 files changed, 9 insertions, 7 deletions
diff --git a/build2/algorithm.cxx b/build2/algorithm.cxx
index ccbbae6..51a683c 100644
--- a/build2/algorithm.cxx
+++ b/build2/algorithm.cxx
@@ -836,6 +836,7 @@ namespace build2
// Try to atomically change applied to busy. Note that we are in the
// execution phase so the target shall not be spin-locked.
//
+ size_t touc (target::count_touched ());
size_t matc (target::count_matched ());
size_t exec (target::count_executed ());
size_t busy (target::count_busy ());
@@ -848,9 +849,9 @@ namespace build2
memory_order_acq_rel, // Synchronize on success.
memory_order_acquire)) // Synchronize on failure.
{
- // Overriden match-only or noop recipe.
+ // Overriden touch/match-only or noop recipe.
//
- if (tc == matc || t.state_ == target_state::unchanged)
+ if (tc == touc || tc == matc || t.state_ == target_state::unchanged)
{
t.state_ = target_state::unchanged;
t.task_count.store (exec, memory_order_release);
@@ -885,11 +886,11 @@ namespace build2
if (tc >= busy) return target_state::busy;
else if (tc != exec)
{
- // This can happen is we matched (a noop) recipe which then got
- // overridden as part of group resolution but not all the way to
+ // This can happen if we touched/matched (a noop) recipe which then
+ // got overridden as part of group resolution but not all the way to
// applied. In this case we treat it as noop.
//
- assert (tc == matc && t.action > a);
+ assert ((tc == touc || tc == matc) && t.action > a);
continue;
}
}
@@ -907,6 +908,7 @@ namespace build2
// Similar logic to match() above.
//
+ size_t touc (target::count_touched ());
size_t matc (target::count_matched ());
size_t exec (target::count_executed ());
size_t busy (target::count_busy ());
@@ -919,7 +921,7 @@ namespace build2
memory_order_acq_rel, // Synchronize on success.
memory_order_acquire)) // Synchronize on failure.
{
- if (tc == matc || t.state_ == target_state::unchanged)
+ if (tc == touc || tc == matc || t.state_ == target_state::unchanged)
{
t.state_ = target_state::unchanged;
t.task_count.store (exec, memory_order_release);
@@ -935,7 +937,7 @@ namespace build2
if (tc >= busy) sched.wait (exec, t.task_count, scheduler::work_none);
else if (tc != exec)
{
- assert (tc == matc && t.action > a);
+ assert ((tc == touc || tc == matc) && t.action > a);
continue;
}
}