[K/N][Runtime] Use std::atomic_flag in SpinLock

This commit is contained in:
Ilya Matveev
2021-09-30 18:07:02 +07:00
committed by Space
parent a619b78954
commit ca7ae0d539
+8 -14
View File
@@ -17,7 +17,7 @@
#ifndef RUNTIME_MUTEX_H #ifndef RUNTIME_MUTEX_H
#define RUNTIME_MUTEX_H #define RUNTIME_MUTEX_H
#include <cstdint> #include <atomic>
#include <thread> #include <thread>
#include "KAssert.h" #include "KAssert.h"
@@ -37,20 +37,17 @@ template <>
class SpinLock<MutexThreadStateHandling::kIgnore> : private Pinned { class SpinLock<MutexThreadStateHandling::kIgnore> : private Pinned {
public: public:
void lock() noexcept { void lock() noexcept {
while (!__sync_bool_compare_and_swap(&atomicInt, 0, 1)) { while(flag_.test_and_set(std::memory_order_acquire)) {
std::this_thread::yield(); std::this_thread::yield();
} }
} }
void unlock() noexcept { void unlock() noexcept {
if (!__sync_bool_compare_and_swap(&atomicInt, 1, 0)) { flag_.clear(std::memory_order_release);
RuntimeAssert(false, "Unable to unlock");
}
} }
private: private:
// TODO: Consider using `std::atomic_flag`. std::atomic_flag flag_ = ATOMIC_FLAG_INIT;
int32_t atomicInt = 0;
}; };
template <> template <>
@@ -58,25 +55,22 @@ class SpinLock<MutexThreadStateHandling::kSwitchIfRegistered> : private Pinned {
public: public:
void lock() noexcept { void lock() noexcept {
// Fast path without thread state switching. // Fast path without thread state switching.
if (__sync_bool_compare_and_swap(&atomicInt, 0, 1)) { if (!flag_.test_and_set(std::memory_order_acquire)) {
return; return;
} }
kotlin::NativeOrUnregisteredThreadGuard guard(/* reentrant = */ true); kotlin::NativeOrUnregisteredThreadGuard guard(/* reentrant = */ true);
while (!__sync_bool_compare_and_swap(&atomicInt, 0, 1)) { while (flag_.test_and_set(std::memory_order_acquire)) {
std::this_thread::yield(); std::this_thread::yield();
} }
} }
void unlock() noexcept { void unlock() noexcept {
if (!__sync_bool_compare_and_swap(&atomicInt, 1, 0)) { flag_.clear(std::memory_order_release);
RuntimeAssert(false, "Unable to unlock");
}
} }
private: private:
// TODO: Consider using `std::atomic_flag`. std::atomic_flag flag_ = ATOMIC_FLAG_INIT;
int32_t atomicInt = 0;
}; };
} // namespace kotlin } // namespace kotlin