From b805ee653f3d178ed2b4b2e0a403bb0ab61dad8b Mon Sep 17 00:00:00 2001
From: bunnei <bunneidev@gmail.com>
Date: Tue, 4 May 2021 21:35:42 -0700
Subject: [PATCH] hle: kernel: Move slab resource counts to Kernel.

---
 src/core/hle/kernel/init/init_slab_setup.cpp | 54 ++++++++++----------
 src/core/hle/kernel/init/init_slab_setup.h   |  9 ++--
 src/core/hle/kernel/kernel.cpp               | 12 ++++-
 src/core/hle/kernel/kernel.h                 | 10 ++++
 4 files changed, 52 insertions(+), 33 deletions(-)

diff --git a/src/core/hle/kernel/init/init_slab_setup.cpp b/src/core/hle/kernel/init/init_slab_setup.cpp
index 2dd792e71..69ae405e6 100644
--- a/src/core/hle/kernel/init/init_slab_setup.cpp
+++ b/src/core/hle/kernel/init/init_slab_setup.cpp
@@ -25,7 +25,7 @@
 
 namespace Kernel::Init {
 
-#define SLAB_COUNT(CLASS) g_slab_resource_counts.num_##CLASS
+#define SLAB_COUNT(CLASS) kernel.SlabResourceCounts().num_##CLASS
 
 #define FOREACH_SLAB_TYPE(HANDLER, ...)                                                            \
     HANDLER(KProcess, (SLAB_COUNT(KProcess)), ##__VA_ARGS__)                                       \
@@ -67,26 +67,6 @@ constexpr size_t SlabCountKBeta = 6;
 
 constexpr size_t SlabCountExtraKThread = 160;
 
-// Global to hold our resource counts.
-KSlabResourceCounts g_slab_resource_counts = {
-    .num_KProcess = SlabCountKProcess,
-    .num_KThread = SlabCountKThread,
-    .num_KEvent = SlabCountKEvent,
-    .num_KInterruptEvent = SlabCountKInterruptEvent,
-    .num_KPort = SlabCountKPort,
-    .num_KSharedMemory = SlabCountKSharedMemory,
-    .num_KTransferMemory = SlabCountKTransferMemory,
-    .num_KCodeMemory = SlabCountKCodeMemory,
-    .num_KDeviceAddressSpace = SlabCountKDeviceAddressSpace,
-    .num_KSession = SlabCountKSession,
-    .num_KLightSession = SlabCountKLightSession,
-    .num_KObjectName = SlabCountKObjectName,
-    .num_KResourceLimit = SlabCountKResourceLimit,
-    .num_KDebug = SlabCountKDebug,
-    .num_KAlpha = SlabCountKAlpha,
-    .num_KBeta = SlabCountKBeta,
-};
-
 template <typename T>
 VAddr InitializeSlabHeap(Core::System& system, KMemoryLayout& memory_layout, VAddr address,
                          size_t num_objects) {
@@ -105,19 +85,35 @@ VAddr InitializeSlabHeap(Core::System& system, KMemoryLayout& memory_layout, VAd
 
 } // namespace
 
-const KSlabResourceCounts& GetSlabResourceCounts() {
-    return g_slab_resource_counts;
+KSlabResourceCounts KSlabResourceCounts::CreateDefault() {
+    return {
+        .num_KProcess = SlabCountKProcess,
+        .num_KThread = SlabCountKThread,
+        .num_KEvent = SlabCountKEvent,
+        .num_KInterruptEvent = SlabCountKInterruptEvent,
+        .num_KPort = SlabCountKPort,
+        .num_KSharedMemory = SlabCountKSharedMemory,
+        .num_KTransferMemory = SlabCountKTransferMemory,
+        .num_KCodeMemory = SlabCountKCodeMemory,
+        .num_KDeviceAddressSpace = SlabCountKDeviceAddressSpace,
+        .num_KSession = SlabCountKSession,
+        .num_KLightSession = SlabCountKLightSession,
+        .num_KObjectName = SlabCountKObjectName,
+        .num_KResourceLimit = SlabCountKResourceLimit,
+        .num_KDebug = SlabCountKDebug,
+        .num_KAlpha = SlabCountKAlpha,
+        .num_KBeta = SlabCountKBeta,
+    };
 }
 
-void InitializeSlabResourceCounts() {
-    // Note: Nintendo initializes all fields here, but we initialize all constants at compile-time.
-
+void InitializeSlabResourceCounts(KernelCore& kernel) {
+    kernel.SlabResourceCounts() = KSlabResourceCounts::CreateDefault();
     if (KSystemControl::Init::ShouldIncreaseThreadResourceLimit()) {
-        g_slab_resource_counts.num_KThread += SlabCountExtraKThread;
+        kernel.SlabResourceCounts().num_KThread += SlabCountExtraKThread;
     }
 }
 
-size_t CalculateTotalSlabHeapSize() {
+size_t CalculateTotalSlabHeapSize(const KernelCore& kernel) {
     size_t size = 0;
 
 #define ADD_SLAB_SIZE(NAME, COUNT, ...)                                                            \
@@ -138,6 +134,8 @@ size_t CalculateTotalSlabHeapSize() {
 }
 
 void InitializeSlabHeaps(Core::System& system, KMemoryLayout& memory_layout) {
+    auto& kernel = system.Kernel();
+
     // Get the start of the slab region, since that's where we'll be working.
     VAddr address = memory_layout.GetSlabRegionAddress();
 
diff --git a/src/core/hle/kernel/init/init_slab_setup.h b/src/core/hle/kernel/init/init_slab_setup.h
index 6418b97ac..a8f7e0918 100644
--- a/src/core/hle/kernel/init/init_slab_setup.h
+++ b/src/core/hle/kernel/init/init_slab_setup.h
@@ -9,12 +9,15 @@ class System;
 } // namespace Core
 
 namespace Kernel {
+class KernelCore;
 class KMemoryLayout;
 } // namespace Kernel
 
 namespace Kernel::Init {
 
 struct KSlabResourceCounts {
+    static KSlabResourceCounts CreateDefault();
+
     size_t num_KProcess;
     size_t num_KThread;
     size_t num_KEvent;
@@ -33,10 +36,8 @@ struct KSlabResourceCounts {
     size_t num_KBeta;
 };
 
-void InitializeSlabResourceCounts();
-const KSlabResourceCounts& GetSlabResourceCounts();
-
-size_t CalculateTotalSlabHeapSize();
+void InitializeSlabResourceCounts(KernelCore& kernel);
+size_t CalculateTotalSlabHeapSize(const KernelCore& kernel);
 void InitializeSlabHeaps(Core::System& system, KMemoryLayout& memory_layout);
 
 } // namespace Kernel::Init
diff --git a/src/core/hle/kernel/kernel.cpp b/src/core/hle/kernel/kernel.cpp
index 5ebd47e49..32bbf2d9b 100644
--- a/src/core/hle/kernel/kernel.cpp
+++ b/src/core/hle/kernel/kernel.cpp
@@ -69,6 +69,7 @@ struct KernelCore::Impl {
         InitializePhysicalCores();
 
         // Derive the initial memory layout from the emulated board
+        Init::InitializeSlabResourceCounts(kernel);
         KMemoryLayout memory_layout;
         DeriveInitialMemoryLayout(memory_layout);
         Init::InitializeSlabHeaps(system, memory_layout);
@@ -395,7 +396,7 @@ struct KernelCore::Impl {
 
         // Determine the size of the slab region.
         const size_t slab_region_size =
-            Common::AlignUp(Init::CalculateTotalSlabHeapSize(), PageSize);
+            Common::AlignUp(Init::CalculateTotalSlabHeapSize(system.Kernel()), PageSize);
         ASSERT(slab_region_size <= resource_region_size);
 
         // Setup the slab region.
@@ -642,6 +643,7 @@ struct KernelCore::Impl {
     std::unique_ptr<Kernel::GlobalSchedulerContext> global_scheduler_context;
     Kernel::TimeManager time_manager;
 
+    Init::KSlabResourceCounts slab_resource_counts{};
     KResourceLimit* system_resource_limit{};
 
     std::shared_ptr<Core::Timing::EventType> preemption_event;
@@ -995,6 +997,14 @@ void KernelCore::ReleaseServiceThread(std::weak_ptr<Kernel::ServiceThread> servi
     });
 }
 
+Init::KSlabResourceCounts& KernelCore::SlabResourceCounts() {
+    return impl->slab_resource_counts;
+}
+
+const Init::KSlabResourceCounts& KernelCore::SlabResourceCounts() const {
+    return impl->slab_resource_counts;
+}
+
 bool KernelCore::IsPhantomModeForSingleCore() const {
     return impl->IsPhantomModeForSingleCore();
 }
diff --git a/src/core/hle/kernel/kernel.h b/src/core/hle/kernel/kernel.h
index 7c46aa997..51aaccbc7 100644
--- a/src/core/hle/kernel/kernel.h
+++ b/src/core/hle/kernel/kernel.h
@@ -51,6 +51,10 @@ class ServiceThread;
 class Synchronization;
 class TimeManager;
 
+namespace Init {
+struct KSlabResourceCounts;
+}
+
 template <typename T>
 class KSlabHeap;
 
@@ -292,6 +296,12 @@ public:
         }
     }
 
+    /// Gets the current slab resource counts.
+    Init::KSlabResourceCounts& SlabResourceCounts();
+
+    /// Gets the current slab resource counts.
+    const Init::KSlabResourceCounts& SlabResourceCounts() const;
+
 private:
     friend class KProcess;
     friend class KThread;