ソースを参照

kernel: resource_limit: Improvements to implementation.

bunnei 6 年 前
コミット
b0e3cbef7a

+ 42 - 8
src/core/hle/kernel/resource_limit.cpp

@@ -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

+ 8 - 4
src/core/hle/kernel/resource_limit.h

@@ -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