diff options
author | David <25727384+ogniK5377@users.noreply.github.com> | 2020-06-28 01:34:07 +1000 |
---|---|---|
committer | GitHub <noreply@github.com> | 2020-06-28 01:34:07 +1000 |
commit | 0ea4a8bcc4bca14bb7c65b248ed1899d2e7167cf (patch) | |
tree | a83acb1e779b98d31fa54389bae4be5669573a41 /src/common/spin_lock.cpp | |
parent | 6205965df9682c3a52adbdcf260e7b24c02b24d4 (diff) | |
parent | 7b893c7963a57bf41f5dad7dd1709985971ce291 (diff) |
Merge pull request #3396 from FernandoS27/prometheus-1
Implement SpinLocks, Fibers and a Host Timer
Diffstat (limited to 'src/common/spin_lock.cpp')
-rw-r--r-- | src/common/spin_lock.cpp | 54 |
1 files changed, 54 insertions, 0 deletions
diff --git a/src/common/spin_lock.cpp b/src/common/spin_lock.cpp new file mode 100644 index 0000000000..c7b46aac6b --- /dev/null +++ b/src/common/spin_lock.cpp @@ -0,0 +1,54 @@ +// 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); +} + +bool SpinLock::try_lock() { + if (lck.test_and_set(std::memory_order_acquire)) { + return false; + } + return true; +} + +} // namespace Common |