aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authoreeight <eeight@yandex-team.ru>2022-05-17 10:20:05 +0300
committereeight <eeight@yandex-team.ru>2022-05-17 10:20:05 +0300
commitf3ec69ca4abe595abc22fe786710538cfc9b016a (patch)
tree02f8e499b2bcfbe70a927dc23801ce2264110688
parent7f57a1b674d2b1cd7b35ed078e00e3b656e7f25f (diff)
downloadydb-f3ec69ca4abe595abc22fe786710538cfc9b016a.tar.gz
IGNIETFERRO-1105 Use std::atomic in spinlock
ref:dca14f354fc9b9698f83663ceb0e62e797fe98c5
-rw-r--r--util/system/atexit.cpp2
-rw-r--r--util/system/guard.h1
-rw-r--r--util/system/spinlock.h102
3 files changed, 49 insertions, 56 deletions
diff --git a/util/system/atexit.cpp b/util/system/atexit.cpp
index 74fb10b6b1..aeb29466b3 100644
--- a/util/system/atexit.cpp
+++ b/util/system/atexit.cpp
@@ -76,7 +76,7 @@ namespace {
TPriorityQueue<TFunc*, TVector<TFunc*>, TCmp> Items_;
};
- static TAtomic atExitLock = 0;
+ static TAdaptiveLock atExitLock;
static TAtExit* volatile atExitPtr = nullptr;
alignas(TAtExit) static char atExitMem[sizeof(TAtExit)];
diff --git a/util/system/guard.h b/util/system/guard.h
index efc091d5f8..b6ca45fff6 100644
--- a/util/system/guard.h
+++ b/util/system/guard.h
@@ -1,6 +1,7 @@
#pragma once
#include <util/generic/noncopyable.h>
+#include <util/system/defaults.h>
template <class T>
struct TCommonLockOps {
diff --git a/util/system/spinlock.h b/util/system/spinlock.h
index af2630890a..3fbe8a6441 100644
--- a/util/system/spinlock.h
+++ b/util/system/spinlock.h
@@ -1,21 +1,34 @@
#pragma once
-#include "atomic.h"
#include "spin_wait.h"
+#include <atomic>
+
class TSpinLockBase {
protected:
- inline TSpinLockBase() noexcept {
- AtomicSet(Val_, 0);
+ TSpinLockBase() = default;
+
+ // These were unearthed in IGNIETFERRO-1105
+ // Need to get rid of them separately
+ TSpinLockBase(const TSpinLockBase& other)
+ : Val_(other.Val_.load())
+ {
+ }
+
+ TSpinLockBase& operator=(const TSpinLockBase& other)
+ {
+ Val_.store(other.Val_);
+ return *this;
}
public:
inline bool IsLocked() const noexcept {
- return AtomicGet(Val_);
+ return Val_.load();
}
inline bool TryAcquire() noexcept {
- return AtomicTryLock(&Val_);
+ intptr_t zero = 0;
+ return Val_.compare_exchange_strong(zero, 1);
}
inline bool try_lock() noexcept {
@@ -23,7 +36,7 @@ public:
}
protected:
- TAtomic Val_;
+ std::atomic<intptr_t> Val_{0};
};
static inline void SpinLockPause() {
@@ -37,18 +50,6 @@ static inline void SpinLockPause() {
#endif
}
-static inline void AcquireSpinLock(TAtomic* l) {
- if (!AtomicTryLock(l)) {
- do {
- SpinLockPause();
- } while (!AtomicTryAndTryLock(l));
- }
-}
-
-static inline void ReleaseSpinLock(TAtomic* l) {
- AtomicUnlock(l);
-}
-
/*
* You should almost always use TAdaptiveLock instead of TSpinLock
*/
@@ -57,11 +58,19 @@ public:
using TSpinLockBase::TSpinLockBase;
inline void Release() noexcept {
- ReleaseSpinLock(&Val_);
+ Val_.store(0, std::memory_order_release);
}
inline void Acquire() noexcept {
- AcquireSpinLock(&Val_);
+ intptr_t zero = 0;
+ if (Val_.compare_exchange_strong(zero, 1)) {
+ return;
+ }
+ do {
+ SpinLockPause();
+ zero = 0;
+ } while (Val_.load(std::memory_order_acquire) != 0 ||
+ !Val_.compare_exchange_strong(zero, 1));
}
inline void unlock() noexcept {
@@ -73,30 +82,30 @@ public:
}
};
-static inline void AcquireAdaptiveLock(TAtomic* l) {
- if (!AtomicTryLock(l)) {
- TSpinWait sw;
-
- while (!AtomicTryAndTryLock(l)) {
- sw.Sleep();
- }
- }
-}
-
-static inline void ReleaseAdaptiveLock(TAtomic* l) {
- AtomicUnlock(l);
-}
-
class TAdaptiveLock: public TSpinLockBase {
public:
using TSpinLockBase::TSpinLockBase;
- inline void Release() noexcept {
- ReleaseAdaptiveLock(&Val_);
+ void Release() noexcept {
+ Val_.store(0, std::memory_order_release);
}
- inline void Acquire() noexcept {
- AcquireAdaptiveLock(&Val_);
+ void Acquire() noexcept {
+ intptr_t zero = 0;
+ if (Val_.compare_exchange_strong(zero, 1)) {
+ return;
+ }
+
+ TSpinWait sw;
+
+ for (;;) {
+ zero = 0;
+ if (Val_.load(std::memory_order_acquire) == 0 &&
+ Val_.compare_exchange_strong(zero, 1)) {
+ break;
+ }
+ sw.Sleep();
+ }
}
inline void unlock() noexcept {
@@ -107,20 +116,3 @@ public:
Acquire();
}
};
-
-#include "guard.h"
-
-template <>
-struct TCommonLockOps<TAtomic> {
- static inline void Acquire(TAtomic* v) noexcept {
- AcquireAdaptiveLock(v);
- }
-
- static inline bool TryAcquire(TAtomic* v) noexcept {
- return AtomicTryLock(v);
- }
-
- static inline void Release(TAtomic* v) noexcept {
- ReleaseAdaptiveLock(v);
- }
-};