Просмотр исходного кода

hle: kernel: Use std::mutex instead of spin locks for most kernel locking.

bunnei 4 лет назад
Родитель
Сommit
8deaac8bd1

+ 3 - 2
src/common/fiber.cpp

@@ -2,9 +2,10 @@
 // Licensed under GPLv2 or any later version
 // Refer to the license.txt file included.
 
+#include <mutex>
+
 #include "common/assert.h"
 #include "common/fiber.h"
-#include "common/spin_lock.h"
 #include "common/virtual_buffer.h"
 
 #include <boost/context/detail/fcontext.hpp>
@@ -19,7 +20,7 @@ struct Fiber::FiberImpl {
     VirtualBuffer<u8> stack;
     VirtualBuffer<u8> rewind_stack;
 
-    SpinLock guard{};
+    std::mutex guard;
     std::function<void(void*)> entry_point;
     std::function<void(void*)> rewind_point;
     void* rewind_parameter{};

+ 3 - 3
src/core/core_timing.h

@@ -8,13 +8,13 @@
 #include <chrono>
 #include <functional>
 #include <memory>
+#include <mutex>
 #include <optional>
 #include <string>
 #include <thread>
 #include <vector>
 
 #include "common/common_types.h"
-#include "common/spin_lock.h"
 #include "common/thread.h"
 #include "common/wall_clock.h"
 
@@ -149,8 +149,8 @@ private:
     std::shared_ptr<EventType> ev_lost;
     Common::Event event{};
     Common::Event pause_event{};
-    Common::SpinLock basic_lock{};
-    Common::SpinLock advance_lock{};
+    std::mutex basic_lock;
+    std::mutex advance_lock;
     std::unique_ptr<std::thread> timer_thread;
     std::atomic<bool> paused{};
     std::atomic<bool> paused_set{};

+ 1 - 2
src/core/hle/kernel/global_scheduler_context.h

@@ -8,7 +8,6 @@
 #include <vector>
 
 #include "common/common_types.h"
-#include "common/spin_lock.h"
 #include "core/hardware_properties.h"
 #include "core/hle/kernel/k_priority_queue.h"
 #include "core/hle/kernel/k_scheduler_lock.h"
@@ -80,7 +79,7 @@ private:
 
     /// Lists all thread ids that aren't deleted/etc.
     std::vector<KThread*> thread_list;
-    Common::SpinLock global_list_guard{};
+    std::mutex global_list_guard;
 };
 
 } // namespace Kernel

+ 4 - 4
src/core/hle/kernel/k_scheduler.cpp

@@ -705,7 +705,7 @@ void KScheduler::Unload(KThread* thread) {
         prev_thread = nullptr;
     }
 
-    thread->context_guard.Unlock();
+    thread->context_guard.unlock();
 }
 
 void KScheduler::Reload(KThread* thread) {
@@ -794,13 +794,13 @@ void KScheduler::SwitchToCurrent() {
         do {
             auto next_thread = current_thread.load();
             if (next_thread != nullptr) {
-                const auto locked = next_thread->context_guard.TryLock();
+                const auto locked = next_thread->context_guard.try_lock();
                 if (state.needs_scheduling.load()) {
-                    next_thread->context_guard.Unlock();
+                    next_thread->context_guard.unlock();
                     break;
                 }
                 if (next_thread->GetActiveCore() != core_id) {
-                    next_thread->context_guard.Unlock();
+                    next_thread->context_guard.unlock();
                     break;
                 }
                 if (!locked) {

+ 3 - 8
src/core/hle/kernel/k_spin_lock.cpp

@@ -35,20 +35,15 @@ void ThreadPause() {
 namespace Kernel {
 
 void KSpinLock::Lock() {
-    while (lck.test_and_set(std::memory_order_acquire)) {
-        ThreadPause();
-    }
+    lck.lock();
 }
 
 void KSpinLock::Unlock() {
-    lck.clear(std::memory_order_release);
+    lck.unlock();
 }
 
 bool KSpinLock::TryLock() {
-    if (lck.test_and_set(std::memory_order_acquire)) {
-        return false;
-    }
-    return true;
+    return lck.try_lock();
 }
 
 } // namespace Kernel

+ 2 - 2
src/core/hle/kernel/k_spin_lock.h

@@ -4,7 +4,7 @@
 
 #pragma once
 
-#include <atomic>
+#include <mutex>
 
 #include "core/hle/kernel/k_scoped_lock.h"
 
@@ -25,7 +25,7 @@ public:
     [[nodiscard]] bool TryLock();
 
 private:
-    std::atomic_flag lck = ATOMIC_FLAG_INIT;
+    std::mutex lck;
 };
 
 // TODO(bunnei): Alias for now, in case we want to implement these accurately in the future.

+ 2 - 1
src/core/hle/kernel/k_thread.h

@@ -15,6 +15,7 @@
 
 #include "common/common_types.h"
 #include "common/intrusive_red_black_tree.h"
+#include "common/spin_lock.h"
 #include "core/arm/arm_interface.h"
 #include "core/hle/kernel/k_affinity_mask.h"
 #include "core/hle/kernel/k_light_lock.h"
@@ -762,7 +763,7 @@ private:
     s8 priority_inheritance_count{};
     bool resource_limit_release_hint{};
     StackParameters stack_parameters{};
-    KSpinLock context_guard{};
+    Common::SpinLock context_guard{};
     KSpinLock dummy_wait_lock{};
 
     // For emulation

+ 1 - 2
src/core/hle/kernel/physical_core.cpp

@@ -2,7 +2,6 @@
 // Licensed under GPLv2 or any later version
 // Refer to the license.txt file included.
 
-#include "common/spin_lock.h"
 #include "core/arm/cpu_interrupt_handler.h"
 #include "core/arm/dynarmic/arm_dynarmic_32.h"
 #include "core/arm/dynarmic/arm_dynarmic_64.h"
@@ -16,7 +15,7 @@ namespace Kernel {
 PhysicalCore::PhysicalCore(std::size_t core_index_, Core::System& system_, KScheduler& scheduler_,
                            Core::CPUInterrupts& interrupts_)
     : core_index{core_index_}, system{system_}, scheduler{scheduler_},
-      interrupts{interrupts_}, guard{std::make_unique<Common::SpinLock>()} {
+      interrupts{interrupts_}, guard{std::make_unique<std::mutex>()} {
 #ifdef ARCHITECTURE_x86_64
     // TODO(bunnei): Initialization relies on a core being available. We may later replace this with
     // a 32-bit instance of Dynarmic. This should be abstracted out to a CPU manager.

+ 2 - 5
src/core/hle/kernel/physical_core.h

@@ -6,13 +6,10 @@
 
 #include <cstddef>
 #include <memory>
+#include <mutex>
 
 #include "core/arm/arm_interface.h"
 
-namespace Common {
-class SpinLock;
-}
-
 namespace Kernel {
 class KScheduler;
 } // namespace Kernel
@@ -91,7 +88,7 @@ private:
     Core::System& system;
     Kernel::KScheduler& scheduler;
     Core::CPUInterrupts& interrupts;
-    std::unique_ptr<Common::SpinLock> guard;
+    std::unique_ptr<std::mutex> guard;
     std::unique_ptr<Core::ARM_Interface> arm_interface;
 };
 

+ 2 - 3
src/core/hle/service/service.h

@@ -9,7 +9,6 @@
 #include <string>
 #include <boost/container/flat_map.hpp>
 #include "common/common_types.h"
-#include "common/spin_lock.h"
 #include "core/hle/kernel/hle_ipc.h"
 
 ////////////////////////////////////////////////////////////////////////////////////////////////////
@@ -90,7 +89,7 @@ protected:
     using HandlerFnP = void (Self::*)(Kernel::HLERequestContext&);
 
     /// Used to gain exclusive access to the service members, e.g. from CoreTiming thread.
-    [[nodiscard]] std::scoped_lock<Common::SpinLock> LockService() {
+    [[nodiscard]] std::scoped_lock<std::mutex> LockService() {
         return std::scoped_lock{lock_service};
     }
 
@@ -135,7 +134,7 @@ private:
     boost::container::flat_map<u32, FunctionInfoBase> handlers_tipc;
 
     /// Used to gain exclusive access to the service members, e.g. from CoreTiming thread.
-    Common::SpinLock lock_service;
+    std::mutex lock_service;
 };
 
 /**