kernel: KScopedReservation implementation
This implements KScopedReservation, allowing resource limit reservations to be more HW accurate, and release upon failure without requiring too many conditionals.
This commit is contained in:
parent
37939482fb
commit
5fa6b15215
6 changed files with 152 additions and 26 deletions
|
@ -30,6 +30,7 @@
|
|||
#include "core/hle/kernel/k_readable_event.h"
|
||||
#include "core/hle/kernel/k_resource_limit.h"
|
||||
#include "core/hle/kernel/k_scheduler.h"
|
||||
#include "core/hle/kernel/k_scoped_resource_reservation.h"
|
||||
#include "core/hle/kernel/k_scoped_scheduler_lock_and_sleep.h"
|
||||
#include "core/hle/kernel/k_synchronization_object.h"
|
||||
#include "core/hle/kernel/k_thread.h"
|
||||
|
@ -1516,8 +1517,13 @@ static ResultCode CreateThread(Core::System& system, Handle* out_handle, VAddr e
|
|||
return ResultInvalidPriority;
|
||||
}
|
||||
|
||||
ASSERT(process.GetResourceLimit()->Reserve(
|
||||
LimitableResource::Threads, 1, system.CoreTiming().GetGlobalTimeNs().count() + 100000000));
|
||||
KScopedResourceReservation thread_reservation(
|
||||
kernel.CurrentProcess(), LimitableResource::Threads, 1,
|
||||
system.CoreTiming().GetGlobalTimeNs().count() + 100000000);
|
||||
if (!thread_reservation.Succeeded()) {
|
||||
LOG_ERROR(Kernel_SVC, "Could not reserve a new thread");
|
||||
return ERR_RESOURCE_LIMIT_EXCEEDED;
|
||||
}
|
||||
|
||||
std::shared_ptr<KThread> thread;
|
||||
{
|
||||
|
@ -1537,6 +1543,7 @@ static ResultCode CreateThread(Core::System& system, Handle* out_handle, VAddr e
|
|||
// Set the thread name for debugging purposes.
|
||||
thread->SetName(
|
||||
fmt::format("thread[entry_point={:X}, handle={:X}]", entry_point, *new_thread_handle));
|
||||
thread_reservation.Commit();
|
||||
|
||||
return RESULT_SUCCESS;
|
||||
}
|
||||
|
@ -1884,6 +1891,13 @@ static ResultCode CreateTransferMemory(Core::System& system, Handle* handle, VAd
|
|||
}
|
||||
|
||||
auto& kernel = system.Kernel();
|
||||
// Reserve a new transfer memory from the process resource limit.
|
||||
KScopedResourceReservation trmem_reservation(kernel.CurrentProcess(),
|
||||
LimitableResource::TransferMemory);
|
||||
if (!trmem_reservation.Succeeded()) {
|
||||
LOG_ERROR(Kernel_SVC, "Could not reserve a new transfer memory");
|
||||
return ERR_RESOURCE_LIMIT_EXCEEDED;
|
||||
}
|
||||
auto transfer_mem_handle = TransferMemory::Create(kernel, system.Memory(), addr, size, perms);
|
||||
|
||||
if (const auto reserve_result{transfer_mem_handle->Reserve()}; reserve_result.IsError()) {
|
||||
|
@ -1895,6 +1909,7 @@ static ResultCode CreateTransferMemory(Core::System& system, Handle* handle, VAd
|
|||
if (result.Failed()) {
|
||||
return result.Code();
|
||||
}
|
||||
trmem_reservation.Commit();
|
||||
|
||||
*handle = *result;
|
||||
return RESULT_SUCCESS;
|
||||
|
@ -2002,8 +2017,17 @@ static ResultCode SetThreadCoreMask32(Core::System& system, Handle thread_handle
|
|||
static ResultCode SignalEvent(Core::System& system, Handle event_handle) {
|
||||
LOG_DEBUG(Kernel_SVC, "called, event_handle=0x{:08X}", event_handle);
|
||||
|
||||
auto& kernel = system.Kernel();
|
||||
// Get the current handle table.
|
||||
const HandleTable& handle_table = system.Kernel().CurrentProcess()->GetHandleTable();
|
||||
const HandleTable& handle_table = kernel.CurrentProcess()->GetHandleTable();
|
||||
|
||||
// Reserve a new event from the process resource limit.
|
||||
KScopedResourceReservation event_reservation(kernel.CurrentProcess(),
|
||||
LimitableResource::Events);
|
||||
if (!event_reservation.Succeeded()) {
|
||||
LOG_ERROR(Kernel, "Could not reserve a new event");
|
||||
return ERR_RESOURCE_LIMIT_EXCEEDED;
|
||||
}
|
||||
|
||||
// Get the writable event.
|
||||
auto writable_event = handle_table.Get<KWritableEvent>(event_handle);
|
||||
|
@ -2012,6 +2036,9 @@ static ResultCode SignalEvent(Core::System& system, Handle event_handle) {
|
|||
return ResultInvalidHandle;
|
||||
}
|
||||
|
||||
// Commit the successfuly reservation.
|
||||
event_reservation.Commit();
|
||||
|
||||
return writable_event->Signal();
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue