1 // Copyright 2020 yuzu Emulator Project
2 // Licensed under GPLv2 or any later version
3 // Refer to the license.txt file included.
4 
5 #include "common/spin_lock.h"
6 
7 #if _MSC_VER
8 #include <intrin.h>
9 #if _M_AMD64
10 #define __x86_64__ 1
11 #endif
12 #if _M_ARM64
13 #define __aarch64__ 1
14 #endif
15 #else
16 #if __x86_64__
17 #include <xmmintrin.h>
18 #endif
19 #endif
20 
21 namespace {
22 
ThreadPause()23 void ThreadPause() {
24 #if __x86_64__
25     _mm_pause();
26 #elif __aarch64__ && _MSC_VER
27     __yield();
28 #elif __aarch64__
29     asm("yield");
30 #endif
31 }
32 
33 } // Anonymous namespace
34 
35 namespace Common {
36 
lock()37 void SpinLock::lock() {
38     while (lck.test_and_set(std::memory_order_acquire)) {
39         ThreadPause();
40     }
41 }
42 
unlock()43 void SpinLock::unlock() {
44     lck.clear(std::memory_order_release);
45 }
46 
try_lock()47 bool SpinLock::try_lock() {
48     if (lck.test_and_set(std::memory_order_acquire)) {
49         return false;
50     }
51     return true;
52 }
53 
54 } // namespace Common
55