summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGravatar bunnei2022-04-07 16:01:26 -0700
committerGravatar bunnei2022-04-11 21:13:40 -0700
commit8deaac8bd1707f56f29d61e427ad53964a0920fd (patch)
treed17e4ed20b9249507ad587aa0eb82e277daff614
parentMerge pull request #8157 from lat9nq/kernel-races (diff)
downloadyuzu-8deaac8bd1707f56f29d61e427ad53964a0920fd.tar.gz
yuzu-8deaac8bd1707f56f29d61e427ad53964a0920fd.tar.xz
yuzu-8deaac8bd1707f56f29d61e427ad53964a0920fd.zip
hle: kernel: Use std::mutex instead of spin locks for most kernel locking.
Diffstat (limited to '')
-rw-r--r--src/common/fiber.cpp5
-rw-r--r--src/core/core_timing.h6
-rw-r--r--src/core/hle/kernel/global_scheduler_context.h3
-rw-r--r--src/core/hle/kernel/k_scheduler.cpp8
-rw-r--r--src/core/hle/kernel/k_spin_lock.cpp11
-rw-r--r--src/core/hle/kernel/k_spin_lock.h4
-rw-r--r--src/core/hle/kernel/k_thread.h3
-rw-r--r--src/core/hle/kernel/physical_core.cpp3
-rw-r--r--src/core/hle/kernel/physical_core.h7
-rw-r--r--src/core/hle/service/service.h5
10 files changed, 23 insertions, 32 deletions
diff --git a/src/common/fiber.cpp b/src/common/fiber.cpp
index 81b212e4b..177a74deb 100644
--- a/src/common/fiber.cpp
+++ b/src/common/fiber.cpp
@@ -2,9 +2,10 @@
2// Licensed under GPLv2 or any later version 2// Licensed under GPLv2 or any later version
3// Refer to the license.txt file included. 3// Refer to the license.txt file included.
4 4
5#include <mutex>
6
5#include "common/assert.h" 7#include "common/assert.h"
6#include "common/fiber.h" 8#include "common/fiber.h"
7#include "common/spin_lock.h"
8#include "common/virtual_buffer.h" 9#include "common/virtual_buffer.h"
9 10
10#include <boost/context/detail/fcontext.hpp> 11#include <boost/context/detail/fcontext.hpp>
@@ -19,7 +20,7 @@ struct Fiber::FiberImpl {
19 VirtualBuffer<u8> stack; 20 VirtualBuffer<u8> stack;
20 VirtualBuffer<u8> rewind_stack; 21 VirtualBuffer<u8> rewind_stack;
21 22
22 SpinLock guard{}; 23 std::mutex guard;
23 std::function<void(void*)> entry_point; 24 std::function<void(void*)> entry_point;
24 std::function<void(void*)> rewind_point; 25 std::function<void(void*)> rewind_point;
25 void* rewind_parameter{}; 26 void* rewind_parameter{};
diff --git a/src/core/core_timing.h b/src/core/core_timing.h
index 888828fd0..28b63be43 100644
--- a/src/core/core_timing.h
+++ b/src/core/core_timing.h
@@ -8,13 +8,13 @@
8#include <chrono> 8#include <chrono>
9#include <functional> 9#include <functional>
10#include <memory> 10#include <memory>
11#include <mutex>
11#include <optional> 12#include <optional>
12#include <string> 13#include <string>
13#include <thread> 14#include <thread>
14#include <vector> 15#include <vector>
15 16
16#include "common/common_types.h" 17#include "common/common_types.h"
17#include "common/spin_lock.h"
18#include "common/thread.h" 18#include "common/thread.h"
19#include "common/wall_clock.h" 19#include "common/wall_clock.h"
20 20
@@ -149,8 +149,8 @@ private:
149 std::shared_ptr<EventType> ev_lost; 149 std::shared_ptr<EventType> ev_lost;
150 Common::Event event{}; 150 Common::Event event{};
151 Common::Event pause_event{}; 151 Common::Event pause_event{};
152 Common::SpinLock basic_lock{}; 152 std::mutex basic_lock;
153 Common::SpinLock advance_lock{}; 153 std::mutex advance_lock;
154 std::unique_ptr<std::thread> timer_thread; 154 std::unique_ptr<std::thread> timer_thread;
155 std::atomic<bool> paused{}; 155 std::atomic<bool> paused{};
156 std::atomic<bool> paused_set{}; 156 std::atomic<bool> paused_set{};
diff --git a/src/core/hle/kernel/global_scheduler_context.h b/src/core/hle/kernel/global_scheduler_context.h
index 6f44b534f..47425a3a1 100644
--- a/src/core/hle/kernel/global_scheduler_context.h
+++ b/src/core/hle/kernel/global_scheduler_context.h
@@ -8,7 +8,6 @@
8#include <vector> 8#include <vector>
9 9
10#include "common/common_types.h" 10#include "common/common_types.h"
11#include "common/spin_lock.h"
12#include "core/hardware_properties.h" 11#include "core/hardware_properties.h"
13#include "core/hle/kernel/k_priority_queue.h" 12#include "core/hle/kernel/k_priority_queue.h"
14#include "core/hle/kernel/k_scheduler_lock.h" 13#include "core/hle/kernel/k_scheduler_lock.h"
@@ -80,7 +79,7 @@ private:
80 79
81 /// Lists all thread ids that aren't deleted/etc. 80 /// Lists all thread ids that aren't deleted/etc.
82 std::vector<KThread*> thread_list; 81 std::vector<KThread*> thread_list;
83 Common::SpinLock global_list_guard{}; 82 std::mutex global_list_guard;
84}; 83};
85 84
86} // namespace Kernel 85} // namespace Kernel
diff --git a/src/core/hle/kernel/k_scheduler.cpp b/src/core/hle/kernel/k_scheduler.cpp
index 6c0bb1672..526eb4b70 100644
--- a/src/core/hle/kernel/k_scheduler.cpp
+++ b/src/core/hle/kernel/k_scheduler.cpp
@@ -705,7 +705,7 @@ void KScheduler::Unload(KThread* thread) {
705 prev_thread = nullptr; 705 prev_thread = nullptr;
706 } 706 }
707 707
708 thread->context_guard.Unlock(); 708 thread->context_guard.unlock();
709} 709}
710 710
711void KScheduler::Reload(KThread* thread) { 711void KScheduler::Reload(KThread* thread) {
@@ -794,13 +794,13 @@ void KScheduler::SwitchToCurrent() {
794 do { 794 do {
795 auto next_thread = current_thread.load(); 795 auto next_thread = current_thread.load();
796 if (next_thread != nullptr) { 796 if (next_thread != nullptr) {
797 const auto locked = next_thread->context_guard.TryLock(); 797 const auto locked = next_thread->context_guard.try_lock();
798 if (state.needs_scheduling.load()) { 798 if (state.needs_scheduling.load()) {
799 next_thread->context_guard.Unlock(); 799 next_thread->context_guard.unlock();
800 break; 800 break;
801 } 801 }
802 if (next_thread->GetActiveCore() != core_id) { 802 if (next_thread->GetActiveCore() != core_id) {
803 next_thread->context_guard.Unlock(); 803 next_thread->context_guard.unlock();
804 break; 804 break;
805 } 805 }
806 if (!locked) { 806 if (!locked) {
diff --git a/src/core/hle/kernel/k_spin_lock.cpp b/src/core/hle/kernel/k_spin_lock.cpp
index 4412aa4bb..4df2e5c1a 100644
--- a/src/core/hle/kernel/k_spin_lock.cpp
+++ b/src/core/hle/kernel/k_spin_lock.cpp
@@ -35,20 +35,15 @@ void ThreadPause() {
35namespace Kernel { 35namespace Kernel {
36 36
37void KSpinLock::Lock() { 37void KSpinLock::Lock() {
38 while (lck.test_and_set(std::memory_order_acquire)) { 38 lck.lock();
39 ThreadPause();
40 }
41} 39}
42 40
43void KSpinLock::Unlock() { 41void KSpinLock::Unlock() {
44 lck.clear(std::memory_order_release); 42 lck.unlock();
45} 43}
46 44
47bool KSpinLock::TryLock() { 45bool KSpinLock::TryLock() {
48 if (lck.test_and_set(std::memory_order_acquire)) { 46 return lck.try_lock();
49 return false;
50 }
51 return true;
52} 47}
53 48
54} // namespace Kernel 49} // namespace Kernel
diff --git a/src/core/hle/kernel/k_spin_lock.h b/src/core/hle/kernel/k_spin_lock.h
index 4d87d006a..7868b25a5 100644
--- a/src/core/hle/kernel/k_spin_lock.h
+++ b/src/core/hle/kernel/k_spin_lock.h
@@ -4,7 +4,7 @@
4 4
5#pragma once 5#pragma once
6 6
7#include <atomic> 7#include <mutex>
8 8
9#include "core/hle/kernel/k_scoped_lock.h" 9#include "core/hle/kernel/k_scoped_lock.h"
10 10
@@ -25,7 +25,7 @@ public:
25 [[nodiscard]] bool TryLock(); 25 [[nodiscard]] bool TryLock();
26 26
27private: 27private:
28 std::atomic_flag lck = ATOMIC_FLAG_INIT; 28 std::mutex lck;
29}; 29};
30 30
31// TODO(bunnei): Alias for now, in case we want to implement these accurately in the future. 31// TODO(bunnei): Alias for now, in case we want to implement these accurately in the future.
diff --git a/src/core/hle/kernel/k_thread.h b/src/core/hle/kernel/k_thread.h
index d0fd85130..c141fc11b 100644
--- a/src/core/hle/kernel/k_thread.h
+++ b/src/core/hle/kernel/k_thread.h
@@ -15,6 +15,7 @@
15 15
16#include "common/common_types.h" 16#include "common/common_types.h"
17#include "common/intrusive_red_black_tree.h" 17#include "common/intrusive_red_black_tree.h"
18#include "common/spin_lock.h"
18#include "core/arm/arm_interface.h" 19#include "core/arm/arm_interface.h"
19#include "core/hle/kernel/k_affinity_mask.h" 20#include "core/hle/kernel/k_affinity_mask.h"
20#include "core/hle/kernel/k_light_lock.h" 21#include "core/hle/kernel/k_light_lock.h"
@@ -762,7 +763,7 @@ private:
762 s8 priority_inheritance_count{}; 763 s8 priority_inheritance_count{};
763 bool resource_limit_release_hint{}; 764 bool resource_limit_release_hint{};
764 StackParameters stack_parameters{}; 765 StackParameters stack_parameters{};
765 KSpinLock context_guard{}; 766 Common::SpinLock context_guard{};
766 KSpinLock dummy_wait_lock{}; 767 KSpinLock dummy_wait_lock{};
767 768
768 // For emulation 769 // For emulation
diff --git a/src/core/hle/kernel/physical_core.cpp b/src/core/hle/kernel/physical_core.cpp
index 18a5f40f8..cc49e8c7e 100644
--- a/src/core/hle/kernel/physical_core.cpp
+++ b/src/core/hle/kernel/physical_core.cpp
@@ -2,7 +2,6 @@
2// Licensed under GPLv2 or any later version 2// Licensed under GPLv2 or any later version
3// Refer to the license.txt file included. 3// Refer to the license.txt file included.
4 4
5#include "common/spin_lock.h"
6#include "core/arm/cpu_interrupt_handler.h" 5#include "core/arm/cpu_interrupt_handler.h"
7#include "core/arm/dynarmic/arm_dynarmic_32.h" 6#include "core/arm/dynarmic/arm_dynarmic_32.h"
8#include "core/arm/dynarmic/arm_dynarmic_64.h" 7#include "core/arm/dynarmic/arm_dynarmic_64.h"
@@ -16,7 +15,7 @@ namespace Kernel {
16PhysicalCore::PhysicalCore(std::size_t core_index_, Core::System& system_, KScheduler& scheduler_, 15PhysicalCore::PhysicalCore(std::size_t core_index_, Core::System& system_, KScheduler& scheduler_,
17 Core::CPUInterrupts& interrupts_) 16 Core::CPUInterrupts& interrupts_)
18 : core_index{core_index_}, system{system_}, scheduler{scheduler_}, 17 : core_index{core_index_}, system{system_}, scheduler{scheduler_},
19 interrupts{interrupts_}, guard{std::make_unique<Common::SpinLock>()} { 18 interrupts{interrupts_}, guard{std::make_unique<std::mutex>()} {
20#ifdef ARCHITECTURE_x86_64 19#ifdef ARCHITECTURE_x86_64
21 // TODO(bunnei): Initialization relies on a core being available. We may later replace this with 20 // TODO(bunnei): Initialization relies on a core being available. We may later replace this with
22 // a 32-bit instance of Dynarmic. This should be abstracted out to a CPU manager. 21 // a 32-bit instance of Dynarmic. This should be abstracted out to a CPU manager.
diff --git a/src/core/hle/kernel/physical_core.h b/src/core/hle/kernel/physical_core.h
index 16a032e89..f2112fc1d 100644
--- a/src/core/hle/kernel/physical_core.h
+++ b/src/core/hle/kernel/physical_core.h
@@ -6,13 +6,10 @@
6 6
7#include <cstddef> 7#include <cstddef>
8#include <memory> 8#include <memory>
9#include <mutex>
9 10
10#include "core/arm/arm_interface.h" 11#include "core/arm/arm_interface.h"
11 12
12namespace Common {
13class SpinLock;
14}
15
16namespace Kernel { 13namespace Kernel {
17class KScheduler; 14class KScheduler;
18} // namespace Kernel 15} // namespace Kernel
@@ -91,7 +88,7 @@ private:
91 Core::System& system; 88 Core::System& system;
92 Kernel::KScheduler& scheduler; 89 Kernel::KScheduler& scheduler;
93 Core::CPUInterrupts& interrupts; 90 Core::CPUInterrupts& interrupts;
94 std::unique_ptr<Common::SpinLock> guard; 91 std::unique_ptr<std::mutex> guard;
95 std::unique_ptr<Core::ARM_Interface> arm_interface; 92 std::unique_ptr<Core::ARM_Interface> arm_interface;
96}; 93};
97 94
diff --git a/src/core/hle/service/service.h b/src/core/hle/service/service.h
index c78b2baeb..148265218 100644
--- a/src/core/hle/service/service.h
+++ b/src/core/hle/service/service.h
@@ -9,7 +9,6 @@
9#include <string> 9#include <string>
10#include <boost/container/flat_map.hpp> 10#include <boost/container/flat_map.hpp>
11#include "common/common_types.h" 11#include "common/common_types.h"
12#include "common/spin_lock.h"
13#include "core/hle/kernel/hle_ipc.h" 12#include "core/hle/kernel/hle_ipc.h"
14 13
15//////////////////////////////////////////////////////////////////////////////////////////////////// 14////////////////////////////////////////////////////////////////////////////////////////////////////
@@ -90,7 +89,7 @@ protected:
90 using HandlerFnP = void (Self::*)(Kernel::HLERequestContext&); 89 using HandlerFnP = void (Self::*)(Kernel::HLERequestContext&);
91 90
92 /// Used to gain exclusive access to the service members, e.g. from CoreTiming thread. 91 /// Used to gain exclusive access to the service members, e.g. from CoreTiming thread.
93 [[nodiscard]] std::scoped_lock<Common::SpinLock> LockService() { 92 [[nodiscard]] std::scoped_lock<std::mutex> LockService() {
94 return std::scoped_lock{lock_service}; 93 return std::scoped_lock{lock_service};
95 } 94 }
96 95
@@ -135,7 +134,7 @@ private:
135 boost::container::flat_map<u32, FunctionInfoBase> handlers_tipc; 134 boost::container::flat_map<u32, FunctionInfoBase> handlers_tipc;
136 135
137 /// Used to gain exclusive access to the service members, e.g. from CoreTiming thread. 136 /// Used to gain exclusive access to the service members, e.g. from CoreTiming thread.
138 Common::SpinLock lock_service; 137 std::mutex lock_service;
139}; 138};
140 139
141/** 140/**