15 #include "absl/base/internal/spinlock.h"
21 #include "absl/base/attributes.h"
22 #include "absl/base/internal/atomic_hook.h"
23 #include "absl/base/internal/cycleclock.h"
24 #include "absl/base/internal/spinlock_wait.h"
25 #include "absl/base/internal/sysinfo.h"
26 #include "absl/base/call_once.h"
58 namespace base_internal {
61 const void *lock,
int64_t wait_cycles)>
78 : lockword_(IsCooperative(
mode) ? kSpinLockCooperative : 0) {
94 int c = adaptive_spin_count;
97 lock_value = lockword_.load(std::memory_order_relaxed);
98 }
while ((lock_value & kSpinLockHeld) != 0 && --
c > 0);
102 void SpinLock::SlowLock() {
104 lock_value = TryLockInternal(lock_value, 0);
105 if ((lock_value & kSpinLockHeld) == 0) {
110 if ((lock_value & kSpinLockCooperative) != 0) {
122 int lock_wait_call_count = 0;
123 while ((lock_value & kSpinLockHeld) != 0) {
126 if ((lock_value & kWaitTimeMask) == 0) {
131 if (lockword_.compare_exchange_strong(
132 lock_value, lock_value | kSpinLockSleeper,
133 std::memory_order_relaxed, std::memory_order_relaxed)) {
137 lock_value |= kSpinLockSleeper;
138 }
else if ((lock_value & kSpinLockHeld) == 0) {
142 lock_value = TryLockInternal(lock_value, wait_cycles);
144 }
else if ((lock_value & kWaitTimeMask) == 0) {
164 lock_value = SpinLoop();
166 lock_value = TryLockInternal(lock_value, wait_cycles);
170 void SpinLock::SlowUnlock(
uint32_t lock_value) {
177 if ((lock_value & kWaitTimeMask) != kSpinLockSleeper) {
178 const uint64_t wait_cycles = DecodeWaitCycles(lock_value);
198 static const int64_t kMaxWaitTime =
209 return kSpinLockSleeper;
214 if (clamped == kSpinLockSleeper) {
223 static_cast<uint32_t>(lock_value & kWaitTimeMask);