From 3be1a565f895d5399a6c1f6d0997dc528537fe86 Mon Sep 17 00:00:00 2001
From: Chloe Marcec <dmarcecguzman@gmail.com>
Date: Sat, 30 Jan 2021 20:40:49 +1100
Subject: [PATCH 1/8] kernel: Rewrite resource limit to be more accurate

Matches closer to hardware
---
 src/core/CMakeLists.txt                       |   5 +-
 .../hle/kernel/k_light_condition_variable.h   |  60 +++++++
 src/core/hle/kernel/k_resource_limit.cpp      | 155 ++++++++++++++++++
 src/core/hle/kernel/k_resource_limit.h        |  80 +++++++++
 src/core/hle/kernel/k_thread.cpp              |   4 +-
 src/core/hle/kernel/kernel.cpp                |  30 ++--
 src/core/hle/kernel/kernel.h                  |   4 +-
 src/core/hle/kernel/memory/page_table.cpp     |  13 +-
 src/core/hle/kernel/process.cpp               |  24 +--
 src/core/hle/kernel/process.h                 |   6 +-
 src/core/hle/kernel/resource_limit.cpp        |  73 ---------
 src/core/hle/kernel/resource_limit.h          | 106 ------------
 src/core/hle/kernel/svc.cpp                   |  28 ++--
 13 files changed, 357 insertions(+), 231 deletions(-)
 create mode 100644 src/core/hle/kernel/k_light_condition_variable.h
 create mode 100644 src/core/hle/kernel/k_resource_limit.cpp
 create mode 100644 src/core/hle/kernel/k_resource_limit.h
 delete mode 100644 src/core/hle/kernel/resource_limit.cpp
 delete mode 100644 src/core/hle/kernel/resource_limit.h

diff --git a/src/core/CMakeLists.txt b/src/core/CMakeLists.txt
index 397cc028fd..0ee02c81dc 100644
--- a/src/core/CMakeLists.txt
+++ b/src/core/CMakeLists.txt
@@ -160,9 +160,12 @@ add_library(core STATIC
     hle/kernel/k_affinity_mask.h
     hle/kernel/k_condition_variable.cpp
     hle/kernel/k_condition_variable.h
+    hle/kernel/k_light_condition_variable.h
     hle/kernel/k_light_lock.cpp
     hle/kernel/k_light_lock.h
     hle/kernel/k_priority_queue.h
+    hle/kernel/k_resource_limit.cpp
+    hle/kernel/k_resource_limit.h
     hle/kernel/k_scheduler.cpp
     hle/kernel/k_scheduler.h
     hle/kernel/k_scheduler_lock.h
@@ -203,8 +206,6 @@ add_library(core STATIC
     hle/kernel/process_capability.h
     hle/kernel/readable_event.cpp
     hle/kernel/readable_event.h
-    hle/kernel/resource_limit.cpp
-    hle/kernel/resource_limit.h
     hle/kernel/server_port.cpp
     hle/kernel/server_port.h
     hle/kernel/server_session.cpp
diff --git a/src/core/hle/kernel/k_light_condition_variable.h b/src/core/hle/kernel/k_light_condition_variable.h
new file mode 100644
index 0000000000..26573a2397
--- /dev/null
+++ b/src/core/hle/kernel/k_light_condition_variable.h
@@ -0,0 +1,60 @@
+// Copyright 2020 yuzu Emulator Project
+// Licensed under GPLv2 or any later version
+// Refer to the license.txt file included.
+
+// This file references various implementation details from Atmosphere, an open-source firmware for
+// the Nintendo Switch. Copyright 2018-2020 Atmosphere-NX.
+
+#pragma once
+
+#include "common/common_types.h"
+#include "core/hle/kernel/k_scheduler.h"
+#include "core/hle/kernel/k_scoped_scheduler_lock_and_sleep.h"
+#include "core/hle/kernel/k_thread_queue.h"
+#include "core/hle/kernel/time_manager.h"
+
+namespace Kernel {
+class KernelCore;
+
+class KLightConditionVariable {
+private:
+    KThreadQueue m_thread_queue;
+
+public:
+    KLightConditionVariable(KernelCore& kernel) : m_thread_queue(kernel), kernel(kernel) {}
+
+    void Wait(KLightLock* lock, s64 timeout = -1ll) {
+        WaitImpl(lock, timeout);
+        lock->Lock();
+    }
+
+    void Broadcast() {
+        KScopedSchedulerLock lk{kernel};
+        while (m_thread_queue.WakeupFrontThread() != nullptr) {
+            /* We want to signal all threads, and so should continue waking up until there's nothing
+             * to wake. */
+        }
+    }
+
+private:
+    void WaitImpl(KLightLock* lock, s64 timeout) {
+        KThread* owner = GetCurrentThreadPointer(kernel);
+        // KHardwareTimer* timer;
+
+        /* Sleep the thread. */
+        {
+            KScopedSchedulerLockAndSleep lk(kernel, owner, timeout);
+            lock->Unlock();
+
+            if (!m_thread_queue.SleepThread(owner)) {
+                lk.CancelSleep();
+                return;
+            }
+        }
+
+        /* Cancel the task that the sleep setup. */
+        kernel.TimeManager().UnscheduleTimeEvent(owner);
+    }
+    KernelCore& kernel;
+};
+} // namespace Kernel
diff --git a/src/core/hle/kernel/k_resource_limit.cpp b/src/core/hle/kernel/k_resource_limit.cpp
new file mode 100644
index 0000000000..f943d65624
--- /dev/null
+++ b/src/core/hle/kernel/k_resource_limit.cpp
@@ -0,0 +1,155 @@
+// Copyright 2020 yuzu Emulator Project
+// Licensed under GPLv2 or any later version
+// Refer to the license.txt file included.
+
+// This file references various implementation details from Atmosphere, an open-source firmware for
+// the Nintendo Switch. Copyright 2018-2020 Atmosphere-NX.
+
+#include "common/assert.h"
+#include "core/core.h"
+#include "core/core_timing.h"
+#include "core/core_timing_util.h"
+#include "core/hle/kernel/k_resource_limit.h"
+#include "core/hle/kernel/svc_results.h"
+
+namespace Kernel {
+namespace {
+static const s64 DefaultTimeout =
+    Core::Timing::msToCycles(std::chrono::milliseconds{10000}); // 10 seconds
+}
+
+KResourceLimit::KResourceLimit(KernelCore& kernel, Core::System& system)
+    : Object{kernel}, m_lock{kernel}, cond_var{kernel}, kernel{kernel}, system(system) {}
+KResourceLimit::~KResourceLimit() = default;
+
+s64 KResourceLimit::GetLimitValue(LimitableResource which) const {
+    const auto index = static_cast<std::size_t>(which);
+    s64 value{};
+    {
+        KScopedLightLock lk{m_lock};
+        value = limit_values[index];
+        ASSERT(value >= 0);
+        ASSERT(current_values[index] <= limit_values[index]);
+        ASSERT(current_hints[index] <= current_values[index]);
+    }
+    return value;
+}
+
+s64 KResourceLimit::GetCurrentValue(LimitableResource which) const {
+    const auto index = static_cast<std::size_t>(which);
+    s64 value{};
+    {
+        KScopedLightLock lk{m_lock};
+        value = current_values[index];
+        ASSERT(value >= 0);
+        ASSERT(current_values[index] <= limit_values[index]);
+        ASSERT(current_hints[index] <= current_values[index]);
+    }
+    return value;
+}
+
+s64 KResourceLimit::GetPeakValue(LimitableResource which) const {
+    const auto index = static_cast<std::size_t>(which);
+    s64 value{};
+    {
+        KScopedLightLock lk{m_lock};
+        value = peak_values[index];
+        ASSERT(value >= 0);
+        ASSERT(current_values[index] <= limit_values[index]);
+        ASSERT(current_hints[index] <= current_values[index]);
+    }
+    return value;
+}
+
+s64 KResourceLimit::GetFreeValue(LimitableResource which) const {
+    const auto index = static_cast<std::size_t>(which);
+    s64 value{};
+    {
+        KScopedLightLock lk(m_lock);
+        ASSERT(current_values[index] >= 0);
+        ASSERT(current_values[index] <= limit_values[index]);
+        ASSERT(current_hints[index] <= current_values[index]);
+        value = limit_values[index] - current_values[index];
+    }
+
+    return value;
+}
+
+ResultCode KResourceLimit::SetLimitValue(LimitableResource which, s64 value) {
+    const auto index = static_cast<std::size_t>(which);
+    KScopedLightLock lk(m_lock);
+    R_UNLESS(current_values[index] <= value, Svc::ResultInvalidState);
+
+    limit_values[index] = value;
+
+    return RESULT_SUCCESS;
+}
+
+bool KResourceLimit::Reserve(LimitableResource which, s64 value) {
+    return Reserve(which, value, system.CoreTiming().GetClockTicks() + DefaultTimeout);
+}
+
+bool KResourceLimit::Reserve(LimitableResource which, s64 value, s64 timeout) {
+    ASSERT(value >= 0);
+    const auto index = static_cast<std::size_t>(which);
+    KScopedLightLock lk(m_lock);
+
+    ASSERT(current_hints[index] <= current_values[index]);
+    if (current_hints[index] >= limit_values[index]) {
+        return false;
+    }
+
+    /* Loop until we reserve or run out of time. */
+    while (true) {
+        ASSERT(current_values[index] <= limit_values[index]);
+        ASSERT(current_hints[index] <= current_values[index]);
+
+        /* If we would overflow, don't allow to succeed. */
+        if (current_values[index] + value <= current_values[index]) {
+            break;
+        }
+
+        if (current_values[index] + value <= limit_values[index]) {
+            current_values[index] += value;
+            current_hints[index] += value;
+            peak_values[index] = std::max(peak_values[index], current_values[index]);
+            return true;
+        }
+
+        if (current_hints[index] + value <= limit_values[index] &&
+            (timeout < 0 || system.CoreTiming().GetClockTicks() < static_cast<u64>(timeout))) {
+            waiter_count++;
+            cond_var.Wait(&m_lock, timeout);
+            waiter_count--;
+        } else {
+            break;
+        }
+    }
+
+    return false;
+}
+
+void KResourceLimit::Release(LimitableResource which, s64 value) {
+    Release(which, value, value);
+}
+
+void KResourceLimit::Release(LimitableResource which, s64 value, s64 hint) {
+    ASSERT(value >= 0);
+    ASSERT(hint >= 0);
+
+    const auto index = static_cast<std::size_t>(which);
+    KScopedLightLock lk(m_lock);
+    ASSERT(current_values[index] <= limit_values[index]);
+    ASSERT(current_hints[index] <= current_values[index]);
+    ASSERT(value <= current_values[index]);
+    ASSERT(hint <= current_hints[index]);
+
+    current_values[index] -= value;
+    current_hints[index] -= hint;
+
+    if (waiter_count != 0) {
+        cond_var.Broadcast();
+    }
+}
+
+} // namespace Kernel
diff --git a/src/core/hle/kernel/k_resource_limit.h b/src/core/hle/kernel/k_resource_limit.h
new file mode 100644
index 0000000000..84c59177c0
--- /dev/null
+++ b/src/core/hle/kernel/k_resource_limit.h
@@ -0,0 +1,80 @@
+// Copyright 2020 yuzu Emulator Project
+// Licensed under GPLv2 or any later version
+// Refer to the license.txt file included.
+
+// This file references various implementation details from Atmosphere, an open-source firmware for
+// the Nintendo Switch. Copyright 2018-2020 Atmosphere-NX.
+
+#pragma once
+
+#include <array>
+#include "common/common_types.h"
+#include "core/hle/kernel/k_light_condition_variable.h"
+#include "core/hle/kernel/k_light_lock.h"
+#include "core/hle/kernel/object.h"
+
+union ResultCode;
+
+namespace Core {
+class System;
+}
+
+namespace Kernel {
+class KernelCore;
+enum class LimitableResource : u32 {
+    PhysicalMemoryMax = 0,
+    ThreadCountMax = 1,
+    EventCountMax = 2,
+    TransferMemoryCountMax = 3,
+    SessionCountMax = 4,
+
+    Count,
+};
+
+constexpr bool IsValidResourceType(LimitableResource type) {
+    return type < LimitableResource::Count;
+}
+
+class KResourceLimit final : public Object {
+public:
+    KResourceLimit(KernelCore& kernel, Core::System& system);
+    ~KResourceLimit();
+
+    s64 GetLimitValue(LimitableResource which) const;
+    s64 GetCurrentValue(LimitableResource which) const;
+    s64 GetPeakValue(LimitableResource which) const;
+    s64 GetFreeValue(LimitableResource which) const;
+
+    ResultCode SetLimitValue(LimitableResource which, s64 value);
+
+    bool Reserve(LimitableResource which, s64 value);
+    bool Reserve(LimitableResource which, s64 value, s64 timeout);
+    void Release(LimitableResource which, s64 value);
+    void Release(LimitableResource which, s64 value, s64 hint);
+
+    std::string GetTypeName() const override {
+        return "KResourceLimit";
+    }
+    std::string GetName() const override {
+        return GetTypeName();
+    }
+
+    static constexpr HandleType HANDLE_TYPE = HandleType::ResourceLimit;
+    HandleType GetHandleType() const override {
+        return HANDLE_TYPE;
+    }
+
+    virtual void Finalize() override {}
+
+private:
+    std::array<s64, static_cast<std::size_t>(LimitableResource::Count)> limit_values{};
+    std::array<s64, static_cast<std::size_t>(LimitableResource::Count)> current_values{};
+    std::array<s64, static_cast<std::size_t>(LimitableResource::Count)> current_hints{};
+    std::array<s64, static_cast<std::size_t>(LimitableResource::Count)> peak_values{};
+    mutable KLightLock m_lock;
+    s32 waiter_count{};
+    KLightConditionVariable cond_var;
+    KernelCore& kernel;
+    Core::System& system;
+};
+} // namespace Kernel
diff --git a/src/core/hle/kernel/k_thread.cpp b/src/core/hle/kernel/k_thread.cpp
index aa100e1390..38fd8e500c 100644
--- a/src/core/hle/kernel/k_thread.cpp
+++ b/src/core/hle/kernel/k_thread.cpp
@@ -21,6 +21,7 @@
 #include "core/hle/kernel/errors.h"
 #include "core/hle/kernel/handle_table.h"
 #include "core/hle/kernel/k_condition_variable.h"
+#include "core/hle/kernel/k_resource_limit.h"
 #include "core/hle/kernel/k_scheduler.h"
 #include "core/hle/kernel/k_scoped_scheduler_lock_and_sleep.h"
 #include "core/hle/kernel/k_thread.h"
@@ -29,7 +30,6 @@
 #include "core/hle/kernel/memory/memory_layout.h"
 #include "core/hle/kernel/object.h"
 #include "core/hle/kernel/process.h"
-#include "core/hle/kernel/resource_limit.h"
 #include "core/hle/kernel/svc_results.h"
 #include "core/hle/kernel/time_manager.h"
 #include "core/hle/result.h"
@@ -247,7 +247,7 @@ void KThread::Finalize() {
     // Decrement the parent process's thread count.
     if (parent != nullptr) {
         parent->DecrementThreadCount();
-        parent->GetResourceLimit()->Release(ResourceType::Threads, 1);
+        parent->GetResourceLimit()->Release(LimitableResource::ThreadCountMax, 1);
     }
 }
 
diff --git a/src/core/hle/kernel/kernel.cpp b/src/core/hle/kernel/kernel.cpp
index df309d523d..c66a993c24 100644
--- a/src/core/hle/kernel/kernel.cpp
+++ b/src/core/hle/kernel/kernel.cpp
@@ -28,6 +28,7 @@
 #include "core/hle/kernel/client_port.h"
 #include "core/hle/kernel/errors.h"
 #include "core/hle/kernel/handle_table.h"
+#include "core/hle/kernel/k_resource_limit.h"
 #include "core/hle/kernel/k_scheduler.h"
 #include "core/hle/kernel/k_thread.h"
 #include "core/hle/kernel/kernel.h"
@@ -36,7 +37,6 @@
 #include "core/hle/kernel/memory/slab_heap.h"
 #include "core/hle/kernel/physical_core.h"
 #include "core/hle/kernel/process.h"
-#include "core/hle/kernel/resource_limit.h"
 #include "core/hle/kernel/service_thread.h"
 #include "core/hle/kernel/shared_memory.h"
 #include "core/hle/kernel/time_manager.h"
@@ -66,7 +66,7 @@ struct KernelCore::Impl {
         is_phantom_mode_for_singlecore = false;
 
         InitializePhysicalCores();
-        InitializeSystemResourceLimit(kernel);
+        InitializeSystemResourceLimit(kernel, system);
         InitializeMemoryLayout();
         InitializePreemption(kernel);
         InitializeSchedulers();
@@ -131,19 +131,23 @@ struct KernelCore::Impl {
     }
 
     // Creates the default system resource limit
-    void InitializeSystemResourceLimit(KernelCore& kernel) {
-        system_resource_limit = ResourceLimit::Create(kernel);
+    void InitializeSystemResourceLimit(KernelCore& kernel, Core::System& system) {
+        system_resource_limit = std::make_shared<KResourceLimit>(kernel, system);
 
         // If setting the default system values fails, then something seriously wrong has occurred.
-        ASSERT(system_resource_limit->SetLimitValue(ResourceType::PhysicalMemory, 0x100000000)
+        ASSERT(
+            system_resource_limit->SetLimitValue(LimitableResource::PhysicalMemoryMax, 0x100000000)
+                .IsSuccess());
+        ASSERT(system_resource_limit->SetLimitValue(LimitableResource::ThreadCountMax, 800)
+                   .IsSuccess());
+        ASSERT(system_resource_limit->SetLimitValue(LimitableResource::EventCountMax, 700)
+                   .IsSuccess());
+        ASSERT(system_resource_limit->SetLimitValue(LimitableResource::TransferMemoryCountMax, 200)
+                   .IsSuccess());
+        ASSERT(system_resource_limit->SetLimitValue(LimitableResource::SessionCountMax, 900)
                    .IsSuccess());
-        ASSERT(system_resource_limit->SetLimitValue(ResourceType::Threads, 800).IsSuccess());
-        ASSERT(system_resource_limit->SetLimitValue(ResourceType::Events, 700).IsSuccess());
-        ASSERT(system_resource_limit->SetLimitValue(ResourceType::TransferMemory, 200).IsSuccess());
-        ASSERT(system_resource_limit->SetLimitValue(ResourceType::Sessions, 900).IsSuccess());
 
-        if (!system_resource_limit->Reserve(ResourceType::PhysicalMemory, 0) ||
-            !system_resource_limit->Reserve(ResourceType::PhysicalMemory, 0x60000)) {
+        if (!system_resource_limit->Reserve(LimitableResource::PhysicalMemoryMax, 0x60000)) {
             UNREACHABLE();
         }
     }
@@ -320,7 +324,7 @@ struct KernelCore::Impl {
     std::unique_ptr<Kernel::GlobalSchedulerContext> global_scheduler_context;
     Kernel::TimeManager time_manager;
 
-    std::shared_ptr<ResourceLimit> system_resource_limit;
+    std::shared_ptr<KResourceLimit> system_resource_limit;
 
     std::shared_ptr<Core::Timing::EventType> preemption_event;
 
@@ -390,7 +394,7 @@ void KernelCore::Shutdown() {
     impl->Shutdown();
 }
 
-std::shared_ptr<ResourceLimit> KernelCore::GetSystemResourceLimit() const {
+std::shared_ptr<KResourceLimit> KernelCore::GetSystemResourceLimit() const {
     return impl->system_resource_limit;
 }
 
diff --git a/src/core/hle/kernel/kernel.h b/src/core/hle/kernel/kernel.h
index e7c77727bf..806a0d9868 100644
--- a/src/core/hle/kernel/kernel.h
+++ b/src/core/hle/kernel/kernel.h
@@ -38,7 +38,7 @@ class GlobalSchedulerContext;
 class HandleTable;
 class PhysicalCore;
 class Process;
-class ResourceLimit;
+class KResourceLimit;
 class KScheduler;
 class SharedMemory;
 class ServiceThread;
@@ -85,7 +85,7 @@ public:
     void Shutdown();
 
     /// Retrieves a shared pointer to the system resource limit instance.
-    std::shared_ptr<ResourceLimit> GetSystemResourceLimit() const;
+    std::shared_ptr<KResourceLimit> GetSystemResourceLimit() const;
 
     /// Retrieves a shared pointer to a Thread instance within the thread wakeup handle table.
     std::shared_ptr<KThread> RetrieveThreadFromGlobalHandleTable(Handle handle) const;
diff --git a/src/core/hle/kernel/memory/page_table.cpp b/src/core/hle/kernel/memory/page_table.cpp
index 0808865540..d8c7d980a4 100644
--- a/src/core/hle/kernel/memory/page_table.cpp
+++ b/src/core/hle/kernel/memory/page_table.cpp
@@ -7,6 +7,7 @@
 #include "common/scope_exit.h"
 #include "core/core.h"
 #include "core/hle/kernel/errors.h"
+#include "core/hle/kernel/k_resource_limit.h"
 #include "core/hle/kernel/kernel.h"
 #include "core/hle/kernel/memory/address_space_info.h"
 #include "core/hle/kernel/memory/memory_block.h"
@@ -15,7 +16,6 @@
 #include "core/hle/kernel/memory/page_table.h"
 #include "core/hle/kernel/memory/system_control.h"
 #include "core/hle/kernel/process.h"
-#include "core/hle/kernel/resource_limit.h"
 #include "core/memory.h"
 
 namespace Kernel::Memory {
@@ -413,8 +413,8 @@ ResultCode PageTable::MapPhysicalMemory(VAddr addr, std::size_t size) {
     const std::size_t remaining_size{size - mapped_size};
     const std::size_t remaining_pages{remaining_size / PageSize};
 
-    if (process->GetResourceLimit() &&
-        !process->GetResourceLimit()->Reserve(ResourceType::PhysicalMemory, remaining_size)) {
+    if (process->GetResourceLimit() && !process->GetResourceLimit()->Reserve(
+                                           LimitableResource::PhysicalMemoryMax, remaining_size)) {
         return ERR_RESOURCE_LIMIT_EXCEEDED;
     }
 
@@ -422,7 +422,8 @@ ResultCode PageTable::MapPhysicalMemory(VAddr addr, std::size_t size) {
     {
         auto block_guard = detail::ScopeExit([&] {
             system.Kernel().MemoryManager().Free(page_linked_list, remaining_pages, memory_pool);
-            process->GetResourceLimit()->Release(ResourceType::PhysicalMemory, remaining_size);
+            process->GetResourceLimit()->Release(LimitableResource::PhysicalMemoryMax,
+                                                 remaining_size);
         });
 
         CASCADE_CODE(system.Kernel().MemoryManager().Allocate(page_linked_list, remaining_pages,
@@ -474,7 +475,7 @@ ResultCode PageTable::UnmapPhysicalMemory(VAddr addr, std::size_t size) {
     CASCADE_CODE(UnmapMemory(addr, size));
 
     auto process{system.Kernel().CurrentProcess()};
-    process->GetResourceLimit()->Release(ResourceType::PhysicalMemory, mapped_size);
+    process->GetResourceLimit()->Release(LimitableResource::PhysicalMemoryMax, mapped_size);
     physical_memory_usage -= mapped_size;
 
     return RESULT_SUCCESS;
@@ -783,7 +784,7 @@ ResultVal<VAddr> PageTable::SetHeapSize(std::size_t size) {
 
         auto process{system.Kernel().CurrentProcess()};
         if (process->GetResourceLimit() && delta != 0 &&
-            !process->GetResourceLimit()->Reserve(ResourceType::PhysicalMemory, delta)) {
+            !process->GetResourceLimit()->Reserve(LimitableResource::PhysicalMemoryMax, delta)) {
             return ERR_RESOURCE_LIMIT_EXCEEDED;
         }
 
diff --git a/src/core/hle/kernel/process.cpp b/src/core/hle/kernel/process.cpp
index 0edbfc4cca..6b63a32c56 100644
--- a/src/core/hle/kernel/process.cpp
+++ b/src/core/hle/kernel/process.cpp
@@ -15,6 +15,7 @@
 #include "core/file_sys/program_metadata.h"
 #include "core/hle/kernel/code_set.h"
 #include "core/hle/kernel/errors.h"
+#include "core/hle/kernel/k_resource_limit.h"
 #include "core/hle/kernel/k_scheduler.h"
 #include "core/hle/kernel/k_thread.h"
 #include "core/hle/kernel/kernel.h"
@@ -22,7 +23,6 @@
 #include "core/hle/kernel/memory/page_table.h"
 #include "core/hle/kernel/memory/slab_heap.h"
 #include "core/hle/kernel/process.h"
-#include "core/hle/kernel/resource_limit.h"
 #include "core/hle/lock.h"
 #include "core/memory.h"
 #include "core/settings.h"
@@ -116,7 +116,7 @@ std::shared_ptr<Process> Process::Create(Core::System& system, std::string name,
 
     std::shared_ptr<Process> process = std::make_shared<Process>(system);
     process->name = std::move(name);
-    process->resource_limit = ResourceLimit::Create(kernel);
+    process->resource_limit = std::make_shared<KResourceLimit>(kernel, system);
     process->status = ProcessStatus::Created;
     process->program_id = 0;
     process->process_id = type == ProcessType::KernelInternal ? kernel.CreateNewKernelProcessID()
@@ -132,7 +132,7 @@ std::shared_ptr<Process> Process::Create(Core::System& system, std::string name,
     return process;
 }
 
-std::shared_ptr<ResourceLimit> Process::GetResourceLimit() const {
+std::shared_ptr<KResourceLimit> Process::GetResourceLimit() const {
     return resource_limit;
 }
 
@@ -154,7 +154,7 @@ void Process::DecrementThreadCount() {
 }
 
 u64 Process::GetTotalPhysicalMemoryAvailable() const {
-    const u64 capacity{resource_limit->GetCurrentResourceValue(ResourceType::PhysicalMemory) +
+    const u64 capacity{resource_limit->GetCurrentValue(LimitableResource::PhysicalMemoryMax) +
                        page_table->GetTotalHeapSize() + GetSystemResourceSize() + image_size +
                        main_thread_stack_size};
 
@@ -308,13 +308,13 @@ ResultCode Process::LoadFromMetadata(const FileSys::ProgramMetadata& metadata,
 
     // Set initial resource limits
     resource_limit->SetLimitValue(
-        ResourceType::PhysicalMemory,
+        LimitableResource::PhysicalMemoryMax,
         kernel.MemoryManager().GetSize(Memory::MemoryManager::Pool::Application));
-    resource_limit->SetLimitValue(ResourceType::Threads, 608);
-    resource_limit->SetLimitValue(ResourceType::Events, 700);
-    resource_limit->SetLimitValue(ResourceType::TransferMemory, 128);
-    resource_limit->SetLimitValue(ResourceType::Sessions, 894);
-    ASSERT(resource_limit->Reserve(ResourceType::PhysicalMemory, code_size));
+    resource_limit->SetLimitValue(LimitableResource::ThreadCountMax, 608);
+    resource_limit->SetLimitValue(LimitableResource::EventCountMax, 700);
+    resource_limit->SetLimitValue(LimitableResource::TransferMemoryCountMax, 128);
+    resource_limit->SetLimitValue(LimitableResource::SessionCountMax, 894);
+    ASSERT(resource_limit->Reserve(LimitableResource::PhysicalMemoryMax, code_size));
 
     // Create TLS region
     tls_region_address = CreateTLSRegion();
@@ -331,8 +331,8 @@ void Process::Run(s32 main_thread_priority, u64 stack_size) {
     ChangeStatus(ProcessStatus::Running);
 
     SetupMainThread(system, *this, main_thread_priority, main_thread_stack_top);
-    resource_limit->Reserve(ResourceType::Threads, 1);
-    resource_limit->Reserve(ResourceType::PhysicalMemory, main_thread_stack_size);
+    resource_limit->Reserve(LimitableResource::ThreadCountMax, 1);
+    resource_limit->Reserve(LimitableResource::PhysicalMemoryMax, main_thread_stack_size);
 }
 
 void Process::PrepareForTermination() {
diff --git a/src/core/hle/kernel/process.h b/src/core/hle/kernel/process.h
index 26e647743e..c8af76ce8b 100644
--- a/src/core/hle/kernel/process.h
+++ b/src/core/hle/kernel/process.h
@@ -29,7 +29,7 @@ class ProgramMetadata;
 namespace Kernel {
 
 class KernelCore;
-class ResourceLimit;
+class KResourceLimit;
 class KThread;
 class TLSPage;
 
@@ -170,7 +170,7 @@ public:
     }
 
     /// Gets the resource limit descriptor for this process
-    std::shared_ptr<ResourceLimit> GetResourceLimit() const;
+    std::shared_ptr<KResourceLimit> GetResourceLimit() const;
 
     /// Gets the ideal CPU core ID for this process
     u8 GetIdealCoreId() const {
@@ -402,7 +402,7 @@ private:
     u32 system_resource_size = 0;
 
     /// Resource limit descriptor for this process
-    std::shared_ptr<ResourceLimit> resource_limit;
+    std::shared_ptr<KResourceLimit> resource_limit;
 
     /// The ideal CPU core for this process, threads are scheduled on this core by default.
     u8 ideal_core = 0;
diff --git a/src/core/hle/kernel/resource_limit.cpp b/src/core/hle/kernel/resource_limit.cpp
deleted file mode 100644
index 7bf50339d2..0000000000
--- a/src/core/hle/kernel/resource_limit.cpp
+++ /dev/null
@@ -1,73 +0,0 @@
-// Copyright 2015 Citra Emulator Project
-// Licensed under GPLv2 or any later version
-// Refer to the license.txt file included.
-
-#include "core/hle/kernel/errors.h"
-#include "core/hle/kernel/resource_limit.h"
-#include "core/hle/result.h"
-
-namespace Kernel {
-namespace {
-constexpr std::size_t ResourceTypeToIndex(ResourceType type) {
-    return static_cast<std::size_t>(type);
-}
-} // Anonymous namespace
-
-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;
-    if (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 (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 limit.at(ResourceTypeToIndex(resource)) - current.at(ResourceTypeToIndex(resource));
-}
-
-s64 ResourceLimit::GetMaxResourceValue(ResourceType resource) const {
-    return limit.at(ResourceTypeToIndex(resource));
-}
-
-ResultCode ResourceLimit::SetLimitValue(ResourceType resource, s64 value) {
-    const std::size_t index{ResourceTypeToIndex(resource)};
-    if (current[index] <= value) {
-        limit[index] = value;
-        return RESULT_SUCCESS;
-    } else {
-        LOG_ERROR(Kernel, "Limit value is too large! resource={}, value={}, index={}", resource,
-                  value, index);
-        return ERR_INVALID_STATE;
-    }
-}
-} // namespace Kernel
diff --git a/src/core/hle/kernel/resource_limit.h b/src/core/hle/kernel/resource_limit.h
deleted file mode 100644
index 464d4f2a61..0000000000
--- a/src/core/hle/kernel/resource_limit.h
+++ /dev/null
@@ -1,106 +0,0 @@
-// Copyright 2015 Citra Emulator Project
-// Licensed under GPLv2 or any later version
-// Refer to the license.txt file included.
-
-#pragma once
-
-#include <array>
-#include <memory>
-
-#include "common/common_types.h"
-#include "core/hle/kernel/object.h"
-
-union ResultCode;
-
-namespace Kernel {
-
-class KernelCore;
-
-enum class ResourceType : u32 {
-    PhysicalMemory,
-    Threads,
-    Events,
-    TransferMemory,
-    Sessions,
-
-    // Used as a count, not an actual type.
-    ResourceTypeCount
-};
-
-constexpr bool IsValidResourceType(ResourceType type) {
-    return type < ResourceType::ResourceTypeCount;
-}
-
-class ResourceLimit final : public Object {
-public:
-    explicit ResourceLimit(KernelCore& kernel);
-    ~ResourceLimit() override;
-
-    /// Creates a resource limit object.
-    static std::shared_ptr<ResourceLimit> Create(KernelCore& kernel);
-
-    std::string GetTypeName() const override {
-        return "ResourceLimit";
-    }
-    std::string GetName() const override {
-        return GetTypeName();
-    }
-
-    static constexpr HandleType HANDLE_TYPE = HandleType::ResourceLimit;
-    HandleType GetHandleType() const override {
-        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
-     * @returns The current value of the resource type
-     */
-    s64 GetCurrentResourceValue(ResourceType resource) const;
-
-    /**
-     * Gets the max value for the specified resource.
-     * @param resource Requested resource type
-     * @returns The max value of the resource type
-     */
-    s64 GetMaxResourceValue(ResourceType resource) const;
-
-    /**
-     * Sets the limit value for a given resource type.
-     *
-     * @param resource The resource type to apply the limit to.
-     * @param value    The limit to apply to the given resource type.
-     *
-     * @return A result code indicating if setting the limit value
-     *         was successful or not.
-     *
-     * @note The supplied limit value *must* be greater than or equal to
-     *       the current resource value for the given resource type,
-     *       otherwise ERR_INVALID_STATE will be returned.
-     */
-    ResultCode SetLimitValue(ResourceType resource, s64 value);
-
-    void Finalize() override {}
-
-private:
-    // TODO(Subv): Increment resource limit current values in their respective Kernel::T::Create
-    // functions
-    //
-    // Currently we have no way of distinguishing if a Create was called by the running application,
-    // or by a service module. Approach this once we have separated the service modules into their
-    // own processes
-
-    using ResourceArray =
-        std::array<s64, static_cast<std::size_t>(ResourceType::ResourceTypeCount)>;
-
-    ResourceArray limit{};
-    ResourceArray current{};
-    ResourceArray available{};
-};
-
-} // namespace Kernel
diff --git a/src/core/hle/kernel/svc.cpp b/src/core/hle/kernel/svc.cpp
index 7fd514e9d3..4bae37d105 100644
--- a/src/core/hle/kernel/svc.cpp
+++ b/src/core/hle/kernel/svc.cpp
@@ -26,6 +26,7 @@
 #include "core/hle/kernel/handle_table.h"
 #include "core/hle/kernel/k_address_arbiter.h"
 #include "core/hle/kernel/k_condition_variable.h"
+#include "core/hle/kernel/k_resource_limit.h"
 #include "core/hle/kernel/k_scheduler.h"
 #include "core/hle/kernel/k_scoped_scheduler_lock_and_sleep.h"
 #include "core/hle/kernel/k_synchronization_object.h"
@@ -37,7 +38,6 @@
 #include "core/hle/kernel/physical_core.h"
 #include "core/hle/kernel/process.h"
 #include "core/hle/kernel/readable_event.h"
-#include "core/hle/kernel/resource_limit.h"
 #include "core/hle/kernel/shared_memory.h"
 #include "core/hle/kernel/svc.h"
 #include "core/hle/kernel/svc_results.h"
@@ -141,7 +141,7 @@ enum class ResourceLimitValueType {
 ResultVal<s64> RetrieveResourceLimitValue(Core::System& system, Handle resource_limit,
                                           u32 resource_type, ResourceLimitValueType value_type) {
     std::lock_guard lock{HLE::g_hle_lock};
-    const auto type = static_cast<ResourceType>(resource_type);
+    const auto type = static_cast<LimitableResource>(resource_type);
     if (!IsValidResourceType(type)) {
         LOG_ERROR(Kernel_SVC, "Invalid resource limit type: '{}'", resource_type);
         return ERR_INVALID_ENUM_VALUE;
@@ -151,7 +151,7 @@ ResultVal<s64> RetrieveResourceLimitValue(Core::System& system, Handle resource_
     ASSERT(current_process != nullptr);
 
     const auto resource_limit_object =
-        current_process->GetHandleTable().Get<ResourceLimit>(resource_limit);
+        current_process->GetHandleTable().Get<KResourceLimit>(resource_limit);
     if (!resource_limit_object) {
         LOG_ERROR(Kernel_SVC, "Handle to non-existent resource limit instance used. Handle={:08X}",
                   resource_limit);
@@ -159,10 +159,10 @@ ResultVal<s64> RetrieveResourceLimitValue(Core::System& system, Handle resource_
     }
 
     if (value_type == ResourceLimitValueType::CurrentValue) {
-        return MakeResult(resource_limit_object->GetCurrentResourceValue(type));
+        return MakeResult(resource_limit_object->GetCurrentValue(type));
     }
 
-    return MakeResult(resource_limit_object->GetMaxResourceValue(type));
+    return MakeResult(resource_limit_object->GetLimitValue(type));
 }
 } // Anonymous namespace
 
@@ -312,7 +312,8 @@ static ResultCode ConnectToNamedPort(Core::System& system, Handle* out_handle,
         return ERR_NOT_FOUND;
     }
 
-    ASSERT(kernel.CurrentProcess()->GetResourceLimit()->Reserve(ResourceType::Sessions, 1));
+    ASSERT(kernel.CurrentProcess()->GetResourceLimit()->Reserve(LimitableResource::SessionCountMax,
+                                                                1));
 
     auto client_port = it->second;
 
@@ -1450,7 +1451,10 @@ static ResultCode CreateThread(Core::System& system, Handle* out_handle, VAddr e
              Svc::ResultInvalidPriority);
     R_UNLESS(process.CheckThreadPriority(priority), Svc::ResultInvalidPriority);
 
-    ASSERT(process.GetResourceLimit()->Reserve(ResourceType::Threads, 1));
+    ASSERT(process.GetResourceLimit()->Reserve(
+        LimitableResource::ThreadCountMax, 1,
+        system.CoreTiming().GetClockTicks() +
+            Core::Timing::msToCycles(std::chrono::milliseconds{100})));
 
     std::shared_ptr<KThread> thread;
     {
@@ -1972,7 +1976,7 @@ static ResultCode CreateResourceLimit(Core::System& system, Handle* out_handle)
     LOG_DEBUG(Kernel_SVC, "called");
 
     auto& kernel = system.Kernel();
-    auto resource_limit = ResourceLimit::Create(kernel);
+    auto resource_limit = std::make_shared<KResourceLimit>(kernel, system);
 
     auto* const current_process = kernel.CurrentProcess();
     ASSERT(current_process != nullptr);
@@ -2019,7 +2023,7 @@ static ResultCode SetResourceLimitLimitValue(Core::System& system, Handle resour
     LOG_DEBUG(Kernel_SVC, "called. Handle={:08X}, Resource type={}, Value={}", resource_limit,
               resource_type, value);
 
-    const auto type = static_cast<ResourceType>(resource_type);
+    const auto type = static_cast<LimitableResource>(resource_type);
     if (!IsValidResourceType(type)) {
         LOG_ERROR(Kernel_SVC, "Invalid resource limit type: '{}'", resource_type);
         return ERR_INVALID_ENUM_VALUE;
@@ -2029,7 +2033,7 @@ static ResultCode SetResourceLimitLimitValue(Core::System& system, Handle resour
     ASSERT(current_process != nullptr);
 
     auto resource_limit_object =
-        current_process->GetHandleTable().Get<ResourceLimit>(resource_limit);
+        current_process->GetHandleTable().Get<KResourceLimit>(resource_limit);
     if (!resource_limit_object) {
         LOG_ERROR(Kernel_SVC, "Handle to non-existent resource limit instance used. Handle={:08X}",
                   resource_limit);
@@ -2041,8 +2045,8 @@ static ResultCode SetResourceLimitLimitValue(Core::System& system, Handle resour
         LOG_ERROR(
             Kernel_SVC,
             "Attempted to lower resource limit ({}) for category '{}' below its current value ({})",
-            resource_limit_object->GetMaxResourceValue(type), resource_type,
-            resource_limit_object->GetCurrentResourceValue(type));
+            resource_limit_object->GetLimitValue(type), resource_type,
+            resource_limit_object->GetCurrentValue(type));
         return set_result;
     }
 

From 3bf62c7a8a68822e608c2f5f5748bd111d7ee4cf Mon Sep 17 00:00:00 2001
From: Chloe Marcec <dmarcecguzman@gmail.com>
Date: Sat, 30 Jan 2021 21:03:10 +1100
Subject: [PATCH 2/8] Move to GetGlobalTimeNs, fix
 GetTotalPhysicalMemoryAvailable

---
 src/core/hle/kernel/k_resource_limit.cpp | 7 +++----
 src/core/hle/kernel/process.cpp          | 2 +-
 src/core/hle/kernel/svc.cpp              | 7 +++----
 3 files changed, 7 insertions(+), 9 deletions(-)

diff --git a/src/core/hle/kernel/k_resource_limit.cpp b/src/core/hle/kernel/k_resource_limit.cpp
index f943d65624..b3076b030d 100644
--- a/src/core/hle/kernel/k_resource_limit.cpp
+++ b/src/core/hle/kernel/k_resource_limit.cpp
@@ -14,8 +14,7 @@
 
 namespace Kernel {
 namespace {
-static const s64 DefaultTimeout =
-    Core::Timing::msToCycles(std::chrono::milliseconds{10000}); // 10 seconds
+constexpr s64 DefaultTimeout = 10000000000; // 10 seconds
 }
 
 KResourceLimit::KResourceLimit(KernelCore& kernel, Core::System& system)
@@ -86,7 +85,7 @@ ResultCode KResourceLimit::SetLimitValue(LimitableResource which, s64 value) {
 }
 
 bool KResourceLimit::Reserve(LimitableResource which, s64 value) {
-    return Reserve(which, value, system.CoreTiming().GetClockTicks() + DefaultTimeout);
+    return Reserve(which, value, system.CoreTiming().GetGlobalTimeNs().count() + DefaultTimeout);
 }
 
 bool KResourceLimit::Reserve(LimitableResource which, s64 value, s64 timeout) {
@@ -117,7 +116,7 @@ bool KResourceLimit::Reserve(LimitableResource which, s64 value, s64 timeout) {
         }
 
         if (current_hints[index] + value <= limit_values[index] &&
-            (timeout < 0 || system.CoreTiming().GetClockTicks() < static_cast<u64>(timeout))) {
+            (timeout < 0 || system.CoreTiming().GetGlobalTimeNs().count() < timeout)) {
             waiter_count++;
             cond_var.Wait(&m_lock, timeout);
             waiter_count--;
diff --git a/src/core/hle/kernel/process.cpp b/src/core/hle/kernel/process.cpp
index 6b63a32c56..9efcb95f36 100644
--- a/src/core/hle/kernel/process.cpp
+++ b/src/core/hle/kernel/process.cpp
@@ -154,7 +154,7 @@ void Process::DecrementThreadCount() {
 }
 
 u64 Process::GetTotalPhysicalMemoryAvailable() const {
-    const u64 capacity{resource_limit->GetCurrentValue(LimitableResource::PhysicalMemoryMax) +
+    const u64 capacity{resource_limit->GetFreeValue(LimitableResource::PhysicalMemoryMax) +
                        page_table->GetTotalHeapSize() + GetSystemResourceSize() + image_size +
                        main_thread_stack_size};
 
diff --git a/src/core/hle/kernel/svc.cpp b/src/core/hle/kernel/svc.cpp
index 4bae37d105..d89873104e 100644
--- a/src/core/hle/kernel/svc.cpp
+++ b/src/core/hle/kernel/svc.cpp
@@ -1451,10 +1451,9 @@ static ResultCode CreateThread(Core::System& system, Handle* out_handle, VAddr e
              Svc::ResultInvalidPriority);
     R_UNLESS(process.CheckThreadPriority(priority), Svc::ResultInvalidPriority);
 
-    ASSERT(process.GetResourceLimit()->Reserve(
-        LimitableResource::ThreadCountMax, 1,
-        system.CoreTiming().GetClockTicks() +
-            Core::Timing::msToCycles(std::chrono::milliseconds{100})));
+    ASSERT(process.GetResourceLimit()->Reserve(LimitableResource::ThreadCountMax, 1,
+                                               system.CoreTiming().GetGlobalTimeNs().count() +
+                                                   100000000));
 
     std::shared_ptr<KThread> thread;
     {

From 7791cfd9603d983fe58d3463e94d87448ad9e5a6 Mon Sep 17 00:00:00 2001
From: Chloe Marcec <dmarcecguzman@gmail.com>
Date: Sat, 30 Jan 2021 21:19:49 +1100
Subject: [PATCH 3/8] Drop m_ from lock

---
 src/core/hle/kernel/k_resource_limit.cpp | 16 ++++++++--------
 src/core/hle/kernel/k_resource_limit.h   |  2 +-
 2 files changed, 9 insertions(+), 9 deletions(-)

diff --git a/src/core/hle/kernel/k_resource_limit.cpp b/src/core/hle/kernel/k_resource_limit.cpp
index b3076b030d..65c30e9b3b 100644
--- a/src/core/hle/kernel/k_resource_limit.cpp
+++ b/src/core/hle/kernel/k_resource_limit.cpp
@@ -18,14 +18,14 @@ constexpr s64 DefaultTimeout = 10000000000; // 10 seconds
 }
 
 KResourceLimit::KResourceLimit(KernelCore& kernel, Core::System& system)
-    : Object{kernel}, m_lock{kernel}, cond_var{kernel}, kernel{kernel}, system(system) {}
+    : Object{kernel}, lock{kernel}, cond_var{kernel}, kernel{kernel}, system(system) {}
 KResourceLimit::~KResourceLimit() = default;
 
 s64 KResourceLimit::GetLimitValue(LimitableResource which) const {
     const auto index = static_cast<std::size_t>(which);
     s64 value{};
     {
-        KScopedLightLock lk{m_lock};
+        KScopedLightLock lk{lock};
         value = limit_values[index];
         ASSERT(value >= 0);
         ASSERT(current_values[index] <= limit_values[index]);
@@ -51,7 +51,7 @@ s64 KResourceLimit::GetPeakValue(LimitableResource which) const {
     const auto index = static_cast<std::size_t>(which);
     s64 value{};
     {
-        KScopedLightLock lk{m_lock};
+        KScopedLightLock lk{lock};
         value = peak_values[index];
         ASSERT(value >= 0);
         ASSERT(current_values[index] <= limit_values[index]);
@@ -64,7 +64,7 @@ s64 KResourceLimit::GetFreeValue(LimitableResource which) const {
     const auto index = static_cast<std::size_t>(which);
     s64 value{};
     {
-        KScopedLightLock lk(m_lock);
+        KScopedLightLock lk(lock);
         ASSERT(current_values[index] >= 0);
         ASSERT(current_values[index] <= limit_values[index]);
         ASSERT(current_hints[index] <= current_values[index]);
@@ -76,7 +76,7 @@ s64 KResourceLimit::GetFreeValue(LimitableResource which) const {
 
 ResultCode KResourceLimit::SetLimitValue(LimitableResource which, s64 value) {
     const auto index = static_cast<std::size_t>(which);
-    KScopedLightLock lk(m_lock);
+    KScopedLightLock lk(lock);
     R_UNLESS(current_values[index] <= value, Svc::ResultInvalidState);
 
     limit_values[index] = value;
@@ -91,7 +91,7 @@ bool KResourceLimit::Reserve(LimitableResource which, s64 value) {
 bool KResourceLimit::Reserve(LimitableResource which, s64 value, s64 timeout) {
     ASSERT(value >= 0);
     const auto index = static_cast<std::size_t>(which);
-    KScopedLightLock lk(m_lock);
+    KScopedLightLock lk(lock);
 
     ASSERT(current_hints[index] <= current_values[index]);
     if (current_hints[index] >= limit_values[index]) {
@@ -118,7 +118,7 @@ bool KResourceLimit::Reserve(LimitableResource which, s64 value, s64 timeout) {
         if (current_hints[index] + value <= limit_values[index] &&
             (timeout < 0 || system.CoreTiming().GetGlobalTimeNs().count() < timeout)) {
             waiter_count++;
-            cond_var.Wait(&m_lock, timeout);
+            cond_var.Wait(&lock, timeout);
             waiter_count--;
         } else {
             break;
@@ -137,7 +137,7 @@ void KResourceLimit::Release(LimitableResource which, s64 value, s64 hint) {
     ASSERT(hint >= 0);
 
     const auto index = static_cast<std::size_t>(which);
-    KScopedLightLock lk(m_lock);
+    KScopedLightLock lk(lock);
     ASSERT(current_values[index] <= limit_values[index]);
     ASSERT(current_hints[index] <= current_values[index]);
     ASSERT(value <= current_values[index]);
diff --git a/src/core/hle/kernel/k_resource_limit.h b/src/core/hle/kernel/k_resource_limit.h
index 84c59177c0..5f916c99cf 100644
--- a/src/core/hle/kernel/k_resource_limit.h
+++ b/src/core/hle/kernel/k_resource_limit.h
@@ -71,7 +71,7 @@ private:
     std::array<s64, static_cast<std::size_t>(LimitableResource::Count)> current_values{};
     std::array<s64, static_cast<std::size_t>(LimitableResource::Count)> current_hints{};
     std::array<s64, static_cast<std::size_t>(LimitableResource::Count)> peak_values{};
-    mutable KLightLock m_lock;
+    mutable KLightLock lock;
     s32 waiter_count{};
     KLightConditionVariable cond_var;
     KernelCore& kernel;

From 56742c6222b7185b43a3463955c58a142ed33c1e Mon Sep 17 00:00:00 2001
From: Chloe Marcec <dmarcecguzman@gmail.com>
Date: Sat, 30 Jan 2021 21:20:35 +1100
Subject: [PATCH 4/8] cleanup commenting

---
 src/core/hle/kernel/k_resource_limit.cpp | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/src/core/hle/kernel/k_resource_limit.cpp b/src/core/hle/kernel/k_resource_limit.cpp
index 65c30e9b3b..1bcc390ff9 100644
--- a/src/core/hle/kernel/k_resource_limit.cpp
+++ b/src/core/hle/kernel/k_resource_limit.cpp
@@ -98,12 +98,12 @@ bool KResourceLimit::Reserve(LimitableResource which, s64 value, s64 timeout) {
         return false;
     }
 
-    /* Loop until we reserve or run out of time. */
+    // Loop until we reserve or run out of time.
     while (true) {
         ASSERT(current_values[index] <= limit_values[index]);
         ASSERT(current_hints[index] <= current_values[index]);
 
-        /* If we would overflow, don't allow to succeed. */
+        // If we would overflow, don't allow to succeed.
         if (current_values[index] + value <= current_values[index]) {
             break;
         }

From ee333e063d9de4b36ccbc0c5b7b3e323bff9eda3 Mon Sep 17 00:00:00 2001
From: Chloe Marcec <dmarcecguzman@gmail.com>
Date: Sat, 30 Jan 2021 21:51:22 +1100
Subject: [PATCH 5/8] fix compile error

---
 src/core/hle/kernel/k_resource_limit.cpp | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/src/core/hle/kernel/k_resource_limit.cpp b/src/core/hle/kernel/k_resource_limit.cpp
index 1bcc390ff9..3cee8d0f71 100644
--- a/src/core/hle/kernel/k_resource_limit.cpp
+++ b/src/core/hle/kernel/k_resource_limit.cpp
@@ -38,7 +38,7 @@ s64 KResourceLimit::GetCurrentValue(LimitableResource which) const {
     const auto index = static_cast<std::size_t>(which);
     s64 value{};
     {
-        KScopedLightLock lk{m_lock};
+        KScopedLightLock lk{lock};
         value = current_values[index];
         ASSERT(value >= 0);
         ASSERT(current_values[index] <= limit_values[index]);

From 9e4b2d60bc4827552b0d74675ae03fec06f73452 Mon Sep 17 00:00:00 2001
From: Chloe Marcec <dmarcecguzman@gmail.com>
Date: Tue, 2 Feb 2021 13:23:00 +1100
Subject: [PATCH 6/8] Address issues

---
 .../hle/kernel/k_light_condition_variable.h   | 21 ++++++++-----------
 src/core/hle/kernel/k_resource_limit.cpp      |  2 --
 src/core/hle/kernel/k_resource_limit.h        | 11 +++++-----
 3 files changed, 15 insertions(+), 19 deletions(-)

diff --git a/src/core/hle/kernel/k_light_condition_variable.h b/src/core/hle/kernel/k_light_condition_variable.h
index 26573a2397..26d94d7c0c 100644
--- a/src/core/hle/kernel/k_light_condition_variable.h
+++ b/src/core/hle/kernel/k_light_condition_variable.h
@@ -17,44 +17,41 @@ namespace Kernel {
 class KernelCore;
 
 class KLightConditionVariable {
-private:
-    KThreadQueue m_thread_queue;
-
 public:
-    KLightConditionVariable(KernelCore& kernel) : m_thread_queue(kernel), kernel(kernel) {}
+    explicit KLightConditionVariable(KernelCore& kernel) : thread_queue(kernel), kernel(kernel) {}
 
-    void Wait(KLightLock* lock, s64 timeout = -1ll) {
+    void Wait(KLightLock* lock, s64 timeout = -1) {
         WaitImpl(lock, timeout);
         lock->Lock();
     }
 
     void Broadcast() {
         KScopedSchedulerLock lk{kernel};
-        while (m_thread_queue.WakeupFrontThread() != nullptr) {
-            /* We want to signal all threads, and so should continue waking up until there's nothing
-             * to wake. */
+        while (thread_queue.WakeupFrontThread() != nullptr) {
+            // We want to signal all threads, and so should continue waking up until there's nothing
+            // to wake.
         }
     }
 
 private:
     void WaitImpl(KLightLock* lock, s64 timeout) {
         KThread* owner = GetCurrentThreadPointer(kernel);
-        // KHardwareTimer* timer;
 
-        /* Sleep the thread. */
+        // Sleep the thread.
         {
             KScopedSchedulerLockAndSleep lk(kernel, owner, timeout);
             lock->Unlock();
 
-            if (!m_thread_queue.SleepThread(owner)) {
+            if (!thread_queue.SleepThread(owner)) {
                 lk.CancelSleep();
                 return;
             }
         }
 
-        /* Cancel the task that the sleep setup. */
+        // Cancel the task that the sleep setup.
         kernel.TimeManager().UnscheduleTimeEvent(owner);
     }
     KernelCore& kernel;
+    KThreadQueue thread_queue;
 };
 } // namespace Kernel
diff --git a/src/core/hle/kernel/k_resource_limit.cpp b/src/core/hle/kernel/k_resource_limit.cpp
index 3cee8d0f71..ab2ab683f7 100644
--- a/src/core/hle/kernel/k_resource_limit.cpp
+++ b/src/core/hle/kernel/k_resource_limit.cpp
@@ -13,9 +13,7 @@
 #include "core/hle/kernel/svc_results.h"
 
 namespace Kernel {
-namespace {
 constexpr s64 DefaultTimeout = 10000000000; // 10 seconds
-}
 
 KResourceLimit::KResourceLimit(KernelCore& kernel, Core::System& system)
     : Object{kernel}, lock{kernel}, cond_var{kernel}, kernel{kernel}, system(system) {}
diff --git a/src/core/hle/kernel/k_resource_limit.h b/src/core/hle/kernel/k_resource_limit.h
index 5f916c99cf..6b3437ea6e 100644
--- a/src/core/hle/kernel/k_resource_limit.h
+++ b/src/core/hle/kernel/k_resource_limit.h
@@ -37,7 +37,7 @@ constexpr bool IsValidResourceType(LimitableResource type) {
 
 class KResourceLimit final : public Object {
 public:
-    KResourceLimit(KernelCore& kernel, Core::System& system);
+    explicit KResourceLimit(KernelCore& kernel, Core::System& system);
     ~KResourceLimit();
 
     s64 GetLimitValue(LimitableResource which) const;
@@ -67,10 +67,11 @@ public:
     virtual void Finalize() override {}
 
 private:
-    std::array<s64, static_cast<std::size_t>(LimitableResource::Count)> limit_values{};
-    std::array<s64, static_cast<std::size_t>(LimitableResource::Count)> current_values{};
-    std::array<s64, static_cast<std::size_t>(LimitableResource::Count)> current_hints{};
-    std::array<s64, static_cast<std::size_t>(LimitableResource::Count)> peak_values{};
+    using ResourceArray = std::array<s64, static_cast<std::size_t>(LimitableResource::Count)>;
+    ResourceArray limit_values{};
+    ResourceArray current_values{};
+    ResourceArray current_hints{};
+    ResourceArray peak_values{};
     mutable KLightLock lock;
     s32 waiter_count{};
     KLightConditionVariable cond_var;

From 64c35827051f12232caba423cc43364d471ee001 Mon Sep 17 00:00:00 2001
From: Chloe Marcec <dmarcecguzman@gmail.com>
Date: Tue, 2 Feb 2021 13:23:34 +1100
Subject: [PATCH 7/8] Compile error

---
 src/core/hle/kernel/k_light_condition_variable.h | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/src/core/hle/kernel/k_light_condition_variable.h b/src/core/hle/kernel/k_light_condition_variable.h
index 26d94d7c0c..362d0db284 100644
--- a/src/core/hle/kernel/k_light_condition_variable.h
+++ b/src/core/hle/kernel/k_light_condition_variable.h
@@ -51,7 +51,7 @@ private:
         // Cancel the task that the sleep setup.
         kernel.TimeManager().UnscheduleTimeEvent(owner);
     }
-    KernelCore& kernel;
     KThreadQueue thread_queue;
+    KernelCore& kernel;
 };
 } // namespace Kernel

From 2c6e94049362f592bfb578a2b078f6f3067ed0d8 Mon Sep 17 00:00:00 2001
From: Chloe Marcec <dmarcecguzman@gmail.com>
Date: Wed, 3 Feb 2021 12:55:16 +1100
Subject: [PATCH 8/8] Simplify limitableresource names

---
 src/core/hle/kernel/k_resource_limit.h    | 10 +++++-----
 src/core/hle/kernel/k_thread.cpp          |  2 +-
 src/core/hle/kernel/kernel.cpp            | 16 ++++++----------
 src/core/hle/kernel/memory/page_table.cpp | 11 +++++------
 src/core/hle/kernel/process.cpp           | 18 +++++++++---------
 src/core/hle/kernel/svc.cpp               |  8 +++-----
 6 files changed, 29 insertions(+), 36 deletions(-)

diff --git a/src/core/hle/kernel/k_resource_limit.h b/src/core/hle/kernel/k_resource_limit.h
index 6b3437ea6e..58ae456f1f 100644
--- a/src/core/hle/kernel/k_resource_limit.h
+++ b/src/core/hle/kernel/k_resource_limit.h
@@ -22,11 +22,11 @@ class System;
 namespace Kernel {
 class KernelCore;
 enum class LimitableResource : u32 {
-    PhysicalMemoryMax = 0,
-    ThreadCountMax = 1,
-    EventCountMax = 2,
-    TransferMemoryCountMax = 3,
-    SessionCountMax = 4,
+    PhysicalMemory = 0,
+    Threads = 1,
+    Events = 2,
+    TransferMemory = 3,
+    Sessions = 4,
 
     Count,
 };
diff --git a/src/core/hle/kernel/k_thread.cpp b/src/core/hle/kernel/k_thread.cpp
index 38fd8e500c..b59259c4f2 100644
--- a/src/core/hle/kernel/k_thread.cpp
+++ b/src/core/hle/kernel/k_thread.cpp
@@ -247,7 +247,7 @@ void KThread::Finalize() {
     // Decrement the parent process's thread count.
     if (parent != nullptr) {
         parent->DecrementThreadCount();
-        parent->GetResourceLimit()->Release(LimitableResource::ThreadCountMax, 1);
+        parent->GetResourceLimit()->Release(LimitableResource::Threads, 1);
     }
 }
 
diff --git a/src/core/hle/kernel/kernel.cpp b/src/core/hle/kernel/kernel.cpp
index c66a993c24..b20c2d13a0 100644
--- a/src/core/hle/kernel/kernel.cpp
+++ b/src/core/hle/kernel/kernel.cpp
@@ -135,19 +135,15 @@ struct KernelCore::Impl {
         system_resource_limit = std::make_shared<KResourceLimit>(kernel, system);
 
         // If setting the default system values fails, then something seriously wrong has occurred.
-        ASSERT(
-            system_resource_limit->SetLimitValue(LimitableResource::PhysicalMemoryMax, 0x100000000)
-                .IsSuccess());
-        ASSERT(system_resource_limit->SetLimitValue(LimitableResource::ThreadCountMax, 800)
+        ASSERT(system_resource_limit->SetLimitValue(LimitableResource::PhysicalMemory, 0x100000000)
                    .IsSuccess());
-        ASSERT(system_resource_limit->SetLimitValue(LimitableResource::EventCountMax, 700)
-                   .IsSuccess());
-        ASSERT(system_resource_limit->SetLimitValue(LimitableResource::TransferMemoryCountMax, 200)
-                   .IsSuccess());
-        ASSERT(system_resource_limit->SetLimitValue(LimitableResource::SessionCountMax, 900)
+        ASSERT(system_resource_limit->SetLimitValue(LimitableResource::Threads, 800).IsSuccess());
+        ASSERT(system_resource_limit->SetLimitValue(LimitableResource::Events, 700).IsSuccess());
+        ASSERT(system_resource_limit->SetLimitValue(LimitableResource::TransferMemory, 200)
                    .IsSuccess());
+        ASSERT(system_resource_limit->SetLimitValue(LimitableResource::Sessions, 900).IsSuccess());
 
-        if (!system_resource_limit->Reserve(LimitableResource::PhysicalMemoryMax, 0x60000)) {
+        if (!system_resource_limit->Reserve(LimitableResource::PhysicalMemory, 0x60000)) {
             UNREACHABLE();
         }
     }
diff --git a/src/core/hle/kernel/memory/page_table.cpp b/src/core/hle/kernel/memory/page_table.cpp
index d8c7d980a4..7de91c7689 100644
--- a/src/core/hle/kernel/memory/page_table.cpp
+++ b/src/core/hle/kernel/memory/page_table.cpp
@@ -413,8 +413,8 @@ ResultCode PageTable::MapPhysicalMemory(VAddr addr, std::size_t size) {
     const std::size_t remaining_size{size - mapped_size};
     const std::size_t remaining_pages{remaining_size / PageSize};
 
-    if (process->GetResourceLimit() && !process->GetResourceLimit()->Reserve(
-                                           LimitableResource::PhysicalMemoryMax, remaining_size)) {
+    if (process->GetResourceLimit() &&
+        !process->GetResourceLimit()->Reserve(LimitableResource::PhysicalMemory, remaining_size)) {
         return ERR_RESOURCE_LIMIT_EXCEEDED;
     }
 
@@ -422,8 +422,7 @@ ResultCode PageTable::MapPhysicalMemory(VAddr addr, std::size_t size) {
     {
         auto block_guard = detail::ScopeExit([&] {
             system.Kernel().MemoryManager().Free(page_linked_list, remaining_pages, memory_pool);
-            process->GetResourceLimit()->Release(LimitableResource::PhysicalMemoryMax,
-                                                 remaining_size);
+            process->GetResourceLimit()->Release(LimitableResource::PhysicalMemory, remaining_size);
         });
 
         CASCADE_CODE(system.Kernel().MemoryManager().Allocate(page_linked_list, remaining_pages,
@@ -475,7 +474,7 @@ ResultCode PageTable::UnmapPhysicalMemory(VAddr addr, std::size_t size) {
     CASCADE_CODE(UnmapMemory(addr, size));
 
     auto process{system.Kernel().CurrentProcess()};
-    process->GetResourceLimit()->Release(LimitableResource::PhysicalMemoryMax, mapped_size);
+    process->GetResourceLimit()->Release(LimitableResource::PhysicalMemory, mapped_size);
     physical_memory_usage -= mapped_size;
 
     return RESULT_SUCCESS;
@@ -784,7 +783,7 @@ ResultVal<VAddr> PageTable::SetHeapSize(std::size_t size) {
 
         auto process{system.Kernel().CurrentProcess()};
         if (process->GetResourceLimit() && delta != 0 &&
-            !process->GetResourceLimit()->Reserve(LimitableResource::PhysicalMemoryMax, delta)) {
+            !process->GetResourceLimit()->Reserve(LimitableResource::PhysicalMemory, delta)) {
             return ERR_RESOURCE_LIMIT_EXCEEDED;
         }
 
diff --git a/src/core/hle/kernel/process.cpp b/src/core/hle/kernel/process.cpp
index 9efcb95f36..afdb27c548 100644
--- a/src/core/hle/kernel/process.cpp
+++ b/src/core/hle/kernel/process.cpp
@@ -154,7 +154,7 @@ void Process::DecrementThreadCount() {
 }
 
 u64 Process::GetTotalPhysicalMemoryAvailable() const {
-    const u64 capacity{resource_limit->GetFreeValue(LimitableResource::PhysicalMemoryMax) +
+    const u64 capacity{resource_limit->GetFreeValue(LimitableResource::PhysicalMemory) +
                        page_table->GetTotalHeapSize() + GetSystemResourceSize() + image_size +
                        main_thread_stack_size};
 
@@ -308,13 +308,13 @@ ResultCode Process::LoadFromMetadata(const FileSys::ProgramMetadata& metadata,
 
     // Set initial resource limits
     resource_limit->SetLimitValue(
-        LimitableResource::PhysicalMemoryMax,
+        LimitableResource::PhysicalMemory,
         kernel.MemoryManager().GetSize(Memory::MemoryManager::Pool::Application));
-    resource_limit->SetLimitValue(LimitableResource::ThreadCountMax, 608);
-    resource_limit->SetLimitValue(LimitableResource::EventCountMax, 700);
-    resource_limit->SetLimitValue(LimitableResource::TransferMemoryCountMax, 128);
-    resource_limit->SetLimitValue(LimitableResource::SessionCountMax, 894);
-    ASSERT(resource_limit->Reserve(LimitableResource::PhysicalMemoryMax, code_size));
+    resource_limit->SetLimitValue(LimitableResource::Threads, 608);
+    resource_limit->SetLimitValue(LimitableResource::Events, 700);
+    resource_limit->SetLimitValue(LimitableResource::TransferMemory, 128);
+    resource_limit->SetLimitValue(LimitableResource::Sessions, 894);
+    ASSERT(resource_limit->Reserve(LimitableResource::PhysicalMemory, code_size));
 
     // Create TLS region
     tls_region_address = CreateTLSRegion();
@@ -331,8 +331,8 @@ void Process::Run(s32 main_thread_priority, u64 stack_size) {
     ChangeStatus(ProcessStatus::Running);
 
     SetupMainThread(system, *this, main_thread_priority, main_thread_stack_top);
-    resource_limit->Reserve(LimitableResource::ThreadCountMax, 1);
-    resource_limit->Reserve(LimitableResource::PhysicalMemoryMax, main_thread_stack_size);
+    resource_limit->Reserve(LimitableResource::Threads, 1);
+    resource_limit->Reserve(LimitableResource::PhysicalMemory, main_thread_stack_size);
 }
 
 void Process::PrepareForTermination() {
diff --git a/src/core/hle/kernel/svc.cpp b/src/core/hle/kernel/svc.cpp
index d89873104e..74eb901002 100644
--- a/src/core/hle/kernel/svc.cpp
+++ b/src/core/hle/kernel/svc.cpp
@@ -312,8 +312,7 @@ static ResultCode ConnectToNamedPort(Core::System& system, Handle* out_handle,
         return ERR_NOT_FOUND;
     }
 
-    ASSERT(kernel.CurrentProcess()->GetResourceLimit()->Reserve(LimitableResource::SessionCountMax,
-                                                                1));
+    ASSERT(kernel.CurrentProcess()->GetResourceLimit()->Reserve(LimitableResource::Sessions, 1));
 
     auto client_port = it->second;
 
@@ -1451,9 +1450,8 @@ static ResultCode CreateThread(Core::System& system, Handle* out_handle, VAddr e
              Svc::ResultInvalidPriority);
     R_UNLESS(process.CheckThreadPriority(priority), Svc::ResultInvalidPriority);
 
-    ASSERT(process.GetResourceLimit()->Reserve(LimitableResource::ThreadCountMax, 1,
-                                               system.CoreTiming().GetGlobalTimeNs().count() +
-                                                   100000000));
+    ASSERT(process.GetResourceLimit()->Reserve(
+        LimitableResource::Threads, 1, system.CoreTiming().GetGlobalTimeNs().count() + 100000000));
 
     std::shared_ptr<KThread> thread;
     {