Common: Implement a basic SpinLock class

This commit is contained in:
Fernando Sahmkow 2020-02-04 11:23:12 -04:00
parent bfa6193eb9
commit 13ed9438fb
3 changed files with 68 additions and 0 deletions

View file

@ -143,6 +143,8 @@ add_library(common STATIC
scm_rev.cpp
scm_rev.h
scope_exit.h
spin_lock.cpp
spin_lock.h
string_util.cpp
string_util.h
swap.h

46
src/common/spin_lock.cpp Normal file
View file

@ -0,0 +1,46 @@
// Copyright 2020 yuzu Emulator Project
// Licensed under GPLv2 or any later version
// Refer to the license.txt file included.
#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 thread_pause() {
#if __x86_64__
_mm_pause();
#elif __aarch64__ && _MSC_VER
__yield();
#elif __aarch64__
asm("yield");
#endif
}
} // namespace
namespace Common {
void SpinLock::lock() {
while (lck.test_and_set(std::memory_order_acquire))
thread_pause();
}
void SpinLock::unlock() {
lck.clear(std::memory_order_release);
}
} // namespace Common

20
src/common/spin_lock.h Normal file
View file

@ -0,0 +1,20 @@
// Copyright 2020 yuzu Emulator Project
// Licensed under GPLv2 or any later version
// Refer to the license.txt file included.
#pragma once
#include <atomic>
namespace Common {
class SpinLock {
public:
void lock();
void unlock();
private:
std::atomic_flag lck = ATOMIC_FLAG_INIT;
};
} // namespace Common