From 929994132a4f39ca4ab2975caf47a2a99a19b518 Mon Sep 17 00:00:00 2001 From: bunnei Date: Mon, 28 Jun 2021 14:38:14 -0700 Subject: hle: kernel: Provide methods for tracking dangling kernel objects. --- src/core/hle/kernel/kernel.cpp | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) (limited to 'src/core/hle/kernel/kernel.cpp') diff --git a/src/core/hle/kernel/kernel.cpp b/src/core/hle/kernel/kernel.cpp index 64bd0c494..ee60072c2 100644 --- a/src/core/hle/kernel/kernel.cpp +++ b/src/core/hle/kernel/kernel.cpp @@ -142,6 +142,13 @@ struct KernelCore::Impl { // Next host thead ID to use, 0-3 IDs represent core threads, >3 represent others next_host_thread_id = Core::Hardware::NUM_CPU_CORES; + + // Track kernel objects that were not freed on shutdown + if (registered_objects.size()) { + LOG_WARNING(Kernel, "{} kernel objects were dangling on shutdown!", + registered_objects.size()); + registered_objects.clear(); + } } void InitializePhysicalCores() { @@ -656,6 +663,7 @@ struct KernelCore::Impl { /// the ConnectToPort SVC. std::unordered_map service_interface_factory; NamedPortTable named_ports; + std::unordered_set registered_objects; std::unique_ptr exclusive_monitor; std::vector cores; @@ -852,6 +860,14 @@ KClientPort* KernelCore::CreateNamedServicePort(std::string name) { return &search->second(impl->system.ServiceManager(), impl->system); } +void KernelCore::RegisterKernelObject(KAutoObject* object) { + impl->registered_objects.insert(object); +} + +void KernelCore::UnregisterKernelObject(KAutoObject* object) { + impl->registered_objects.erase(object); +} + bool KernelCore::IsValidNamedPort(NamedPortTable::const_iterator port) const { return port != impl->named_ports.cend(); } -- cgit v1.2.3 From fe402d350650de50bf9a0aa70c04bec986863978 Mon Sep 17 00:00:00 2001 From: bunnei Date: Mon, 28 Jun 2021 16:38:13 -0700 Subject: hle: kernel: Ensure global handle table is initialized. --- src/core/hle/kernel/kernel.cpp | 1 + 1 file changed, 1 insertion(+) (limited to 'src/core/hle/kernel/kernel.cpp') diff --git a/src/core/hle/kernel/kernel.cpp b/src/core/hle/kernel/kernel.cpp index ee60072c2..e180db791 100644 --- a/src/core/hle/kernel/kernel.cpp +++ b/src/core/hle/kernel/kernel.cpp @@ -61,6 +61,7 @@ struct KernelCore::Impl { void Initialize(KernelCore& kernel) { global_scheduler_context = std::make_unique(kernel); global_handle_table = std::make_unique(kernel); + global_handle_table->Initialize(KHandleTable::MaxTableSize); is_phantom_mode_for_singlecore = false; -- cgit v1.2.3 From ecf36534446df97bbe18042a098f25069dfd8648 Mon Sep 17 00:00:00 2001 From: bunnei Date: Thu, 1 Jul 2021 21:44:50 -0700 Subject: hle: kernel: Ensure global handle table is finalized before closing. --- src/core/hle/kernel/kernel.cpp | 1 + 1 file changed, 1 insertion(+) (limited to 'src/core/hle/kernel/kernel.cpp') diff --git a/src/core/hle/kernel/kernel.cpp b/src/core/hle/kernel/kernel.cpp index e180db791..b7f9eb5c1 100644 --- a/src/core/hle/kernel/kernel.cpp +++ b/src/core/hle/kernel/kernel.cpp @@ -117,6 +117,7 @@ struct KernelCore::Impl { current_process = nullptr; } + global_handle_table->Finalize(); global_handle_table.reset(); preemption_event = nullptr; -- cgit v1.2.3 From 854c7a3c2826b769d9d41c79570c4dae57e0b3eb Mon Sep 17 00:00:00 2001 From: bunnei Date: Thu, 1 Jul 2021 21:50:42 -0700 Subject: hle: kernel: Ensure current running process is closed. --- src/core/hle/kernel/kernel.cpp | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) (limited to 'src/core/hle/kernel/kernel.cpp') diff --git a/src/core/hle/kernel/kernel.cpp b/src/core/hle/kernel/kernel.cpp index b7f9eb5c1..2d5525839 100644 --- a/src/core/hle/kernel/kernel.cpp +++ b/src/core/hle/kernel/kernel.cpp @@ -91,6 +91,12 @@ struct KernelCore::Impl { } void Shutdown() { + if (current_process) { + current_process->Finalize(); + current_process->Close(); + current_process = nullptr; + } + process_list.clear(); // Ensures all service threads gracefully shutdown @@ -112,11 +118,6 @@ struct KernelCore::Impl { cores.clear(); - if (current_process) { - current_process->Close(); - current_process = nullptr; - } - global_handle_table->Finalize(); global_handle_table.reset(); -- cgit v1.2.3 From 52caa52cc2e47d426b5af38fd8439da237836e0e Mon Sep 17 00:00:00 2001 From: bunnei Date: Fri, 2 Jul 2021 15:19:04 -0700 Subject: hle: kernel: Track and release server sessions, and protect methods with locks. --- src/core/hle/kernel/kernel.cpp | 78 +++++++++++++++++++++++++++++++++++------- 1 file changed, 66 insertions(+), 12 deletions(-) (limited to 'src/core/hle/kernel/kernel.cpp') diff --git a/src/core/hle/kernel/kernel.cpp b/src/core/hle/kernel/kernel.cpp index 2d5525839..92fbc5532 100644 --- a/src/core/hle/kernel/kernel.cpp +++ b/src/core/hle/kernel/kernel.cpp @@ -91,15 +91,39 @@ struct KernelCore::Impl { } void Shutdown() { + // Shutdown all processes. if (current_process) { current_process->Finalize(); current_process->Close(); current_process = nullptr; } - process_list.clear(); - // Ensures all service threads gracefully shutdown + // Close all open server ports. + std::unordered_set server_ports_; + { + std::lock_guard lk(server_ports_lock); + server_ports_ = server_ports; + server_ports.clear(); + } + for (auto* server_port : server_ports_) { + server_port->Close(); + } + // Close all open server sessions. + std::unordered_set server_sessions_; + { + std::lock_guard lk(server_sessions_lock); + server_sessions_ = server_sessions; + server_sessions.clear(); + } + for (auto* server_session : server_sessions_) { + server_session->Close(); + } + + // Ensure that the object list container is finalized and properly shutdown. + object_list_container.Finalize(); + + // Ensures all service threads gracefully shutdown. service_threads.clear(); next_object_id = 0; @@ -147,10 +171,13 @@ struct KernelCore::Impl { next_host_thread_id = Core::Hardware::NUM_CPU_CORES; // Track kernel objects that were not freed on shutdown - if (registered_objects.size()) { - LOG_WARNING(Kernel, "{} kernel objects were dangling on shutdown!", - registered_objects.size()); - registered_objects.clear(); + { + std::lock_guard lk(registered_objects_lock); + if (registered_objects.size()) { + LOG_WARNING(Kernel, "{} kernel objects were dangling on shutdown!", + registered_objects.size()); + registered_objects.clear(); + } } } @@ -640,6 +667,21 @@ struct KernelCore::Impl { user_slab_heap_size); } + KClientPort* CreateNamedServicePort(std::string name) { + auto search = service_interface_factory.find(name); + if (search == service_interface_factory.end()) { + UNIMPLEMENTED(); + return {}; + } + + KClientPort* port = &search->second(system.ServiceManager(), system); + { + std::lock_guard lk(server_ports_lock); + server_ports.insert(&port->GetParent()->GetServerPort()); + } + return port; + } + std::atomic next_object_id{0}; std::atomic next_kernel_process_id{KProcess::InitialKIPIDMin}; std::atomic next_user_process_id{KProcess::ProcessIDMin}; @@ -666,7 +708,12 @@ struct KernelCore::Impl { /// the ConnectToPort SVC. std::unordered_map service_interface_factory; NamedPortTable named_ports; + std::unordered_set server_ports; + std::unordered_set server_sessions; std::unordered_set registered_objects; + std::mutex server_ports_lock; + std::mutex server_sessions_lock; + std::mutex registered_objects_lock; std::unique_ptr exclusive_monitor; std::vector cores; @@ -855,19 +902,26 @@ void KernelCore::RegisterNamedService(std::string name, ServiceInterfaceFactory& } KClientPort* KernelCore::CreateNamedServicePort(std::string name) { - auto search = impl->service_interface_factory.find(name); - if (search == impl->service_interface_factory.end()) { - UNIMPLEMENTED(); - return {}; - } - return &search->second(impl->system.ServiceManager(), impl->system); + return impl->CreateNamedServicePort(std::move(name)); +} + +void KernelCore::RegisterServerSession(KServerSession* server_session) { + std::lock_guard lk(impl->server_sessions_lock); + impl->server_sessions.insert(server_session); +} + +void KernelCore::UnregisterServerSession(KServerSession* server_session) { + std::lock_guard lk(impl->server_sessions_lock); + impl->server_sessions.erase(server_session); } void KernelCore::RegisterKernelObject(KAutoObject* object) { + std::lock_guard lk(impl->registered_objects_lock); impl->registered_objects.insert(object); } void KernelCore::UnregisterKernelObject(KAutoObject* object) { + std::lock_guard lk(impl->registered_objects_lock); impl->registered_objects.erase(object); } -- cgit v1.2.3