summaryrefslogtreecommitdiff
path: root/src/core/hle/kernel/process.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/core/hle/kernel/process.cpp')
-rw-r--r--src/core/hle/kernel/process.cpp34
1 files changed, 27 insertions, 7 deletions
diff --git a/src/core/hle/kernel/process.cpp b/src/core/hle/kernel/process.cpp
index 39dc3898a..47b3ac57b 100644
--- a/src/core/hle/kernel/process.cpp
+++ b/src/core/hle/kernel/process.cpp
@@ -16,6 +16,7 @@
16#include "core/hle/kernel/code_set.h" 16#include "core/hle/kernel/code_set.h"
17#include "core/hle/kernel/k_resource_limit.h" 17#include "core/hle/kernel/k_resource_limit.h"
18#include "core/hle/kernel/k_scheduler.h" 18#include "core/hle/kernel/k_scheduler.h"
19#include "core/hle/kernel/k_scoped_resource_reservation.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"
21#include "core/hle/kernel/memory/memory_block_manager.h" 22#include "core/hle/kernel/memory/memory_block_manager.h"
@@ -38,6 +39,7 @@ namespace {
38 */ 39 */
39void SetupMainThread(Core::System& system, Process& owner_process, u32 priority, VAddr stack_top) { 40void SetupMainThread(Core::System& system, Process& owner_process, u32 priority, VAddr stack_top) {
40 const VAddr entry_point = owner_process.PageTable().GetCodeRegionStart(); 41 const VAddr entry_point = owner_process.PageTable().GetCodeRegionStart();
42 ASSERT(owner_process.GetResourceLimit()->Reserve(LimitableResource::Threads, 1));
41 auto thread_res = KThread::Create(system, ThreadType::User, "main", entry_point, priority, 0, 43 auto thread_res = KThread::Create(system, ThreadType::User, "main", entry_point, priority, 0,
42 owner_process.GetIdealCoreId(), stack_top, &owner_process); 44 owner_process.GetIdealCoreId(), stack_top, &owner_process);
43 45
@@ -116,6 +118,9 @@ std::shared_ptr<Process> Process::Create(Core::System& system, std::string name,
116 118
117 std::shared_ptr<Process> process = std::make_shared<Process>(system); 119 std::shared_ptr<Process> process = std::make_shared<Process>(system);
118 process->name = std::move(name); 120 process->name = std::move(name);
121
122 // TODO: This is inaccurate
123 // The process should hold a reference to the kernel-wide resource limit.
119 process->resource_limit = std::make_shared<KResourceLimit>(kernel, system); 124 process->resource_limit = std::make_shared<KResourceLimit>(kernel, system);
120 process->status = ProcessStatus::Created; 125 process->status = ProcessStatus::Created;
121 process->program_id = 0; 126 process->program_id = 0;
@@ -154,6 +159,9 @@ void Process::DecrementThreadCount() {
154} 159}
155 160
156u64 Process::GetTotalPhysicalMemoryAvailable() const { 161u64 Process::GetTotalPhysicalMemoryAvailable() const {
162 // TODO: This is expected to always return the application memory pool size after accurately
163 // reserving kernel resources. The current workaround uses a process-local resource limit of
164 // application memory pool size, which is inaccurate.
157 const u64 capacity{resource_limit->GetFreeValue(LimitableResource::PhysicalMemory) + 165 const u64 capacity{resource_limit->GetFreeValue(LimitableResource::PhysicalMemory) +
158 page_table->GetTotalHeapSize() + GetSystemResourceSize() + image_size + 166 page_table->GetTotalHeapSize() + GetSystemResourceSize() + image_size +
159 main_thread_stack_size}; 167 main_thread_stack_size};
@@ -263,6 +271,17 @@ ResultCode Process::LoadFromMetadata(const FileSys::ProgramMetadata& metadata,
263 system_resource_size = metadata.GetSystemResourceSize(); 271 system_resource_size = metadata.GetSystemResourceSize();
264 image_size = code_size; 272 image_size = code_size;
265 273
274 // Set initial resource limits
275 resource_limit->SetLimitValue(
276 LimitableResource::PhysicalMemory,
277 kernel.MemoryManager().GetSize(Memory::MemoryManager::Pool::Application));
278 KScopedResourceReservation memory_reservation(resource_limit, LimitableResource::PhysicalMemory,
279 code_size + system_resource_size);
280 if (!memory_reservation.Succeeded()) {
281 LOG_ERROR(Kernel, "Could not reserve process memory requirements of size {:X} bytes",
282 code_size + system_resource_size);
283 return ResultResourceLimitedExceeded;
284 }
266 // Initialize proces address space 285 // Initialize proces address space
267 if (const ResultCode result{ 286 if (const ResultCode result{
268 page_table->InitializeForProcess(metadata.GetAddressSpaceType(), false, 0x8000000, 287 page_table->InitializeForProcess(metadata.GetAddressSpaceType(), false, 0x8000000,
@@ -304,24 +323,22 @@ ResultCode Process::LoadFromMetadata(const FileSys::ProgramMetadata& metadata,
304 UNREACHABLE(); 323 UNREACHABLE();
305 } 324 }
306 325
307 // Set initial resource limits
308 resource_limit->SetLimitValue(
309 LimitableResource::PhysicalMemory,
310 kernel.MemoryManager().GetSize(Memory::MemoryManager::Pool::Application));
311 resource_limit->SetLimitValue(LimitableResource::Threads, 608); 326 resource_limit->SetLimitValue(LimitableResource::Threads, 608);
312 resource_limit->SetLimitValue(LimitableResource::Events, 700); 327 resource_limit->SetLimitValue(LimitableResource::Events, 700);
313 resource_limit->SetLimitValue(LimitableResource::TransferMemory, 128); 328 resource_limit->SetLimitValue(LimitableResource::TransferMemory, 128);
314 resource_limit->SetLimitValue(LimitableResource::Sessions, 894); 329 resource_limit->SetLimitValue(LimitableResource::Sessions, 894);
315 ASSERT(resource_limit->Reserve(LimitableResource::PhysicalMemory, code_size));
316 330
317 // Create TLS region 331 // Create TLS region
318 tls_region_address = CreateTLSRegion(); 332 tls_region_address = CreateTLSRegion();
333 memory_reservation.Commit();
319 334
320 return handle_table.SetSize(capabilities.GetHandleTableSize()); 335 return handle_table.SetSize(capabilities.GetHandleTableSize());
321} 336}
322 337
323void Process::Run(s32 main_thread_priority, u64 stack_size) { 338void Process::Run(s32 main_thread_priority, u64 stack_size) {
324 AllocateMainThreadStack(stack_size); 339 AllocateMainThreadStack(stack_size);
340 resource_limit->Reserve(LimitableResource::Threads, 1);
341 resource_limit->Reserve(LimitableResource::PhysicalMemory, main_thread_stack_size);
325 342
326 const std::size_t heap_capacity{memory_usage_capacity - main_thread_stack_size - image_size}; 343 const std::size_t heap_capacity{memory_usage_capacity - main_thread_stack_size - image_size};
327 ASSERT(!page_table->SetHeapCapacity(heap_capacity).IsError()); 344 ASSERT(!page_table->SetHeapCapacity(heap_capacity).IsError());
@@ -329,8 +346,6 @@ void Process::Run(s32 main_thread_priority, u64 stack_size) {
329 ChangeStatus(ProcessStatus::Running); 346 ChangeStatus(ProcessStatus::Running);
330 347
331 SetupMainThread(system, *this, main_thread_priority, main_thread_stack_top); 348 SetupMainThread(system, *this, main_thread_priority, main_thread_stack_top);
332 resource_limit->Reserve(LimitableResource::Threads, 1);
333 resource_limit->Reserve(LimitableResource::PhysicalMemory, main_thread_stack_size);
334} 349}
335 350
336void Process::PrepareForTermination() { 351void Process::PrepareForTermination() {
@@ -357,6 +372,11 @@ void Process::PrepareForTermination() {
357 FreeTLSRegion(tls_region_address); 372 FreeTLSRegion(tls_region_address);
358 tls_region_address = 0; 373 tls_region_address = 0;
359 374
375 if (resource_limit) {
376 resource_limit->Release(LimitableResource::PhysicalMemory,
377 main_thread_stack_size + image_size);
378 }
379
360 ChangeStatus(ProcessStatus::Exited); 380 ChangeStatus(ProcessStatus::Exited);
361} 381}
362 382