svc: Implement svcGetResourceLimitCurrentValue()
This kernel service function is essentially the exact same as svcGetResourceLimitLimitValue(), with the only difference being that it retrieves the current value for a given resource category using the provided resource limit handle, rather than retrieving the limiting value of that resource limit instance. Given these are exactly the same and only differ on returned values, we can extract the existing code for svcGetResourceLimitLimitValue() to handle both values.
This commit is contained in:
parent
1d6399c222
commit
eb5596044d
1 changed files with 49 additions and 16 deletions
|
@ -105,6 +105,38 @@ ResultCode MapUnmapMemorySanityChecks(const VMManager& vm_manager, VAddr dst_add
|
||||||
|
|
||||||
return RESULT_SUCCESS;
|
return RESULT_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
enum class ResourceLimitValueType {
|
||||||
|
CurrentValue,
|
||||||
|
LimitValue,
|
||||||
|
};
|
||||||
|
|
||||||
|
ResultVal<s64> RetrieveResourceLimitValue(Handle resource_limit, u32 resource_type,
|
||||||
|
ResourceLimitValueType value_type) {
|
||||||
|
const auto type = static_cast<ResourceType>(resource_type);
|
||||||
|
if (!IsValidResourceType(type)) {
|
||||||
|
LOG_ERROR(Kernel_SVC, "Invalid resource limit type: '{}'", resource_type);
|
||||||
|
return ERR_INVALID_ENUM_VALUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
const auto& kernel = Core::System::GetInstance().Kernel();
|
||||||
|
const auto* const current_process = kernel.CurrentProcess();
|
||||||
|
ASSERT(current_process != nullptr);
|
||||||
|
|
||||||
|
const auto resource_limit_object =
|
||||||
|
current_process->GetHandleTable().Get<ResourceLimit>(resource_limit);
|
||||||
|
if (!resource_limit_object) {
|
||||||
|
LOG_ERROR(Kernel_SVC, "Handle to non-existent resource limit instance used. Handle={:08X}",
|
||||||
|
resource_limit);
|
||||||
|
return ERR_INVALID_HANDLE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (value_type == ResourceLimitValueType::CurrentValue) {
|
||||||
|
return MakeResult(resource_limit_object->GetCurrentResourceValue(type));
|
||||||
|
}
|
||||||
|
|
||||||
|
return MakeResult(resource_limit_object->GetMaxResourceValue(type));
|
||||||
|
}
|
||||||
} // Anonymous namespace
|
} // Anonymous namespace
|
||||||
|
|
||||||
/// Set the process heap to a given Size. It can both extend and shrink the heap.
|
/// Set the process heap to a given Size. It can both extend and shrink the heap.
|
||||||
|
@ -1368,26 +1400,27 @@ static ResultCode GetResourceLimitLimitValue(u64* out_value, Handle resource_lim
|
||||||
u32 resource_type) {
|
u32 resource_type) {
|
||||||
LOG_DEBUG(Kernel_SVC, "called. Handle={:08X}, Resource type={}", resource_limit, resource_type);
|
LOG_DEBUG(Kernel_SVC, "called. Handle={:08X}, Resource type={}", resource_limit, resource_type);
|
||||||
|
|
||||||
const auto type = static_cast<ResourceType>(resource_type);
|
const auto limit_value = RetrieveResourceLimitValue(resource_limit, resource_type,
|
||||||
if (!IsValidResourceType(type)) {
|
ResourceLimitValueType::LimitValue);
|
||||||
LOG_ERROR(Kernel_SVC, "Invalid resource limit type: '{}'.", resource_type);
|
if (limit_value.Failed()) {
|
||||||
return ERR_INVALID_ENUM_VALUE;
|
return limit_value.Code();
|
||||||
}
|
}
|
||||||
|
|
||||||
const auto& kernel = Core::System::GetInstance().Kernel();
|
*out_value = static_cast<u64>(*limit_value);
|
||||||
const auto* const current_process = kernel.CurrentProcess();
|
return RESULT_SUCCESS;
|
||||||
ASSERT(current_process != nullptr);
|
}
|
||||||
|
|
||||||
const auto resource_limit_object =
|
static ResultCode GetResourceLimitCurrentValue(u64* out_value, Handle resource_limit,
|
||||||
current_process->GetHandleTable().Get<ResourceLimit>(resource_limit);
|
u32 resource_type) {
|
||||||
if (!resource_limit_object) {
|
LOG_DEBUG(Kernel_SVC, "called. Handle={:08X}, Resource type={}", resource_limit, resource_type);
|
||||||
LOG_ERROR(Kernel_SVC, "Handle to non-existent resource limit instance used. Handle={:08X}",
|
|
||||||
resource_limit);
|
const auto current_value = RetrieveResourceLimitValue(resource_limit, resource_type,
|
||||||
return ERR_INVALID_HANDLE;
|
ResourceLimitValueType::CurrentValue);
|
||||||
|
if (current_value.Failed()) {
|
||||||
|
return current_value.Code();
|
||||||
}
|
}
|
||||||
|
|
||||||
const s64 limit_value = resource_limit_object->GetMaxResourceValue(type);
|
*out_value = static_cast<u64>(*current_value);
|
||||||
*out_value = static_cast<u64>(limit_value);
|
|
||||||
return RESULT_SUCCESS;
|
return RESULT_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1451,7 +1484,7 @@ static const FunctionDef SVC_Table[] = {
|
||||||
{0x2E, nullptr, "GetFutureThreadInfo"},
|
{0x2E, nullptr, "GetFutureThreadInfo"},
|
||||||
{0x2F, nullptr, "GetLastThreadInfo"},
|
{0x2F, nullptr, "GetLastThreadInfo"},
|
||||||
{0x30, SvcWrap<GetResourceLimitLimitValue>, "GetResourceLimitLimitValue"},
|
{0x30, SvcWrap<GetResourceLimitLimitValue>, "GetResourceLimitLimitValue"},
|
||||||
{0x31, nullptr, "GetResourceLimitCurrentValue"},
|
{0x31, SvcWrap<GetResourceLimitCurrentValue>, "GetResourceLimitCurrentValue"},
|
||||||
{0x32, SvcWrap<SetThreadActivity>, "SetThreadActivity"},
|
{0x32, SvcWrap<SetThreadActivity>, "SetThreadActivity"},
|
||||||
{0x33, SvcWrap<GetThreadContext>, "GetThreadContext"},
|
{0x33, SvcWrap<GetThreadContext>, "GetThreadContext"},
|
||||||
{0x34, SvcWrap<WaitForAddress>, "WaitForAddress"},
|
{0x34, SvcWrap<WaitForAddress>, "WaitForAddress"},
|
||||||
|
|
Loading…
Reference in a new issue