hle: kernel: Add KSpinLock implementation.
This commit is contained in:
		| @@ -177,6 +177,8 @@ add_library(core STATIC | ||||
|     hle/kernel/k_scoped_scheduler_lock_and_sleep.h | ||||
|     hle/kernel/k_shared_memory.cpp | ||||
|     hle/kernel/k_shared_memory.h | ||||
|     hle/kernel/k_spin_lock.cpp | ||||
|     hle/kernel/k_spin_lock.h | ||||
|     hle/kernel/k_synchronization_object.cpp | ||||
|     hle/kernel/k_synchronization_object.h | ||||
|     hle/kernel/k_thread.cpp | ||||
|   | ||||
							
								
								
									
										54
									
								
								src/core/hle/kernel/k_spin_lock.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										54
									
								
								src/core/hle/kernel/k_spin_lock.cpp
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,54 @@ | ||||
| // Copyright 2021 yuzu Emulator Project | ||||
| // Licensed under GPLv2 or any later version | ||||
| // Refer to the license.txt file included. | ||||
|  | ||||
| #include "core/hle/kernel/k_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 | ||||
| } | ||||
|  | ||||
| } // namespace | ||||
|  | ||||
| namespace Kernel { | ||||
|  | ||||
| void KSpinLock::Lock() { | ||||
|     while (lck.test_and_set(std::memory_order_acquire)) { | ||||
|         ThreadPause(); | ||||
|     } | ||||
| } | ||||
|  | ||||
| void KSpinLock::Unlock() { | ||||
|     lck.clear(std::memory_order_release); | ||||
| } | ||||
|  | ||||
| bool KSpinLock::TryLock() { | ||||
|     if (lck.test_and_set(std::memory_order_acquire)) { | ||||
|         return false; | ||||
|     } | ||||
|     return true; | ||||
| } | ||||
|  | ||||
| } // namespace Kernel | ||||
							
								
								
									
										33
									
								
								src/core/hle/kernel/k_spin_lock.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										33
									
								
								src/core/hle/kernel/k_spin_lock.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,33 @@ | ||||
| // Copyright 2021 yuzu Emulator Project | ||||
| // Licensed under GPLv2 or any later version | ||||
| // Refer to the license.txt file included. | ||||
|  | ||||
| #pragma once | ||||
|  | ||||
| #include <atomic> | ||||
|  | ||||
| #include "core/hle/kernel/k_scoped_lock.h" | ||||
|  | ||||
| namespace Kernel { | ||||
|  | ||||
| class KSpinLock { | ||||
| public: | ||||
|     KSpinLock() = default; | ||||
|  | ||||
|     KSpinLock(const KSpinLock&) = delete; | ||||
|     KSpinLock& operator=(const KSpinLock&) = delete; | ||||
|  | ||||
|     KSpinLock(KSpinLock&&) = delete; | ||||
|     KSpinLock& operator=(KSpinLock&&) = delete; | ||||
|  | ||||
|     void Lock(); | ||||
|     void Unlock(); | ||||
|     [[nodiscard]] bool TryLock(); | ||||
|  | ||||
| private: | ||||
|     std::atomic_flag lck = ATOMIC_FLAG_INIT; | ||||
| }; | ||||
|  | ||||
| using KScopedSpinLock = KScopedLock<KSpinLock>; | ||||
|  | ||||
| } // namespace Kernel | ||||
		Reference in New Issue
	
	Block a user