summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to '')
-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
-rw-r--r--src/core/memory.cpp9
6 files changed, 46 insertions, 4 deletions
diff --git a/src/core/CMakeLists.txt b/src/core/CMakeLists.txt
index 53bd50eb2..662030782 100644
--- a/src/core/CMakeLists.txt
+++ b/src/core/CMakeLists.txt
@@ -59,6 +59,7 @@ set(SRCS
59 hle/kernel/timer.cpp 59 hle/kernel/timer.cpp
60 hle/kernel/vm_manager.cpp 60 hle/kernel/vm_manager.cpp
61 hle/kernel/wait_object.cpp 61 hle/kernel/wait_object.cpp
62 hle/lock.cpp
62 hle/romfs.cpp 63 hle/romfs.cpp
63 hle/service/ac/ac.cpp 64 hle/service/ac/ac.cpp
64 hle/service/ac/ac_i.cpp 65 hle/service/ac/ac_i.cpp
@@ -256,6 +257,7 @@ set(HEADERS
256 hle/kernel/timer.h 257 hle/kernel/timer.h
257 hle/kernel/vm_manager.h 258 hle/kernel/vm_manager.h
258 hle/kernel/wait_object.h 259 hle/kernel/wait_object.h
260 hle/lock.h
259 hle/result.h 261 hle/result.h
260 hle/romfs.h 262 hle/romfs.h
261 hle/service/ac/ac.h 263 hle/service/ac/ac.h
diff --git a/src/core/hle/kernel/kernel.h b/src/core/hle/kernel/kernel.h
index 142bb84b2..73fab3981 100644
--- a/src/core/hle/kernel/kernel.h
+++ b/src/core/hle/kernel/kernel.h
@@ -132,4 +132,4 @@ void Init(u32 system_mode);
132/// Shutdown the kernel 132/// Shutdown the kernel
133void Shutdown(); 133void Shutdown();
134 134
135} // namespace 135} // namespace Kernel
diff --git a/src/core/hle/lock.cpp b/src/core/hle/lock.cpp
new file mode 100644
index 000000000..082f689c8
--- /dev/null
+++ b/src/core/hle/lock.cpp
@@ -0,0 +1,11 @@
1// Copyright 2017 Citra 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 <core/hle/lock.h>
8
9namespace HLE {
10std::mutex g_hle_lock;
11}
diff --git a/src/core/hle/lock.h b/src/core/hle/lock.h
new file mode 100644
index 000000000..8265621e1
--- /dev/null
+++ b/src/core/hle/lock.h
@@ -0,0 +1,18 @@
1// Copyright 2017 Citra 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 <mutex>
8
9namespace HLE {
10/*
11 * Synchronizes access to the internal HLE kernel structures, it is acquired when a guest
12 * application thread performs a syscall. It should be acquired by any host threads that read or
13 * modify the HLE kernel state. Note: Any operation that directly or indirectly reads from or writes
14 * to the emulated memory is not protected by this mutex, and should be avoided in any threads other
15 * than the CPU thread.
16 */
17extern std::mutex g_hle_lock;
18} // namespace HLE
diff --git a/src/core/hle/svc.cpp b/src/core/hle/svc.cpp
index e4b803046..b98938cb4 100644
--- a/src/core/hle/svc.cpp
+++ b/src/core/hle/svc.cpp
@@ -31,6 +31,7 @@
31#include "core/hle/kernel/timer.h" 31#include "core/hle/kernel/timer.h"
32#include "core/hle/kernel/vm_manager.h" 32#include "core/hle/kernel/vm_manager.h"
33#include "core/hle/kernel/wait_object.h" 33#include "core/hle/kernel/wait_object.h"
34#include "core/hle/lock.h"
34#include "core/hle/result.h" 35#include "core/hle/result.h"
35#include "core/hle/service/service.h" 36#include "core/hle/service/service.h"
36 37
@@ -1188,7 +1189,7 @@ struct FunctionDef {
1188 Func* func; 1189 Func* func;
1189 const char* name; 1190 const char* name;
1190}; 1191};
1191} 1192} // namespace
1192 1193
1193static const FunctionDef SVC_Table[] = { 1194static const FunctionDef SVC_Table[] = {
1194 {0x00, nullptr, "Unknown"}, 1195 {0x00, nullptr, "Unknown"},
@@ -1332,6 +1333,9 @@ MICROPROFILE_DEFINE(Kernel_SVC, "Kernel", "SVC", MP_RGB(70, 200, 70));
1332void CallSVC(u32 immediate) { 1333void CallSVC(u32 immediate) {
1333 MICROPROFILE_SCOPE(Kernel_SVC); 1334 MICROPROFILE_SCOPE(Kernel_SVC);
1334 1335
1336 // Lock the global kernel mutex when we enter the kernel HLE.
1337 std::lock_guard<std::mutex> lock(HLE::g_hle_lock);
1338
1335 const FunctionDef* info = GetSVCInfo(immediate); 1339 const FunctionDef* info = GetSVCInfo(immediate);
1336 if (info) { 1340 if (info) {
1337 if (info->func) { 1341 if (info->func) {
@@ -1342,4 +1346,4 @@ void CallSVC(u32 immediate) {
1342 } 1346 }
1343} 1347}
1344 1348
1345} // namespace 1349} // namespace SVC
diff --git a/src/core/memory.cpp b/src/core/memory.cpp
index 65649d9d7..a3c5f4a9d 100644
--- a/src/core/memory.cpp
+++ b/src/core/memory.cpp
@@ -9,6 +9,7 @@
9#include "common/logging/log.h" 9#include "common/logging/log.h"
10#include "common/swap.h" 10#include "common/swap.h"
11#include "core/hle/kernel/process.h" 11#include "core/hle/kernel/process.h"
12#include "core/hle/lock.h"
12#include "core/memory.h" 13#include "core/memory.h"
13#include "core/memory_setup.h" 14#include "core/memory_setup.h"
14#include "core/mmio.h" 15#include "core/mmio.h"
@@ -181,6 +182,9 @@ T Read(const VAddr vaddr) {
181 return value; 182 return value;
182 } 183 }
183 184
185 // The memory access might do an MMIO or cached access, so we have to lock the HLE kernel state
186 std::lock_guard<std::mutex> lock(HLE::g_hle_lock);
187
184 PageType type = current_page_table->attributes[vaddr >> PAGE_BITS]; 188 PageType type = current_page_table->attributes[vaddr >> PAGE_BITS];
185 switch (type) { 189 switch (type) {
186 case PageType::Unmapped: 190 case PageType::Unmapped:
@@ -219,6 +223,9 @@ void Write(const VAddr vaddr, const T data) {
219 return; 223 return;
220 } 224 }
221 225
226 // The memory access might do an MMIO or cached access, so we have to lock the HLE kernel state
227 std::lock_guard<std::mutex> lock(HLE::g_hle_lock);
228
222 PageType type = current_page_table->attributes[vaddr >> PAGE_BITS]; 229 PageType type = current_page_table->attributes[vaddr >> PAGE_BITS];
223 switch (type) { 230 switch (type) {
224 case PageType::Unmapped: 231 case PageType::Unmapped:
@@ -746,4 +753,4 @@ boost::optional<VAddr> PhysicalToVirtualAddress(const PAddr addr) {
746 return boost::none; 753 return boost::none;
747} 754}
748 755
749} // namespace 756} // namespace Memory