3
0
Fork 0
forked from suyu/suyu

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() = 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) {
return std::make_shared<ResourceLimit>(kernel);
}
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 {
return limits.at(ResourceTypeToIndex(resource));
return limit.at(ResourceTypeToIndex(resource));
}
ResultCode ResourceLimit::SetLimitValue(ResourceType resource, s64 value) {
const auto index = ResourceTypeToIndex(resource);
if (value < values[index]) {
const std::size_t index{ResourceTypeToIndex(resource)};
if (current[index] <= value) {
limit[index] = value;
return RESULT_SUCCESS;
} else {
return ERR_INVALID_STATE;
}
values[index] = value;
return RESULT_SUCCESS;
}
} // namespace Kernel

View file

@ -51,6 +51,11 @@ public:
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.
* @param resource Requested resource type
@ -91,10 +96,9 @@ private:
using ResourceArray =
std::array<s64, static_cast<std::size_t>(ResourceType::ResourceTypeCount)>;
/// Maximum values a resource type may reach.
ResourceArray limits{};
/// Current resource limit values.
ResourceArray values{};
ResourceArray limit{};
ResourceArray current{};
ResourceArray available{};
};
} // namespace Kernel