Browse Source
[common] move spinlock to pure header def
[common] move spinlock to pure header def
Signed-off-by: lizzie <lizzie@eden-emu.dev>pull/3287/head
committed by
crueter
3 changed files with 36 additions and 73 deletions
@ -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-License-Identifier: GPL-2.0-or-later |
|||
|
|||
#pragma once |
|||
|
|||
#ifdef _MSC_VER |
|||
#include <intrin.h> |
|||
#elif defined(ARCHITECTURE_x86_64) |
|||
#include <xmmintrin.h> |
|||
#endif |
|||
#include <atomic> |
|||
|
|||
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; |
|||
}; |
|||
|
|||
|
|||
Write
Preview
Loading…
Cancel
Save
Reference in new issue