diff options
| author | 2021-09-25 23:01:53 +0800 | |
|---|---|---|
| committer | 2021-09-29 09:51:20 +0800 | |
| commit | 5fbfc4c19eaca2ad88bf34ec33d068ffab6fe672 (patch) | |
| tree | 95a899841bb6e1505372f5994bda3537ee2f940a /src | |
| parent | Fix KScopedAutoObject object leak when SendSyncRequest (diff) | |
| download | yuzu-5fbfc4c19eaca2ad88bf34ec33d068ffab6fe672.tar.gz yuzu-5fbfc4c19eaca2ad88bf34ec33d068ffab6fe672.tar.xz yuzu-5fbfc4c19eaca2ad88bf34ec33d068ffab6fe672.zip | |
Fix KShareMemory object leak
Diffstat (limited to 'src')
| -rw-r--r-- | src/core/CMakeLists.txt | 1 | ||||
| -rw-r--r-- | src/core/hle/kernel/k_process.cpp | 54 | ||||
| -rw-r--r-- | src/core/hle/kernel/k_process.h | 4 | ||||
| -rw-r--r-- | src/core/hle/kernel/k_shared_memory_info.h | 46 | ||||
| -rw-r--r-- | src/core/hle/kernel/kernel.h | 4 |
5 files changed, 106 insertions, 3 deletions
diff --git a/src/core/CMakeLists.txt b/src/core/CMakeLists.txt index 7140d0db8..6f98fbc08 100644 --- a/src/core/CMakeLists.txt +++ b/src/core/CMakeLists.txt | |||
| @@ -218,6 +218,7 @@ add_library(core STATIC | |||
| 218 | hle/kernel/k_session.h | 218 | hle/kernel/k_session.h |
| 219 | hle/kernel/k_shared_memory.cpp | 219 | hle/kernel/k_shared_memory.cpp |
| 220 | hle/kernel/k_shared_memory.h | 220 | hle/kernel/k_shared_memory.h |
| 221 | hle/kernel/k_shared_memory_info.h | ||
| 221 | hle/kernel/k_slab_heap.h | 222 | hle/kernel/k_slab_heap.h |
| 222 | hle/kernel/k_spin_lock.cpp | 223 | hle/kernel/k_spin_lock.cpp |
| 223 | hle/kernel/k_spin_lock.h | 224 | hle/kernel/k_spin_lock.h |
diff --git a/src/core/hle/kernel/k_process.cpp b/src/core/hle/kernel/k_process.cpp index 8ead1a769..211157ccc 100644 --- a/src/core/hle/kernel/k_process.cpp +++ b/src/core/hle/kernel/k_process.cpp | |||
| @@ -23,6 +23,7 @@ | |||
| 23 | #include "core/hle/kernel/k_scheduler.h" | 23 | #include "core/hle/kernel/k_scheduler.h" |
| 24 | #include "core/hle/kernel/k_scoped_resource_reservation.h" | 24 | #include "core/hle/kernel/k_scoped_resource_reservation.h" |
| 25 | #include "core/hle/kernel/k_shared_memory.h" | 25 | #include "core/hle/kernel/k_shared_memory.h" |
| 26 | #include "core/hle/kernel/k_shared_memory_info.h" | ||
| 26 | #include "core/hle/kernel/k_slab_heap.h" | 27 | #include "core/hle/kernel/k_slab_heap.h" |
| 27 | #include "core/hle/kernel/k_thread.h" | 28 | #include "core/hle/kernel/k_thread.h" |
| 28 | #include "core/hle/kernel/kernel.h" | 29 | #include "core/hle/kernel/kernel.h" |
| @@ -254,10 +255,26 @@ ResultCode KProcess::AddSharedMemory(KSharedMemory* shmem, [[maybe_unused]] VAdd | |||
| 254 | // Lock ourselves, to prevent concurrent access. | 255 | // Lock ourselves, to prevent concurrent access. |
| 255 | KScopedLightLock lk(state_lock); | 256 | KScopedLightLock lk(state_lock); |
| 256 | 257 | ||
| 257 | // TODO(bunnei): Manage KSharedMemoryInfo list here. | 258 | // Try to find an existing info for the memory. |
| 259 | KSharedMemoryInfo* shemen_info = nullptr; | ||
| 260 | const auto iter = std::find_if( | ||
| 261 | shared_memory_list.begin(), shared_memory_list.end(), | ||
| 262 | [shmem](const KSharedMemoryInfo* info) { return info->GetSharedMemory() == shmem; }); | ||
| 263 | if (iter != shared_memory_list.end()) { | ||
| 264 | shemen_info = *iter; | ||
| 265 | } | ||
| 266 | |||
| 267 | if (shemen_info == nullptr) { | ||
| 268 | shemen_info = KSharedMemoryInfo::Allocate(kernel); | ||
| 269 | R_UNLESS(shemen_info != nullptr, ResultOutOfMemory); | ||
| 270 | |||
| 271 | shemen_info->Initialize(shmem); | ||
| 272 | shared_memory_list.push_back(shemen_info); | ||
| 273 | } | ||
| 258 | 274 | ||
| 259 | // Open a reference to the shared memory. | 275 | // Open a reference to the shared memory and its info. |
| 260 | shmem->Open(); | 276 | shmem->Open(); |
| 277 | shemen_info->Open(); | ||
| 261 | 278 | ||
| 262 | return ResultSuccess; | 279 | return ResultSuccess; |
| 263 | } | 280 | } |
| @@ -267,7 +284,20 @@ void KProcess::RemoveSharedMemory(KSharedMemory* shmem, [[maybe_unused]] VAddr a | |||
| 267 | // Lock ourselves, to prevent concurrent access. | 284 | // Lock ourselves, to prevent concurrent access. |
| 268 | KScopedLightLock lk(state_lock); | 285 | KScopedLightLock lk(state_lock); |
| 269 | 286 | ||
| 270 | // TODO(bunnei): Manage KSharedMemoryInfo list here. | 287 | KSharedMemoryInfo* shemen_info = nullptr; |
| 288 | const auto iter = std::find_if( | ||
| 289 | shared_memory_list.begin(), shared_memory_list.end(), | ||
| 290 | [shmem](const KSharedMemoryInfo* info) { return info->GetSharedMemory() == shmem; }); | ||
| 291 | if (iter != shared_memory_list.end()) { | ||
| 292 | shemen_info = *iter; | ||
| 293 | } | ||
| 294 | |||
| 295 | ASSERT(shemen_info != nullptr); | ||
| 296 | |||
| 297 | if (shemen_info->Close()) { | ||
| 298 | shared_memory_list.erase(iter); | ||
| 299 | KSharedMemoryInfo::Free(kernel, shemen_info); | ||
| 300 | } | ||
| 271 | 301 | ||
| 272 | // Close a reference to the shared memory. | 302 | // Close a reference to the shared memory. |
| 273 | shmem->Close(); | 303 | shmem->Close(); |
| @@ -412,6 +442,24 @@ void KProcess::Finalize() { | |||
| 412 | // Finalize the handle table and close any open handles. | 442 | // Finalize the handle table and close any open handles. |
| 413 | handle_table.Finalize(); | 443 | handle_table.Finalize(); |
| 414 | 444 | ||
| 445 | // Free all shared memory infos. | ||
| 446 | { | ||
| 447 | auto it = shared_memory_list.begin(); | ||
| 448 | while (it != shared_memory_list.end()) { | ||
| 449 | KSharedMemoryInfo* info = *it; | ||
| 450 | KSharedMemory* shmem = info->GetSharedMemory(); | ||
| 451 | |||
| 452 | while (!info->Close()) { | ||
| 453 | shmem->Close(); | ||
| 454 | } | ||
| 455 | |||
| 456 | shmem->Close(); | ||
| 457 | |||
| 458 | it = shared_memory_list.erase(it); | ||
| 459 | KSharedMemoryInfo::Free(kernel, info); | ||
| 460 | } | ||
| 461 | } | ||
| 462 | |||
| 415 | // Perform inherited finalization. | 463 | // Perform inherited finalization. |
| 416 | KAutoObjectWithSlabHeapAndContainer<KProcess, KSynchronizationObject>::Finalize(); | 464 | KAutoObjectWithSlabHeapAndContainer<KProcess, KSynchronizationObject>::Finalize(); |
| 417 | } | 465 | } |
diff --git a/src/core/hle/kernel/k_process.h b/src/core/hle/kernel/k_process.h index a03c074fb..1a53e2be7 100644 --- a/src/core/hle/kernel/k_process.h +++ b/src/core/hle/kernel/k_process.h | |||
| @@ -34,6 +34,7 @@ class KernelCore; | |||
| 34 | class KPageTable; | 34 | class KPageTable; |
| 35 | class KResourceLimit; | 35 | class KResourceLimit; |
| 36 | class KThread; | 36 | class KThread; |
| 37 | class KSharedMemoryInfo; | ||
| 37 | class TLSPage; | 38 | class TLSPage; |
| 38 | 39 | ||
| 39 | struct CodeSet; | 40 | struct CodeSet; |
| @@ -448,6 +449,9 @@ private: | |||
| 448 | /// List of threads that are running with this process as their owner. | 449 | /// List of threads that are running with this process as their owner. |
| 449 | std::list<const KThread*> thread_list; | 450 | std::list<const KThread*> thread_list; |
| 450 | 451 | ||
| 452 | /// List of shared memory that are running with this process as their owner. | ||
| 453 | std::list<KSharedMemoryInfo*> shared_memory_list; | ||
| 454 | |||
| 451 | /// Address of the top of the main thread's stack | 455 | /// Address of the top of the main thread's stack |
| 452 | VAddr main_thread_stack_top{}; | 456 | VAddr main_thread_stack_top{}; |
| 453 | 457 | ||
diff --git a/src/core/hle/kernel/k_shared_memory_info.h b/src/core/hle/kernel/k_shared_memory_info.h new file mode 100644 index 000000000..bf97a0184 --- /dev/null +++ b/src/core/hle/kernel/k_shared_memory_info.h | |||
| @@ -0,0 +1,46 @@ | |||
| 1 | // Copyright 2021 yuzu Emulator Project | ||
| 2 | // Licensed under GPLv2 or any later version | ||
| 3 | // Refer to the license.txt file included. | ||
| 4 | |||
| 5 | #pragma once | ||
| 6 | |||
| 7 | #include <memory> | ||
| 8 | #include <string> | ||
| 9 | |||
| 10 | #include <boost/intrusive/list.hpp> | ||
| 11 | |||
| 12 | #include "common/assert.h" | ||
| 13 | #include "core/hle/kernel/slab_helpers.h" | ||
| 14 | |||
| 15 | namespace Kernel { | ||
| 16 | |||
| 17 | class KSharedMemory; | ||
| 18 | |||
| 19 | class KSharedMemoryInfo final : public KSlabAllocated<KSharedMemoryInfo>, | ||
| 20 | public boost::intrusive::list_base_hook<> { | ||
| 21 | |||
| 22 | public: | ||
| 23 | explicit KSharedMemoryInfo() = default; | ||
| 24 | |||
| 25 | constexpr void Initialize(KSharedMemory* shmem) { | ||
| 26 | shared_memory = shmem; | ||
| 27 | } | ||
| 28 | |||
| 29 | constexpr KSharedMemory* GetSharedMemory() const { | ||
| 30 | return shared_memory; | ||
| 31 | } | ||
| 32 | |||
| 33 | constexpr void Open() { | ||
| 34 | ++reference_count; | ||
| 35 | } | ||
| 36 | |||
| 37 | constexpr bool Close() { | ||
| 38 | return (--reference_count) == 0; | ||
| 39 | } | ||
| 40 | |||
| 41 | private: | ||
| 42 | KSharedMemory* shared_memory{}; | ||
| 43 | size_t reference_count{}; | ||
| 44 | }; | ||
| 45 | |||
| 46 | } // namespace Kernel | ||
diff --git a/src/core/hle/kernel/kernel.h b/src/core/hle/kernel/kernel.h index 901d43da9..b6658b437 100644 --- a/src/core/hle/kernel/kernel.h +++ b/src/core/hle/kernel/kernel.h | |||
| @@ -49,6 +49,7 @@ class KScheduler; | |||
| 49 | class KServerSession; | 49 | class KServerSession; |
| 50 | class KSession; | 50 | class KSession; |
| 51 | class KSharedMemory; | 51 | class KSharedMemory; |
| 52 | class KSharedMemoryInfo; | ||
| 52 | class KThread; | 53 | class KThread; |
| 53 | class KTransferMemory; | 54 | class KTransferMemory; |
| 54 | class KWritableEvent; | 55 | class KWritableEvent; |
| @@ -309,6 +310,8 @@ public: | |||
| 309 | return slab_heap_container->session; | 310 | return slab_heap_container->session; |
| 310 | } else if constexpr (std::is_same_v<T, KSharedMemory>) { | 311 | } else if constexpr (std::is_same_v<T, KSharedMemory>) { |
| 311 | return slab_heap_container->shared_memory; | 312 | return slab_heap_container->shared_memory; |
| 313 | } else if constexpr (std::is_same_v<T, KSharedMemoryInfo>) { | ||
| 314 | return slab_heap_container->shared_memory_info; | ||
| 312 | } else if constexpr (std::is_same_v<T, KThread>) { | 315 | } else if constexpr (std::is_same_v<T, KThread>) { |
| 313 | return slab_heap_container->thread; | 316 | return slab_heap_container->thread; |
| 314 | } else if constexpr (std::is_same_v<T, KTransferMemory>) { | 317 | } else if constexpr (std::is_same_v<T, KTransferMemory>) { |
| @@ -362,6 +365,7 @@ private: | |||
| 362 | KSlabHeap<KResourceLimit> resource_limit; | 365 | KSlabHeap<KResourceLimit> resource_limit; |
| 363 | KSlabHeap<KSession> session; | 366 | KSlabHeap<KSession> session; |
| 364 | KSlabHeap<KSharedMemory> shared_memory; | 367 | KSlabHeap<KSharedMemory> shared_memory; |
| 368 | KSlabHeap<KSharedMemoryInfo> shared_memory_info; | ||
| 365 | KSlabHeap<KThread> thread; | 369 | KSlabHeap<KThread> thread; |
| 366 | KSlabHeap<KTransferMemory> transfer_memory; | 370 | KSlabHeap<KTransferMemory> transfer_memory; |
| 367 | KSlabHeap<KWritableEvent> writeable_event; | 371 | KSlabHeap<KWritableEvent> writeable_event; |