summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGravatar Feng Chen2021-10-25 18:55:20 +0800
committerGravatar Feng Chen2021-10-27 09:06:22 +0800
commita8b01049235bffa13d18a010311c16c8b9c316b4 (patch)
tree3e8f433c3da629b09a4b3e000047ceb6f8ac3ec0
parentMerge pull request #7218 from bylaws/aswdqdsam (diff)
downloadyuzu-a8b01049235bffa13d18a010311c16c8b9c316b4.tar.gz
yuzu-a8b01049235bffa13d18a010311c16c8b9c316b4.tar.xz
yuzu-a8b01049235bffa13d18a010311c16c8b9c316b4.zip
Fix memory leak
-rw-r--r--src/core/hle/kernel/k_handle_table.cpp1
-rw-r--r--src/core/hle/kernel/kernel.cpp23
-rw-r--r--src/core/hle/kernel/kernel.h8
-rw-r--r--src/core/hle/kernel/svc.cpp6
4 files changed, 38 insertions, 0 deletions
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/kernel.cpp b/src/core/hle/kernel/kernel.cpp
index bea945301..d054a7925 100644
--- a/src/core/hle/kernel/kernel.cpp
+++ b/src/core/hle/kernel/kernel.cpp
@@ -170,6 +170,17 @@ struct KernelCore::Impl {
170 // 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
171 next_host_thread_id = Core::Hardware::NUM_CPU_CORES; 171 next_host_thread_id = Core::Hardware::NUM_CPU_CORES;
172 172
173 // Close kernel objects that were not freed on shutdown
174 {
175 std::lock_guard lk(registered_in_use_objects_lock);
176 if (registered_in_use_objects.size()) {
177 for (auto thread : registered_in_use_objects) {
178 thread->Close();
179 }
180 registered_in_use_objects.clear();
181 }
182 }
183
173 // Track kernel objects that were not freed on shutdown 184 // Track kernel objects that were not freed on shutdown
174 { 185 {
175 std::lock_guard lk(registered_objects_lock); 186 std::lock_guard lk(registered_objects_lock);
@@ -714,9 +725,11 @@ struct KernelCore::Impl {
714 std::unordered_set<KServerPort*> server_ports; 725 std::unordered_set<KServerPort*> server_ports;
715 std::unordered_set<KServerSession*> server_sessions; 726 std::unordered_set<KServerSession*> server_sessions;
716 std::unordered_set<KAutoObject*> registered_objects; 727 std::unordered_set<KAutoObject*> registered_objects;
728 std::unordered_set<KAutoObject*> registered_in_use_objects;
717 std::mutex server_ports_lock; 729 std::mutex server_ports_lock;
718 std::mutex server_sessions_lock; 730 std::mutex server_sessions_lock;
719 std::mutex registered_objects_lock; 731 std::mutex registered_objects_lock;
732 std::mutex registered_in_use_objects_lock;
720 733
721 std::unique_ptr<Core::ExclusiveMonitor> exclusive_monitor; 734 std::unique_ptr<Core::ExclusiveMonitor> exclusive_monitor;
722 std::vector<Kernel::PhysicalCore> cores; 735 std::vector<Kernel::PhysicalCore> cores;
@@ -928,6 +941,16 @@ void KernelCore::UnregisterKernelObject(KAutoObject* object) {
928 impl->registered_objects.erase(object); 941 impl->registered_objects.erase(object);
929} 942}
930 943
944void KernelCore::RegisterInUseObject(KAutoObject* object) {
945 std::lock_guard lk(impl->registered_in_use_objects_lock);
946 impl->registered_in_use_objects.insert(object);
947}
948
949void KernelCore::UnregisterInUseObject(KAutoObject* object) {
950 std::lock_guard lk(impl->registered_in_use_objects_lock);
951 impl->registered_in_use_objects.erase(object);
952}
953
931bool KernelCore::IsValidNamedPort(NamedPortTable::const_iterator port) const { 954bool KernelCore::IsValidNamedPort(NamedPortTable::const_iterator port) const {
932 return port != impl->named_ports.cend(); 955 return port != impl->named_ports.cend();
933} 956}
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 f98f24a60..d30755b7e 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 });
@@ -1544,6 +1548,7 @@ static ResultCode StartThread(Core::System& system, Handle thread_handle) {
1544 1548
1545 // If we succeeded, persist a reference to the thread. 1549 // If we succeeded, persist a reference to the thread.
1546 thread->Open(); 1550 thread->Open();
1551 system.Kernel().RegisterInUseObject(thread.GetPointerUnsafe());
1547 1552
1548 return ResultSuccess; 1553 return ResultSuccess;
1549} 1554}
@@ -1559,6 +1564,7 @@ static void ExitThread(Core::System& system) {
1559 auto* const current_thread = system.Kernel().CurrentScheduler()->GetCurrentThread(); 1564 auto* const current_thread = system.Kernel().CurrentScheduler()->GetCurrentThread();
1560 system.GlobalSchedulerContext().RemoveThread(current_thread); 1565 system.GlobalSchedulerContext().RemoveThread(current_thread);
1561 current_thread->Exit(); 1566 current_thread->Exit();
1567 system.Kernel().UnregisterInUseObject(current_thread);
1562} 1568}
1563 1569
1564static void ExitThread32(Core::System& system) { 1570static void ExitThread32(Core::System& system) {