Przeglądaj źródła

core: hle: kernel: k_thread: Add KScopedDisableDispatch.

bunnei 5 lat temu
rodzic
commit
04daefa488
2 zmienionych plików z 47 dodań i 1 usunięć
  1. 16 1
      src/core/hle/kernel/k_thread.cpp
  2. 31 0
      src/core/hle/kernel/k_thread.h

+ 16 - 1
src/core/hle/kernel/k_thread.cpp

@@ -184,7 +184,7 @@ ResultCode KThread::Initialize(KThreadFunction func, uintptr_t arg, VAddr user_s
     // Setup the stack parameters.
     StackParameters& sp = GetStackParameters();
     sp.cur_thread = this;
-    sp.disable_count = 1;
+    sp.disable_count = 0;
     SetInExceptionHandler();
 
     // Set thread ID.
@@ -966,6 +966,9 @@ ResultCode KThread::Run() {
 
         // Set our state and finish.
         SetState(ThreadState::Runnable);
+
+        DisableDispatch();
+
         return ResultSuccess;
     }
 }
@@ -1050,4 +1053,16 @@ s32 GetCurrentCoreId(KernelCore& kernel) {
     return GetCurrentThread(kernel).GetCurrentCore();
 }
 
+KScopedDisableDispatch::~KScopedDisableDispatch() {
+    if (GetCurrentThread(kernel).GetDisableDispatchCount() <= 1) {
+        auto scheduler = kernel.CurrentScheduler();
+
+        if (scheduler) {
+            scheduler->RescheduleCurrentCore();
+        }
+    } else {
+        GetCurrentThread(kernel).EnableDispatch();
+    }
+}
+
 } // namespace Kernel

+ 31 - 0
src/core/hle/kernel/k_thread.h

@@ -450,16 +450,35 @@ public:
         sleeping_queue = q;
     }
 
+    [[nodiscard]] bool IsKernelThread() const {
+        return GetActiveCore() == 3;
+    }
+
     [[nodiscard]] s32 GetDisableDispatchCount() const {
+        if (IsKernelThread()) {
+            // TODO(bunnei): Until kernel threads are emulated, we cannot enable/disable dispatch.
+            return 1;
+        }
+
         return this->GetStackParameters().disable_count;
     }
 
     void DisableDispatch() {
+        if (IsKernelThread()) {
+            // TODO(bunnei): Until kernel threads are emulated, we cannot enable/disable dispatch.
+            return;
+        }
+
         ASSERT(GetCurrentThread(kernel).GetDisableDispatchCount() >= 0);
         this->GetStackParameters().disable_count++;
     }
 
     void EnableDispatch() {
+        if (IsKernelThread()) {
+            // TODO(bunnei): Until kernel threads are emulated, we cannot enable/disable dispatch.
+            return;
+        }
+
         ASSERT(GetCurrentThread(kernel).GetDisableDispatchCount() > 0);
         this->GetStackParameters().disable_count--;
     }
@@ -752,4 +771,16 @@ public:
     }
 };
 
+class KScopedDisableDispatch {
+public:
+    explicit KScopedDisableDispatch(KernelCore& kernel_) : kernel{kernel_} {
+        GetCurrentThread(kernel).DisableDispatch();
+    }
+
+    ~KScopedDisableDispatch();
+
+private:
+    KernelCore& kernel;
+};
+
 } // namespace Kernel