aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBoris Kolpackov <boris@codesynthesis.com>2017-03-06 09:57:15 +0200
committerBoris Kolpackov <boris@codesynthesis.com>2017-03-06 09:57:15 +0200
commitd1d1d444f0b4abbb628625240025bfe3cfe77459 (patch)
treefcf205ddca672679eb59f4ce41dc99d238588c21
parent02f717d4b7883451f37bb690c7708dda21cc4419 (diff)
Tweak target locking logic
-rw-r--r--build2/algorithm.cxx27
-rw-r--r--build2/target.cxx11
2 files changed, 18 insertions, 20 deletions
diff --git a/build2/algorithm.cxx b/build2/algorithm.cxx
index c4342d3..4e5ec78 100644
--- a/build2/algorithm.cxx
+++ b/build2/algorithm.cxx
@@ -104,7 +104,6 @@ namespace build2
size_t b (target::count_base ());
size_t e (b + target::offset_touched - 1);
- size_t exec (b + target::offset_executed);
size_t lock (b + target::offset_locked);
size_t busy (b + target::offset_busy);
@@ -147,18 +146,6 @@ namespace build2
for (; e == lock; e = ct.task_count.load (memory_order_acquire))
this_thread::yield ();
}
-
- // We don't lock already executed targets.
- //
- if (e == exec)
- {
- // Sanity check: we better not be overriding a recipe for an already
- // executed target.
- //
- assert (ct.action == a);
-
- return target_lock {nullptr, target::offset_executed};
- }
}
// We now have the sping lock. Analyze the old value and decide what to
@@ -181,6 +168,20 @@ namespace build2
switch (offset)
{
+ case target::offset_executed:
+ {
+ if (a == t.action)
+ {
+ // We don't lock already executed targets.
+ //
+ t.task_count.store (e, memory_order_release);
+ return target_lock {nullptr, target::offset_executed};
+ }
+
+ // Override, fall through.
+ //
+ assert (a > t.action);
+ }
case target::offset_touched:
case target::offset_matched:
case target::offset_applied:
diff --git a/build2/target.cxx b/build2/target.cxx
index dacf534..fa8378c 100644
--- a/build2/target.cxx
+++ b/build2/target.cxx
@@ -149,15 +149,12 @@ namespace build2
if (e >= busy)
return target_state::unchanged; // Override in progress.
+ // Unlike lock_impl(), we are only called after being matched for this
+ // action so if we see executed, then it means executed for this action
+ // (or noop).
+ //
if (e == exec)
- {
- // Sanity check: we better not be overriding a recipe for an already
- // executed target.
- //
- assert (action == a);
-
return group_state () ? group->state_ : state_;
- }
// Try to grab the spin-lock.
//