summaryrefslogtreecommitdiff
path: root/src/core/hle/kernel/svc.cpp
diff options
context:
space:
mode:
authorGravatar bunnei2021-04-20 21:28:11 -0700
committerGravatar bunnei2021-05-05 16:40:52 -0700
commitb57c5a9b54b23a348d7e80e51943f27a54fb8c2f (patch)
treee3f3c81a2fddb94c43b6a1dd641c61a7ca9c8225 /src/core/hle/kernel/svc.cpp
parenthle: kernel: svc: Migrate WaitSynchronization. (diff)
downloadyuzu-b57c5a9b54b23a348d7e80e51943f27a54fb8c2f.tar.gz
yuzu-b57c5a9b54b23a348d7e80e51943f27a54fb8c2f.tar.xz
yuzu-b57c5a9b54b23a348d7e80e51943f27a54fb8c2f.zip
hle: kernel: Migrate KResourceLimit to KAutoObject.
Diffstat (limited to 'src/core/hle/kernel/svc.cpp')
-rw-r--r--src/core/hle/kernel/svc.cpp127
1 files changed, 64 insertions, 63 deletions
diff --git a/src/core/hle/kernel/svc.cpp b/src/core/hle/kernel/svc.cpp
index 9e8184758..a78bfd1da 100644
--- a/src/core/hle/kernel/svc.cpp
+++ b/src/core/hle/kernel/svc.cpp
@@ -153,9 +153,9 @@ ResultVal<s64> RetrieveResourceLimitValue(Core::System& system, Handle resource_
153 const auto* const current_process = system.Kernel().CurrentProcess(); 153 const auto* const current_process = system.Kernel().CurrentProcess();
154 ASSERT(current_process != nullptr); 154 ASSERT(current_process != nullptr);
155 155
156 const auto resource_limit_object = 156 auto resource_limit_object =
157 current_process->GetHandleTable().Get<KResourceLimit>(resource_limit); 157 current_process->GetHandleTable().GetObject<KResourceLimit>(resource_limit);
158 if (!resource_limit_object) { 158 if (resource_limit_object.IsNull()) {
159 LOG_ERROR(Kernel_SVC, "Handle to non-existent resource limit instance used. Handle={:08X}", 159 LOG_ERROR(Kernel_SVC, "Handle to non-existent resource limit instance used. Handle={:08X}",
160 resource_limit); 160 resource_limit);
161 return ResultInvalidHandle; 161 return ResultInvalidHandle;
@@ -843,12 +843,10 @@ static ResultCode GetInfo(Core::System& system, u64* result, u64 info_id, Handle
843 return RESULT_SUCCESS; 843 return RESULT_SUCCESS;
844 } 844 }
845 845
846 const auto table_result = handle_table.Create(resource_limit.get()); 846 Handle handle{};
847 if (table_result.Failed()) { 847 R_TRY(handle_table.Add(&handle, resource_limit));
848 return table_result.Code();
849 }
850 848
851 *result = *table_result; 849 *result = handle;
852 return RESULT_SUCCESS; 850 return RESULT_SUCCESS;
853 } 851 }
854 852
@@ -2093,83 +2091,86 @@ static ResultCode GetProcessInfo(Core::System& system, u64* out, Handle process_
2093} 2091}
2094 2092
2095static ResultCode CreateResourceLimit(Core::System& system, Handle* out_handle) { 2093static ResultCode CreateResourceLimit(Core::System& system, Handle* out_handle) {
2096 std::lock_guard lock{HLE::g_hle_lock};
2097 LOG_DEBUG(Kernel_SVC, "called"); 2094 LOG_DEBUG(Kernel_SVC, "called");
2098 2095
2096 // Create a new resource limit.
2099 auto& kernel = system.Kernel(); 2097 auto& kernel = system.Kernel();
2100 auto resource_limit = std::make_shared<KResourceLimit>(kernel, system.CoreTiming()); 2098 KResourceLimit* resource_limit = KResourceLimit::Create(kernel);
2099 R_UNLESS(resource_limit != nullptr, ResultOutOfResource);
2101 2100
2102 auto* const current_process = kernel.CurrentProcess(); 2101 // Ensure we don't leak a reference to the limit.
2103 ASSERT(current_process != nullptr); 2102 SCOPE_EXIT({ resource_limit->Close(); });
2104 2103
2105 const auto handle = current_process->GetHandleTable().Create(resource_limit.get()); 2104 // Initialize the resource limit.
2106 if (handle.Failed()) { 2105 resource_limit->Initialize(&system.CoreTiming());
2107 return handle.Code(); 2106
2108 } 2107 // Register the limit.
2108 KResourceLimit::Register(kernel, resource_limit);
2109
2110 // Add the limit to the handle table.
2111 R_TRY(kernel.CurrentProcess()->GetHandleTable().Add(out_handle, resource_limit));
2109 2112
2110 *out_handle = *handle;
2111 return RESULT_SUCCESS; 2113 return RESULT_SUCCESS;
2112} 2114}
2113 2115
2114static ResultCode GetResourceLimitLimitValue(Core::System& system, u64* out_value, 2116static ResultCode GetResourceLimitLimitValue(Core::System& system, u64* out_limit_value,
2115 Handle resource_limit, u32 resource_type) { 2117 Handle resource_limit_handle,
2116 LOG_DEBUG(Kernel_SVC, "called. Handle={:08X}, Resource type={}", resource_limit, resource_type); 2118 LimitableResource which) {
2119 LOG_DEBUG(Kernel_SVC, "called, resource_limit_handle={:08X}, which={}", resource_limit_handle,
2120 which);
2117 2121
2118 const auto limit_value = RetrieveResourceLimitValue(system, resource_limit, resource_type, 2122 // Validate the resource.
2119 ResourceLimitValueType::LimitValue); 2123 R_UNLESS(IsValidResourceType(which), ResultInvalidEnumValue);
2120 if (limit_value.Failed()) { 2124
2121 return limit_value.Code(); 2125 // Get the resource limit.
2122 } 2126 auto& kernel = system.Kernel();
2127 KScopedAutoObject resource_limit =
2128 kernel.CurrentProcess()->GetHandleTable().GetObject<KResourceLimit>(resource_limit_handle);
2129 R_UNLESS(resource_limit.IsNotNull(), ResultInvalidHandle);
2130
2131 // Get the limit value.
2132 *out_limit_value = resource_limit->GetLimitValue(which);
2123 2133
2124 *out_value = static_cast<u64>(*limit_value);
2125 return RESULT_SUCCESS; 2134 return RESULT_SUCCESS;
2126} 2135}
2127 2136
2128static ResultCode GetResourceLimitCurrentValue(Core::System& system, u64* out_value, 2137static ResultCode GetResourceLimitCurrentValue(Core::System& system, u64* out_current_value,
2129 Handle resource_limit, u32 resource_type) { 2138 Handle resource_limit_handle,
2130 LOG_DEBUG(Kernel_SVC, "called. Handle={:08X}, Resource type={}", resource_limit, resource_type); 2139 LimitableResource which) {
2140 LOG_DEBUG(Kernel_SVC, "called, resource_limit_handle={:08X}, which={}", resource_limit_handle,
2141 which);
2131 2142
2132 const auto current_value = RetrieveResourceLimitValue(system, resource_limit, resource_type, 2143 // Validate the resource.
2133 ResourceLimitValueType::CurrentValue); 2144 R_UNLESS(IsValidResourceType(which), ResultInvalidEnumValue);
2134 if (current_value.Failed()) { 2145
2135 return current_value.Code(); 2146 // Get the resource limit.
2136 } 2147 auto& kernel = system.Kernel();
2148 KScopedAutoObject resource_limit =
2149 kernel.CurrentProcess()->GetHandleTable().GetObject<KResourceLimit>(resource_limit_handle);
2150 R_UNLESS(resource_limit.IsNotNull(), ResultInvalidHandle);
2151
2152 // Get the current value.
2153 *out_current_value = resource_limit->GetCurrentValue(which);
2137 2154
2138 *out_value = static_cast<u64>(*current_value);
2139 return RESULT_SUCCESS; 2155 return RESULT_SUCCESS;
2140} 2156}
2141 2157
2142static ResultCode SetResourceLimitLimitValue(Core::System& system, Handle resource_limit, 2158static ResultCode SetResourceLimitLimitValue(Core::System& system, Handle resource_limit_handle,
2143 u32 resource_type, u64 value) { 2159 LimitableResource which, u64 limit_value) {
2144 LOG_DEBUG(Kernel_SVC, "called. Handle={:08X}, Resource type={}, Value={}", resource_limit, 2160 LOG_DEBUG(Kernel_SVC, "called, resource_limit_handle={:08X}, which={}, limit_value={}",
2145 resource_type, value); 2161 resource_limit_handle, which, limit_value);
2146 2162
2147 const auto type = static_cast<LimitableResource>(resource_type); 2163 // Validate the resource.
2148 if (!IsValidResourceType(type)) { 2164 R_UNLESS(IsValidResourceType(which), ResultInvalidEnumValue);
2149 LOG_ERROR(Kernel_SVC, "Invalid resource limit type: '{}'", resource_type);
2150 return ResultInvalidEnumValue;
2151 }
2152
2153 auto* const current_process = system.Kernel().CurrentProcess();
2154 ASSERT(current_process != nullptr);
2155 2165
2156 auto resource_limit_object = 2166 // Get the resource limit.
2157 current_process->GetHandleTable().Get<KResourceLimit>(resource_limit); 2167 auto& kernel = system.Kernel();
2158 if (!resource_limit_object) { 2168 KScopedAutoObject resource_limit =
2159 LOG_ERROR(Kernel_SVC, "Handle to non-existent resource limit instance used. Handle={:08X}", 2169 kernel.CurrentProcess()->GetHandleTable().GetObject<KResourceLimit>(resource_limit_handle);
2160 resource_limit); 2170 R_UNLESS(resource_limit.IsNotNull(), ResultInvalidHandle);
2161 return ResultInvalidHandle;
2162 }
2163 2171
2164 const auto set_result = resource_limit_object->SetLimitValue(type, static_cast<s64>(value)); 2172 // Set the limit value.
2165 if (set_result.IsError()) { 2173 R_TRY(resource_limit->SetLimitValue(which, limit_value));
2166 LOG_ERROR(Kernel_SVC,
2167 "Attempted to lower resource limit ({}) for category '{}' below its current "
2168 "value ({})",
2169 resource_limit_object->GetLimitValue(type), resource_type,
2170 resource_limit_object->GetCurrentValue(type));
2171 return set_result;
2172 }
2173 2174
2174 return RESULT_SUCCESS; 2175 return RESULT_SUCCESS;
2175} 2176}