summaryrefslogtreecommitdiff
path: root/src/core/hle/kernel/kernel.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/core/hle/kernel/kernel.cpp')
-rw-r--r--src/core/hle/kernel/kernel.cpp97
1 files changed, 85 insertions, 12 deletions
diff --git a/src/core/hle/kernel/kernel.cpp b/src/core/hle/kernel/kernel.cpp
index 64bd0c494..92fbc5532 100644
--- a/src/core/hle/kernel/kernel.cpp
+++ b/src/core/hle/kernel/kernel.cpp
@@ -61,6 +61,7 @@ struct KernelCore::Impl {
61 void Initialize(KernelCore& kernel) { 61 void Initialize(KernelCore& kernel) {
62 global_scheduler_context = std::make_unique<Kernel::GlobalSchedulerContext>(kernel); 62 global_scheduler_context = std::make_unique<Kernel::GlobalSchedulerContext>(kernel);
63 global_handle_table = std::make_unique<Kernel::KHandleTable>(kernel); 63 global_handle_table = std::make_unique<Kernel::KHandleTable>(kernel);
64 global_handle_table->Initialize(KHandleTable::MaxTableSize);
64 65
65 is_phantom_mode_for_singlecore = false; 66 is_phantom_mode_for_singlecore = false;
66 67
@@ -90,9 +91,39 @@ struct KernelCore::Impl {
90 } 91 }
91 92
92 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 }
93 process_list.clear(); 100 process_list.clear();
94 101
95 // Ensures all service threads gracefully shutdown 102 // Close all open server ports.
103 std::unordered_set<KServerPort*> server_ports_;
104 {
105 std::lock_guard lk(server_ports_lock);
106 server_ports_ = server_ports;
107 server_ports.clear();
108 }
109 for (auto* server_port : server_ports_) {
110 server_port->Close();
111 }
112 // Close all open server sessions.
113 std::unordered_set<KServerSession*> server_sessions_;
114 {
115 std::lock_guard lk(server_sessions_lock);
116 server_sessions_ = server_sessions;
117 server_sessions.clear();
118 }
119 for (auto* server_session : server_sessions_) {
120 server_session->Close();
121 }
122
123 // Ensure that the object list container is finalized and properly shutdown.
124 object_list_container.Finalize();
125
126 // Ensures all service threads gracefully shutdown.
96 service_threads.clear(); 127 service_threads.clear();
97 128
98 next_object_id = 0; 129 next_object_id = 0;
@@ -111,11 +142,7 @@ struct KernelCore::Impl {
111 142
112 cores.clear(); 143 cores.clear();
113 144
114 if (current_process) { 145 global_handle_table->Finalize();
115 current_process->Close();
116 current_process = nullptr;
117 }
118
119 global_handle_table.reset(); 146 global_handle_table.reset();
120 147
121 preemption_event = nullptr; 148 preemption_event = nullptr;
@@ -142,6 +169,16 @@ struct KernelCore::Impl {
142 169
143 // Next host thead ID to use, 0-3 IDs represent core threads, >3 represent others 170 // Next host thead ID to use, 0-3 IDs represent core threads, >3 represent others
144 next_host_thread_id = Core::Hardware::NUM_CPU_CORES; 171 next_host_thread_id = Core::Hardware::NUM_CPU_CORES;
172
173 // Track kernel objects that were not freed on shutdown
174 {
175 std::lock_guard lk(registered_objects_lock);
176 if (registered_objects.size()) {
177 LOG_WARNING(Kernel, "{} kernel objects were dangling on shutdown!",
178 registered_objects.size());
179 registered_objects.clear();
180 }
181 }
145 } 182 }
146 183
147 void InitializePhysicalCores() { 184 void InitializePhysicalCores() {
@@ -630,6 +667,21 @@ struct KernelCore::Impl {
630 user_slab_heap_size); 667 user_slab_heap_size);
631 } 668 }
632 669
670 KClientPort* CreateNamedServicePort(std::string name) {
671 auto search = service_interface_factory.find(name);
672 if (search == service_interface_factory.end()) {
673 UNIMPLEMENTED();
674 return {};
675 }
676
677 KClientPort* port = &search->second(system.ServiceManager(), system);
678 {
679 std::lock_guard lk(server_ports_lock);
680 server_ports.insert(&port->GetParent()->GetServerPort());
681 }
682 return port;
683 }
684
633 std::atomic<u32> next_object_id{0}; 685 std::atomic<u32> next_object_id{0};
634 std::atomic<u64> next_kernel_process_id{KProcess::InitialKIPIDMin}; 686 std::atomic<u64> next_kernel_process_id{KProcess::InitialKIPIDMin};
635 std::atomic<u64> next_user_process_id{KProcess::ProcessIDMin}; 687 std::atomic<u64> next_user_process_id{KProcess::ProcessIDMin};
@@ -656,6 +708,12 @@ struct KernelCore::Impl {
656 /// the ConnectToPort SVC. 708 /// the ConnectToPort SVC.
657 std::unordered_map<std::string, ServiceInterfaceFactory> service_interface_factory; 709 std::unordered_map<std::string, ServiceInterfaceFactory> service_interface_factory;
658 NamedPortTable named_ports; 710 NamedPortTable named_ports;
711 std::unordered_set<KServerPort*> server_ports;
712 std::unordered_set<KServerSession*> server_sessions;
713 std::unordered_set<KAutoObject*> registered_objects;
714 std::mutex server_ports_lock;
715 std::mutex server_sessions_lock;
716 std::mutex registered_objects_lock;
659 717
660 std::unique_ptr<Core::ExclusiveMonitor> exclusive_monitor; 718 std::unique_ptr<Core::ExclusiveMonitor> exclusive_monitor;
661 std::vector<Kernel::PhysicalCore> cores; 719 std::vector<Kernel::PhysicalCore> cores;
@@ -844,12 +902,27 @@ void KernelCore::RegisterNamedService(std::string name, ServiceInterfaceFactory&
844} 902}
845 903
846KClientPort* KernelCore::CreateNamedServicePort(std::string name) { 904KClientPort* KernelCore::CreateNamedServicePort(std::string name) {
847 auto search = impl->service_interface_factory.find(name); 905 return impl->CreateNamedServicePort(std::move(name));
848 if (search == impl->service_interface_factory.end()) { 906}
849 UNIMPLEMENTED(); 907
850 return {}; 908void KernelCore::RegisterServerSession(KServerSession* server_session) {
851 } 909 std::lock_guard lk(impl->server_sessions_lock);
852 return &search->second(impl->system.ServiceManager(), impl->system); 910 impl->server_sessions.insert(server_session);
911}
912
913void KernelCore::UnregisterServerSession(KServerSession* server_session) {
914 std::lock_guard lk(impl->server_sessions_lock);
915 impl->server_sessions.erase(server_session);
916}
917
918void KernelCore::RegisterKernelObject(KAutoObject* object) {
919 std::lock_guard lk(impl->registered_objects_lock);
920 impl->registered_objects.insert(object);
921}
922
923void KernelCore::UnregisterKernelObject(KAutoObject* object) {
924 std::lock_guard lk(impl->registered_objects_lock);
925 impl->registered_objects.erase(object);
853} 926}
854 927
855bool KernelCore::IsValidNamedPort(NamedPortTable::const_iterator port) const { 928bool KernelCore::IsValidNamedPort(NamedPortTable::const_iterator port) const {