Merge pull request #12117 from JosJuice/config-callback-cpu

Don't call RunAsCPUThread in config callbacks
This commit is contained in:
Admiral H. Curtiss 2023-08-26 16:34:46 +02:00 committed by GitHub
commit 2502e412b3
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
33 changed files with 234 additions and 49 deletions

View file

@ -10,6 +10,7 @@
#include "AudioCommon/SurroundDecoder.h"
#include "AudioCommon/WaveFile.h"
#include "Common/CommonTypes.h"
#include "Common/Config/Config.h"
class PointerWrap;
@ -120,5 +121,5 @@ private:
int m_config_timing_variance;
bool m_config_audio_stretch;
size_t m_config_changed_callback_id;
Config::ConfigChangedCallbackID m_config_changed_callback_id;
};

View file

@ -16,7 +16,7 @@ namespace Config
using Layers = std::map<LayerType, std::shared_ptr<Layer>>;
static Layers s_layers;
static std::vector<std::pair<size_t, ConfigChangedCallback>> s_callbacks;
static std::vector<std::pair<ConfigChangedCallbackID, ConfigChangedCallback>> s_callbacks;
static size_t s_next_callback_id = 0;
static u32 s_callback_guards = 0;
static std::atomic<u64> s_config_version = 0;
@ -65,15 +65,15 @@ void RemoveLayer(LayerType layer)
OnConfigChanged();
}
size_t AddConfigChangedCallback(ConfigChangedCallback func)
ConfigChangedCallbackID AddConfigChangedCallback(ConfigChangedCallback func)
{
const size_t callback_id = s_next_callback_id;
const ConfigChangedCallbackID callback_id{s_next_callback_id};
++s_next_callback_id;
s_callbacks.emplace_back(std::make_pair(callback_id, std::move(func)));
return callback_id;
}
void RemoveConfigChangedCallback(size_t callback_id)
void RemoveConfigChangedCallback(ConfigChangedCallbackID callback_id)
{
for (auto it = s_callbacks.begin(); it != s_callbacks.end(); ++it)
{
@ -138,7 +138,6 @@ void Shutdown()
WriteLock lock(s_layers_rw_lock);
s_layers.clear();
s_callbacks.clear();
}
void ClearCurrentRunLayer()

View file

@ -15,6 +15,14 @@
namespace Config
{
struct ConfigChangedCallbackID
{
size_t id = -1;
bool operator==(const ConfigChangedCallbackID&) const = default;
bool operator!=(const ConfigChangedCallbackID&) const = default;
};
using ConfigChangedCallback = std::function<void()>;
// Layer management
@ -22,9 +30,10 @@ void AddLayer(std::unique_ptr<ConfigLayerLoader> loader);
std::shared_ptr<Layer> GetLayer(LayerType layer);
void RemoveLayer(LayerType layer);
// returns an ID that can be passed to RemoveConfigChangedCallback()
size_t AddConfigChangedCallback(ConfigChangedCallback func);
void RemoveConfigChangedCallback(size_t callback_id);
// Returns an ID that can be passed to RemoveConfigChangedCallback().
// The callback may be called from any thread.
ConfigChangedCallbackID AddConfigChangedCallback(ConfigChangedCallback func);
void RemoveConfigChangedCallback(ConfigChangedCallbackID callback_id);
void OnConfigChanged();
// Returns the number of times the config has changed in the current execution of the program

View file

@ -59,6 +59,8 @@ add_library(core
Core.h
CoreTiming.cpp
CoreTiming.h
CPUThreadConfigCallback.cpp
CPUThreadConfigCallback.h
Debugger/CodeTrace.cpp
Debugger/CodeTrace.h
Debugger/DebugInterface.h

View file

@ -0,0 +1,75 @@
// Copyright 2023 Dolphin Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later
#include "Core/CPUThreadConfigCallback.h"
#include <atomic>
#include "Common/Assert.h"
#include "Common/Config/Config.h"
#include "Core/Core.h"
namespace
{
std::atomic<bool> s_should_run_callbacks = false;
static std::vector<
std::pair<CPUThreadConfigCallback::ConfigChangedCallbackID, Config::ConfigChangedCallback>>
s_callbacks;
static size_t s_next_callback_id = 0;
void RunCallbacks()
{
for (const auto& callback : s_callbacks)
callback.second();
}
void OnConfigChanged()
{
if (Core::IsCPUThread())
{
s_should_run_callbacks.store(false, std::memory_order_relaxed);
RunCallbacks();
}
else
{
s_should_run_callbacks.store(true, std::memory_order_relaxed);
}
}
}; // namespace
namespace CPUThreadConfigCallback
{
ConfigChangedCallbackID AddConfigChangedCallback(Config::ConfigChangedCallback func)
{
static auto s_config_changed_callback_id = Config::AddConfigChangedCallback(&OnConfigChanged);
const ConfigChangedCallbackID callback_id{s_next_callback_id};
++s_next_callback_id;
s_callbacks.emplace_back(std::make_pair(callback_id, std::move(func)));
return callback_id;
}
void RemoveConfigChangedCallback(ConfigChangedCallbackID callback_id)
{
for (auto it = s_callbacks.begin(); it != s_callbacks.end(); ++it)
{
if (it->first == callback_id)
{
s_callbacks.erase(it);
return;
}
}
}
void CheckForConfigChanges()
{
DEBUG_ASSERT(Core::IsCPUThread());
if (s_should_run_callbacks.exchange(false, std::memory_order_relaxed))
RunCallbacks();
}
}; // namespace CPUThreadConfigCallback

View file

@ -0,0 +1,30 @@
// Copyright 2023 Dolphin Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later
#pragma once
#include "Common/Config/Config.h"
// This file lets you register callbacks like in Common/Config/Config.h, with the difference that
// callbacks registered here are guaranteed to run on the CPU thread. Callbacks registered here may
// run with a slight delay compared to regular config callbacks.
namespace CPUThreadConfigCallback
{
struct ConfigChangedCallbackID
{
size_t id = -1;
bool operator==(const ConfigChangedCallbackID&) const = default;
bool operator!=(const ConfigChangedCallbackID&) const = default;
};
// returns an ID that can be passed to RemoveConfigChangedCallback()
ConfigChangedCallbackID AddConfigChangedCallback(Config::ConfigChangedCallback func);
void RemoveConfigChangedCallback(ConfigChangedCallbackID callback_id);
// Should be called regularly from the CPU thread
void CheckForConfigChanges();
}; // namespace CPUThreadConfigCallback

View file

@ -41,6 +41,7 @@
#include "Core/AchievementManager.h"
#include "Core/Boot/Boot.h"
#include "Core/BootManager.h"
#include "Core/CPUThreadConfigCallback.h"
#include "Core/Config/MainSettings.h"
#include "Core/ConfigManager.h"
#include "Core/CoreTiming.h"
@ -511,6 +512,9 @@ static void EmuThread(std::unique_ptr<BootParameters> boot, WindowSystemInfo wsi
DeclareAsCPUThread();
s_frame_step = false;
// If settings have changed since the previous run, notify callbacks.
CPUThreadConfigCallback::CheckForConfigChanges();
// Switch the window used for inputs to the render window. This way, the cursor position
// is relative to the render window, instead of the main window.
ASSERT(g_controller_interface.IsInit());

View file

@ -16,6 +16,7 @@
#include "Common/Logging/Log.h"
#include "Common/SPSCQueue.h"
#include "Core/CPUThreadConfigCallback.h"
#include "Core/Config/MainSettings.h"
#include "Core/Core.h"
#include "Core/PowerPC/PowerPC.h"
@ -88,8 +89,8 @@ void CoreTimingManager::UnregisterAllEvents()
void CoreTimingManager::Init()
{
m_registered_config_callback_id = Config::AddConfigChangedCallback(
[this]() { Core::RunAsCPUThread([this]() { RefreshConfig(); }); });
m_registered_config_callback_id =
CPUThreadConfigCallback::AddConfigChangedCallback([this]() { RefreshConfig(); });
RefreshConfig();
m_last_oc_factor = m_config_oc_factor;
@ -118,7 +119,7 @@ void CoreTimingManager::Shutdown()
MoveEvents();
ClearPendingEvents();
UnregisterAllEvents();
Config::RemoveConfigChangedCallback(m_registered_config_callback_id);
CPUThreadConfigCallback::RemoveConfigChangedCallback(m_registered_config_callback_id);
}
void CoreTimingManager::RefreshConfig()
@ -311,11 +312,13 @@ void CoreTimingManager::MoveEvents()
void CoreTimingManager::Advance()
{
auto& power_pc = m_system.GetPowerPC();
auto& ppc_state = power_pc.GetPPCState();
CPUThreadConfigCallback::CheckForConfigChanges();
MoveEvents();
auto& power_pc = m_system.GetPowerPC();
auto& ppc_state = power_pc.GetPPCState();
int cyclesExecuted = m_globals.slice_length - DowncountToCycles(ppc_state.downcount);
m_globals.global_timer += cyclesExecuted;
m_last_oc_factor = m_config_oc_factor;

View file

@ -23,6 +23,7 @@
#include "Common/CommonTypes.h"
#include "Common/SPSCQueue.h"
#include "Core/CPUThreadConfigCallback.h"
class PointerWrap;
@ -182,7 +183,7 @@ private:
EventType* m_ev_lost = nullptr;
size_t m_registered_config_callback_id = 0;
CPUThreadConfigCallback::ConfigChangedCallbackID m_registered_config_callback_id;
float m_config_oc_factor = 0.0f;
float m_config_oc_inv_factor = 0.0f;
bool m_config_sync_on_skip_idle = false;

View file

@ -10,6 +10,7 @@
#include <vector>
#include "Common/Assert.h"
#include "Common/Config/Config.h"
#include "Core/FifoPlayer/FifoDataFile.h"
#include "Core/PowerPC/CPUCoreBase.h"
#include "VideoCommon/CPMemory.h"
@ -189,7 +190,7 @@ private:
CallbackFunc m_FileLoadedCb = nullptr;
CallbackFunc m_FrameWrittenCb = nullptr;
size_t m_config_changed_callback_id;
Config::ConfigChangedCallbackID m_config_changed_callback_id;
std::unique_ptr<FifoDataFile> m_File;

View file

@ -2,6 +2,8 @@
// SPDX-License-Identifier: GPL-2.0-or-later
#include "Core/FreeLookConfig.h"
#include "Core/CPUThreadConfigCallback.h"
#include "Core/Config/FreeLookSettings.h"
#include "Core/ConfigManager.h"
#include "Core/Core.h"
@ -37,7 +39,7 @@ void Config::Refresh()
{
if (!s_has_registered_callback)
{
::Config::AddConfigChangedCallback([] { Core::RunAsCPUThread([] { s_config.Refresh(); }); });
CPUThreadConfigCallback::AddConfigChangedCallback([] { s_config.Refresh(); });
s_has_registered_callback = true;
}

View file

@ -10,6 +10,7 @@
#include "AudioCommon/AudioCommon.h"
#include "Common/CommonTypes.h"
#include "Common/Event.h"
#include "Core/CPUThreadConfigCallback.h"
#include "Core/Core.h"
#include "Core/Host.h"
#include "Core/PowerPC/GDBStub.h"
@ -75,6 +76,7 @@ void CPUManager::Run()
{
m_state_cpu_cvar.wait(state_lock, [this] { return !m_state_paused_and_locked; });
ExecutePendingJobs(state_lock);
CPUThreadConfigCallback::CheckForConfigChanges();
Common::Event gdb_step_sync_event;
switch (m_state)
@ -113,6 +115,7 @@ void CPUManager::Run()
// Wait for step command.
m_state_cpu_cvar.wait(state_lock, [this, &state_lock, &gdb_step_sync_event] {
ExecutePendingJobs(state_lock);
CPUThreadConfigCallback::CheckForConfigChanges();
state_lock.unlock();
if (GDBStub::IsActive() && GDBStub::HasControl())
{

View file

@ -30,7 +30,7 @@ static std::array<u8, MAX_BBMOTES> s_last_connect_request_counter;
namespace
{
static std::array<std::atomic<WiimoteSource>, MAX_BBMOTES> s_wiimote_sources;
static std::optional<size_t> s_config_callback_id = std::nullopt;
static std::optional<Config::ConfigChangedCallbackID> s_config_callback_id = std::nullopt;
WiimoteSource GetSource(unsigned int index)
{

View file

@ -9,6 +9,7 @@
#include <string>
#include "Common/Common.h"
#include "Common/Config/Config.h"
#include "Core/HW/WiimoteCommon/WiimoteReport.h"
@ -343,6 +344,6 @@ private:
IMUCursorState m_imu_cursor_state;
size_t m_config_changed_callback_id;
Config::ConfigChangedCallbackID m_config_changed_callback_id;
};
} // namespace WiimoteEmu

View file

@ -11,6 +11,7 @@
#include <vector>
#include "Common/Common.h"
#include "Common/Config/Config.h"
#include "Common/Event.h"
#include "Common/Flag.h"
#include "Common/SPSCQueue.h"
@ -157,7 +158,7 @@ private:
bool m_speaker_enabled_in_dolphin_config = false;
int m_balance_board_dump_port = 0;
size_t m_config_changed_callback_id;
Config::ConfigChangedCallbackID m_config_changed_callback_id;
};
class WiimoteScannerBackend

View file

@ -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"
@ -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();
}
}

View file

@ -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"
@ -166,7 +167,7 @@ private:
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

View file

@ -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"
@ -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()

View file

@ -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"
@ -129,7 +130,7 @@ protected:
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;

View file

@ -8,6 +8,7 @@
#include <vector>
#include "Common/CommonTypes.h"
#include "Common/Config/Config.h"
class PointerWrap;
@ -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;

View file

@ -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" />
@ -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" />

View file

@ -219,7 +219,7 @@ private:
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)

View file

@ -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"
@ -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{};

View file

@ -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)
{

View file

@ -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"
@ -121,7 +122,7 @@ private:
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;

View file

@ -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"
@ -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"
@ -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;
}

View file

@ -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"
@ -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;

View file

@ -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"
@ -52,6 +54,9 @@ public:
TEST(Jit64, ConvertDoubleToSingle)
{
Core::DeclareAsCPUThread();
Common::ScopeGuard cpu_thread_guard([] { Core::UndeclareAsCPUThread(); });
TestCommonAsmRoutines routines(Core::System::GetInstance());
for (const u64 input : double_test_values)

View file

@ -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"
@ -59,6 +61,9 @@ public:
TEST(Jit64, Frsqrte)
{
Core::DeclareAsCPUThread();
Common::ScopeGuard cpu_thread_guard([] { Core::UndeclareAsCPUThread(); });
TestCommonAsmRoutines routines(Core::System::GetInstance());
UReg_FPSCR fpscr;

View file

@ -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"
@ -120,6 +122,9 @@ private:
TEST(JitArm64, ConvertDoubleToSingle)
{
Core::DeclareAsCPUThread();
Common::ScopeGuard cpu_thread_guard([] { Core::UndeclareAsCPUThread(); });
TestConversion test(Core::System::GetInstance());
for (const u64 input : double_test_values)
@ -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)

View file

@ -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"
@ -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);

View file

@ -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"
@ -51,6 +53,9 @@ public:
TEST(JitArm64, Fres)
{
Core::DeclareAsCPUThread();
Common::ScopeGuard cpu_thread_guard([] { Core::UndeclareAsCPUThread(); });
TestFres test(Core::System::GetInstance());
for (const u64 ivalue : double_test_values)

View file

@ -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"
@ -51,6 +53,9 @@ public:
TEST(JitArm64, Frsqrte)
{
Core::DeclareAsCPUThread();
Common::ScopeGuard cpu_thread_guard([] { Core::UndeclareAsCPUThread(); });
TestFrsqrte test(Core::System::GetInstance());
for (const u64 ivalue : double_test_values)