29 #ifndef ABSL_BASE_INTERNAL_SPINLOCK_H_
30 #define ABSL_BASE_INTERNAL_SPINLOCK_H_
33 #include <sys/types.h>
37 #include "absl/base/attributes.h"
38 #include "absl/base/const_init.h"
39 #include "absl/base/dynamic_annotations.h"
40 #include "absl/base/internal/low_level_scheduling.h"
41 #include "absl/base/internal/raw_logging.h"
42 #include "absl/base/internal/scheduling_mode.h"
43 #include "absl/base/internal/tsan_mutex_interface.h"
44 #include "absl/base/macros.h"
45 #include "absl/base/port.h"
46 #include "absl/base/thread_annotations.h"
50 namespace base_internal {
64 : lockword_(IsCooperative(
mode) ? kSpinLockCooperative : 0) {}
69 #ifdef ABSL_INTERNAL_HAVE_TSAN_INTERFACE
72 ~SpinLock() =
default;
90 bool res = TryLockImpl();
92 this, __tsan_mutex_try_lock | (res ? 0 : __tsan_mutex_try_lock_failed),
100 uint32_t lock_value = lockword_.load(std::memory_order_relaxed);
101 lock_value = lockword_.exchange(lock_value & kSpinLockCooperative,
102 std::memory_order_release);
104 if ((lock_value & kSpinLockDisabledScheduling) != 0) {
107 if ((lock_value & kWaitTimeMask) != 0) {
111 SlowUnlock(lock_value);
120 return (lockword_.load(std::memory_order_relaxed) & kSpinLockHeld) != 0;
165 static constexpr
uint32_t kSpinLockCooperative = 2;
166 static constexpr
uint32_t kSpinLockDisabledScheduling = 4;
170 ~(kSpinLockHeld | kSpinLockCooperative | kSpinLockDisabledScheduling);
183 inline
bool TryLockImpl() {
184 uint32_t lock_value = lockword_.load(std::memory_order_relaxed);
185 return (TryLockInternal(lock_value, 0) & kSpinLockHeld) == 0;
244 kSpinLockHeld | lock_value | wait_cycles | sched_disabled_bit,
245 std::memory_order_acquire, std::memory_order_relaxed)) {
256 #endif // ABSL_BASE_INTERNAL_SPINLOCK_H_