aboutsummaryrefslogtreecommitdiff
path: root/libbuild2/target.ixx
diff options
context:
space:
mode:
authorBoris Kolpackov <boris@codesynthesis.com>2023-06-22 07:30:31 +0200
committerBoris Kolpackov <boris@codesynthesis.com>2023-06-22 07:30:31 +0200
commit7879d172dec3300341d3eff15808425e01c15569 (patch)
tree3d16d0b081f49fb4b7dca9a19c161e99cdf12498 /libbuild2/target.ixx
parentcb6e76b0fdffe89ec79dab005dbb14f1be48144f (diff)
Fix wraparound in task_count logic
Diffstat (limited to 'libbuild2/target.ixx')
-rw-r--r--libbuild2/target.ixx15
1 files changed, 8 insertions, 7 deletions
diff --git a/libbuild2/target.ixx b/libbuild2/target.ixx
index a550acb..f0d5cea 100644
--- a/libbuild2/target.ixx
+++ b/libbuild2/target.ixx
@@ -240,8 +240,8 @@ namespace build2
assert (ctx.phase == run_phase::match ||
ctx.phase == run_phase::execute);
- const opstate& s (state[a]);
- size_t c (s.task_count.load (mo) - ctx.count_base ());
+ size_t c (state[a].task_count.load (mo));
+ size_t b (ctx.count_base ()); // Note: cannot do (c - b)!
if (ctx.phase == run_phase::match)
{
@@ -250,7 +250,7 @@ namespace build2
// Note that we can't do >= offset_applied since offset_busy means it is
// being matched.
//
- return c == offset_applied || c == offset_executed;
+ return c == (b + offset_applied) || c == (b + offset_executed);
}
else
{
@@ -258,7 +258,7 @@ namespace build2
// least offset_matched since it must have been "achieved" before the
// phase switch.
//
- return c >= offset_matched;
+ return c >= (b + offset_matched);
}
}
@@ -298,9 +298,10 @@ namespace build2
// Note: already synchronized.
//
- size_t o (s.task_count.load (memory_order_relaxed) - ctx.count_base ());
+ size_t c (s.task_count.load (memory_order_relaxed));
+ size_t b (ctx.count_base ()); // Note: cannot do (c - b)!
- if (o == offset_tried)
+ if (c == (b + offset_tried))
return make_pair (false, target_state::unknown);
else
{
@@ -308,7 +309,7 @@ namespace build2
// latter case we are guaranteed to be synchronized since we are in the
// match phase.
//
- assert (o == offset_applied || o == offset_executed);
+ assert (c == (b + offset_applied) || c == (b + offset_executed));
return make_pair (true, (group_state (a) ? group->state[a] : s).state);
}
}