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

hle: kernel: KProcess: Improvements for thread pinning.

bunnei 4 лет назад
Родитель
Сommit
316a2dd22a
2 измененных файлов с 26 добавлено и 8 удалено
  1. 22 5
      src/core/hle/kernel/k_process.cpp
  2. 4 3
      src/core/hle/kernel/k_process.h

+ 22 - 5
src/core/hle/kernel/k_process.cpp

@@ -228,12 +228,15 @@ void KProcess::PinCurrentThread() {
     const s32 core_id = GetCurrentCoreId(kernel);
     const s32 core_id = GetCurrentCoreId(kernel);
     KThread* cur_thread = GetCurrentThreadPointer(kernel);
     KThread* cur_thread = GetCurrentThreadPointer(kernel);
 
 
-    // Pin it.
-    PinThread(core_id, cur_thread);
-    cur_thread->Pin();
+    // If the thread isn't terminated, pin it.
+    if (!cur_thread->IsTerminationRequested()) {
+        // Pin it.
+        PinThread(core_id, cur_thread);
+        cur_thread->Pin();
 
 
-    // An update is needed.
-    KScheduler::SetSchedulerUpdateNeeded(kernel);
+        // An update is needed.
+        KScheduler::SetSchedulerUpdateNeeded(kernel);
+    }
 }
 }
 
 
 void KProcess::UnpinCurrentThread() {
 void KProcess::UnpinCurrentThread() {
@@ -251,6 +254,20 @@ void KProcess::UnpinCurrentThread() {
     KScheduler::SetSchedulerUpdateNeeded(kernel);
     KScheduler::SetSchedulerUpdateNeeded(kernel);
 }
 }
 
 
+void KProcess::UnpinThread(KThread* thread) {
+    ASSERT(kernel.GlobalSchedulerContext().IsLocked());
+
+    // Get the thread's core id.
+    const auto core_id = thread->GetActiveCore();
+
+    // Unpin it.
+    UnpinThread(core_id, thread);
+    thread->Unpin();
+
+    // An update is needed.
+    KScheduler::SetSchedulerUpdateNeeded(kernel);
+}
+
 ResultCode KProcess::AddSharedMemory(KSharedMemory* shmem, [[maybe_unused]] VAddr address,
 ResultCode KProcess::AddSharedMemory(KSharedMemory* shmem, [[maybe_unused]] VAddr address,
                                      [[maybe_unused]] size_t size) {
                                      [[maybe_unused]] size_t size) {
     // Lock ourselves, to prevent concurrent access.
     // Lock ourselves, to prevent concurrent access.

+ 4 - 3
src/core/hle/kernel/k_process.h

@@ -259,7 +259,7 @@ public:
 
 
     [[nodiscard]] KThread* GetPinnedThread(s32 core_id) const {
     [[nodiscard]] KThread* GetPinnedThread(s32 core_id) const {
         ASSERT(0 <= core_id && core_id < static_cast<s32>(Core::Hardware::NUM_CPU_CORES));
         ASSERT(0 <= core_id && core_id < static_cast<s32>(Core::Hardware::NUM_CPU_CORES));
-        return pinned_threads[core_id];
+        return pinned_threads.at(core_id);
     }
     }
 
 
     /// Gets 8 bytes of random data for svcGetInfo RandomEntropy
     /// Gets 8 bytes of random data for svcGetInfo RandomEntropy
@@ -347,6 +347,7 @@ public:
 
 
     void PinCurrentThread();
     void PinCurrentThread();
     void UnpinCurrentThread();
     void UnpinCurrentThread();
+    void UnpinThread(KThread* thread);
 
 
     KLightLock& GetStateLock() {
     KLightLock& GetStateLock() {
         return state_lock;
         return state_lock;
@@ -368,14 +369,14 @@ private:
     void PinThread(s32 core_id, KThread* thread) {
     void PinThread(s32 core_id, KThread* thread) {
         ASSERT(0 <= core_id && core_id < static_cast<s32>(Core::Hardware::NUM_CPU_CORES));
         ASSERT(0 <= core_id && core_id < static_cast<s32>(Core::Hardware::NUM_CPU_CORES));
         ASSERT(thread != nullptr);
         ASSERT(thread != nullptr);
-        ASSERT(pinned_threads[core_id] == nullptr);
+        ASSERT(pinned_threads.at(core_id) == nullptr);
         pinned_threads[core_id] = thread;
         pinned_threads[core_id] = thread;
     }
     }
 
 
     void UnpinThread(s32 core_id, KThread* thread) {
     void UnpinThread(s32 core_id, KThread* thread) {
         ASSERT(0 <= core_id && core_id < static_cast<s32>(Core::Hardware::NUM_CPU_CORES));
         ASSERT(0 <= core_id && core_id < static_cast<s32>(Core::Hardware::NUM_CPU_CORES));
         ASSERT(thread != nullptr);
         ASSERT(thread != nullptr);
-        ASSERT(pinned_threads[core_id] == thread);
+        ASSERT(pinned_threads.at(core_id) == thread);
         pinned_threads[core_id] = nullptr;
         pinned_threads[core_id] = nullptr;
     }
     }