diff options
| author | 2020-03-23 15:30:22 -0400 | |
|---|---|---|
| committer | 2020-04-17 00:59:27 -0400 | |
| commit | b0e3cbef7ae60736f356e346b9c1e52115db752f (patch) | |
| tree | a8e9b02af9cb2a254e32aaa2d5b2d325039a06ea /src | |
| parent | loader: nso: Fix loading of static objects to be properly sized and aligned. (diff) | |
| download | yuzu-b0e3cbef7ae60736f356e346b9c1e52115db752f.tar.gz yuzu-b0e3cbef7ae60736f356e346b9c1e52115db752f.tar.xz yuzu-b0e3cbef7ae60736f356e346b9c1e52115db752f.zip | |
kernel: resource_limit: Improvements to implementation.
Diffstat (limited to 'src')
| -rw-r--r-- | src/core/hle/kernel/resource_limit.cpp | 50 | ||||
| -rw-r--r-- | src/core/hle/kernel/resource_limit.h | 12 |
2 files changed, 50 insertions, 12 deletions
diff --git a/src/core/hle/kernel/resource_limit.cpp b/src/core/hle/kernel/resource_limit.cpp index b53423462..96e5b9892 100644 --- a/src/core/hle/kernel/resource_limit.cpp +++ b/src/core/hle/kernel/resource_limit.cpp | |||
| @@ -16,26 +16,60 @@ constexpr std::size_t ResourceTypeToIndex(ResourceType type) { | |||
| 16 | ResourceLimit::ResourceLimit(KernelCore& kernel) : Object{kernel} {} | 16 | ResourceLimit::ResourceLimit(KernelCore& kernel) : Object{kernel} {} |
| 17 | ResourceLimit::~ResourceLimit() = default; | 17 | ResourceLimit::~ResourceLimit() = default; |
| 18 | 18 | ||
| 19 | bool ResourceLimit::Reserve(ResourceType resource, s64 amount) { | ||
| 20 | return Reserve(resource, amount, 10000000000); | ||
| 21 | } | ||
| 22 | |||
| 23 | bool ResourceLimit::Reserve(ResourceType resource, s64 amount, u64 timeout) { | ||
| 24 | const std::size_t index{ResourceTypeToIndex(resource)}; | ||
| 25 | |||
| 26 | s64 new_value = current[index] + amount; | ||
| 27 | while (new_value > limit[index] && available[index] + amount <= limit[index]) { | ||
| 28 | // TODO(bunnei): This is wrong for multicore, we should wait the calling thread for timeout | ||
| 29 | new_value = current[index] + amount; | ||
| 30 | |||
| 31 | if (timeout >= 0) { | ||
| 32 | break; | ||
| 33 | } | ||
| 34 | } | ||
| 35 | |||
| 36 | if (new_value <= limit[index]) { | ||
| 37 | current[index] = new_value; | ||
| 38 | return true; | ||
| 39 | } | ||
| 40 | return false; | ||
| 41 | } | ||
| 42 | |||
| 43 | void ResourceLimit::Release(ResourceType resource, u64 amount) { | ||
| 44 | Release(resource, amount, amount); | ||
| 45 | } | ||
| 46 | |||
| 47 | void ResourceLimit::Release(ResourceType resource, u64 used_amount, u64 available_amount) { | ||
| 48 | const std::size_t index{ResourceTypeToIndex(resource)}; | ||
| 49 | |||
| 50 | current[index] -= used_amount; | ||
| 51 | available[index] -= available_amount; | ||
| 52 | } | ||
| 53 | |||
| 19 | std::shared_ptr<ResourceLimit> ResourceLimit::Create(KernelCore& kernel) { | 54 | std::shared_ptr<ResourceLimit> ResourceLimit::Create(KernelCore& kernel) { |
| 20 | return std::make_shared<ResourceLimit>(kernel); | 55 | return std::make_shared<ResourceLimit>(kernel); |
| 21 | } | 56 | } |
| 22 | 57 | ||
| 23 | s64 ResourceLimit::GetCurrentResourceValue(ResourceType resource) const { | 58 | s64 ResourceLimit::GetCurrentResourceValue(ResourceType resource) const { |
| 24 | return values.at(ResourceTypeToIndex(resource)); | 59 | return limit.at(ResourceTypeToIndex(resource)) - current.at(ResourceTypeToIndex(resource)); |
| 25 | } | 60 | } |
| 26 | 61 | ||
| 27 | s64 ResourceLimit::GetMaxResourceValue(ResourceType resource) const { | 62 | s64 ResourceLimit::GetMaxResourceValue(ResourceType resource) const { |
| 28 | return limits.at(ResourceTypeToIndex(resource)); | 63 | return limit.at(ResourceTypeToIndex(resource)); |
| 29 | } | 64 | } |
| 30 | 65 | ||
| 31 | ResultCode ResourceLimit::SetLimitValue(ResourceType resource, s64 value) { | 66 | ResultCode ResourceLimit::SetLimitValue(ResourceType resource, s64 value) { |
| 32 | const auto index = ResourceTypeToIndex(resource); | 67 | const std::size_t index{ResourceTypeToIndex(resource)}; |
| 33 | 68 | if (current[index] <= value) { | |
| 34 | if (value < values[index]) { | 69 | limit[index] = value; |
| 70 | return RESULT_SUCCESS; | ||
| 71 | } else { | ||
| 35 | return ERR_INVALID_STATE; | 72 | return ERR_INVALID_STATE; |
| 36 | } | 73 | } |
| 37 | |||
| 38 | values[index] = value; | ||
| 39 | return RESULT_SUCCESS; | ||
| 40 | } | 74 | } |
| 41 | } // namespace Kernel | 75 | } // namespace Kernel |
diff --git a/src/core/hle/kernel/resource_limit.h b/src/core/hle/kernel/resource_limit.h index 53b89e621..936cc4d0f 100644 --- a/src/core/hle/kernel/resource_limit.h +++ b/src/core/hle/kernel/resource_limit.h | |||
| @@ -51,6 +51,11 @@ public: | |||
| 51 | return HANDLE_TYPE; | 51 | return HANDLE_TYPE; |
| 52 | } | 52 | } |
| 53 | 53 | ||
| 54 | bool Reserve(ResourceType resource, s64 amount); | ||
| 55 | bool Reserve(ResourceType resource, s64 amount, u64 timeout); | ||
| 56 | void Release(ResourceType resource, u64 amount); | ||
| 57 | void Release(ResourceType resource, u64 used_amount, u64 available_amount); | ||
| 58 | |||
| 54 | /** | 59 | /** |
| 55 | * Gets the current value for the specified resource. | 60 | * Gets the current value for the specified resource. |
| 56 | * @param resource Requested resource type | 61 | * @param resource Requested resource type |
| @@ -91,10 +96,9 @@ private: | |||
| 91 | using ResourceArray = | 96 | using ResourceArray = |
| 92 | std::array<s64, static_cast<std::size_t>(ResourceType::ResourceTypeCount)>; | 97 | std::array<s64, static_cast<std::size_t>(ResourceType::ResourceTypeCount)>; |
| 93 | 98 | ||
| 94 | /// Maximum values a resource type may reach. | 99 | ResourceArray limit{}; |
| 95 | ResourceArray limits{}; | 100 | ResourceArray current{}; |
| 96 | /// Current resource limit values. | 101 | ResourceArray available{}; |
| 97 | ResourceArray values{}; | ||
| 98 | }; | 102 | }; |
| 99 | 103 | ||
| 100 | } // namespace Kernel | 104 | } // namespace Kernel |