summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
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
-rw-r--r--src/core/hle/kernel/svc.cpp14
6 files changed, 114 insertions, 9 deletions
diff --git a/src/core/CMakeLists.txt b/src/core/CMakeLists.txt
index aa3b26628..9f0fbba2d 100644
--- a/src/core/CMakeLists.txt
+++ b/src/core/CMakeLists.txt
@@ -216,6 +216,7 @@ add_library(core STATIC
hle/kernel/k_session.h
hle/kernel/k_shared_memory.cpp
hle/kernel/k_shared_memory.h
+ hle/kernel/k_shared_memory_info.h
hle/kernel/k_slab_heap.h
hle/kernel/k_spin_lock.cpp
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 @@
#include "core/hle/kernel/k_scheduler.h"
#include "core/hle/kernel/k_scoped_resource_reservation.h"
#include "core/hle/kernel/k_shared_memory.h"
+#include "core/hle/kernel/k_shared_memory_info.h"
#include "core/hle/kernel/k_slab_heap.h"
#include "core/hle/kernel/k_thread.h"
#include "core/hle/kernel/kernel.h"
@@ -254,10 +255,26 @@ ResultCode KProcess::AddSharedMemory(KSharedMemory* shmem, [[maybe_unused]] VAdd
// Lock ourselves, to prevent concurrent access.
KScopedLightLock lk(state_lock);
- // TODO(bunnei): Manage KSharedMemoryInfo list here.
+ // Try to find an existing info for the memory.
+ KSharedMemoryInfo* shemen_info = nullptr;
+ const auto iter = std::find_if(
+ shared_memory_list.begin(), shared_memory_list.end(),
+ [shmem](const KSharedMemoryInfo* info) { return info->GetSharedMemory() == shmem; });
+ if (iter != shared_memory_list.end()) {
+ shemen_info = *iter;
+ }
+
+ if (shemen_info == nullptr) {
+ shemen_info = KSharedMemoryInfo::Allocate(kernel);
+ R_UNLESS(shemen_info != nullptr, ResultOutOfMemory);
+
+ shemen_info->Initialize(shmem);
+ shared_memory_list.push_back(shemen_info);
+ }
- // Open a reference to the shared memory.
+ // Open a reference to the shared memory and its info.
shmem->Open();
+ shemen_info->Open();
return ResultSuccess;
}
@@ -267,7 +284,20 @@ void KProcess::RemoveSharedMemory(KSharedMemory* shmem, [[maybe_unused]] VAddr a
// Lock ourselves, to prevent concurrent access.
KScopedLightLock lk(state_lock);
- // TODO(bunnei): Manage KSharedMemoryInfo list here.
+ KSharedMemoryInfo* shemen_info = nullptr;
+ const auto iter = std::find_if(
+ shared_memory_list.begin(), shared_memory_list.end(),
+ [shmem](const KSharedMemoryInfo* info) { return info->GetSharedMemory() == shmem; });
+ if (iter != shared_memory_list.end()) {
+ shemen_info = *iter;
+ }
+
+ ASSERT(shemen_info != nullptr);
+
+ if (shemen_info->Close()) {
+ shared_memory_list.erase(iter);
+ KSharedMemoryInfo::Free(kernel, shemen_info);
+ }
// Close a reference to the shared memory.
shmem->Close();
@@ -412,6 +442,24 @@ void KProcess::Finalize() {
// Finalize the handle table and close any open handles.
handle_table.Finalize();
+ // Free all shared memory infos.
+ {
+ auto it = shared_memory_list.begin();
+ while (it != shared_memory_list.end()) {
+ KSharedMemoryInfo* info = *it;
+ KSharedMemory* shmem = info->GetSharedMemory();
+
+ while (!info->Close()) {
+ shmem->Close();
+ }
+
+ shmem->Close();
+
+ it = shared_memory_list.erase(it);
+ KSharedMemoryInfo::Free(kernel, info);
+ }
+ }
+
// Perform inherited finalization.
KAutoObjectWithSlabHeapAndContainer<KProcess, KSynchronizationObject>::Finalize();
}
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;
class KPageTable;
class KResourceLimit;
class KThread;
+class KSharedMemoryInfo;
class TLSPage;
struct CodeSet;
@@ -448,6 +449,9 @@ private:
/// List of threads that are running with this process as their owner.
std::list<const KThread*> thread_list;
+ /// List of shared memory that are running with this process as their owner.
+ std::list<KSharedMemoryInfo*> shared_memory_list;
+
/// Address of the top of the main thread's stack
VAddr main_thread_stack_top{};
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 @@
+// Copyright 2021 yuzu Emulator Project
+// Licensed under GPLv2 or any later version
+// Refer to the license.txt file included.
+
+#pragma once
+
+#include <memory>
+#include <string>
+
+#include <boost/intrusive/list.hpp>
+
+#include "common/assert.h"
+#include "core/hle/kernel/slab_helpers.h"
+
+namespace Kernel {
+
+class KSharedMemory;
+
+class KSharedMemoryInfo final : public KSlabAllocated<KSharedMemoryInfo>,
+ public boost::intrusive::list_base_hook<> {
+
+public:
+ explicit KSharedMemoryInfo() = default;
+
+ constexpr void Initialize(KSharedMemory* shmem) {
+ shared_memory = shmem;
+ }
+
+ constexpr KSharedMemory* GetSharedMemory() const {
+ return shared_memory;
+ }
+
+ constexpr void Open() {
+ ++reference_count;
+ }
+
+ constexpr bool Close() {
+ return (--reference_count) == 0;
+ }
+
+private:
+ KSharedMemory* shared_memory{};
+ size_t reference_count{};
+};
+
+} // 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;
class KServerSession;
class KSession;
class KSharedMemory;
+class KSharedMemoryInfo;
class KThread;
class KTransferMemory;
class KWritableEvent;
@@ -309,6 +310,8 @@ public:
return slab_heap_container->session;
} else if constexpr (std::is_same_v<T, KSharedMemory>) {
return slab_heap_container->shared_memory;
+ } else if constexpr (std::is_same_v<T, KSharedMemoryInfo>) {
+ return slab_heap_container->shared_memory_info;
} else if constexpr (std::is_same_v<T, KThread>) {
return slab_heap_container->thread;
} else if constexpr (std::is_same_v<T, KTransferMemory>) {
@@ -362,6 +365,7 @@ private:
KSlabHeap<KResourceLimit> resource_limit;
KSlabHeap<KSession> session;
KSlabHeap<KSharedMemory> shared_memory;
+ KSlabHeap<KSharedMemoryInfo> shared_memory_info;
KSlabHeap<KThread> thread;
KSlabHeap<KTransferMemory> transfer_memory;
KSlabHeap<KWritableEvent> writeable_event;
diff --git a/src/core/hle/kernel/svc.cpp b/src/core/hle/kernel/svc.cpp
index 62fb06c45..f98f24a60 100644
--- a/src/core/hle/kernel/svc.cpp
+++ b/src/core/hle/kernel/svc.cpp
@@ -320,17 +320,19 @@ static ResultCode SendSyncRequest(Core::System& system, Handle handle) {
auto& kernel = system.Kernel();
- KScopedAutoObject session =
- kernel.CurrentProcess()->GetHandleTable().GetObject<KClientSession>(handle);
- R_UNLESS(session.IsNotNull(), ResultInvalidHandle);
- LOG_TRACE(Kernel_SVC, "called handle=0x{:08X}({})", handle, session->GetName());
-
auto thread = kernel.CurrentScheduler()->GetCurrentThread();
{
KScopedSchedulerLock lock(kernel);
thread->SetState(ThreadState::Waiting);
thread->SetWaitReasonForDebugging(ThreadWaitReasonForDebugging::IPC);
- session->SendSyncRequest(thread, system.Memory(), system.CoreTiming());
+
+ {
+ KScopedAutoObject session =
+ kernel.CurrentProcess()->GetHandleTable().GetObject<KClientSession>(handle);
+ R_UNLESS(session.IsNotNull(), ResultInvalidHandle);
+ LOG_TRACE(Kernel_SVC, "called handle=0x{:08X}({})", handle, session->GetName());
+ session->SendSyncRequest(thread, system.Memory(), system.CoreTiming());
+ }
}
KSynchronizationObject* dummy{};