19 changes: 8 additions & 11 deletions Source/Core/Core/IOS/SDIO/SDIOSlot0.cpp
Expand Up @@ -15,6 +15,7 @@
#include "Common/Logging/Log.h"
#include "Common/SDCardUtil.h"

#include "Core/CPUThreadConfigCallback.h"
#include "Core/Config/MainSettings.h"
#include "Core/Config/SessionSettings.h"
#include "Core/Core.h"
Expand All @@ -32,27 +33,23 @@ SDIOSlot0Device::SDIOSlot0Device(EmulationKernel& ios, const std::string& device
if (!Config::Get(Config::MAIN_ALLOW_SD_WRITES))
INFO_LOG_FMT(IOS_SD, "Writes to SD card disabled by user");

m_config_callback_id = Config::AddConfigChangedCallback([this] { RefreshConfig(); });
m_config_callback_id =
CPUThreadConfigCallback::AddConfigChangedCallback([this] { RefreshConfig(); });
m_sd_card_inserted = Config::Get(Config::MAIN_WII_SD_CARD);
}

SDIOSlot0Device::~SDIOSlot0Device()
{
Config::RemoveConfigChangedCallback(m_config_callback_id);
CPUThreadConfigCallback::RemoveConfigChangedCallback(m_config_callback_id);
}

void SDIOSlot0Device::RefreshConfig()
{
if (m_sd_card_inserted != Config::Get(Config::MAIN_WII_SD_CARD))
const bool sd_card_inserted = Config::Get(Config::MAIN_WII_SD_CARD);
if (m_sd_card_inserted != sd_card_inserted)
{
Core::RunAsCPUThread([this] {
const bool sd_card_inserted = Config::Get(Config::MAIN_WII_SD_CARD);
if (m_sd_card_inserted != sd_card_inserted)
{
m_sd_card_inserted = sd_card_inserted;
EventNotify();
}
});
m_sd_card_inserted = sd_card_inserted;
EventNotify();
}
}

Expand Down
3 changes: 2 additions & 1 deletion Source/Core/Core/IOS/SDIO/SDIOSlot0.h
Expand Up @@ -10,6 +10,7 @@

#include "Common/CommonTypes.h"
#include "Common/IOFile.h"
#include "Core/CPUThreadConfigCallback.h"
#include "Core/IOS/Device.h"
#include "Core/IOS/IOS.h"

Expand Down Expand Up @@ -166,7 +167,7 @@ class SDIOSlot0Device : public EmulationDevice

File::IOFile m_card;

size_t m_config_callback_id;
CPUThreadConfigCallback::ConfigChangedCallbackID m_config_callback_id;
bool m_sd_card_inserted = false;
};
} // namespace IOS::HLE
8 changes: 5 additions & 3 deletions Source/Core/Core/PowerPC/JitCommon/JitBase.cpp
Expand Up @@ -7,6 +7,8 @@
#include "Common/CommonTypes.h"
#include "Common/MemoryUtil.h"
#include "Common/Thread.h"

#include "Core/CPUThreadConfigCallback.h"
#include "Core/Config/MainSettings.h"
#include "Core/ConfigManager.h"
#include "Core/Core.h"
Expand Down Expand Up @@ -64,14 +66,14 @@ JitBase::JitBase(Core::System& system)
: m_code_buffer(code_buffer_size), m_system(system), m_ppc_state(system.GetPPCState()),
m_mmu(system.GetMMU())
{
m_registered_config_callback_id = Config::AddConfigChangedCallback(
[this] { Core::RunAsCPUThread([this] { RefreshConfig(); }); });
m_registered_config_callback_id =
CPUThreadConfigCallback::AddConfigChangedCallback([this] { RefreshConfig(); });
RefreshConfig();
}

JitBase::~JitBase()
{
Config::RemoveConfigChangedCallback(m_registered_config_callback_id);
CPUThreadConfigCallback::RemoveConfigChangedCallback(m_registered_config_callback_id);
}

void JitBase::RefreshConfig()
Expand Down
3 changes: 2 additions & 1 deletion Source/Core/Core/PowerPC/JitCommon/JitBase.h
Expand Up @@ -10,6 +10,7 @@
#include "Common/BitSet.h"
#include "Common/CommonTypes.h"
#include "Common/x64Emitter.h"
#include "Core/CPUThreadConfigCallback.h"
#include "Core/ConfigManager.h"
#include "Core/MachineContext.h"
#include "Core/PowerPC/CPUCoreBase.h"
Expand Down Expand Up @@ -129,7 +130,7 @@ class JitBase : public CPUCoreBase
PPCAnalyst::CodeBuffer m_code_buffer;
PPCAnalyst::PPCAnalyzer analyzer;

size_t m_registered_config_callback_id;
CPUThreadConfigCallback::ConfigChangedCallbackID m_registered_config_callback_id;
bool bJITOff = false;
bool bJITLoadStoreOff = false;
bool bJITLoadStorelXzOff = false;
Expand Down
3 changes: 2 additions & 1 deletion Source/Core/Core/PowerPC/PPCCache.h
Expand Up @@ -8,6 +8,7 @@
#include <vector>

#include "Common/CommonTypes.h"
#include "Common/Config/Config.h"

class PointerWrap;

Expand Down Expand Up @@ -61,7 +62,7 @@ struct Cache

struct InstructionCache : public Cache
{
std::optional<size_t> m_config_callback_id = std::nullopt;
std::optional<Config::ConfigChangedCallbackID> m_config_callback_id = std::nullopt;

bool m_disable_icache = false;

Expand Down
2 changes: 2 additions & 0 deletions Source/Core/DolphinLib.props
Expand Up @@ -191,6 +191,7 @@
<ClInclude Include="Core\ConfigManager.h" />
<ClInclude Include="Core\Core.h" />
<ClInclude Include="Core\CoreTiming.h" />
<ClInclude Include="Core\CPUThreadConfigCallback.h" />
<ClInclude Include="Core\Debugger\CodeTrace.h" />
<ClInclude Include="Core\Debugger\DebugInterface.h" />
<ClInclude Include="Core\Debugger\Debugger_SymbolMap.h" />
Expand Down Expand Up @@ -837,6 +838,7 @@
<ClCompile Include="Core\ConfigManager.cpp" />
<ClCompile Include="Core\Core.cpp" />
<ClCompile Include="Core\CoreTiming.cpp" />
<ClCompile Include="Core\CPUThreadConfigCallback.cpp" />
<ClCompile Include="Core\Debugger\CodeTrace.cpp" />
<ClCompile Include="Core\Debugger\Debugger_SymbolMap.cpp" />
<ClCompile Include="Core\Debugger\Dump.cpp" />
Expand Down
Expand Up @@ -219,7 +219,7 @@ class InputBackend final : public ciface::InputBackend
SteadyClock::time_point m_next_listports_time;
std::thread m_hotplug_thread;
Common::Flag m_hotplug_thread_running;
std::size_t m_config_change_callback_id;
Config::ConfigChangedCallbackID m_config_change_callback_id;
};

std::unique_ptr<ciface::InputBackend> CreateInputBackend(ControllerInterface* controller_interface)
Expand Down
3 changes: 2 additions & 1 deletion Source/Core/InputCommon/GCAdapter.cpp
Expand Up @@ -23,6 +23,7 @@
#endif

#include "Common/BitUtils.h"
#include "Common/Config/Config.h"
#include "Common/Event.h"
#include "Common/Flag.h"
#include "Common/Logging/Log.h"
Expand Down Expand Up @@ -158,7 +159,7 @@ static u8 s_endpoint_out = 0;

static u64 s_last_init = 0;

static std::optional<size_t> s_config_callback_id = std::nullopt;
static std::optional<Config::ConfigChangedCallbackID> s_config_callback_id = std::nullopt;

static bool s_is_adapter_wanted = false;
static std::array<bool, SerialInterface::MAX_SI_CHANNELS> s_config_rumble_enabled{};
Expand Down
2 changes: 1 addition & 1 deletion Source/Core/UICommon/UICommon.cpp
Expand Up @@ -62,7 +62,7 @@

namespace UICommon
{
static size_t s_config_changed_callback_id;
static Config::ConfigChangedCallbackID s_config_changed_callback_id;

static void CreateDumpPath(std::string path)
{
Expand Down
3 changes: 2 additions & 1 deletion Source/Core/VideoCommon/Fifo.h
Expand Up @@ -9,6 +9,7 @@

#include "Common/BlockingLoop.h"
#include "Common/CommonTypes.h"
#include "Common/Config/Config.h"
#include "Common/Event.h"
#include "Common/Flag.h"

Expand Down Expand Up @@ -121,7 +122,7 @@ class FifoManager final
bool m_syncing_suspended = false;
Common::Event m_sync_wakeup_event;

std::optional<size_t> m_config_callback_id = std::nullopt;
std::optional<Config::ConfigChangedCallbackID> m_config_callback_id = std::nullopt;
bool m_config_sync_gpu = false;
int m_config_sync_gpu_max_distance = 0;
int m_config_sync_gpu_min_distance = 0;
Expand Down
25 changes: 17 additions & 8 deletions Source/Core/VideoCommon/VideoConfig.cpp
Expand Up @@ -9,6 +9,7 @@
#include "Common/CommonTypes.h"
#include "Common/StringUtil.h"

#include "Core/CPUThreadConfigCallback.h"
#include "Core/Config/GraphicsSettings.h"
#include "Core/Config/MainSettings.h"
#include "Core/ConfigManager.h"
Expand All @@ -19,6 +20,7 @@
#include "VideoCommon/AbstractGfx.h"
#include "VideoCommon/BPFunctions.h"
#include "VideoCommon/DriverDetails.h"
#include "VideoCommon/Fifo.h"
#include "VideoCommon/FramebufferManager.h"
#include "VideoCommon/FreeLookCamera.h"
#include "VideoCommon/GraphicsModSystem/Config/GraphicsMod.h"
Expand Down Expand Up @@ -57,14 +59,21 @@ void VideoConfig::Refresh()
{
// There was a race condition between the video thread and the host thread here, if
// corrections need to be made by VerifyValidity(). Briefly, the config will contain
// invalid values. Instead, pause emulation first, which will flush the video thread,
// update the config and correct it, then resume emulation, after which the video
// thread will detect the config has changed and act accordingly.
Config::AddConfigChangedCallback([]() {
Core::RunAsCPUThread([]() {
g_Config.Refresh();
g_Config.VerifyValidity();
});
// invalid values. Instead, pause the video thread first, update the config and correct
// it, then resume emulation, after which the video thread will detect the config has
// changed and act accordingly.
CPUThreadConfigCallback::AddConfigChangedCallback([]() {
auto& system = Core::System::GetInstance();

const bool lock_gpu_thread = Core::IsRunningAndStarted();
if (lock_gpu_thread)
system.GetFifo().PauseAndLock(system, true, false);

g_Config.Refresh();
g_Config.VerifyValidity();

if (lock_gpu_thread)
system.GetFifo().PauseAndLock(system, false, true);
});
s_has_registered_callback = true;
}
Expand Down
5 changes: 5 additions & 0 deletions Source/UnitTests/Core/PageFaultTest.cpp
Expand Up @@ -5,7 +5,9 @@
#include <fmt/format.h>

#include "Common/CommonTypes.h"
#include "Common/ScopeGuard.h"
#include "Common/Timer.h"
#include "Core/Core.h"
#include "Core/MemTools.h"
#include "Core/PowerPC/JitCommon/JitBase.h"
#include "Core/PowerPC/JitInterface.h"
Expand Down Expand Up @@ -75,6 +77,9 @@ TEST(PageFault, PageFault)
EXPECT_NE(data, nullptr);
Common::WriteProtectMemory(data, PAGE_GRAN, false);

Core::DeclareAsCPUThread();
Common::ScopeGuard cpu_thread_guard([] { Core::UndeclareAsCPUThread(); });

auto& system = Core::System::GetInstance();
auto unique_pfjit = std::make_unique<PageFaultFakeJit>(system);
auto& pfjit = *unique_pfjit;
Expand Down
Expand Up @@ -5,7 +5,9 @@
#include <tuple>

#include "Common/CommonTypes.h"
#include "Common/ScopeGuard.h"
#include "Common/x64ABI.h"
#include "Core/Core.h"
#include "Core/PowerPC/Gekko.h"
#include "Core/PowerPC/Interpreter/Interpreter_FPUtils.h"
#include "Core/PowerPC/Jit64/Jit.h"
Expand Down Expand Up @@ -52,6 +54,9 @@ class TestCommonAsmRoutines : public CommonAsmRoutines

TEST(Jit64, ConvertDoubleToSingle)
{
Core::DeclareAsCPUThread();
Common::ScopeGuard cpu_thread_guard([] { Core::UndeclareAsCPUThread(); });

TestCommonAsmRoutines routines(Core::System::GetInstance());

for (const u64 input : double_test_values)
Expand Down
5 changes: 5 additions & 0 deletions Source/UnitTests/Core/PowerPC/Jit64Common/Frsqrte.cpp
Expand Up @@ -6,7 +6,9 @@
#include "Common/BitUtils.h"
#include "Common/CommonTypes.h"
#include "Common/FloatUtils.h"
#include "Common/ScopeGuard.h"
#include "Common/x64ABI.h"
#include "Core/Core.h"
#include "Core/PowerPC/Gekko.h"
#include "Core/PowerPC/Jit64/Jit.h"
#include "Core/PowerPC/Jit64Common/Jit64AsmCommon.h"
Expand Down Expand Up @@ -59,6 +61,9 @@ class TestCommonAsmRoutines : public CommonAsmRoutines

TEST(Jit64, Frsqrte)
{
Core::DeclareAsCPUThread();
Common::ScopeGuard cpu_thread_guard([] { Core::UndeclareAsCPUThread(); });

TestCommonAsmRoutines routines(Core::System::GetInstance());

UReg_FPSCR fpscr;
Expand Down
Expand Up @@ -7,6 +7,8 @@
#include "Common/BitUtils.h"
#include "Common/CommonTypes.h"
#include "Common/FPURoundMode.h"
#include "Common/ScopeGuard.h"
#include "Core/Core.h"
#include "Core/PowerPC/Interpreter/Interpreter_FPUtils.h"
#include "Core/PowerPC/JitArm64/Jit.h"
#include "Core/System.h"
Expand Down Expand Up @@ -120,6 +122,9 @@ class TestConversion : private JitArm64

TEST(JitArm64, ConvertDoubleToSingle)
{
Core::DeclareAsCPUThread();
Common::ScopeGuard cpu_thread_guard([] { Core::UndeclareAsCPUThread(); });

TestConversion test(Core::System::GetInstance());

for (const u64 input : double_test_values)
Expand Down Expand Up @@ -155,6 +160,9 @@ TEST(JitArm64, ConvertDoubleToSingle)

TEST(JitArm64, ConvertSingleToDouble)
{
Core::DeclareAsCPUThread();
Common::ScopeGuard cpu_thread_guard([] { Core::UndeclareAsCPUThread(); });

TestConversion test(Core::System::GetInstance());

for (const u32 input : single_test_values)
Expand Down
5 changes: 5 additions & 0 deletions Source/UnitTests/Core/PowerPC/JitArm64/FPRF.cpp
Expand Up @@ -7,6 +7,8 @@
#include "Common/Arm64Emitter.h"
#include "Common/BitUtils.h"
#include "Common/CommonTypes.h"
#include "Common/ScopeGuard.h"
#include "Core/Core.h"
#include "Core/PowerPC/Interpreter/Interpreter_FPUtils.h"
#include "Core/PowerPC/JitArm64/Jit.h"
#include "Core/PowerPC/PowerPC.h"
Expand Down Expand Up @@ -70,6 +72,9 @@ static u32 RunUpdateFPRF(PowerPC::PowerPCState& ppc_state, const std::function<v

TEST(JitArm64, FPRF)
{
Core::DeclareAsCPUThread();
Common::ScopeGuard cpu_thread_guard([] { Core::UndeclareAsCPUThread(); });

auto& system = Core::System::GetInstance();
auto& ppc_state = system.GetPPCState();
TestFPRF test(system);
Expand Down
5 changes: 5 additions & 0 deletions Source/UnitTests/Core/PowerPC/JitArm64/Fres.cpp
Expand Up @@ -6,6 +6,8 @@
#include "Common/Arm64Emitter.h"
#include "Common/BitUtils.h"
#include "Common/CommonTypes.h"
#include "Common/ScopeGuard.h"
#include "Core/Core.h"
#include "Core/PowerPC/Interpreter/Interpreter_FPUtils.h"
#include "Core/PowerPC/JitArm64/Jit.h"
#include "Core/PowerPC/PowerPC.h"
Expand Down Expand Up @@ -51,6 +53,9 @@ class TestFres : public JitArm64

TEST(JitArm64, Fres)
{
Core::DeclareAsCPUThread();
Common::ScopeGuard cpu_thread_guard([] { Core::UndeclareAsCPUThread(); });

TestFres test(Core::System::GetInstance());

for (const u64 ivalue : double_test_values)
Expand Down
5 changes: 5 additions & 0 deletions Source/UnitTests/Core/PowerPC/JitArm64/Frsqrte.cpp
Expand Up @@ -6,6 +6,8 @@
#include "Common/Arm64Emitter.h"
#include "Common/BitUtils.h"
#include "Common/CommonTypes.h"
#include "Common/ScopeGuard.h"
#include "Core/Core.h"
#include "Core/PowerPC/Interpreter/Interpreter_FPUtils.h"
#include "Core/PowerPC/JitArm64/Jit.h"
#include "Core/PowerPC/PowerPC.h"
Expand Down Expand Up @@ -51,6 +53,9 @@ class TestFrsqrte : public JitArm64

TEST(JitArm64, Frsqrte)
{
Core::DeclareAsCPUThread();
Common::ScopeGuard cpu_thread_guard([] { Core::UndeclareAsCPUThread(); });

TestFrsqrte test(Core::System::GetInstance());

for (const u64 ivalue : double_test_values)
Expand Down