[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:
lizzie 2026-01-13 04:17:27 +01:00 committed by crueter
parent 3bae47cd94
commit b1daffad19
No known key found for this signature in database
GPG Key ID: 425ACD2D4830EBC6
3 changed files with 33 additions and 70 deletions

View File

@ -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

View File

@ -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

View File

@ -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;
}; };