summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorGravatar Feng Chen2021-09-25 23:01:53 +0800
committerGravatar Feng Chen2021-09-29 09:51:20 +0800
commit5fbfc4c19eaca2ad88bf34ec33d068ffab6fe672 (patch)
tree95a899841bb6e1505372f5994bda3537ee2f940a /src
parentFix KScopedAutoObject object leak when SendSyncRequest (diff)
downloadyuzu-5fbfc4c19eaca2ad88bf34ec33d068ffab6fe672.tar.gz
yuzu-5fbfc4c19eaca2ad88bf34ec33d068ffab6fe672.tar.xz
yuzu-5fbfc4c19eaca2ad88bf34ec33d068ffab6fe672.zip
Fix KShareMemory object leak
Diffstat (limited to 'src')
-rw-r--r--src/core/CMakeLists.txt1
-rw-r--r--src/core/hle/kernel/k_process.cpp54
-rw-r--r--src/core/hle/kernel/k_process.h4
-rw-r--r--src/core/hle/kernel/k_shared_memory_info.h46
-rw-r--r--src/core/hle/kernel/kernel.h4
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;
34class KPageTable; 34class KPageTable;
35class KResourceLimit; 35class KResourceLimit;
36class KThread; 36class KThread;
37class KSharedMemoryInfo;
37class TLSPage; 38class TLSPage;
38 39
39struct CodeSet; 40struct 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
15namespace Kernel {
16
17class KSharedMemory;
18
19class KSharedMemoryInfo final : public KSlabAllocated<KSharedMemoryInfo>,
20 public boost::intrusive::list_base_hook<> {
21
22public:
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
41private:
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;
49class KServerSession; 49class KServerSession;
50class KSession; 50class KSession;
51class KSharedMemory; 51class KSharedMemory;
52class KSharedMemoryInfo;
52class KThread; 53class KThread;
53class KTransferMemory; 54class KTransferMemory;
54class KWritableEvent; 55class 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;