summaryrefslogtreecommitdiffstats
path: root/src/core/hle/kernel
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--src/core/hle/kernel/svc.cpp35
1 files changed, 21 insertions, 14 deletions
diff --git a/src/core/hle/kernel/svc.cpp b/src/core/hle/kernel/svc.cpp
index bebb86154..036603315 100644
--- a/src/core/hle/kernel/svc.cpp
+++ b/src/core/hle/kernel/svc.cpp
@@ -1521,6 +1521,7 @@ static ResultCode CreateThread(Core::System& system, Handle* out_handle, VAddr e
return ResultInvalidPriority;
}
+ // Reserve a new thread from the process resource limit (waiting up to 100ms).
KScopedResourceReservation thread_reservation(
kernel.CurrentProcess(), LimitableResource::Threads, 1,
system.CoreTiming().GetGlobalTimeNs().count() + 100000000);
@@ -1529,27 +1530,33 @@ static ResultCode CreateThread(Core::System& system, Handle* out_handle, VAddr e
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.
- 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();
+ // 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;
}