summaryrefslogtreecommitdiff
path: root/src/core/hle/kernel/svc.cpp
diff options
context:
space:
mode:
authorGravatar ameerj2021-02-04 20:06:54 -0500
committerGravatar ameerj2021-02-12 18:57:34 -0500
commit5fa6b15215d2c15a1601c88ac1125a28c55797fc (patch)
tree4a25c58180aecd1eb9bcc3560a1a3dfa18c67761 /src/core/hle/kernel/svc.cpp
parentkernel: Unify result codes (#5890) (diff)
downloadyuzu-5fa6b15215d2c15a1601c88ac1125a28c55797fc.tar.gz
yuzu-5fa6b15215d2c15a1601c88ac1125a28c55797fc.tar.xz
yuzu-5fa6b15215d2c15a1601c88ac1125a28c55797fc.zip
kernel: KScopedReservation implementation
This implements KScopedReservation, allowing resource limit reservations to be more HW accurate, and release upon failure without requiring too many conditionals.
Diffstat (limited to 'src/core/hle/kernel/svc.cpp')
-rw-r--r--src/core/hle/kernel/svc.cpp33
1 files changed, 30 insertions, 3 deletions
diff --git a/src/core/hle/kernel/svc.cpp b/src/core/hle/kernel/svc.cpp
index 4ef3c7ac5..1d377ffe6 100644
--- a/src/core/hle/kernel/svc.cpp
+++ b/src/core/hle/kernel/svc.cpp
@@ -30,6 +30,7 @@
30#include "core/hle/kernel/k_readable_event.h" 30#include "core/hle/kernel/k_readable_event.h"
31#include "core/hle/kernel/k_resource_limit.h" 31#include "core/hle/kernel/k_resource_limit.h"
32#include "core/hle/kernel/k_scheduler.h" 32#include "core/hle/kernel/k_scheduler.h"
33#include "core/hle/kernel/k_scoped_resource_reservation.h"
33#include "core/hle/kernel/k_scoped_scheduler_lock_and_sleep.h" 34#include "core/hle/kernel/k_scoped_scheduler_lock_and_sleep.h"
34#include "core/hle/kernel/k_synchronization_object.h" 35#include "core/hle/kernel/k_synchronization_object.h"
35#include "core/hle/kernel/k_thread.h" 36#include "core/hle/kernel/k_thread.h"
@@ -1516,8 +1517,13 @@ static ResultCode CreateThread(Core::System& system, Handle* out_handle, VAddr e
1516 return ResultInvalidPriority; 1517 return ResultInvalidPriority;
1517 } 1518 }
1518 1519
1519 ASSERT(process.GetResourceLimit()->Reserve( 1520 KScopedResourceReservation thread_reservation(
1520 LimitableResource::Threads, 1, system.CoreTiming().GetGlobalTimeNs().count() + 100000000)); 1521 kernel.CurrentProcess(), LimitableResource::Threads, 1,
1522 system.CoreTiming().GetGlobalTimeNs().count() + 100000000);
1523 if (!thread_reservation.Succeeded()) {
1524 LOG_ERROR(Kernel_SVC, "Could not reserve a new thread");
1525 return ERR_RESOURCE_LIMIT_EXCEEDED;
1526 }
1521 1527
1522 std::shared_ptr<KThread> thread; 1528 std::shared_ptr<KThread> thread;
1523 { 1529 {
@@ -1537,6 +1543,7 @@ static ResultCode CreateThread(Core::System& system, Handle* out_handle, VAddr e
1537 // Set the thread name for debugging purposes. 1543 // Set the thread name for debugging purposes.
1538 thread->SetName( 1544 thread->SetName(
1539 fmt::format("thread[entry_point={:X}, handle={:X}]", entry_point, *new_thread_handle)); 1545 fmt::format("thread[entry_point={:X}, handle={:X}]", entry_point, *new_thread_handle));
1546 thread_reservation.Commit();
1540 1547
1541 return RESULT_SUCCESS; 1548 return RESULT_SUCCESS;
1542} 1549}
@@ -1884,6 +1891,13 @@ static ResultCode CreateTransferMemory(Core::System& system, Handle* handle, VAd
1884 } 1891 }
1885 1892
1886 auto& kernel = system.Kernel(); 1893 auto& kernel = system.Kernel();
1894 // Reserve a new transfer memory from the process resource limit.
1895 KScopedResourceReservation trmem_reservation(kernel.CurrentProcess(),
1896 LimitableResource::TransferMemory);
1897 if (!trmem_reservation.Succeeded()) {
1898 LOG_ERROR(Kernel_SVC, "Could not reserve a new transfer memory");
1899 return ERR_RESOURCE_LIMIT_EXCEEDED;
1900 }
1887 auto transfer_mem_handle = TransferMemory::Create(kernel, system.Memory(), addr, size, perms); 1901 auto transfer_mem_handle = TransferMemory::Create(kernel, system.Memory(), addr, size, perms);
1888 1902
1889 if (const auto reserve_result{transfer_mem_handle->Reserve()}; reserve_result.IsError()) { 1903 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
1895 if (result.Failed()) { 1909 if (result.Failed()) {
1896 return result.Code(); 1910 return result.Code();
1897 } 1911 }
1912 trmem_reservation.Commit();
1898 1913
1899 *handle = *result; 1914 *handle = *result;
1900 return RESULT_SUCCESS; 1915 return RESULT_SUCCESS;
@@ -2002,8 +2017,17 @@ static ResultCode SetThreadCoreMask32(Core::System& system, Handle thread_handle
2002static ResultCode SignalEvent(Core::System& system, Handle event_handle) { 2017static ResultCode SignalEvent(Core::System& system, Handle event_handle) {
2003 LOG_DEBUG(Kernel_SVC, "called, event_handle=0x{:08X}", event_handle); 2018 LOG_DEBUG(Kernel_SVC, "called, event_handle=0x{:08X}", event_handle);
2004 2019
2020 auto& kernel = system.Kernel();
2005 // Get the current handle table. 2021 // Get the current handle table.
2006 const HandleTable& handle_table = system.Kernel().CurrentProcess()->GetHandleTable(); 2022 const HandleTable& handle_table = kernel.CurrentProcess()->GetHandleTable();
2023
2024 // Reserve a new event from the process resource limit.
2025 KScopedResourceReservation event_reservation(kernel.CurrentProcess(),
2026 LimitableResource::Events);
2027 if (!event_reservation.Succeeded()) {
2028 LOG_ERROR(Kernel, "Could not reserve a new event");
2029 return ERR_RESOURCE_LIMIT_EXCEEDED;
2030 }
2007 2031
2008 // Get the writable event. 2032 // Get the writable event.
2009 auto writable_event = handle_table.Get<KWritableEvent>(event_handle); 2033 auto writable_event = handle_table.Get<KWritableEvent>(event_handle);
@@ -2012,6 +2036,9 @@ static ResultCode SignalEvent(Core::System& system, Handle event_handle) {
2012 return ResultInvalidHandle; 2036 return ResultInvalidHandle;
2013 } 2037 }
2014 2038
2039 // Commit the successfuly reservation.
2040 event_reservation.Commit();
2041
2015 return writable_event->Signal(); 2042 return writable_event->Signal();
2016} 2043}
2017 2044