diff options
Diffstat (limited to 'src/core/hle/kernel/svc.cpp')
| -rw-r--r-- | src/core/hle/kernel/svc.cpp | 35 |
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 | |||
| 1521 | return ResultInvalidPriority; | 1521 | return ResultInvalidPriority; |
| 1522 | } | 1522 | } |
| 1523 | 1523 | ||
| 1524 | // Reserve a new thread from the process resource limit (waiting up to 100ms). | ||
| 1524 | KScopedResourceReservation thread_reservation( | 1525 | KScopedResourceReservation thread_reservation( |
| 1525 | kernel.CurrentProcess(), LimitableResource::Threads, 1, | 1526 | kernel.CurrentProcess(), LimitableResource::Threads, 1, |
| 1526 | system.CoreTiming().GetGlobalTimeNs().count() + 100000000); | 1527 | system.CoreTiming().GetGlobalTimeNs().count() + 100000000); |
| @@ -1529,27 +1530,33 @@ static ResultCode CreateThread(Core::System& system, Handle* out_handle, VAddr e | |||
| 1529 | return ResultResourceLimitedExceeded; | 1530 | return ResultResourceLimitedExceeded; |
| 1530 | } | 1531 | } |
| 1531 | 1532 | ||
| 1532 | std::shared_ptr<KThread> thread; | 1533 | // Create the thread. |
| 1533 | { | 1534 | KThread* thread = KThread::CreateWithKernel(kernel); |
| 1534 | KScopedLightLock lk{process.GetStateLock()}; | 1535 | if (!thread) { |
| 1535 | CASCADE_RESULT(thread, | 1536 | LOG_ERROR(Kernel_SVC, "Unable to create new threads. Thread creation limit reached."); |
| 1536 | KThread::CreateUserThread(system, ThreadType::User, "", entry_point, | 1537 | return ResultOutOfResource; |
| 1537 | priority, arg, core_id, stack_bottom, &process)); | ||
| 1538 | } | 1538 | } |
| 1539 | SCOPE_EXIT({ thread->Close(); }); | ||
| 1539 | 1540 | ||
| 1540 | const auto new_thread_handle = process.GetHandleTable().Create(thread); | 1541 | // Initialize the thread. |
| 1541 | if (new_thread_handle.Failed()) { | 1542 | { |
| 1542 | LOG_ERROR(Kernel_SVC, "Failed to create handle with error=0x{:X}", | 1543 | KScopedLightLock lk{process.GetStateLock()}; |
| 1543 | new_thread_handle.Code().raw); | 1544 | R_TRY(KThread::InitializeUserThread(system, thread, entry_point, arg, stack_bottom, |
| 1544 | return new_thread_handle.Code(); | 1545 | priority, core_id, &process)); |
| 1545 | } | 1546 | } |
| 1546 | *out_handle = *new_thread_handle; | ||
| 1547 | 1547 | ||
| 1548 | // Set the thread name for debugging purposes. | 1548 | // Set the thread name for debugging purposes. |
| 1549 | thread->SetName( | 1549 | thread->SetName(fmt::format("thread[entry_point={:X}, handle={:X}]", entry_point, *out_handle)); |
| 1550 | fmt::format("thread[entry_point={:X}, handle={:X}]", entry_point, *new_thread_handle)); | 1550 | |
| 1551 | // Commit the thread reservation. | ||
| 1551 | thread_reservation.Commit(); | 1552 | thread_reservation.Commit(); |
| 1552 | 1553 | ||
| 1554 | // Register the new thread. | ||
| 1555 | KThread::Register(thread); | ||
| 1556 | |||
| 1557 | // Add the thread to the handle table. | ||
| 1558 | R_TRY(process.GetHandleTable().Add(out_handle, thread)); | ||
| 1559 | |||
| 1553 | return RESULT_SUCCESS; | 1560 | return RESULT_SUCCESS; |
| 1554 | } | 1561 | } |
| 1555 | 1562 | ||