kernel: resource_limit: Improvements to implementation.

This commit is contained in:
bunnei 2020-03-23 15:30:22 -04:00
parent 7aa0e4a7ca
commit b0e3cbef7a
2 changed files with 50 additions and 12 deletions

View file

@ -16,26 +16,60 @@ constexpr std::size_t ResourceTypeToIndex(ResourceType type) {
ResourceLimit::ResourceLimit(KernelCore& kernel) : Object{kernel} {} ResourceLimit::ResourceLimit(KernelCore& kernel) : Object{kernel} {}
ResourceLimit::~ResourceLimit() = default; ResourceLimit::~ResourceLimit() = default;
bool ResourceLimit::Reserve(ResourceType resource, s64 amount) {
return Reserve(resource, amount, 10000000000);
}
bool ResourceLimit::Reserve(ResourceType resource, s64 amount, u64 timeout) {
const std::size_t index{ResourceTypeToIndex(resource)};
s64 new_value = current[index] + amount;
while (new_value > limit[index] && available[index] + amount <= limit[index]) {
// TODO(bunnei): This is wrong for multicore, we should wait the calling thread for timeout
new_value = current[index] + amount;
if (timeout >= 0) {
break;
}
}
if (new_value <= limit[index]) {
current[index] = new_value;
return true;
}
return false;
}
void ResourceLimit::Release(ResourceType resource, u64 amount) {
Release(resource, amount, amount);
}
void ResourceLimit::Release(ResourceType resource, u64 used_amount, u64 available_amount) {
const std::size_t index{ResourceTypeToIndex(resource)};
current[index] -= used_amount;
available[index] -= available_amount;
}
std::shared_ptr<ResourceLimit> ResourceLimit::Create(KernelCore& kernel) { std::shared_ptr<ResourceLimit> ResourceLimit::Create(KernelCore& kernel) {
return std::make_shared<ResourceLimit>(kernel); return std::make_shared<ResourceLimit>(kernel);
} }
s64 ResourceLimit::GetCurrentResourceValue(ResourceType resource) const { s64 ResourceLimit::GetCurrentResourceValue(ResourceType resource) const {
return values.at(ResourceTypeToIndex(resource)); return limit.at(ResourceTypeToIndex(resource)) - current.at(ResourceTypeToIndex(resource));
} }
s64 ResourceLimit::GetMaxResourceValue(ResourceType resource) const { s64 ResourceLimit::GetMaxResourceValue(ResourceType resource) const {
return limits.at(ResourceTypeToIndex(resource)); return limit.at(ResourceTypeToIndex(resource));
} }
ResultCode ResourceLimit::SetLimitValue(ResourceType resource, s64 value) { ResultCode ResourceLimit::SetLimitValue(ResourceType resource, s64 value) {
const auto index = ResourceTypeToIndex(resource); const std::size_t index{ResourceTypeToIndex(resource)};
if (current[index] <= value) {
if (value < values[index]) { limit[index] = value;
return RESULT_SUCCESS;
} else {
return ERR_INVALID_STATE; return ERR_INVALID_STATE;
} }
values[index] = value;
return RESULT_SUCCESS;
} }
} // namespace Kernel } // namespace Kernel

View file

@ -51,6 +51,11 @@ public:
return HANDLE_TYPE; return HANDLE_TYPE;
} }
bool Reserve(ResourceType resource, s64 amount);
bool Reserve(ResourceType resource, s64 amount, u64 timeout);
void Release(ResourceType resource, u64 amount);
void Release(ResourceType resource, u64 used_amount, u64 available_amount);
/** /**
* Gets the current value for the specified resource. * Gets the current value for the specified resource.
* @param resource Requested resource type * @param resource Requested resource type
@ -91,10 +96,9 @@ private:
using ResourceArray = using ResourceArray =
std::array<s64, static_cast<std::size_t>(ResourceType::ResourceTypeCount)>; std::array<s64, static_cast<std::size_t>(ResourceType::ResourceTypeCount)>;
/// Maximum values a resource type may reach. ResourceArray limit{};
ResourceArray limits{}; ResourceArray current{};
/// Current resource limit values. ResourceArray available{};
ResourceArray values{};
}; };
} // namespace Kernel } // namespace Kernel