diff options
author | Boris Kolpackov <boris@codesynthesis.com> | 2017-07-29 14:17:27 +0200 |
---|---|---|
committer | Boris Kolpackov <boris@codesynthesis.com> | 2017-07-29 14:25:14 +0200 |
commit | 495e79341b8bbbd43bcb92d4cff5ad87111886f0 (patch) | |
tree | 5f85d428ff5e6cdab336eef2fc033976582d9209 | |
parent | 28055d044d0c21ff5556de52c3e273d5f4969408 (diff) |
Fix bug in execution algorithms
-rw-r--r-- | build2/algorithm.cxx | 26 | ||||
-rw-r--r-- | build2/target.hxx | 4 |
2 files changed, 9 insertions, 21 deletions
diff --git a/build2/algorithm.cxx b/build2/algorithm.cxx index 5e18441..dc1c418 100644 --- a/build2/algorithm.cxx +++ b/build2/algorithm.cxx @@ -1020,11 +1020,6 @@ namespace build2 return t.executed_state (); } - // We use the target pointer mark mechanism to indicate whether the target - // was already busy. Probably not worth it (we are saving an atomic load), - // but what the hell. Note that this means we have to always "harvest" all - // the targets to clear the mark. - // template <typename T> target_state straight_execute_members (action a, const target& t, T ts[], size_t n) @@ -1051,14 +1046,13 @@ namespace build2 r |= s; mt = nullptr; } - else if (s == target_state::busy) - mark (mt); } wg.wait (); - // Now all the targets in prerequisite_targets must be executed and - // synchronized (and we have blanked out all the postponed ones). + // Now all the targets in prerequisite_targets must be either still busy + // or executed and synchronized (and we have blanked out all the postponed + // ones). // for (size_t i (0); i != n; ++i) { @@ -1067,9 +1061,9 @@ namespace build2 if (mt == nullptr) continue; - // If the target was already busy, wait for its completion. + // If the target is still busy, wait for its completion. // - if (unmark (mt)) + if (mt->task_count.load (memory_order_acquire) >= target::count_busy ()) sched.wait ( target::count_executed (), mt->task_count, scheduler::work_none); @@ -1105,8 +1099,6 @@ namespace build2 r |= s; mt = nullptr; } - else if (s == target_state::busy) - mark (mt); } wg.wait (); @@ -1118,7 +1110,7 @@ namespace build2 if (mt == nullptr) continue; - if (unmark (mt)) + if (mt->task_count.load (memory_order_acquire) >= target::count_busy ()) sched.wait ( target::count_executed (), mt->task_count, scheduler::work_none); @@ -1181,8 +1173,6 @@ namespace build2 rs |= s; pt = nullptr; } - else if (s == target_state::busy) - mark (pt); } wg.wait (); @@ -1197,9 +1187,7 @@ namespace build2 if (pt == nullptr) continue; - // If the target was already busy, wait for its completion. - // - if (unmark (pt)) + if (pt->task_count.load (memory_order_acquire) >= target::count_busy ()) sched.wait ( target::count_executed (), pt->task_count, scheduler::work_none); diff --git a/build2/target.hxx b/build2/target.hxx index 92c5768..7cc7f95 100644 --- a/build2/target.hxx +++ b/build2/target.hxx @@ -478,8 +478,8 @@ namespace build2 mutable atomic_count task_count {0}; // Start offset_touched - 1. // This function should only be called during match if we have observed - // (synchronization-wise) that the this target has been matched (i.e., - // the rule has been applied) for this action. + // (synchronization-wise) that this target has been matched (i.e., the + // rule has been applied) for this action. // target_state matched_state (action a, bool fail = true) const; |