kernel: resource_limit: Improvements to implementation.
This commit is contained in:
		| @@ -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 | ||||||
|   | |||||||
| @@ -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 | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user