Browse Source

hle: kernel: svc: Migrate CreateThread.

bunnei 5 years ago
parent
commit
de4746ff69
1 changed files with 21 additions and 14 deletions
  1. 21 14
      src/core/hle/kernel/svc.cpp

+ 21 - 14
src/core/hle/kernel/svc.cpp

@@ -1521,6 +1521,7 @@ static ResultCode CreateThread(Core::System& system, Handle* out_handle, VAddr e
         return ResultInvalidPriority;
         return ResultInvalidPriority;
     }
     }
 
 
+    // Reserve a new thread from the process resource limit (waiting up to 100ms).
     KScopedResourceReservation thread_reservation(
     KScopedResourceReservation thread_reservation(
         kernel.CurrentProcess(), LimitableResource::Threads, 1,
         kernel.CurrentProcess(), LimitableResource::Threads, 1,
         system.CoreTiming().GetGlobalTimeNs().count() + 100000000);
         system.CoreTiming().GetGlobalTimeNs().count() + 100000000);
@@ -1529,27 +1530,33 @@ static ResultCode CreateThread(Core::System& system, Handle* out_handle, VAddr e
         return ResultResourceLimitedExceeded;
         return ResultResourceLimitedExceeded;
     }
     }
 
 
-    std::shared_ptr<KThread> thread;
-    {
-        KScopedLightLock lk{process.GetStateLock()};
-        CASCADE_RESULT(thread,
-                       KThread::CreateUserThread(system, ThreadType::User, "", entry_point,
-                                                 priority, arg, core_id, stack_bottom, &process));
+    // Create the thread.
+    KThread* thread = KThread::CreateWithKernel(kernel);
+    if (!thread) {
+        LOG_ERROR(Kernel_SVC, "Unable to create new threads. Thread creation limit reached.");
+        return ResultOutOfResource;
     }
     }
+    SCOPE_EXIT({ thread->Close(); });
 
 
-    const auto new_thread_handle = process.GetHandleTable().Create(thread);
-    if (new_thread_handle.Failed()) {
-        LOG_ERROR(Kernel_SVC, "Failed to create handle with error=0x{:X}",
-                  new_thread_handle.Code().raw);
-        return new_thread_handle.Code();
+    // Initialize the thread.
+    {
+        KScopedLightLock lk{process.GetStateLock()};
+        R_TRY(KThread::InitializeUserThread(system, thread, entry_point, arg, stack_bottom,
+                                            priority, core_id, &process));
     }
     }
-    *out_handle = *new_thread_handle;
 
 
     // Set the thread name for debugging purposes.
     // Set the thread name for debugging purposes.
-    thread->SetName(
-        fmt::format("thread[entry_point={:X}, handle={:X}]", entry_point, *new_thread_handle));
+    thread->SetName(fmt::format("thread[entry_point={:X}, handle={:X}]", entry_point, *out_handle));
+
+    // Commit the thread reservation.
     thread_reservation.Commit();
     thread_reservation.Commit();
 
 
+    // Register the new thread.
+    KThread::Register(thread);
+
+    // Add the thread to the handle table.
+    R_TRY(process.GetHandleTable().Add(out_handle, thread));
+
     return RESULT_SUCCESS;
     return RESULT_SUCCESS;
 }
 }