diff options
author | 2020-11-30 21:23:11 -0800 | |
---|---|---|
committer | 2020-12-01 09:51:56 -0500 | |
commit | 592924480acf034aec0454160492a20bccdbdf3e (patch) | |
tree | 7f390a1dc3cfb802d8d60b067c3a51366a0c3de5 /absl/base/call_once.h | |
parent | e80c0b3536e1bdee68a874d529a9ba951faffe8b (diff) |
Export of internal Abseil changes
--
7b6a68aa92dcc7247236d1a1813914e035383bf8 by Abseil Team <absl-team@google.com>:
Use atomic exchange to mark completion in absl::once_flag
This prevents a potential for a missed wakeup if one thread marks
itself as a waiter while another thread is completing the invocation.
PiperOrigin-RevId: 344946791
--
ddff21d1dde08d1368d8be5fca81b154e78be2fc by Abseil Team <absl-team@google.com>:
Add missing string_view include. This is currently used transitively through the cord header.
PiperOrigin-RevId: 344845266
GitOrigin-RevId: 7b6a68aa92dcc7247236d1a1813914e035383bf8
Change-Id: Ia24e98a1df832fc4cb491d888fdf21182b5954f4
Diffstat (limited to 'absl/base/call_once.h')
-rw-r--r-- | absl/base/call_once.h | 11 |
1 files changed, 2 insertions, 9 deletions
diff --git a/absl/base/call_once.h b/absl/base/call_once.h index 5b468af8..96109f53 100644 --- a/absl/base/call_once.h +++ b/absl/base/call_once.h @@ -177,15 +177,8 @@ void CallOnceImpl(std::atomic<uint32_t>* control, scheduling_mode) == kOnceInit) { base_internal::invoke(std::forward<Callable>(fn), std::forward<Args>(args)...); - // The call to SpinLockWake below is an optimization, because the waiter - // in SpinLockWait is waiting with a short timeout. The atomic load/store - // sequence is slightly faster than an atomic exchange: - // old_control = control->exchange(base_internal::kOnceDone, - // std::memory_order_release); - // We opt for a slightly faster case when there are no waiters, in spite - // of longer tail latency when there are waiters. - old_control = control->load(std::memory_order_relaxed); - control->store(base_internal::kOnceDone, std::memory_order_release); + old_control = + control->exchange(base_internal::kOnceDone, std::memory_order_release); if (old_control == base_internal::kOnceWaiter) { base_internal::SpinLockWake(control, true); } |