diff --git a/src/core/CMakeLists.txt b/src/core/CMakeLists.txt index 360f407f3..14027e182 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 9cf288b08..255cda359 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 000000000..082f689c8 --- /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 000000000..8265621e1 --- /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 e4b803046..b98938cb4 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