diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/core/core.cpp | 16 | ||||
| -rw-r--r-- | src/core/hle/kernel/k_handle_table.cpp | 1 | ||||
| -rw-r--r-- | src/core/hle/kernel/k_process.cpp | 11 | ||||
| -rw-r--r-- | src/core/hle/kernel/kernel.cpp | 36 | ||||
| -rw-r--r-- | src/core/hle/kernel/kernel.h | 8 | ||||
| -rw-r--r-- | src/core/hle/kernel/svc.cpp | 6 |
6 files changed, 54 insertions, 24 deletions
diff --git a/src/core/core.cpp b/src/core/core.cpp index 3c75f42ae..c3a0f9dae 100644 --- a/src/core/core.cpp +++ b/src/core/core.cpp | |||
| @@ -83,12 +83,6 @@ FileSys::StorageId GetStorageIdForFrontendSlot( | |||
| 83 | } | 83 | } |
| 84 | } | 84 | } |
| 85 | 85 | ||
| 86 | void KProcessDeleter(Kernel::KProcess* process) { | ||
| 87 | process->Destroy(); | ||
| 88 | } | ||
| 89 | |||
| 90 | using KProcessPtr = std::unique_ptr<Kernel::KProcess, decltype(&KProcessDeleter)>; | ||
| 91 | |||
| 92 | } // Anonymous namespace | 86 | } // Anonymous namespace |
| 93 | 87 | ||
| 94 | FileSys::VirtualFile GetGameFileFromPath(const FileSys::VirtualFilesystem& vfs, | 88 | FileSys::VirtualFile GetGameFileFromPath(const FileSys::VirtualFilesystem& vfs, |
| @@ -261,11 +255,10 @@ struct System::Impl { | |||
| 261 | } | 255 | } |
| 262 | 256 | ||
| 263 | telemetry_session->AddInitialInfo(*app_loader, fs_controller, *content_provider); | 257 | telemetry_session->AddInitialInfo(*app_loader, fs_controller, *content_provider); |
| 264 | main_process = KProcessPtr{Kernel::KProcess::Create(system.Kernel()), KProcessDeleter}; | 258 | auto main_process = Kernel::KProcess::Create(system.Kernel()); |
| 265 | ASSERT(Kernel::KProcess::Initialize(main_process.get(), system, "main", | 259 | ASSERT(Kernel::KProcess::Initialize(main_process, system, "main", |
| 266 | Kernel::KProcess::ProcessType::Userland) | 260 | Kernel::KProcess::ProcessType::Userland) |
| 267 | .IsSuccess()); | 261 | .IsSuccess()); |
| 268 | main_process->Open(); | ||
| 269 | const auto [load_result, load_parameters] = app_loader->Load(*main_process, system); | 262 | const auto [load_result, load_parameters] = app_loader->Load(*main_process, system); |
| 270 | if (load_result != Loader::ResultStatus::Success) { | 263 | if (load_result != Loader::ResultStatus::Success) { |
| 271 | LOG_CRITICAL(Core, "Failed to load ROM (Error {})!", load_result); | 264 | LOG_CRITICAL(Core, "Failed to load ROM (Error {})!", load_result); |
| @@ -275,7 +268,7 @@ struct System::Impl { | |||
| 275 | static_cast<u32>(SystemResultStatus::ErrorLoader) + static_cast<u32>(load_result)); | 268 | static_cast<u32>(SystemResultStatus::ErrorLoader) + static_cast<u32>(load_result)); |
| 276 | } | 269 | } |
| 277 | AddGlueRegistrationForProcess(*app_loader, *main_process); | 270 | AddGlueRegistrationForProcess(*app_loader, *main_process); |
| 278 | kernel.MakeCurrentProcess(main_process.get()); | 271 | kernel.MakeCurrentProcess(main_process); |
| 279 | kernel.InitializeCores(); | 272 | kernel.InitializeCores(); |
| 280 | 273 | ||
| 281 | // Initialize cheat engine | 274 | // Initialize cheat engine |
| @@ -340,8 +333,6 @@ struct System::Impl { | |||
| 340 | kernel.Shutdown(); | 333 | kernel.Shutdown(); |
| 341 | memory.Reset(); | 334 | memory.Reset(); |
| 342 | applet_manager.ClearAll(); | 335 | applet_manager.ClearAll(); |
| 343 | // TODO: The main process should be freed based on KAutoObject ref counting. | ||
| 344 | main_process.reset(); | ||
| 345 | 336 | ||
| 346 | LOG_DEBUG(Core, "Shutdown OK"); | 337 | LOG_DEBUG(Core, "Shutdown OK"); |
| 347 | } | 338 | } |
| @@ -403,7 +394,6 @@ struct System::Impl { | |||
| 403 | std::unique_ptr<Tegra::GPU> gpu_core; | 394 | std::unique_ptr<Tegra::GPU> gpu_core; |
| 404 | std::unique_ptr<Hardware::InterruptManager> interrupt_manager; | 395 | std::unique_ptr<Hardware::InterruptManager> interrupt_manager; |
| 405 | std::unique_ptr<Core::DeviceMemory> device_memory; | 396 | std::unique_ptr<Core::DeviceMemory> device_memory; |
| 406 | KProcessPtr main_process{nullptr, KProcessDeleter}; | ||
| 407 | Core::Memory::Memory memory; | 397 | Core::Memory::Memory memory; |
| 408 | CpuManager cpu_manager; | 398 | CpuManager cpu_manager; |
| 409 | std::atomic_bool is_powered_on{}; | 399 | std::atomic_bool is_powered_on{}; |
diff --git a/src/core/hle/kernel/k_handle_table.cpp b/src/core/hle/kernel/k_handle_table.cpp index 44d13169f..e90fc0628 100644 --- a/src/core/hle/kernel/k_handle_table.cpp +++ b/src/core/hle/kernel/k_handle_table.cpp | |||
| @@ -56,6 +56,7 @@ bool KHandleTable::Remove(Handle handle) { | |||
| 56 | } | 56 | } |
| 57 | 57 | ||
| 58 | // Close the object. | 58 | // Close the object. |
| 59 | kernel.UnregisterInUseObject(obj); | ||
| 59 | obj->Close(); | 60 | obj->Close(); |
| 60 | return true; | 61 | return true; |
| 61 | } | 62 | } |
diff --git a/src/core/hle/kernel/k_process.cpp b/src/core/hle/kernel/k_process.cpp index 211157ccc..76fd8c285 100644 --- a/src/core/hle/kernel/k_process.cpp +++ b/src/core/hle/kernel/k_process.cpp | |||
| @@ -434,11 +434,6 @@ void KProcess::PrepareForTermination() { | |||
| 434 | } | 434 | } |
| 435 | 435 | ||
| 436 | void KProcess::Finalize() { | 436 | void KProcess::Finalize() { |
| 437 | // Release memory to the resource limit. | ||
| 438 | if (resource_limit != nullptr) { | ||
| 439 | resource_limit->Close(); | ||
| 440 | } | ||
| 441 | |||
| 442 | // Finalize the handle table and close any open handles. | 437 | // Finalize the handle table and close any open handles. |
| 443 | handle_table.Finalize(); | 438 | handle_table.Finalize(); |
| 444 | 439 | ||
| @@ -460,6 +455,12 @@ void KProcess::Finalize() { | |||
| 460 | } | 455 | } |
| 461 | } | 456 | } |
| 462 | 457 | ||
| 458 | // Release memory to the resource limit. | ||
| 459 | if (resource_limit != nullptr) { | ||
| 460 | resource_limit->Close(); | ||
| 461 | resource_limit = nullptr; | ||
| 462 | } | ||
| 463 | |||
| 463 | // Perform inherited finalization. | 464 | // Perform inherited finalization. |
| 464 | KAutoObjectWithSlabHeapAndContainer<KProcess, KSynchronizationObject>::Finalize(); | 465 | KAutoObjectWithSlabHeapAndContainer<KProcess, KSynchronizationObject>::Finalize(); |
| 465 | } | 466 | } |
diff --git a/src/core/hle/kernel/kernel.cpp b/src/core/hle/kernel/kernel.cpp index bea945301..4a139c5e7 100644 --- a/src/core/hle/kernel/kernel.cpp +++ b/src/core/hle/kernel/kernel.cpp | |||
| @@ -91,12 +91,6 @@ struct KernelCore::Impl { | |||
| 91 | } | 91 | } |
| 92 | 92 | ||
| 93 | void Shutdown() { | 93 | void Shutdown() { |
| 94 | // Shutdown all processes. | ||
| 95 | if (current_process) { | ||
| 96 | current_process->Finalize(); | ||
| 97 | current_process->Close(); | ||
| 98 | current_process = nullptr; | ||
| 99 | } | ||
| 100 | process_list.clear(); | 94 | process_list.clear(); |
| 101 | 95 | ||
| 102 | // Close all open server ports. | 96 | // Close all open server ports. |
| @@ -170,6 +164,24 @@ struct KernelCore::Impl { | |||
| 170 | // Next host thead ID to use, 0-3 IDs represent core threads, >3 represent others | 164 | // Next host thead ID to use, 0-3 IDs represent core threads, >3 represent others |
| 171 | next_host_thread_id = Core::Hardware::NUM_CPU_CORES; | 165 | next_host_thread_id = Core::Hardware::NUM_CPU_CORES; |
| 172 | 166 | ||
| 167 | // Close kernel objects that were not freed on shutdown | ||
| 168 | { | ||
| 169 | std::lock_guard lk(registered_in_use_objects_lock); | ||
| 170 | if (registered_in_use_objects.size()) { | ||
| 171 | for (auto& object : registered_in_use_objects) { | ||
| 172 | object->Close(); | ||
| 173 | } | ||
| 174 | registered_in_use_objects.clear(); | ||
| 175 | } | ||
| 176 | } | ||
| 177 | |||
| 178 | // Shutdown all processes. | ||
| 179 | if (current_process) { | ||
| 180 | current_process->Finalize(); | ||
| 181 | current_process->Close(); | ||
| 182 | current_process = nullptr; | ||
| 183 | } | ||
| 184 | |||
| 173 | // Track kernel objects that were not freed on shutdown | 185 | // Track kernel objects that were not freed on shutdown |
| 174 | { | 186 | { |
| 175 | std::lock_guard lk(registered_objects_lock); | 187 | std::lock_guard lk(registered_objects_lock); |
| @@ -714,9 +726,11 @@ struct KernelCore::Impl { | |||
| 714 | std::unordered_set<KServerPort*> server_ports; | 726 | std::unordered_set<KServerPort*> server_ports; |
| 715 | std::unordered_set<KServerSession*> server_sessions; | 727 | std::unordered_set<KServerSession*> server_sessions; |
| 716 | std::unordered_set<KAutoObject*> registered_objects; | 728 | std::unordered_set<KAutoObject*> registered_objects; |
| 729 | std::unordered_set<KAutoObject*> registered_in_use_objects; | ||
| 717 | std::mutex server_ports_lock; | 730 | std::mutex server_ports_lock; |
| 718 | std::mutex server_sessions_lock; | 731 | std::mutex server_sessions_lock; |
| 719 | std::mutex registered_objects_lock; | 732 | std::mutex registered_objects_lock; |
| 733 | std::mutex registered_in_use_objects_lock; | ||
| 720 | 734 | ||
| 721 | std::unique_ptr<Core::ExclusiveMonitor> exclusive_monitor; | 735 | std::unique_ptr<Core::ExclusiveMonitor> exclusive_monitor; |
| 722 | std::vector<Kernel::PhysicalCore> cores; | 736 | std::vector<Kernel::PhysicalCore> cores; |
| @@ -928,6 +942,16 @@ void KernelCore::UnregisterKernelObject(KAutoObject* object) { | |||
| 928 | impl->registered_objects.erase(object); | 942 | impl->registered_objects.erase(object); |
| 929 | } | 943 | } |
| 930 | 944 | ||
| 945 | void KernelCore::RegisterInUseObject(KAutoObject* object) { | ||
| 946 | std::lock_guard lk(impl->registered_in_use_objects_lock); | ||
| 947 | impl->registered_in_use_objects.insert(object); | ||
| 948 | } | ||
| 949 | |||
| 950 | void KernelCore::UnregisterInUseObject(KAutoObject* object) { | ||
| 951 | std::lock_guard lk(impl->registered_in_use_objects_lock); | ||
| 952 | impl->registered_in_use_objects.erase(object); | ||
| 953 | } | ||
| 954 | |||
| 931 | bool KernelCore::IsValidNamedPort(NamedPortTable::const_iterator port) const { | 955 | bool KernelCore::IsValidNamedPort(NamedPortTable::const_iterator port) const { |
| 932 | return port != impl->named_ports.cend(); | 956 | return port != impl->named_ports.cend(); |
| 933 | } | 957 | } |
diff --git a/src/core/hle/kernel/kernel.h b/src/core/hle/kernel/kernel.h index b6658b437..d2ceae950 100644 --- a/src/core/hle/kernel/kernel.h +++ b/src/core/hle/kernel/kernel.h | |||
| @@ -204,6 +204,14 @@ public: | |||
| 204 | /// destroyed during the current emulation session. | 204 | /// destroyed during the current emulation session. |
| 205 | void UnregisterKernelObject(KAutoObject* object); | 205 | void UnregisterKernelObject(KAutoObject* object); |
| 206 | 206 | ||
| 207 | /// Registers kernel objects with guest in use state, this is purely for close | ||
| 208 | /// after emulation has been shutdown. | ||
| 209 | void RegisterInUseObject(KAutoObject* object); | ||
| 210 | |||
| 211 | /// Unregisters a kernel object previously registered with RegisterInUseObject when it was | ||
| 212 | /// destroyed during the current emulation session. | ||
| 213 | void UnregisterInUseObject(KAutoObject* object); | ||
| 214 | |||
| 207 | /// Determines whether or not the given port is a valid named port. | 215 | /// Determines whether or not the given port is a valid named port. |
| 208 | bool IsValidNamedPort(NamedPortTable::const_iterator port) const; | 216 | bool IsValidNamedPort(NamedPortTable::const_iterator port) const; |
| 209 | 217 | ||
diff --git a/src/core/hle/kernel/svc.cpp b/src/core/hle/kernel/svc.cpp index 7f38ade1c..c43135856 100644 --- a/src/core/hle/kernel/svc.cpp +++ b/src/core/hle/kernel/svc.cpp | |||
| @@ -427,11 +427,15 @@ static ResultCode WaitSynchronization(Core::System& system, s32* index, VAddr ha | |||
| 427 | R_UNLESS(handle_table.GetMultipleObjects<KSynchronizationObject>(objs.data(), handles, | 427 | R_UNLESS(handle_table.GetMultipleObjects<KSynchronizationObject>(objs.data(), handles, |
| 428 | num_handles), | 428 | num_handles), |
| 429 | ResultInvalidHandle); | 429 | ResultInvalidHandle); |
| 430 | for (const auto& obj : objs) { | ||
| 431 | kernel.RegisterInUseObject(obj); | ||
| 432 | } | ||
| 430 | } | 433 | } |
| 431 | 434 | ||
| 432 | // Ensure handles are closed when we're done. | 435 | // Ensure handles are closed when we're done. |
| 433 | SCOPE_EXIT({ | 436 | SCOPE_EXIT({ |
| 434 | for (u64 i = 0; i < num_handles; ++i) { | 437 | for (u64 i = 0; i < num_handles; ++i) { |
| 438 | kernel.UnregisterInUseObject(objs[i]); | ||
| 435 | objs[i]->Close(); | 439 | objs[i]->Close(); |
| 436 | } | 440 | } |
| 437 | }); | 441 | }); |
| @@ -1561,6 +1565,7 @@ static ResultCode StartThread(Core::System& system, Handle thread_handle) { | |||
| 1561 | 1565 | ||
| 1562 | // If we succeeded, persist a reference to the thread. | 1566 | // If we succeeded, persist a reference to the thread. |
| 1563 | thread->Open(); | 1567 | thread->Open(); |
| 1568 | system.Kernel().RegisterInUseObject(thread.GetPointerUnsafe()); | ||
| 1564 | 1569 | ||
| 1565 | return ResultSuccess; | 1570 | return ResultSuccess; |
| 1566 | } | 1571 | } |
| @@ -1576,6 +1581,7 @@ static void ExitThread(Core::System& system) { | |||
| 1576 | auto* const current_thread = system.Kernel().CurrentScheduler()->GetCurrentThread(); | 1581 | auto* const current_thread = system.Kernel().CurrentScheduler()->GetCurrentThread(); |
| 1577 | system.GlobalSchedulerContext().RemoveThread(current_thread); | 1582 | system.GlobalSchedulerContext().RemoveThread(current_thread); |
| 1578 | current_thread->Exit(); | 1583 | current_thread->Exit(); |
| 1584 | system.Kernel().UnregisterInUseObject(current_thread); | ||
| 1579 | } | 1585 | } |
| 1580 | 1586 | ||
| 1581 | static void ExitThread32(Core::System& system) { | 1587 | static void ExitThread32(Core::System& system) { |