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.
master
Lioncash 2018-11-26 19:14:29 +07:00
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;
}
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
/// 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) {
LOG_DEBUG(Kernel_SVC, "called. Handle={:08X}, Resource type={}", resource_limit, resource_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 limit_value = RetrieveResourceLimitValue(resource_limit, resource_type,
ResourceLimitValueType::LimitValue);
if (limit_value.Failed()) {
return limit_value.Code();
}
const auto& kernel = Core::System::GetInstance().Kernel();
const auto* const current_process = kernel.CurrentProcess();
ASSERT(current_process != nullptr);
*out_value = static_cast<u64>(*limit_value);
return RESULT_SUCCESS;
}
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;
static ResultCode GetResourceLimitCurrentValue(u64* out_value, Handle resource_limit,
u32 resource_type) {
LOG_DEBUG(Kernel_SVC, "called. Handle={:08X}, Resource type={}", resource_limit, resource_type);
const auto current_value = RetrieveResourceLimitValue(resource_limit, resource_type,
ResourceLimitValueType::CurrentValue);
if (current_value.Failed()) {
return current_value.Code();
}
const s64 limit_value = resource_limit_object->GetMaxResourceValue(type);
*out_value = static_cast<u64>(limit_value);
*out_value = static_cast<u64>(*current_value);
return RESULT_SUCCESS;
}
@ -1451,7 +1484,7 @@ static const FunctionDef SVC_Table[] = {
{0x2E, nullptr, "GetFutureThreadInfo"},
{0x2F, nullptr, "GetLastThreadInfo"},
{0x30, SvcWrap<GetResourceLimitLimitValue>, "GetResourceLimitLimitValue"},
{0x31, nullptr, "GetResourceLimitCurrentValue"},
{0x31, SvcWrap<GetResourceLimitCurrentValue>, "GetResourceLimitCurrentValue"},
{0x32, SvcWrap<SetThreadActivity>, "SetThreadActivity"},
{0x33, SvcWrap<GetThreadContext>, "GetThreadContext"},
{0x34, SvcWrap<WaitForAddress>, "WaitForAddress"},