diff options
| author | 2021-02-12 18:21:30 -0800 | |
|---|---|---|
| committer | 2021-02-12 18:21:30 -0800 | |
| commit | c86d770af945888c42e45eee2101ea7e0a39fd68 (patch) | |
| tree | fc563f28673dfe851cfaf665951423e0ad759025 /src/core/hle/kernel/svc.cpp | |
| parent | kernel: Unify result codes (#5890) (diff) | |
| parent | kernel: More accurately reserve and release resources (diff) | |
| download | yuzu-c86d770af945888c42e45eee2101ea7e0a39fd68.tar.gz yuzu-c86d770af945888c42e45eee2101ea7e0a39fd68.tar.xz yuzu-c86d770af945888c42e45eee2101ea7e0a39fd68.zip | |
Merge pull request #5877 from ameerj/res-limit-usage
kernel: More accurately utilize resource_limit
Diffstat (limited to 'src/core/hle/kernel/svc.cpp')
| -rw-r--r-- | src/core/hle/kernel/svc.cpp | 48 |
1 files changed, 40 insertions, 8 deletions
diff --git a/src/core/hle/kernel/svc.cpp b/src/core/hle/kernel/svc.cpp index 4ef3c7ac5..31d899e06 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" |
| @@ -137,6 +138,7 @@ ResultCode MapUnmapMemorySanityChecks(const Memory::PageTable& manager, VAddr ds | |||
| 137 | enum class ResourceLimitValueType { | 138 | enum class ResourceLimitValueType { |
| 138 | CurrentValue, | 139 | CurrentValue, |
| 139 | LimitValue, | 140 | LimitValue, |
| 141 | PeakValue, | ||
| 140 | }; | 142 | }; |
| 141 | 143 | ||
| 142 | ResultVal<s64> RetrieveResourceLimitValue(Core::System& system, Handle resource_limit, | 144 | ResultVal<s64> RetrieveResourceLimitValue(Core::System& system, Handle resource_limit, |
| @@ -159,11 +161,17 @@ ResultVal<s64> RetrieveResourceLimitValue(Core::System& system, Handle resource_ | |||
| 159 | return ResultInvalidHandle; | 161 | return ResultInvalidHandle; |
| 160 | } | 162 | } |
| 161 | 163 | ||
| 162 | if (value_type == ResourceLimitValueType::CurrentValue) { | 164 | switch (value_type) { |
| 165 | case ResourceLimitValueType::CurrentValue: | ||
| 163 | return MakeResult(resource_limit_object->GetCurrentValue(type)); | 166 | return MakeResult(resource_limit_object->GetCurrentValue(type)); |
| 167 | case ResourceLimitValueType::LimitValue: | ||
| 168 | return MakeResult(resource_limit_object->GetLimitValue(type)); | ||
| 169 | case ResourceLimitValueType::PeakValue: | ||
| 170 | return MakeResult(resource_limit_object->GetPeakValue(type)); | ||
| 171 | default: | ||
| 172 | LOG_ERROR(Kernel_SVC, "Invalid resource value_type: '{}'", value_type); | ||
| 173 | return ResultInvalidEnumValue; | ||
| 164 | } | 174 | } |
| 165 | |||
| 166 | return MakeResult(resource_limit_object->GetLimitValue(type)); | ||
| 167 | } | 175 | } |
| 168 | } // Anonymous namespace | 176 | } // Anonymous namespace |
| 169 | 177 | ||
| @@ -313,8 +321,6 @@ static ResultCode ConnectToNamedPort(Core::System& system, Handle* out_handle, | |||
| 313 | return ResultNotFound; | 321 | return ResultNotFound; |
| 314 | } | 322 | } |
| 315 | 323 | ||
| 316 | ASSERT(kernel.CurrentProcess()->GetResourceLimit()->Reserve(LimitableResource::Sessions, 1)); | ||
| 317 | |||
| 318 | auto client_port = it->second; | 324 | auto client_port = it->second; |
| 319 | 325 | ||
| 320 | std::shared_ptr<ClientSession> client_session; | 326 | std::shared_ptr<ClientSession> client_session; |
| @@ -1516,8 +1522,13 @@ static ResultCode CreateThread(Core::System& system, Handle* out_handle, VAddr e | |||
| 1516 | return ResultInvalidPriority; | 1522 | return ResultInvalidPriority; |
| 1517 | } | 1523 | } |
| 1518 | 1524 | ||
| 1519 | ASSERT(process.GetResourceLimit()->Reserve( | 1525 | KScopedResourceReservation thread_reservation( |
| 1520 | LimitableResource::Threads, 1, system.CoreTiming().GetGlobalTimeNs().count() + 100000000)); | 1526 | kernel.CurrentProcess(), LimitableResource::Threads, 1, |
| 1527 | system.CoreTiming().GetGlobalTimeNs().count() + 100000000); | ||
| 1528 | if (!thread_reservation.Succeeded()) { | ||
| 1529 | LOG_ERROR(Kernel_SVC, "Could not reserve a new thread"); | ||
| 1530 | return ResultResourceLimitedExceeded; | ||
| 1531 | } | ||
| 1521 | 1532 | ||
| 1522 | std::shared_ptr<KThread> thread; | 1533 | std::shared_ptr<KThread> thread; |
| 1523 | { | 1534 | { |
| @@ -1537,6 +1548,7 @@ static ResultCode CreateThread(Core::System& system, Handle* out_handle, VAddr e | |||
| 1537 | // Set the thread name for debugging purposes. | 1548 | // Set the thread name for debugging purposes. |
| 1538 | thread->SetName( | 1549 | thread->SetName( |
| 1539 | fmt::format("thread[entry_point={:X}, handle={:X}]", entry_point, *new_thread_handle)); | 1550 | fmt::format("thread[entry_point={:X}, handle={:X}]", entry_point, *new_thread_handle)); |
| 1551 | thread_reservation.Commit(); | ||
| 1540 | 1552 | ||
| 1541 | return RESULT_SUCCESS; | 1553 | return RESULT_SUCCESS; |
| 1542 | } | 1554 | } |
| @@ -1884,6 +1896,13 @@ static ResultCode CreateTransferMemory(Core::System& system, Handle* handle, VAd | |||
| 1884 | } | 1896 | } |
| 1885 | 1897 | ||
| 1886 | auto& kernel = system.Kernel(); | 1898 | auto& kernel = system.Kernel(); |
| 1899 | // Reserve a new transfer memory from the process resource limit. | ||
| 1900 | KScopedResourceReservation trmem_reservation(kernel.CurrentProcess(), | ||
| 1901 | LimitableResource::TransferMemory); | ||
| 1902 | if (!trmem_reservation.Succeeded()) { | ||
| 1903 | LOG_ERROR(Kernel_SVC, "Could not reserve a new transfer memory"); | ||
| 1904 | return ResultResourceLimitedExceeded; | ||
| 1905 | } | ||
| 1887 | auto transfer_mem_handle = TransferMemory::Create(kernel, system.Memory(), addr, size, perms); | 1906 | auto transfer_mem_handle = TransferMemory::Create(kernel, system.Memory(), addr, size, perms); |
| 1888 | 1907 | ||
| 1889 | if (const auto reserve_result{transfer_mem_handle->Reserve()}; reserve_result.IsError()) { | 1908 | if (const auto reserve_result{transfer_mem_handle->Reserve()}; reserve_result.IsError()) { |
| @@ -1895,6 +1914,7 @@ static ResultCode CreateTransferMemory(Core::System& system, Handle* handle, VAd | |||
| 1895 | if (result.Failed()) { | 1914 | if (result.Failed()) { |
| 1896 | return result.Code(); | 1915 | return result.Code(); |
| 1897 | } | 1916 | } |
| 1917 | trmem_reservation.Commit(); | ||
| 1898 | 1918 | ||
| 1899 | *handle = *result; | 1919 | *handle = *result; |
| 1900 | return RESULT_SUCCESS; | 1920 | return RESULT_SUCCESS; |
| @@ -2002,8 +2022,17 @@ static ResultCode SetThreadCoreMask32(Core::System& system, Handle thread_handle | |||
| 2002 | static ResultCode SignalEvent(Core::System& system, Handle event_handle) { | 2022 | static ResultCode SignalEvent(Core::System& system, Handle event_handle) { |
| 2003 | LOG_DEBUG(Kernel_SVC, "called, event_handle=0x{:08X}", event_handle); | 2023 | LOG_DEBUG(Kernel_SVC, "called, event_handle=0x{:08X}", event_handle); |
| 2004 | 2024 | ||
| 2025 | auto& kernel = system.Kernel(); | ||
| 2005 | // Get the current handle table. | 2026 | // Get the current handle table. |
| 2006 | const HandleTable& handle_table = system.Kernel().CurrentProcess()->GetHandleTable(); | 2027 | const HandleTable& handle_table = kernel.CurrentProcess()->GetHandleTable(); |
| 2028 | |||
| 2029 | // Reserve a new event from the process resource limit. | ||
| 2030 | KScopedResourceReservation event_reservation(kernel.CurrentProcess(), | ||
| 2031 | LimitableResource::Events); | ||
| 2032 | if (!event_reservation.Succeeded()) { | ||
| 2033 | LOG_ERROR(Kernel, "Could not reserve a new event"); | ||
| 2034 | return ResultResourceLimitedExceeded; | ||
| 2035 | } | ||
| 2007 | 2036 | ||
| 2008 | // Get the writable event. | 2037 | // Get the writable event. |
| 2009 | auto writable_event = handle_table.Get<KWritableEvent>(event_handle); | 2038 | auto writable_event = handle_table.Get<KWritableEvent>(event_handle); |
| @@ -2012,6 +2041,9 @@ static ResultCode SignalEvent(Core::System& system, Handle event_handle) { | |||
| 2012 | return ResultInvalidHandle; | 2041 | return ResultInvalidHandle; |
| 2013 | } | 2042 | } |
| 2014 | 2043 | ||
| 2044 | // Commit the successfuly reservation. | ||
| 2045 | event_reservation.Commit(); | ||
| 2046 | |||
| 2015 | return writable_event->Signal(); | 2047 | return writable_event->Signal(); |
| 2016 | } | 2048 | } |
| 2017 | 2049 | ||