[common] move spinlock to pure header def (#3287)
inline justified because it's like 4-5 assembly instructions max Signed-off-by: lizzie <lizzie@eden-emu.dev> Reviewed-on: https://git.eden-emu.dev/eden-emu/eden/pulls/3287 Reviewed-by: DraVee <dravee@eden-emu.dev> Reviewed-by: CamilleLaVey <camillelavey99@gmail.com> Co-authored-by: lizzie <lizzie@eden-emu.dev> Co-committed-by: lizzie <lizzie@eden-emu.dev>
This commit is contained in:
parent
3bae47cd94
commit
b1daffad19
|
|
@ -120,7 +120,6 @@ add_library(
|
||||||
settings_setting.h
|
settings_setting.h
|
||||||
slot_vector.h
|
slot_vector.h
|
||||||
socket_types.h
|
socket_types.h
|
||||||
spin_lock.cpp
|
|
||||||
spin_lock.h
|
spin_lock.h
|
||||||
stb.cpp
|
stb.cpp
|
||||||
stb.h
|
stb.h
|
||||||
|
|
|
||||||
|
|
@ -1,53 +0,0 @@
|
||||||
// SPDX-FileCopyrightText: Copyright 2020 yuzu Emulator Project
|
|
||||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
|
||||||
|
|
||||||
#include "common/spin_lock.h"
|
|
||||||
|
|
||||||
#if _MSC_VER
|
|
||||||
#include <intrin.h>
|
|
||||||
#if _M_AMD64
|
|
||||||
#define __x86_64__ 1
|
|
||||||
#endif
|
|
||||||
#if _M_ARM64
|
|
||||||
#define __aarch64__ 1
|
|
||||||
#endif
|
|
||||||
#else
|
|
||||||
#if __x86_64__
|
|
||||||
#include <xmmintrin.h>
|
|
||||||
#endif
|
|
||||||
#endif
|
|
||||||
|
|
||||||
namespace {
|
|
||||||
|
|
||||||
void ThreadPause() {
|
|
||||||
#if __x86_64__
|
|
||||||
_mm_pause();
|
|
||||||
#elif __aarch64__ && _MSC_VER
|
|
||||||
__yield();
|
|
||||||
#elif __aarch64__
|
|
||||||
asm("yield");
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
} // Anonymous namespace
|
|
||||||
|
|
||||||
namespace Common {
|
|
||||||
|
|
||||||
void SpinLock::lock() {
|
|
||||||
while (lck.test_and_set(std::memory_order_acquire)) {
|
|
||||||
ThreadPause();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void SpinLock::unlock() {
|
|
||||||
lck.clear(std::memory_order_release);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool SpinLock::try_lock() {
|
|
||||||
if (lck.test_and_set(std::memory_order_acquire)) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace Common
|
|
||||||
|
|
@ -1,32 +1,49 @@
|
||||||
|
// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project
|
||||||
|
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||||
|
|
||||||
// SPDX-FileCopyrightText: Copyright 2020 yuzu Emulator Project
|
// SPDX-FileCopyrightText: Copyright 2020 yuzu Emulator Project
|
||||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#ifdef _MSC_VER
|
||||||
|
#include <intrin.h>
|
||||||
|
#elif defined(ARCHITECTURE_x86_64)
|
||||||
|
#include <xmmintrin.h>
|
||||||
|
#endif
|
||||||
#include <atomic>
|
#include <atomic>
|
||||||
|
|
||||||
namespace Common {
|
namespace Common {
|
||||||
|
|
||||||
/**
|
/// @brief A lock similar to mutex that forces a thread to spin wait instead calling the
|
||||||
* SpinLock class
|
/// supervisor. Should be used on short sequences of code.
|
||||||
* a lock similar to mutex that forces a thread to spin wait instead calling the
|
struct SpinLock {
|
||||||
* supervisor. Should be used on short sequences of code.
|
SpinLock() noexcept = default;
|
||||||
*/
|
SpinLock(const SpinLock&) noexcept = delete;
|
||||||
class SpinLock {
|
SpinLock& operator=(const SpinLock&) noexcept = delete;
|
||||||
public:
|
SpinLock(SpinLock&&) noexcept = delete;
|
||||||
SpinLock() = default;
|
SpinLock& operator=(SpinLock&&) noexcept = delete;
|
||||||
|
|
||||||
SpinLock(const SpinLock&) = delete;
|
inline void lock() noexcept {
|
||||||
SpinLock& operator=(const SpinLock&) = delete;
|
while (lck.test_and_set(std::memory_order_acquire)) {
|
||||||
|
#if defined(ARCHITECTURE_x86_64)
|
||||||
|
_mm_pause();
|
||||||
|
#elif defined(ARCHITECTURE_arm64) && defined(_MSC_VER)
|
||||||
|
__yield();
|
||||||
|
#elif defined(ARCHITECTURE_arm64)
|
||||||
|
asm("yield");
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
SpinLock(SpinLock&&) = delete;
|
inline void unlock() noexcept {
|
||||||
SpinLock& operator=(SpinLock&&) = delete;
|
lck.clear(std::memory_order_release);
|
||||||
|
}
|
||||||
|
|
||||||
void lock();
|
[[nodiscard]] inline bool try_lock() noexcept {
|
||||||
void unlock();
|
return !lck.test_and_set(std::memory_order_acquire);
|
||||||
[[nodiscard]] bool try_lock();
|
}
|
||||||
|
|
||||||
private:
|
|
||||||
std::atomic_flag lck = ATOMIC_FLAG_INIT;
|
std::atomic_flag lck = ATOMIC_FLAG_INIT;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue