diff options
| author | 2021-04-20 21:28:11 -0700 | |
|---|---|---|
| committer | 2021-05-05 16:40:52 -0700 | |
| commit | b57c5a9b54b23a348d7e80e51943f27a54fb8c2f (patch) | |
| tree | e3f3c81a2fddb94c43b6a1dd641c61a7ca9c8225 /src/core/hle/kernel/svc.cpp | |
| parent | hle: kernel: svc: Migrate WaitSynchronization. (diff) | |
| download | yuzu-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.cpp | 127 |
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 | ||
| 2095 | static ResultCode CreateResourceLimit(Core::System& system, Handle* out_handle) { | 2093 | static 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 | ||
| 2114 | static ResultCode GetResourceLimitLimitValue(Core::System& system, u64* out_value, | 2116 | static 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 | ||
| 2128 | static ResultCode GetResourceLimitCurrentValue(Core::System& system, u64* out_value, | 2137 | static 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 | ||
| 2142 | static ResultCode SetResourceLimitLimitValue(Core::System& system, Handle resource_limit, | 2158 | static 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 | } |