diff options
Diffstat (limited to 'src/core/hle/kernel/process.cpp')
| -rw-r--r-- | src/core/hle/kernel/process.cpp | 34 |
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 | */ |
| 39 | void SetupMainThread(Core::System& system, Process& owner_process, u32 priority, VAddr stack_top) { | 40 | void 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 | ||
| 156 | u64 Process::GetTotalPhysicalMemoryAvailable() const { | 161 | u64 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 | ||
| 323 | void Process::Run(s32 main_thread_priority, u64 stack_size) { | 338 | void 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 | ||
| 336 | void Process::PrepareForTermination() { | 351 | void 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 | ||