From d1d1d444f0b4abbb628625240025bfe3cfe77459 Mon Sep 17 00:00:00 2001 From: Boris Kolpackov Date: Mon, 6 Mar 2017 09:57:15 +0200 Subject: Tweak target locking logic --- build2/algorithm.cxx | 27 ++++++++++++++------------- build2/target.cxx | 11 ++++------- 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. // -- cgit v1.1