aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorSubv <subv2112@gmail.com>2017-07-20 23:52:50 -0500
committerSubv <subv2112@gmail.com>2017-08-22 09:30:55 -0500
commitbca8916cea9c437d82509f8350fa3b858720f90e (patch)
tree68375d2bac3a42e64e95702d2edaf8e1825af061 /src
parent5621a65037b1d2a34bbc76a047f925800ecbd47e (diff)
Kernel/HLE: Use a mutex to synchronize access to the HLE kernel state between the cpu thread and any other possible threads that might touch the kernel (network thread, etc).
This mutex is acquired in SVC::CallSVC, ie, as soon as the guest application enters the HLE kernel, and should be acquired by the aforementioned threads before modifying kernel structures.
Diffstat (limited to 'src')
-rw-r--r--src/core/CMakeLists.txt2
-rw-r--r--src/core/hle/kernel/kernel.h2
-rw-r--r--src/core/hle/lock.cpp11
-rw-r--r--src/core/hle/lock.h18
-rw-r--r--src/core/hle/svc.cpp8
5 files changed, 38 insertions, 3 deletions
diff --git a/src/core/CMakeLists.txt b/src/core/CMakeLists.txt
index 360f407f3d..14027e182a 100644
--- a/src/core/CMakeLists.txt
+++ b/src/core/CMakeLists.txt
@@ -60,6 +60,7 @@ set(SRCS
hle/kernel/timer.cpp
hle/kernel/vm_manager.cpp
hle/kernel/wait_object.cpp
+ hle/lock.cpp
hle/romfs.cpp
hle/service/ac/ac.cpp
hle/service/ac/ac_i.cpp
@@ -258,6 +259,7 @@ set(HEADERS
hle/kernel/timer.h
hle/kernel/vm_manager.h
hle/kernel/wait_object.h
+ hle/lock.h
hle/result.h
hle/romfs.h
hle/service/ac/ac.h
diff --git a/src/core/hle/kernel/kernel.h b/src/core/hle/kernel/kernel.h
index 9cf288b084..255cda3594 100644
--- a/src/core/hle/kernel/kernel.h
+++ b/src/core/hle/kernel/kernel.h
@@ -129,4 +129,4 @@ void Init(u32 system_mode);
/// Shutdown the kernel
void Shutdown();
-} // namespace
+} // namespace Kernel
diff --git a/src/core/hle/lock.cpp b/src/core/hle/lock.cpp
new file mode 100644
index 0000000000..082f689c86
--- /dev/null
+++ b/src/core/hle/lock.cpp
@@ -0,0 +1,11 @@
+// Copyright 2017 Citra Emulator Project
+// Licensed under GPLv2 or any later version
+// Refer to the license.txt file included.
+
+#pragma once
+
+#include <core/hle/lock.h>
+
+namespace HLE {
+std::mutex g_hle_lock;
+}
diff --git a/src/core/hle/lock.h b/src/core/hle/lock.h
new file mode 100644
index 0000000000..8265621e1d
--- /dev/null
+++ b/src/core/hle/lock.h
@@ -0,0 +1,18 @@
+// Copyright 2017 Citra Emulator Project
+// Licensed under GPLv2 or any later version
+// Refer to the license.txt file included.
+
+#pragma once
+
+#include <mutex>
+
+namespace HLE {
+/*
+ * Synchronizes access to the internal HLE kernel structures, it is acquired when a guest
+ * application thread performs a syscall. It should be acquired by any host threads that read or
+ * modify the HLE kernel state. Note: Any operation that directly or indirectly reads from or writes
+ * to the emulated memory is not protected by this mutex, and should be avoided in any threads other
+ * than the CPU thread.
+ */
+extern std::mutex g_hle_lock;
+} // namespace HLE
diff --git a/src/core/hle/svc.cpp b/src/core/hle/svc.cpp
index e4b803046e..b98938cb4c 100644
--- a/src/core/hle/svc.cpp
+++ b/src/core/hle/svc.cpp
@@ -31,6 +31,7 @@
#include "core/hle/kernel/timer.h"
#include "core/hle/kernel/vm_manager.h"
#include "core/hle/kernel/wait_object.h"
+#include "core/hle/lock.h"
#include "core/hle/result.h"
#include "core/hle/service/service.h"
@@ -1188,7 +1189,7 @@ struct FunctionDef {
Func* func;
const char* name;
};
-}
+} // namespace
static const FunctionDef SVC_Table[] = {
{0x00, nullptr, "Unknown"},
@@ -1332,6 +1333,9 @@ MICROPROFILE_DEFINE(Kernel_SVC, "Kernel", "SVC", MP_RGB(70, 200, 70));
void CallSVC(u32 immediate) {
MICROPROFILE_SCOPE(Kernel_SVC);
+ // Lock the global kernel mutex when we enter the kernel HLE.
+ std::lock_guard<std::mutex> lock(HLE::g_hle_lock);
+
const FunctionDef* info = GetSVCInfo(immediate);
if (info) {
if (info->func) {
@@ -1342,4 +1346,4 @@ void CallSVC(u32 immediate) {
}
}
-} // namespace
+} // namespace SVC