summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/core/CMakeLists.txt5
-rw-r--r--src/core/hle/kernel/k_light_condition_variable.h60
-rw-r--r--src/core/hle/kernel/k_resource_limit.cpp155
-rw-r--r--src/core/hle/kernel/k_resource_limit.h80
-rw-r--r--src/core/hle/kernel/k_thread.cpp4
-rw-r--r--src/core/hle/kernel/kernel.cpp30
-rw-r--r--src/core/hle/kernel/kernel.h4
-rw-r--r--src/core/hle/kernel/memory/page_table.cpp13
-rw-r--r--src/core/hle/kernel/process.cpp24
-rw-r--r--src/core/hle/kernel/process.h6
-rw-r--r--src/core/hle/kernel/resource_limit.cpp73
-rw-r--r--src/core/hle/kernel/resource_limit.h106
-rw-r--r--src/core/hle/kernel/svc.cpp28
13 files changed, 357 insertions, 231 deletions
diff --git a/src/core/CMakeLists.txt b/src/core/CMakeLists.txt
index 397cc028f..0ee02c81d 100644
--- a/src/core/CMakeLists.txt
+++ b/src/core/CMakeLists.txt
@@ -160,9 +160,12 @@ add_library(core STATIC
160 hle/kernel/k_affinity_mask.h 160 hle/kernel/k_affinity_mask.h
161 hle/kernel/k_condition_variable.cpp 161 hle/kernel/k_condition_variable.cpp
162 hle/kernel/k_condition_variable.h 162 hle/kernel/k_condition_variable.h
163 hle/kernel/k_light_condition_variable.h
163 hle/kernel/k_light_lock.cpp 164 hle/kernel/k_light_lock.cpp
164 hle/kernel/k_light_lock.h 165 hle/kernel/k_light_lock.h
165 hle/kernel/k_priority_queue.h 166 hle/kernel/k_priority_queue.h
167 hle/kernel/k_resource_limit.cpp
168 hle/kernel/k_resource_limit.h
166 hle/kernel/k_scheduler.cpp 169 hle/kernel/k_scheduler.cpp
167 hle/kernel/k_scheduler.h 170 hle/kernel/k_scheduler.h
168 hle/kernel/k_scheduler_lock.h 171 hle/kernel/k_scheduler_lock.h
@@ -203,8 +206,6 @@ add_library(core STATIC
203 hle/kernel/process_capability.h 206 hle/kernel/process_capability.h
204 hle/kernel/readable_event.cpp 207 hle/kernel/readable_event.cpp
205 hle/kernel/readable_event.h 208 hle/kernel/readable_event.h
206 hle/kernel/resource_limit.cpp
207 hle/kernel/resource_limit.h
208 hle/kernel/server_port.cpp 209 hle/kernel/server_port.cpp
209 hle/kernel/server_port.h 210 hle/kernel/server_port.h
210 hle/kernel/server_session.cpp 211 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 000000000..26573a239
--- /dev/null
+++ b/src/core/hle/kernel/k_light_condition_variable.h
@@ -0,0 +1,60 @@
1// Copyright 2020 yuzu Emulator Project
2// Licensed under GPLv2 or any later version
3// Refer to the license.txt file included.
4
5// This file references various implementation details from Atmosphere, an open-source firmware for
6// the Nintendo Switch. Copyright 2018-2020 Atmosphere-NX.
7
8#pragma once
9
10#include "common/common_types.h"
11#include "core/hle/kernel/k_scheduler.h"
12#include "core/hle/kernel/k_scoped_scheduler_lock_and_sleep.h"
13#include "core/hle/kernel/k_thread_queue.h"
14#include "core/hle/kernel/time_manager.h"
15
16namespace Kernel {
17class KernelCore;
18
19class KLightConditionVariable {
20private:
21 KThreadQueue m_thread_queue;
22
23public:
24 KLightConditionVariable(KernelCore& kernel) : m_thread_queue(kernel), kernel(kernel) {}
25
26 void Wait(KLightLock* lock, s64 timeout = -1ll) {
27 WaitImpl(lock, timeout);
28 lock->Lock();
29 }
30
31 void Broadcast() {
32 KScopedSchedulerLock lk{kernel};
33 while (m_thread_queue.WakeupFrontThread() != nullptr) {
34 /* We want to signal all threads, and so should continue waking up until there's nothing
35 * to wake. */
36 }
37 }
38
39private:
40 void WaitImpl(KLightLock* lock, s64 timeout) {
41 KThread* owner = GetCurrentThreadPointer(kernel);
42 // KHardwareTimer* timer;
43
44 /* Sleep the thread. */
45 {
46 KScopedSchedulerLockAndSleep lk(kernel, owner, timeout);
47 lock->Unlock();
48
49 if (!m_thread_queue.SleepThread(owner)) {
50 lk.CancelSleep();
51 return;
52 }
53 }
54
55 /* Cancel the task that the sleep setup. */
56 kernel.TimeManager().UnscheduleTimeEvent(owner);
57 }
58 KernelCore& kernel;
59};
60} // 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 000000000..f943d6562
--- /dev/null
+++ b/src/core/hle/kernel/k_resource_limit.cpp
@@ -0,0 +1,155 @@
1// Copyright 2020 yuzu Emulator Project
2// Licensed under GPLv2 or any later version
3// Refer to the license.txt file included.
4
5// This file references various implementation details from Atmosphere, an open-source firmware for
6// the Nintendo Switch. Copyright 2018-2020 Atmosphere-NX.
7
8#include "common/assert.h"
9#include "core/core.h"
10#include "core/core_timing.h"
11#include "core/core_timing_util.h"
12#include "core/hle/kernel/k_resource_limit.h"
13#include "core/hle/kernel/svc_results.h"
14
15namespace Kernel {
16namespace {
17static const s64 DefaultTimeout =
18 Core::Timing::msToCycles(std::chrono::milliseconds{10000}); // 10 seconds
19}
20
21KResourceLimit::KResourceLimit(KernelCore& kernel, Core::System& system)
22 : Object{kernel}, m_lock{kernel}, cond_var{kernel}, kernel{kernel}, system(system) {}
23KResourceLimit::~KResourceLimit() = default;
24
25s64 KResourceLimit::GetLimitValue(LimitableResource which) const {
26 const auto index = static_cast<std::size_t>(which);
27 s64 value{};
28 {
29 KScopedLightLock lk{m_lock};
30 value = limit_values[index];
31 ASSERT(value >= 0);
32 ASSERT(current_values[index] <= limit_values[index]);
33 ASSERT(current_hints[index] <= current_values[index]);
34 }
35 return value;
36}
37
38s64 KResourceLimit::GetCurrentValue(LimitableResource which) const {
39 const auto index = static_cast<std::size_t>(which);
40 s64 value{};
41 {
42 KScopedLightLock lk{m_lock};
43 value = current_values[index];
44 ASSERT(value >= 0);
45 ASSERT(current_values[index] <= limit_values[index]);
46 ASSERT(current_hints[index] <= current_values[index]);
47 }
48 return value;
49}
50
51s64 KResourceLimit::GetPeakValue(LimitableResource which) const {
52 const auto index = static_cast<std::size_t>(which);
53 s64 value{};
54 {
55 KScopedLightLock lk{m_lock};
56 value = peak_values[index];
57 ASSERT(value >= 0);
58 ASSERT(current_values[index] <= limit_values[index]);
59 ASSERT(current_hints[index] <= current_values[index]);
60 }
61 return value;
62}
63
64s64 KResourceLimit::GetFreeValue(LimitableResource which) const {
65 const auto index = static_cast<std::size_t>(which);
66 s64 value{};
67 {
68 KScopedLightLock lk(m_lock);
69 ASSERT(current_values[index] >= 0);
70 ASSERT(current_values[index] <= limit_values[index]);
71 ASSERT(current_hints[index] <= current_values[index]);
72 value = limit_values[index] - current_values[index];
73 }
74
75 return value;
76}
77
78ResultCode KResourceLimit::SetLimitValue(LimitableResource which, s64 value) {
79 const auto index = static_cast<std::size_t>(which);
80 KScopedLightLock lk(m_lock);
81 R_UNLESS(current_values[index] <= value, Svc::ResultInvalidState);
82
83 limit_values[index] = value;
84
85 return RESULT_SUCCESS;
86}
87
88bool KResourceLimit::Reserve(LimitableResource which, s64 value) {
89 return Reserve(which, value, system.CoreTiming().GetClockTicks() + DefaultTimeout);
90}
91
92bool KResourceLimit::Reserve(LimitableResource which, s64 value, s64 timeout) {
93 ASSERT(value >= 0);
94 const auto index = static_cast<std::size_t>(which);
95 KScopedLightLock lk(m_lock);
96
97 ASSERT(current_hints[index] <= current_values[index]);
98 if (current_hints[index] >= limit_values[index]) {
99 return false;
100 }
101
102 /* Loop until we reserve or run out of time. */
103 while (true) {
104 ASSERT(current_values[index] <= limit_values[index]);
105 ASSERT(current_hints[index] <= current_values[index]);
106
107 /* If we would overflow, don't allow to succeed. */
108 if (current_values[index] + value <= current_values[index]) {
109 break;
110 }
111
112 if (current_values[index] + value <= limit_values[index]) {
113 current_values[index] += value;
114 current_hints[index] += value;
115 peak_values[index] = std::max(peak_values[index], current_values[index]);
116 return true;
117 }
118
119 if (current_hints[index] + value <= limit_values[index] &&
120 (timeout < 0 || system.CoreTiming().GetClockTicks() < static_cast<u64>(timeout))) {
121 waiter_count++;
122 cond_var.Wait(&m_lock, timeout);
123 waiter_count--;
124 } else {
125 break;
126 }
127 }
128
129 return false;
130}
131
132void KResourceLimit::Release(LimitableResource which, s64 value) {
133 Release(which, value, value);
134}
135
136void KResourceLimit::Release(LimitableResource which, s64 value, s64 hint) {
137 ASSERT(value >= 0);
138 ASSERT(hint >= 0);
139
140 const auto index = static_cast<std::size_t>(which);
141 KScopedLightLock lk(m_lock);
142 ASSERT(current_values[index] <= limit_values[index]);
143 ASSERT(current_hints[index] <= current_values[index]);
144 ASSERT(value <= current_values[index]);
145 ASSERT(hint <= current_hints[index]);
146
147 current_values[index] -= value;
148 current_hints[index] -= hint;
149
150 if (waiter_count != 0) {
151 cond_var.Broadcast();
152 }
153}
154
155} // 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 000000000..84c59177c
--- /dev/null
+++ b/src/core/hle/kernel/k_resource_limit.h
@@ -0,0 +1,80 @@
1// Copyright 2020 yuzu Emulator Project
2// Licensed under GPLv2 or any later version
3// Refer to the license.txt file included.
4
5// This file references various implementation details from Atmosphere, an open-source firmware for
6// the Nintendo Switch. Copyright 2018-2020 Atmosphere-NX.
7
8#pragma once
9
10#include <array>
11#include "common/common_types.h"
12#include "core/hle/kernel/k_light_condition_variable.h"
13#include "core/hle/kernel/k_light_lock.h"
14#include "core/hle/kernel/object.h"
15
16union ResultCode;
17
18namespace Core {
19class System;
20}
21
22namespace Kernel {
23class KernelCore;
24enum class LimitableResource : u32 {
25 PhysicalMemoryMax = 0,
26 ThreadCountMax = 1,
27 EventCountMax = 2,
28 TransferMemoryCountMax = 3,
29 SessionCountMax = 4,
30
31 Count,
32};
33
34constexpr bool IsValidResourceType(LimitableResource type) {
35 return type < LimitableResource::Count;
36}
37
38class KResourceLimit final : public Object {
39public:
40 KResourceLimit(KernelCore& kernel, Core::System& system);
41 ~KResourceLimit();
42
43 s64 GetLimitValue(LimitableResource which) const;
44 s64 GetCurrentValue(LimitableResource which) const;
45 s64 GetPeakValue(LimitableResource which) const;
46 s64 GetFreeValue(LimitableResource which) const;
47
48 ResultCode SetLimitValue(LimitableResource which, s64 value);
49
50 bool Reserve(LimitableResource which, s64 value);
51 bool Reserve(LimitableResource which, s64 value, s64 timeout);
52 void Release(LimitableResource which, s64 value);
53 void Release(LimitableResource which, s64 value, s64 hint);
54
55 std::string GetTypeName() const override {
56 return "KResourceLimit";
57 }
58 std::string GetName() const override {
59 return GetTypeName();
60 }
61
62 static constexpr HandleType HANDLE_TYPE = HandleType::ResourceLimit;
63 HandleType GetHandleType() const override {
64 return HANDLE_TYPE;
65 }
66
67 virtual void Finalize() override {}
68
69private:
70 std::array<s64, static_cast<std::size_t>(LimitableResource::Count)> limit_values{};
71 std::array<s64, static_cast<std::size_t>(LimitableResource::Count)> current_values{};
72 std::array<s64, static_cast<std::size_t>(LimitableResource::Count)> current_hints{};
73 std::array<s64, static_cast<std::size_t>(LimitableResource::Count)> peak_values{};
74 mutable KLightLock m_lock;
75 s32 waiter_count{};
76 KLightConditionVariable cond_var;
77 KernelCore& kernel;
78 Core::System& system;
79};
80} // namespace Kernel
diff --git a/src/core/hle/kernel/k_thread.cpp b/src/core/hle/kernel/k_thread.cpp
index aa100e139..38fd8e500 100644
--- a/src/core/hle/kernel/k_thread.cpp
+++ b/src/core/hle/kernel/k_thread.cpp
@@ -21,6 +21,7 @@
21#include "core/hle/kernel/errors.h" 21#include "core/hle/kernel/errors.h"
22#include "core/hle/kernel/handle_table.h" 22#include "core/hle/kernel/handle_table.h"
23#include "core/hle/kernel/k_condition_variable.h" 23#include "core/hle/kernel/k_condition_variable.h"
24#include "core/hle/kernel/k_resource_limit.h"
24#include "core/hle/kernel/k_scheduler.h" 25#include "core/hle/kernel/k_scheduler.h"
25#include "core/hle/kernel/k_scoped_scheduler_lock_and_sleep.h" 26#include "core/hle/kernel/k_scoped_scheduler_lock_and_sleep.h"
26#include "core/hle/kernel/k_thread.h" 27#include "core/hle/kernel/k_thread.h"
@@ -29,7 +30,6 @@
29#include "core/hle/kernel/memory/memory_layout.h" 30#include "core/hle/kernel/memory/memory_layout.h"
30#include "core/hle/kernel/object.h" 31#include "core/hle/kernel/object.h"
31#include "core/hle/kernel/process.h" 32#include "core/hle/kernel/process.h"
32#include "core/hle/kernel/resource_limit.h"
33#include "core/hle/kernel/svc_results.h" 33#include "core/hle/kernel/svc_results.h"
34#include "core/hle/kernel/time_manager.h" 34#include "core/hle/kernel/time_manager.h"
35#include "core/hle/result.h" 35#include "core/hle/result.h"
@@ -247,7 +247,7 @@ void KThread::Finalize() {
247 // Decrement the parent process's thread count. 247 // Decrement the parent process's thread count.
248 if (parent != nullptr) { 248 if (parent != nullptr) {
249 parent->DecrementThreadCount(); 249 parent->DecrementThreadCount();
250 parent->GetResourceLimit()->Release(ResourceType::Threads, 1); 250 parent->GetResourceLimit()->Release(LimitableResource::ThreadCountMax, 1);
251 } 251 }
252} 252}
253 253
diff --git a/src/core/hle/kernel/kernel.cpp b/src/core/hle/kernel/kernel.cpp
index df309d523..c66a993c2 100644
--- a/src/core/hle/kernel/kernel.cpp
+++ b/src/core/hle/kernel/kernel.cpp
@@ -28,6 +28,7 @@
28#include "core/hle/kernel/client_port.h" 28#include "core/hle/kernel/client_port.h"
29#include "core/hle/kernel/errors.h" 29#include "core/hle/kernel/errors.h"
30#include "core/hle/kernel/handle_table.h" 30#include "core/hle/kernel/handle_table.h"
31#include "core/hle/kernel/k_resource_limit.h"
31#include "core/hle/kernel/k_scheduler.h" 32#include "core/hle/kernel/k_scheduler.h"
32#include "core/hle/kernel/k_thread.h" 33#include "core/hle/kernel/k_thread.h"
33#include "core/hle/kernel/kernel.h" 34#include "core/hle/kernel/kernel.h"
@@ -36,7 +37,6 @@
36#include "core/hle/kernel/memory/slab_heap.h" 37#include "core/hle/kernel/memory/slab_heap.h"
37#include "core/hle/kernel/physical_core.h" 38#include "core/hle/kernel/physical_core.h"
38#include "core/hle/kernel/process.h" 39#include "core/hle/kernel/process.h"
39#include "core/hle/kernel/resource_limit.h"
40#include "core/hle/kernel/service_thread.h" 40#include "core/hle/kernel/service_thread.h"
41#include "core/hle/kernel/shared_memory.h" 41#include "core/hle/kernel/shared_memory.h"
42#include "core/hle/kernel/time_manager.h" 42#include "core/hle/kernel/time_manager.h"
@@ -66,7 +66,7 @@ struct KernelCore::Impl {
66 is_phantom_mode_for_singlecore = false; 66 is_phantom_mode_for_singlecore = false;
67 67
68 InitializePhysicalCores(); 68 InitializePhysicalCores();
69 InitializeSystemResourceLimit(kernel); 69 InitializeSystemResourceLimit(kernel, system);
70 InitializeMemoryLayout(); 70 InitializeMemoryLayout();
71 InitializePreemption(kernel); 71 InitializePreemption(kernel);
72 InitializeSchedulers(); 72 InitializeSchedulers();
@@ -131,19 +131,23 @@ struct KernelCore::Impl {
131 } 131 }
132 132
133 // Creates the default system resource limit 133 // Creates the default system resource limit
134 void InitializeSystemResourceLimit(KernelCore& kernel) { 134 void InitializeSystemResourceLimit(KernelCore& kernel, Core::System& system) {
135 system_resource_limit = ResourceLimit::Create(kernel); 135 system_resource_limit = std::make_shared<KResourceLimit>(kernel, system);
136 136
137 // If setting the default system values fails, then something seriously wrong has occurred. 137 // If setting the default system values fails, then something seriously wrong has occurred.
138 ASSERT(system_resource_limit->SetLimitValue(ResourceType::PhysicalMemory, 0x100000000) 138 ASSERT(
139 system_resource_limit->SetLimitValue(LimitableResource::PhysicalMemoryMax, 0x100000000)
140 .IsSuccess());
141 ASSERT(system_resource_limit->SetLimitValue(LimitableResource::ThreadCountMax, 800)
142 .IsSuccess());
143 ASSERT(system_resource_limit->SetLimitValue(LimitableResource::EventCountMax, 700)
144 .IsSuccess());
145 ASSERT(system_resource_limit->SetLimitValue(LimitableResource::TransferMemoryCountMax, 200)
146 .IsSuccess());
147 ASSERT(system_resource_limit->SetLimitValue(LimitableResource::SessionCountMax, 900)
139 .IsSuccess()); 148 .IsSuccess());
140 ASSERT(system_resource_limit->SetLimitValue(ResourceType::Threads, 800).IsSuccess());
141 ASSERT(system_resource_limit->SetLimitValue(ResourceType::Events, 700).IsSuccess());
142 ASSERT(system_resource_limit->SetLimitValue(ResourceType::TransferMemory, 200).IsSuccess());
143 ASSERT(system_resource_limit->SetLimitValue(ResourceType::Sessions, 900).IsSuccess());
144 149
145 if (!system_resource_limit->Reserve(ResourceType::PhysicalMemory, 0) || 150 if (!system_resource_limit->Reserve(LimitableResource::PhysicalMemoryMax, 0x60000)) {
146 !system_resource_limit->Reserve(ResourceType::PhysicalMemory, 0x60000)) {
147 UNREACHABLE(); 151 UNREACHABLE();
148 } 152 }
149 } 153 }
@@ -320,7 +324,7 @@ struct KernelCore::Impl {
320 std::unique_ptr<Kernel::GlobalSchedulerContext> global_scheduler_context; 324 std::unique_ptr<Kernel::GlobalSchedulerContext> global_scheduler_context;
321 Kernel::TimeManager time_manager; 325 Kernel::TimeManager time_manager;
322 326
323 std::shared_ptr<ResourceLimit> system_resource_limit; 327 std::shared_ptr<KResourceLimit> system_resource_limit;
324 328
325 std::shared_ptr<Core::Timing::EventType> preemption_event; 329 std::shared_ptr<Core::Timing::EventType> preemption_event;
326 330
@@ -390,7 +394,7 @@ void KernelCore::Shutdown() {
390 impl->Shutdown(); 394 impl->Shutdown();
391} 395}
392 396
393std::shared_ptr<ResourceLimit> KernelCore::GetSystemResourceLimit() const { 397std::shared_ptr<KResourceLimit> KernelCore::GetSystemResourceLimit() const {
394 return impl->system_resource_limit; 398 return impl->system_resource_limit;
395} 399}
396 400
diff --git a/src/core/hle/kernel/kernel.h b/src/core/hle/kernel/kernel.h
index e7c77727b..806a0d986 100644
--- a/src/core/hle/kernel/kernel.h
+++ b/src/core/hle/kernel/kernel.h
@@ -38,7 +38,7 @@ class GlobalSchedulerContext;
38class HandleTable; 38class HandleTable;
39class PhysicalCore; 39class PhysicalCore;
40class Process; 40class Process;
41class ResourceLimit; 41class KResourceLimit;
42class KScheduler; 42class KScheduler;
43class SharedMemory; 43class SharedMemory;
44class ServiceThread; 44class ServiceThread;
@@ -85,7 +85,7 @@ public:
85 void Shutdown(); 85 void Shutdown();
86 86
87 /// Retrieves a shared pointer to the system resource limit instance. 87 /// Retrieves a shared pointer to the system resource limit instance.
88 std::shared_ptr<ResourceLimit> GetSystemResourceLimit() const; 88 std::shared_ptr<KResourceLimit> GetSystemResourceLimit() const;
89 89
90 /// Retrieves a shared pointer to a Thread instance within the thread wakeup handle table. 90 /// Retrieves a shared pointer to a Thread instance within the thread wakeup handle table.
91 std::shared_ptr<KThread> RetrieveThreadFromGlobalHandleTable(Handle handle) const; 91 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 080886554..d8c7d980a 100644
--- a/src/core/hle/kernel/memory/page_table.cpp
+++ b/src/core/hle/kernel/memory/page_table.cpp
@@ -7,6 +7,7 @@
7#include "common/scope_exit.h" 7#include "common/scope_exit.h"
8#include "core/core.h" 8#include "core/core.h"
9#include "core/hle/kernel/errors.h" 9#include "core/hle/kernel/errors.h"
10#include "core/hle/kernel/k_resource_limit.h"
10#include "core/hle/kernel/kernel.h" 11#include "core/hle/kernel/kernel.h"
11#include "core/hle/kernel/memory/address_space_info.h" 12#include "core/hle/kernel/memory/address_space_info.h"
12#include "core/hle/kernel/memory/memory_block.h" 13#include "core/hle/kernel/memory/memory_block.h"
@@ -15,7 +16,6 @@
15#include "core/hle/kernel/memory/page_table.h" 16#include "core/hle/kernel/memory/page_table.h"
16#include "core/hle/kernel/memory/system_control.h" 17#include "core/hle/kernel/memory/system_control.h"
17#include "core/hle/kernel/process.h" 18#include "core/hle/kernel/process.h"
18#include "core/hle/kernel/resource_limit.h"
19#include "core/memory.h" 19#include "core/memory.h"
20 20
21namespace Kernel::Memory { 21namespace Kernel::Memory {
@@ -413,8 +413,8 @@ ResultCode PageTable::MapPhysicalMemory(VAddr addr, std::size_t size) {
413 const std::size_t remaining_size{size - mapped_size}; 413 const std::size_t remaining_size{size - mapped_size};
414 const std::size_t remaining_pages{remaining_size / PageSize}; 414 const std::size_t remaining_pages{remaining_size / PageSize};
415 415
416 if (process->GetResourceLimit() && 416 if (process->GetResourceLimit() && !process->GetResourceLimit()->Reserve(
417 !process->GetResourceLimit()->Reserve(ResourceType::PhysicalMemory, remaining_size)) { 417 LimitableResource::PhysicalMemoryMax, remaining_size)) {
418 return ERR_RESOURCE_LIMIT_EXCEEDED; 418 return ERR_RESOURCE_LIMIT_EXCEEDED;
419 } 419 }
420 420
@@ -422,7 +422,8 @@ ResultCode PageTable::MapPhysicalMemory(VAddr addr, std::size_t size) {
422 { 422 {
423 auto block_guard = detail::ScopeExit([&] { 423 auto block_guard = detail::ScopeExit([&] {
424 system.Kernel().MemoryManager().Free(page_linked_list, remaining_pages, memory_pool); 424 system.Kernel().MemoryManager().Free(page_linked_list, remaining_pages, memory_pool);
425 process->GetResourceLimit()->Release(ResourceType::PhysicalMemory, remaining_size); 425 process->GetResourceLimit()->Release(LimitableResource::PhysicalMemoryMax,
426 remaining_size);
426 }); 427 });
427 428
428 CASCADE_CODE(system.Kernel().MemoryManager().Allocate(page_linked_list, remaining_pages, 429 CASCADE_CODE(system.Kernel().MemoryManager().Allocate(page_linked_list, remaining_pages,
@@ -474,7 +475,7 @@ ResultCode PageTable::UnmapPhysicalMemory(VAddr addr, std::size_t size) {
474 CASCADE_CODE(UnmapMemory(addr, size)); 475 CASCADE_CODE(UnmapMemory(addr, size));
475 476
476 auto process{system.Kernel().CurrentProcess()}; 477 auto process{system.Kernel().CurrentProcess()};
477 process->GetResourceLimit()->Release(ResourceType::PhysicalMemory, mapped_size); 478 process->GetResourceLimit()->Release(LimitableResource::PhysicalMemoryMax, mapped_size);
478 physical_memory_usage -= mapped_size; 479 physical_memory_usage -= mapped_size;
479 480
480 return RESULT_SUCCESS; 481 return RESULT_SUCCESS;
@@ -783,7 +784,7 @@ ResultVal<VAddr> PageTable::SetHeapSize(std::size_t size) {
783 784
784 auto process{system.Kernel().CurrentProcess()}; 785 auto process{system.Kernel().CurrentProcess()};
785 if (process->GetResourceLimit() && delta != 0 && 786 if (process->GetResourceLimit() && delta != 0 &&
786 !process->GetResourceLimit()->Reserve(ResourceType::PhysicalMemory, delta)) { 787 !process->GetResourceLimit()->Reserve(LimitableResource::PhysicalMemoryMax, delta)) {
787 return ERR_RESOURCE_LIMIT_EXCEEDED; 788 return ERR_RESOURCE_LIMIT_EXCEEDED;
788 } 789 }
789 790
diff --git a/src/core/hle/kernel/process.cpp b/src/core/hle/kernel/process.cpp
index 0edbfc4cc..6b63a32c5 100644
--- a/src/core/hle/kernel/process.cpp
+++ b/src/core/hle/kernel/process.cpp
@@ -15,6 +15,7 @@
15#include "core/file_sys/program_metadata.h" 15#include "core/file_sys/program_metadata.h"
16#include "core/hle/kernel/code_set.h" 16#include "core/hle/kernel/code_set.h"
17#include "core/hle/kernel/errors.h" 17#include "core/hle/kernel/errors.h"
18#include "core/hle/kernel/k_resource_limit.h"
18#include "core/hle/kernel/k_scheduler.h" 19#include "core/hle/kernel/k_scheduler.h"
19#include "core/hle/kernel/k_thread.h" 20#include "core/hle/kernel/k_thread.h"
20#include "core/hle/kernel/kernel.h" 21#include "core/hle/kernel/kernel.h"
@@ -22,7 +23,6 @@
22#include "core/hle/kernel/memory/page_table.h" 23#include "core/hle/kernel/memory/page_table.h"
23#include "core/hle/kernel/memory/slab_heap.h" 24#include "core/hle/kernel/memory/slab_heap.h"
24#include "core/hle/kernel/process.h" 25#include "core/hle/kernel/process.h"
25#include "core/hle/kernel/resource_limit.h"
26#include "core/hle/lock.h" 26#include "core/hle/lock.h"
27#include "core/memory.h" 27#include "core/memory.h"
28#include "core/settings.h" 28#include "core/settings.h"
@@ -116,7 +116,7 @@ std::shared_ptr<Process> Process::Create(Core::System& system, std::string name,
116 116
117 std::shared_ptr<Process> process = std::make_shared<Process>(system); 117 std::shared_ptr<Process> process = std::make_shared<Process>(system);
118 process->name = std::move(name); 118 process->name = std::move(name);
119 process->resource_limit = ResourceLimit::Create(kernel); 119 process->resource_limit = std::make_shared<KResourceLimit>(kernel, system);
120 process->status = ProcessStatus::Created; 120 process->status = ProcessStatus::Created;
121 process->program_id = 0; 121 process->program_id = 0;
122 process->process_id = type == ProcessType::KernelInternal ? kernel.CreateNewKernelProcessID() 122 process->process_id = type == ProcessType::KernelInternal ? kernel.CreateNewKernelProcessID()
@@ -132,7 +132,7 @@ std::shared_ptr<Process> Process::Create(Core::System& system, std::string name,
132 return process; 132 return process;
133} 133}
134 134
135std::shared_ptr<ResourceLimit> Process::GetResourceLimit() const { 135std::shared_ptr<KResourceLimit> Process::GetResourceLimit() const {
136 return resource_limit; 136 return resource_limit;
137} 137}
138 138
@@ -154,7 +154,7 @@ void Process::DecrementThreadCount() {
154} 154}
155 155
156u64 Process::GetTotalPhysicalMemoryAvailable() const { 156u64 Process::GetTotalPhysicalMemoryAvailable() const {
157 const u64 capacity{resource_limit->GetCurrentResourceValue(ResourceType::PhysicalMemory) + 157 const u64 capacity{resource_limit->GetCurrentValue(LimitableResource::PhysicalMemoryMax) +
158 page_table->GetTotalHeapSize() + GetSystemResourceSize() + image_size + 158 page_table->GetTotalHeapSize() + GetSystemResourceSize() + image_size +
159 main_thread_stack_size}; 159 main_thread_stack_size};
160 160
@@ -308,13 +308,13 @@ ResultCode Process::LoadFromMetadata(const FileSys::ProgramMetadata& metadata,
308 308
309 // Set initial resource limits 309 // Set initial resource limits
310 resource_limit->SetLimitValue( 310 resource_limit->SetLimitValue(
311 ResourceType::PhysicalMemory, 311 LimitableResource::PhysicalMemoryMax,
312 kernel.MemoryManager().GetSize(Memory::MemoryManager::Pool::Application)); 312 kernel.MemoryManager().GetSize(Memory::MemoryManager::Pool::Application));
313 resource_limit->SetLimitValue(ResourceType::Threads, 608); 313 resource_limit->SetLimitValue(LimitableResource::ThreadCountMax, 608);
314 resource_limit->SetLimitValue(ResourceType::Events, 700); 314 resource_limit->SetLimitValue(LimitableResource::EventCountMax, 700);
315 resource_limit->SetLimitValue(ResourceType::TransferMemory, 128); 315 resource_limit->SetLimitValue(LimitableResource::TransferMemoryCountMax, 128);
316 resource_limit->SetLimitValue(ResourceType::Sessions, 894); 316 resource_limit->SetLimitValue(LimitableResource::SessionCountMax, 894);
317 ASSERT(resource_limit->Reserve(ResourceType::PhysicalMemory, code_size)); 317 ASSERT(resource_limit->Reserve(LimitableResource::PhysicalMemoryMax, code_size));
318 318
319 // Create TLS region 319 // Create TLS region
320 tls_region_address = CreateTLSRegion(); 320 tls_region_address = CreateTLSRegion();
@@ -331,8 +331,8 @@ void Process::Run(s32 main_thread_priority, u64 stack_size) {
331 ChangeStatus(ProcessStatus::Running); 331 ChangeStatus(ProcessStatus::Running);
332 332
333 SetupMainThread(system, *this, main_thread_priority, main_thread_stack_top); 333 SetupMainThread(system, *this, main_thread_priority, main_thread_stack_top);
334 resource_limit->Reserve(ResourceType::Threads, 1); 334 resource_limit->Reserve(LimitableResource::ThreadCountMax, 1);
335 resource_limit->Reserve(ResourceType::PhysicalMemory, main_thread_stack_size); 335 resource_limit->Reserve(LimitableResource::PhysicalMemoryMax, main_thread_stack_size);
336} 336}
337 337
338void Process::PrepareForTermination() { 338void Process::PrepareForTermination() {
diff --git a/src/core/hle/kernel/process.h b/src/core/hle/kernel/process.h
index 26e647743..c8af76ce8 100644
--- a/src/core/hle/kernel/process.h
+++ b/src/core/hle/kernel/process.h
@@ -29,7 +29,7 @@ class ProgramMetadata;
29namespace Kernel { 29namespace Kernel {
30 30
31class KernelCore; 31class KernelCore;
32class ResourceLimit; 32class KResourceLimit;
33class KThread; 33class KThread;
34class TLSPage; 34class TLSPage;
35 35
@@ -170,7 +170,7 @@ public:
170 } 170 }
171 171
172 /// Gets the resource limit descriptor for this process 172 /// Gets the resource limit descriptor for this process
173 std::shared_ptr<ResourceLimit> GetResourceLimit() const; 173 std::shared_ptr<KResourceLimit> GetResourceLimit() const;
174 174
175 /// Gets the ideal CPU core ID for this process 175 /// Gets the ideal CPU core ID for this process
176 u8 GetIdealCoreId() const { 176 u8 GetIdealCoreId() const {
@@ -402,7 +402,7 @@ private:
402 u32 system_resource_size = 0; 402 u32 system_resource_size = 0;
403 403
404 /// Resource limit descriptor for this process 404 /// Resource limit descriptor for this process
405 std::shared_ptr<ResourceLimit> resource_limit; 405 std::shared_ptr<KResourceLimit> resource_limit;
406 406
407 /// The ideal CPU core for this process, threads are scheduled on this core by default. 407 /// The ideal CPU core for this process, threads are scheduled on this core by default.
408 u8 ideal_core = 0; 408 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 7bf50339d..000000000
--- a/src/core/hle/kernel/resource_limit.cpp
+++ /dev/null
@@ -1,73 +0,0 @@
1// Copyright 2015 Citra Emulator Project
2// Licensed under GPLv2 or any later version
3// Refer to the license.txt file included.
4
5#include "core/hle/kernel/errors.h"
6#include "core/hle/kernel/resource_limit.h"
7#include "core/hle/result.h"
8
9namespace Kernel {
10namespace {
11constexpr std::size_t ResourceTypeToIndex(ResourceType type) {
12 return static_cast<std::size_t>(type);
13}
14} // Anonymous namespace
15
16ResourceLimit::ResourceLimit(KernelCore& kernel) : Object{kernel} {}
17ResourceLimit::~ResourceLimit() = default;
18
19bool ResourceLimit::Reserve(ResourceType resource, s64 amount) {
20 return Reserve(resource, amount, 10000000000);
21}
22
23bool 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 if (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
32 if (new_value <= limit[index]) {
33 current[index] = new_value;
34 return true;
35 }
36 return false;
37}
38
39void ResourceLimit::Release(ResourceType resource, u64 amount) {
40 Release(resource, amount, amount);
41}
42
43void ResourceLimit::Release(ResourceType resource, u64 used_amount, u64 available_amount) {
44 const std::size_t index{ResourceTypeToIndex(resource)};
45
46 current[index] -= used_amount;
47 available[index] -= available_amount;
48}
49
50std::shared_ptr<ResourceLimit> ResourceLimit::Create(KernelCore& kernel) {
51 return std::make_shared<ResourceLimit>(kernel);
52}
53
54s64 ResourceLimit::GetCurrentResourceValue(ResourceType resource) const {
55 return limit.at(ResourceTypeToIndex(resource)) - current.at(ResourceTypeToIndex(resource));
56}
57
58s64 ResourceLimit::GetMaxResourceValue(ResourceType resource) const {
59 return limit.at(ResourceTypeToIndex(resource));
60}
61
62ResultCode ResourceLimit::SetLimitValue(ResourceType resource, s64 value) {
63 const std::size_t index{ResourceTypeToIndex(resource)};
64 if (current[index] <= value) {
65 limit[index] = value;
66 return RESULT_SUCCESS;
67 } else {
68 LOG_ERROR(Kernel, "Limit value is too large! resource={}, value={}, index={}", resource,
69 value, index);
70 return ERR_INVALID_STATE;
71 }
72}
73} // 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 464d4f2a6..000000000
--- a/src/core/hle/kernel/resource_limit.h
+++ /dev/null
@@ -1,106 +0,0 @@
1// Copyright 2015 Citra Emulator Project
2// Licensed under GPLv2 or any later version
3// Refer to the license.txt file included.
4
5#pragma once
6
7#include <array>
8#include <memory>
9
10#include "common/common_types.h"
11#include "core/hle/kernel/object.h"
12
13union ResultCode;
14
15namespace Kernel {
16
17class KernelCore;
18
19enum class ResourceType : u32 {
20 PhysicalMemory,
21 Threads,
22 Events,
23 TransferMemory,
24 Sessions,
25
26 // Used as a count, not an actual type.
27 ResourceTypeCount
28};
29
30constexpr bool IsValidResourceType(ResourceType type) {
31 return type < ResourceType::ResourceTypeCount;
32}
33
34class ResourceLimit final : public Object {
35public:
36 explicit ResourceLimit(KernelCore& kernel);
37 ~ResourceLimit() override;
38
39 /// Creates a resource limit object.
40 static std::shared_ptr<ResourceLimit> Create(KernelCore& kernel);
41
42 std::string GetTypeName() const override {
43 return "ResourceLimit";
44 }
45 std::string GetName() const override {
46 return GetTypeName();
47 }
48
49 static constexpr HandleType HANDLE_TYPE = HandleType::ResourceLimit;
50 HandleType GetHandleType() const override {
51 return HANDLE_TYPE;
52 }
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
59 /**
60 * Gets the current value for the specified resource.
61 * @param resource Requested resource type
62 * @returns The current value of the resource type
63 */
64 s64 GetCurrentResourceValue(ResourceType resource) const;
65
66 /**
67 * Gets the max value for the specified resource.
68 * @param resource Requested resource type
69 * @returns The max value of the resource type
70 */
71 s64 GetMaxResourceValue(ResourceType resource) const;
72
73 /**
74 * Sets the limit value for a given resource type.
75 *
76 * @param resource The resource type to apply the limit to.
77 * @param value The limit to apply to the given resource type.
78 *
79 * @return A result code indicating if setting the limit value
80 * was successful or not.
81 *
82 * @note The supplied limit value *must* be greater than or equal to
83 * the current resource value for the given resource type,
84 * otherwise ERR_INVALID_STATE will be returned.
85 */
86 ResultCode SetLimitValue(ResourceType resource, s64 value);
87
88 void Finalize() override {}
89
90private:
91 // TODO(Subv): Increment resource limit current values in their respective Kernel::T::Create
92 // functions
93 //
94 // Currently we have no way of distinguishing if a Create was called by the running application,
95 // or by a service module. Approach this once we have separated the service modules into their
96 // own processes
97
98 using ResourceArray =
99 std::array<s64, static_cast<std::size_t>(ResourceType::ResourceTypeCount)>;
100
101 ResourceArray limit{};
102 ResourceArray current{};
103 ResourceArray available{};
104};
105
106} // namespace Kernel
diff --git a/src/core/hle/kernel/svc.cpp b/src/core/hle/kernel/svc.cpp
index 7fd514e9d..4bae37d10 100644
--- a/src/core/hle/kernel/svc.cpp
+++ b/src/core/hle/kernel/svc.cpp
@@ -26,6 +26,7 @@
26#include "core/hle/kernel/handle_table.h" 26#include "core/hle/kernel/handle_table.h"
27#include "core/hle/kernel/k_address_arbiter.h" 27#include "core/hle/kernel/k_address_arbiter.h"
28#include "core/hle/kernel/k_condition_variable.h" 28#include "core/hle/kernel/k_condition_variable.h"
29#include "core/hle/kernel/k_resource_limit.h"
29#include "core/hle/kernel/k_scheduler.h" 30#include "core/hle/kernel/k_scheduler.h"
30#include "core/hle/kernel/k_scoped_scheduler_lock_and_sleep.h" 31#include "core/hle/kernel/k_scoped_scheduler_lock_and_sleep.h"
31#include "core/hle/kernel/k_synchronization_object.h" 32#include "core/hle/kernel/k_synchronization_object.h"
@@ -37,7 +38,6 @@
37#include "core/hle/kernel/physical_core.h" 38#include "core/hle/kernel/physical_core.h"
38#include "core/hle/kernel/process.h" 39#include "core/hle/kernel/process.h"
39#include "core/hle/kernel/readable_event.h" 40#include "core/hle/kernel/readable_event.h"
40#include "core/hle/kernel/resource_limit.h"
41#include "core/hle/kernel/shared_memory.h" 41#include "core/hle/kernel/shared_memory.h"
42#include "core/hle/kernel/svc.h" 42#include "core/hle/kernel/svc.h"
43#include "core/hle/kernel/svc_results.h" 43#include "core/hle/kernel/svc_results.h"
@@ -141,7 +141,7 @@ enum class ResourceLimitValueType {
141ResultVal<s64> RetrieveResourceLimitValue(Core::System& system, Handle resource_limit, 141ResultVal<s64> RetrieveResourceLimitValue(Core::System& system, Handle resource_limit,
142 u32 resource_type, ResourceLimitValueType value_type) { 142 u32 resource_type, ResourceLimitValueType value_type) {
143 std::lock_guard lock{HLE::g_hle_lock}; 143 std::lock_guard lock{HLE::g_hle_lock};
144 const auto type = static_cast<ResourceType>(resource_type); 144 const auto type = static_cast<LimitableResource>(resource_type);
145 if (!IsValidResourceType(type)) { 145 if (!IsValidResourceType(type)) {
146 LOG_ERROR(Kernel_SVC, "Invalid resource limit type: '{}'", resource_type); 146 LOG_ERROR(Kernel_SVC, "Invalid resource limit type: '{}'", resource_type);
147 return ERR_INVALID_ENUM_VALUE; 147 return ERR_INVALID_ENUM_VALUE;
@@ -151,7 +151,7 @@ ResultVal<s64> RetrieveResourceLimitValue(Core::System& system, Handle resource_
151 ASSERT(current_process != nullptr); 151 ASSERT(current_process != nullptr);
152 152
153 const auto resource_limit_object = 153 const auto resource_limit_object =
154 current_process->GetHandleTable().Get<ResourceLimit>(resource_limit); 154 current_process->GetHandleTable().Get<KResourceLimit>(resource_limit);
155 if (!resource_limit_object) { 155 if (!resource_limit_object) {
156 LOG_ERROR(Kernel_SVC, "Handle to non-existent resource limit instance used. Handle={:08X}", 156 LOG_ERROR(Kernel_SVC, "Handle to non-existent resource limit instance used. Handle={:08X}",
157 resource_limit); 157 resource_limit);
@@ -159,10 +159,10 @@ ResultVal<s64> RetrieveResourceLimitValue(Core::System& system, Handle resource_
159 } 159 }
160 160
161 if (value_type == ResourceLimitValueType::CurrentValue) { 161 if (value_type == ResourceLimitValueType::CurrentValue) {
162 return MakeResult(resource_limit_object->GetCurrentResourceValue(type)); 162 return MakeResult(resource_limit_object->GetCurrentValue(type));
163 } 163 }
164 164
165 return MakeResult(resource_limit_object->GetMaxResourceValue(type)); 165 return MakeResult(resource_limit_object->GetLimitValue(type));
166} 166}
167} // Anonymous namespace 167} // Anonymous namespace
168 168
@@ -312,7 +312,8 @@ static ResultCode ConnectToNamedPort(Core::System& system, Handle* out_handle,
312 return ERR_NOT_FOUND; 312 return ERR_NOT_FOUND;
313 } 313 }
314 314
315 ASSERT(kernel.CurrentProcess()->GetResourceLimit()->Reserve(ResourceType::Sessions, 1)); 315 ASSERT(kernel.CurrentProcess()->GetResourceLimit()->Reserve(LimitableResource::SessionCountMax,
316 1));
316 317
317 auto client_port = it->second; 318 auto client_port = it->second;
318 319
@@ -1450,7 +1451,10 @@ static ResultCode CreateThread(Core::System& system, Handle* out_handle, VAddr e
1450 Svc::ResultInvalidPriority); 1451 Svc::ResultInvalidPriority);
1451 R_UNLESS(process.CheckThreadPriority(priority), Svc::ResultInvalidPriority); 1452 R_UNLESS(process.CheckThreadPriority(priority), Svc::ResultInvalidPriority);
1452 1453
1453 ASSERT(process.GetResourceLimit()->Reserve(ResourceType::Threads, 1)); 1454 ASSERT(process.GetResourceLimit()->Reserve(
1455 LimitableResource::ThreadCountMax, 1,
1456 system.CoreTiming().GetClockTicks() +
1457 Core::Timing::msToCycles(std::chrono::milliseconds{100})));
1454 1458
1455 std::shared_ptr<KThread> thread; 1459 std::shared_ptr<KThread> thread;
1456 { 1460 {
@@ -1972,7 +1976,7 @@ static ResultCode CreateResourceLimit(Core::System& system, Handle* out_handle)
1972 LOG_DEBUG(Kernel_SVC, "called"); 1976 LOG_DEBUG(Kernel_SVC, "called");
1973 1977
1974 auto& kernel = system.Kernel(); 1978 auto& kernel = system.Kernel();
1975 auto resource_limit = ResourceLimit::Create(kernel); 1979 auto resource_limit = std::make_shared<KResourceLimit>(kernel, system);
1976 1980
1977 auto* const current_process = kernel.CurrentProcess(); 1981 auto* const current_process = kernel.CurrentProcess();
1978 ASSERT(current_process != nullptr); 1982 ASSERT(current_process != nullptr);
@@ -2019,7 +2023,7 @@ static ResultCode SetResourceLimitLimitValue(Core::System& system, Handle resour
2019 LOG_DEBUG(Kernel_SVC, "called. Handle={:08X}, Resource type={}, Value={}", resource_limit, 2023 LOG_DEBUG(Kernel_SVC, "called. Handle={:08X}, Resource type={}, Value={}", resource_limit,
2020 resource_type, value); 2024 resource_type, value);
2021 2025
2022 const auto type = static_cast<ResourceType>(resource_type); 2026 const auto type = static_cast<LimitableResource>(resource_type);
2023 if (!IsValidResourceType(type)) { 2027 if (!IsValidResourceType(type)) {
2024 LOG_ERROR(Kernel_SVC, "Invalid resource limit type: '{}'", resource_type); 2028 LOG_ERROR(Kernel_SVC, "Invalid resource limit type: '{}'", resource_type);
2025 return ERR_INVALID_ENUM_VALUE; 2029 return ERR_INVALID_ENUM_VALUE;
@@ -2029,7 +2033,7 @@ static ResultCode SetResourceLimitLimitValue(Core::System& system, Handle resour
2029 ASSERT(current_process != nullptr); 2033 ASSERT(current_process != nullptr);
2030 2034
2031 auto resource_limit_object = 2035 auto resource_limit_object =
2032 current_process->GetHandleTable().Get<ResourceLimit>(resource_limit); 2036 current_process->GetHandleTable().Get<KResourceLimit>(resource_limit);
2033 if (!resource_limit_object) { 2037 if (!resource_limit_object) {
2034 LOG_ERROR(Kernel_SVC, "Handle to non-existent resource limit instance used. Handle={:08X}", 2038 LOG_ERROR(Kernel_SVC, "Handle to non-existent resource limit instance used. Handle={:08X}",
2035 resource_limit); 2039 resource_limit);
@@ -2041,8 +2045,8 @@ static ResultCode SetResourceLimitLimitValue(Core::System& system, Handle resour
2041 LOG_ERROR( 2045 LOG_ERROR(
2042 Kernel_SVC, 2046 Kernel_SVC,
2043 "Attempted to lower resource limit ({}) for category '{}' below its current value ({})", 2047 "Attempted to lower resource limit ({}) for category '{}' below its current value ({})",
2044 resource_limit_object->GetMaxResourceValue(type), resource_type, 2048 resource_limit_object->GetLimitValue(type), resource_type,
2045 resource_limit_object->GetCurrentResourceValue(type)); 2049 resource_limit_object->GetCurrentValue(type));
2046 return set_result; 2050 return set_result;
2047 } 2051 }
2048 2052