From b1daffad196c98b306a197efa56d48584516da56 Mon Sep 17 00:00:00 2001 From: lizzie Date: Tue, 13 Jan 2026 04:17:27 +0100 Subject: [PATCH] [common] move spinlock to pure header def (#3287) inline justified because it's like 4-5 assembly instructions max Signed-off-by: lizzie Reviewed-on: https://git.eden-emu.dev/eden-emu/eden/pulls/3287 Reviewed-by: DraVee Reviewed-by: CamilleLaVey Co-authored-by: lizzie Co-committed-by: lizzie --- src/common/CMakeLists.txt | 1 - src/common/spin_lock.cpp | 53 ------------------------------------- src/common/spin_lock.h | 55 +++++++++++++++++++++++++-------------- 3 files changed, 36 insertions(+), 73 deletions(-) delete mode 100644 src/common/spin_lock.cpp diff --git a/src/common/CMakeLists.txt b/src/common/CMakeLists.txt index 60e8cfa5da..a3d57ffce4 100644 --- a/src/common/CMakeLists.txt +++ b/src/common/CMakeLists.txt @@ -120,7 +120,6 @@ add_library( settings_setting.h slot_vector.h socket_types.h - spin_lock.cpp spin_lock.h stb.cpp stb.h diff --git a/src/common/spin_lock.cpp b/src/common/spin_lock.cpp deleted file mode 100644 index b2ef4ea1d0..0000000000 --- a/src/common/spin_lock.cpp +++ /dev/null @@ -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 -#if _M_AMD64 -#define __x86_64__ 1 -#endif -#if _M_ARM64 -#define __aarch64__ 1 -#endif -#else -#if __x86_64__ -#include -#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 diff --git a/src/common/spin_lock.h b/src/common/spin_lock.h index a83274851b..93d507ae80 100644 --- a/src/common/spin_lock.h +++ b/src/common/spin_lock.h @@ -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-License-Identifier: GPL-2.0-or-later #pragma once +#ifdef _MSC_VER +#include +#elif defined(ARCHITECTURE_x86_64) +#include +#endif #include namespace Common { -/** - * SpinLock class - * a lock similar to mutex that forces a thread to spin wait instead calling the - * supervisor. Should be used on short sequences of code. - */ -class SpinLock { -public: - SpinLock() = default; - - SpinLock(const SpinLock&) = delete; - SpinLock& operator=(const SpinLock&) = delete; - - SpinLock(SpinLock&&) = delete; - SpinLock& operator=(SpinLock&&) = delete; - - void lock(); - void unlock(); - [[nodiscard]] bool try_lock(); +/// @brief A lock similar to mutex that forces a thread to spin wait instead calling the +/// supervisor. Should be used on short sequences of code. +struct SpinLock { + SpinLock() noexcept = default; + SpinLock(const SpinLock&) noexcept = delete; + SpinLock& operator=(const SpinLock&) noexcept = delete; + SpinLock(SpinLock&&) noexcept = delete; + SpinLock& operator=(SpinLock&&) noexcept = delete; + + inline void lock() noexcept { + 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 + } + } + + inline void unlock() noexcept { + lck.clear(std::memory_order_release); + } + + [[nodiscard]] inline bool try_lock() noexcept { + return !lck.test_and_set(std::memory_order_acquire); + } -private: std::atomic_flag lck = ATOMIC_FLAG_INIT; };