27 #ifndef ABSL_BASE_INTERNAL_SPINLOCK_H_
28 #define ABSL_BASE_INTERNAL_SPINLOCK_H_
31 #include <sys/types.h>
35 #include "absl/base/attributes.h"
36 #include "absl/base/const_init.h"
37 #include "absl/base/dynamic_annotations.h"
38 #include "absl/base/internal/low_level_scheduling.h"
39 #include "absl/base/internal/raw_logging.h"
40 #include "absl/base/internal/scheduling_mode.h"
41 #include "absl/base/internal/tsan_mutex_interface.h"
42 #include "absl/base/macros.h"
43 #include "absl/base/port.h"
44 #include "absl/base/thread_annotations.h"
48 namespace base_internal {
62 : lockword_(IsCooperative(
mode) ? kSpinLockCooperative : 0) {}
67 #ifdef ABSL_INTERNAL_HAVE_TSAN_INTERFACE
70 ~SpinLock() =
default;
88 bool res = TryLockImpl();
90 this, __tsan_mutex_try_lock | (res ? 0 : __tsan_mutex_try_lock_failed),
98 uint32_t lock_value = lockword_.load(std::memory_order_relaxed);
99 lock_value = lockword_.exchange(lock_value & kSpinLockCooperative,
100 std::memory_order_release);
102 if ((lock_value & kSpinLockDisabledScheduling) != 0) {
105 if ((lock_value & kWaitTimeMask) != 0) {
109 SlowUnlock(lock_value);
118 return (lockword_.load(std::memory_order_relaxed) & kSpinLockHeld) != 0;
154 static constexpr
uint32_t kSpinLockHeld = 1;
155 static constexpr
uint32_t kSpinLockCooperative = 2;
156 static constexpr
uint32_t kSpinLockDisabledScheduling = 4;
157 static constexpr
uint32_t kSpinLockSleeper = 8;
159 static constexpr
uint32_t kWaitTimeMask =
160 ~(kSpinLockHeld | kSpinLockCooperative | kSpinLockDisabledScheduling);
173 inline
bool TryLockImpl() {
174 uint32_t lock_value = lockword_.load(std::memory_order_relaxed);
175 return (TryLockInternal(lock_value, 0) & kSpinLockHeld) == 0;
178 std::atomic<uint32_t> lockword_;
234 kSpinLockHeld | lock_value | wait_cycles | sched_disabled_bit,
235 std::memory_order_acquire, std::memory_order_relaxed)) {
246 #endif // ABSL_BASE_INTERNAL_SPINLOCK_H_