summaryrefslogtreecommitdiff
path: root/src/core/hle/kernel/svc.cpp
diff options
context:
space:
mode:
authorGravatar bunnei2021-02-12 18:21:30 -0800
committerGravatar GitHub2021-02-12 18:21:30 -0800
commitc86d770af945888c42e45eee2101ea7e0a39fd68 (patch)
treefc563f28673dfe851cfaf665951423e0ad759025 /src/core/hle/kernel/svc.cpp
parentkernel: Unify result codes (#5890) (diff)
parentkernel: More accurately reserve and release resources (diff)
downloadyuzu-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.cpp48
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
137enum class ResourceLimitValueType { 138enum class ResourceLimitValueType {
138 CurrentValue, 139 CurrentValue,
139 LimitValue, 140 LimitValue,
141 PeakValue,
140}; 142};
141 143
142ResultVal<s64> RetrieveResourceLimitValue(Core::System& system, Handle resource_limit, 144ResultVal<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
2002static ResultCode SignalEvent(Core::System& system, Handle event_handle) { 2022static 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