summaryrefslogtreecommitdiff
path: root/Source/Core
diff options
context:
space:
mode:
authorJosJuice <josjuice@gmail.com>2017-07-22 12:42:55 +0200
committerGitHub <noreply@github.com>2017-07-22 12:42:55 +0200
commit57affaff22c1beeb08b76d998d72fb6f44376a47 (patch)
tree8d9e11ce3a2732b37c5c1bd24e13572a39e045df /Source/Core
parent2f0bec93cb3eb02f159461f13557bde4bd2771bb (diff)
parent5729ac0fc685d42035dfa1c850672822a247851c (diff)
Merge pull request #5803 from leoetlino/pause-and-lock
Replace balanced Core::PauseAndLock calls with RunAsCPUThread
Diffstat (limited to 'Source/Core')
-rw-r--r--Source/Core/Core/Core.cpp51
-rw-r--r--Source/Core/Core/Core.h14
-rw-r--r--Source/Core/Core/HW/DVD/DVDInterface.cpp7
-rw-r--r--Source/Core/Core/Movie.cpp104
-rw-r--r--Source/Core/Core/PowerPC/BreakPoints.cpp28
-rw-r--r--Source/Core/Core/State.cpp252
-rw-r--r--Source/Core/DolphinNoGUI/MainNoGUI.cpp14
-rw-r--r--Source/Core/DolphinQt2/Config/Mapping/IOWindow.cpp29
-rw-r--r--Source/Core/DolphinQt2/Config/Mapping/MappingWindow.cpp28
-rw-r--r--Source/Core/DolphinWX/Config/GCAdapterConfigDiag.cpp12
-rw-r--r--Source/Core/DolphinWX/Frame.cpp4
-rw-r--r--Source/Core/DolphinWX/FrameTools.cpp56
-rw-r--r--Source/Core/DolphinWX/Input/InputConfigDiag.cpp28
13 files changed, 302 insertions, 325 deletions
diff --git a/Source/Core/Core/Core.cpp b/Source/Core/Core/Core.cpp
index 941115f777..31cb2d8b4c 100644
--- a/Source/Core/Core/Core.cpp
+++ b/Source/Core/Core/Core.cpp
@@ -102,7 +102,6 @@ static StoppedCallbackFunc s_on_stopped_callback;
static std::thread s_cpu_thread;
static bool s_request_refresh_info = false;
-static int s_pause_and_lock_depth = 0;
static bool s_is_throttler_temp_disabled = false;
struct HostJob
@@ -759,17 +758,12 @@ void RequestRefreshInfo()
s_request_refresh_info = true;
}
-bool PauseAndLock(bool do_lock, bool unpause_on_unlock)
+static bool PauseAndLock(bool do_lock, bool unpause_on_unlock)
{
// WARNING: PauseAndLock is not fully threadsafe so is only valid on the Host Thread
if (!IsRunning())
return true;
- // let's support recursive locking to simplify things on the caller's side,
- // and let's do it at this outer level in case the individual systems don't support it.
- if (do_lock ? s_pause_and_lock_depth++ : --s_pause_and_lock_depth)
- return true;
-
bool was_unpaused = true;
if (do_lock)
{
@@ -806,6 +800,19 @@ bool PauseAndLock(bool do_lock, bool unpause_on_unlock)
return was_unpaused;
}
+void RunAsCPUThread(std::function<void()> function)
+{
+ const bool is_cpu_thread = IsCPUThread();
+ bool was_unpaused = false;
+ if (!is_cpu_thread)
+ was_unpaused = PauseAndLock(true, true);
+
+ function();
+
+ if (!is_cpu_thread)
+ PauseAndLock(false, was_unpaused);
+}
+
// Display FPS info
// This should only be called from VI
void VideoThrottle()
@@ -955,22 +962,20 @@ void UpdateWantDeterminism(bool initial)
{
NOTICE_LOG(COMMON, "Want determinism <- %s", new_want_determinism ? "true" : "false");
- bool was_unpaused = Core::PauseAndLock(true);
-
- s_wants_determinism = new_want_determinism;
- const auto ios = IOS::HLE::GetIOS();
- if (ios)
- ios->UpdateWantDeterminism(new_want_determinism);
- Fifo::UpdateWantDeterminism(new_want_determinism);
- // We need to clear the cache because some parts of the JIT depend on want_determinism, e.g. use
- // of FMA.
- JitInterface::ClearCache();
-
- // Don't call InitializeWiiRoot during boot, because IOS already does it.
- if (!initial)
- Core::InitializeWiiRoot(s_wants_determinism);
-
- Core::PauseAndLock(false, was_unpaused);
+ RunAsCPUThread([&] {
+ s_wants_determinism = new_want_determinism;
+ const auto ios = IOS::HLE::GetIOS();
+ if (ios)
+ ios->UpdateWantDeterminism(new_want_determinism);
+ Fifo::UpdateWantDeterminism(new_want_determinism);
+ // We need to clear the cache because some parts of the JIT depend on want_determinism,
+ // e.g. use of FMA.
+ JitInterface::ClearCache();
+
+ // Don't call InitializeWiiRoot during boot, because IOS already does it.
+ if (!initial)
+ Core::InitializeWiiRoot(s_wants_determinism);
+ });
}
}
diff --git a/Source/Core/Core/Core.h b/Source/Core/Core/Core.h
index 78b5f5d6c7..e604843a2c 100644
--- a/Source/Core/Core/Core.h
+++ b/Source/Core/Core/Core.h
@@ -74,12 +74,14 @@ void RequestRefreshInfo();
void UpdateTitle();
-// waits until all systems are paused and fully idle, and acquires a lock on that state.
-// or, if doLock is false, releases a lock on that state and optionally unpauses.
-// calls must be balanced (once with doLock true, then once with doLock false) but may be recursive.
-// the return value of the first call should be passed in as the second argument of the second call.
-// [NOT THREADSAFE] Host only
-bool PauseAndLock(bool doLock, bool unpauseOnUnlock = true);
+// Run a function as the CPU thread.
+//
+// If called from the Host thread, the CPU thread is paused and the current thread temporarily
+// becomes the CPU thread while running the function.
+// If called from the CPU thread, the function will be run directly.
+//
+// This should only be called from the CPU thread or the host thread.
+void RunAsCPUThread(std::function<void()> function);
// for calling back into UI code without introducing a dependency on it in core
using StoppedCallbackFunc = std::function<void()>;
diff --git a/Source/Core/Core/HW/DVD/DVDInterface.cpp b/Source/Core/Core/HW/DVD/DVDInterface.cpp
index 4876ba6063..ffee201a97 100644
--- a/Source/Core/Core/HW/DVD/DVDInterface.cpp
+++ b/Source/Core/Core/HW/DVD/DVDInterface.cpp
@@ -476,12 +476,7 @@ static void InsertDiscCallback(u64 userdata, s64 cyclesLate)
// Can only be called by the host thread
void ChangeDiscAsHost(const std::string& new_path)
{
- bool was_unpaused = Core::PauseAndLock(true);
-
- // The host thread is now temporarily the CPU thread
- ChangeDiscAsCPU(new_path);
-
- Core::PauseAndLock(false, was_unpaused);
+ Core::RunAsCPUThread([&] { ChangeDiscAsCPU(new_path); });
}
// Can only be called by the CPU thread
diff --git a/Source/Core/Core/Movie.cpp b/Source/Core/Core/Movie.cpp
index 79104e02c3..d793d908d5 100644
--- a/Source/Core/Core/Movie.cpp
+++ b/Source/Core/Core/Movie.cpp
@@ -544,68 +544,66 @@ bool BeginRecordingInput(int controllers)
if (s_playMode != MODE_NONE || controllers == 0)
return false;
- bool was_unpaused = Core::PauseAndLock(true);
-
- s_controllers = controllers;
- s_currentFrame = s_totalFrames = 0;
- s_currentLagCount = s_totalLagCount = 0;
- s_currentInputCount = s_totalInputCount = 0;
- s_totalTickCount = s_tickCountAtLastInput = 0;
- s_bongos = 0;
- s_memcards = 0;
- if (NetPlay::IsNetPlayRunning())
- {
- s_bNetPlay = true;
- s_recordingStartTime = ExpansionInterface::CEXIIPL::NetPlay_GetEmulatedTime();
- }
- else if (SConfig::GetInstance().bEnableCustomRTC)
- {
- s_recordingStartTime = SConfig::GetInstance().m_customRTCValue;
- }
- else
- {
- s_recordingStartTime = Common::Timer::GetLocalTimeSinceJan1970();
- }
-
- s_rerecords = 0;
+ Core::RunAsCPUThread([controllers] {
+ s_controllers = controllers;
+ s_currentFrame = s_totalFrames = 0;
+ s_currentLagCount = s_totalLagCount = 0;
+ s_currentInputCount = s_totalInputCount = 0;
+ s_totalTickCount = s_tickCountAtLastInput = 0;
+ s_bongos = 0;
+ s_memcards = 0;
+ if (NetPlay::IsNetPlayRunning())
+ {
+ s_bNetPlay = true;
+ s_recordingStartTime = ExpansionInterface::CEXIIPL::NetPlay_GetEmulatedTime();
+ }
+ else if (SConfig::GetInstance().bEnableCustomRTC)
+ {
+ s_recordingStartTime = SConfig::GetInstance().m_customRTCValue;
+ }
+ else
+ {
+ s_recordingStartTime = Common::Timer::GetLocalTimeSinceJan1970();
+ }
- for (int i = 0; i < SerialInterface::MAX_SI_CHANNELS; ++i)
- {
- if (SConfig::GetInstance().m_SIDevice[i] == SerialInterface::SIDEVICE_GC_TARUKONGA)
- s_bongos |= (1 << i);
- }
+ s_rerecords = 0;
- if (Core::IsRunningAndStarted())
- {
- const std::string save_path = File::GetUserPath(D_STATESAVES_IDX) + "dtm.sav";
- if (File::Exists(save_path))
- File::Delete(save_path);
+ for (int i = 0; i < SerialInterface::MAX_SI_CHANNELS; ++i)
+ {
+ if (SConfig::GetInstance().m_SIDevice[i] == SerialInterface::SIDEVICE_GC_TARUKONGA)
+ s_bongos |= (1 << i);
+ }
- State::SaveAs(save_path);
- s_bRecordingFromSaveState = true;
+ if (Core::IsRunningAndStarted())
+ {
+ const std::string save_path = File::GetUserPath(D_STATESAVES_IDX) + "dtm.sav";
+ if (File::Exists(save_path))
+ File::Delete(save_path);
- std::thread md5thread(GetMD5);
- md5thread.detach();
- GetSettings();
- }
+ State::SaveAs(save_path);
+ s_bRecordingFromSaveState = true;
- // Wiimotes cause desync issues if they're not reset before launching the game
- if (!Core::IsRunningAndStarted())
- {
- // This will also reset the wiimotes for gamecube games, but that shouldn't do anything
- Wiimote::ResetAllWiimotes();
- }
+ std::thread md5thread(GetMD5);
+ md5thread.detach();
+ GetSettings();
+ }
- s_playMode = MODE_RECORDING;
- s_author = SConfig::GetInstance().m_strMovieAuthor;
- s_temp_input.clear();
+ // Wiimotes cause desync issues if they're not reset before launching the game
+ if (!Core::IsRunningAndStarted())
+ {
+ // This will also reset the wiimotes for gamecube games, but that shouldn't do anything
+ Wiimote::ResetAllWiimotes();
+ }
- s_currentByte = 0;
+ s_playMode = MODE_RECORDING;
+ s_author = SConfig::GetInstance().m_strMovieAuthor;
+ s_temp_input.clear();
- if (Core::IsRunning())
- Core::UpdateWantDeterminism();
+ s_currentByte = 0;
- Core::PauseAndLock(false, was_unpaused);
+ if (Core::IsRunning())
+ Core::UpdateWantDeterminism();
+ });
Core::DisplayMessage("Starting movie recording", 2000);
return true;
diff --git a/Source/Core/Core/PowerPC/BreakPoints.cpp b/Source/Core/Core/PowerPC/BreakPoints.cpp
index 864793f5e8..e87143bcf8 100644
--- a/Source/Core/Core/PowerPC/BreakPoints.cpp
+++ b/Source/Core/Core/PowerPC/BreakPoints.cpp
@@ -174,14 +174,14 @@ void MemChecks::Add(const TMemCheck& memory_check)
if (GetMemCheck(memory_check.start_address) == nullptr)
{
bool had_any = HasAny();
- bool lock = Core::PauseAndLock(true);
- m_mem_checks.push_back(memory_check);
- // If this is the first one, clear the JIT cache so it can switch to
- // watchpoint-compatible code.
- if (!had_any && g_jit)
- g_jit->ClearCache();
- PowerPC::DBATUpdated();
- Core::PauseAndLock(false, lock);
+ Core::RunAsCPUThread([&] {
+ m_mem_checks.push_back(memory_check);
+ // If this is the first one, clear the JIT cache so it can switch to
+ // watchpoint-compatible code.
+ if (!had_any && g_jit)
+ g_jit->ClearCache();
+ PowerPC::DBATUpdated();
+ });
}
}
@@ -191,12 +191,12 @@ void MemChecks::Remove(u32 address)
{
if (i->start_address == address)
{
- bool lock = Core::PauseAndLock(true);
- m_mem_checks.erase(i);
- if (!HasAny() && g_jit)
- g_jit->ClearCache();
- PowerPC::DBATUpdated();
- Core::PauseAndLock(false, lock);
+ Core::RunAsCPUThread([&] {
+ m_mem_checks.erase(i);
+ if (!HasAny() && g_jit)
+ g_jit->ClearCache();
+ PowerPC::DBATUpdated();
+ });
return;
}
}
diff --git a/Source/Core/Core/State.cpp b/Source/Core/Core/State.cpp
index 5fbc446e16..9af7b25439 100644
--- a/Source/Core/Core/State.cpp
+++ b/Source/Core/Core/State.cpp
@@ -207,42 +207,36 @@ void LoadFromBuffer(std::vector<u8>& buffer)
return;
}
- bool wasUnpaused = Core::PauseAndLock(true);
-
- u8* ptr = &buffer[0];
- PointerWrap p(&ptr, PointerWrap::MODE_READ);
- DoState(p);
-
- Core::PauseAndLock(false, wasUnpaused);
+ Core::RunAsCPUThread([&] {
+ u8* ptr = &buffer[0];
+ PointerWrap p(&ptr, PointerWrap::MODE_READ);
+ DoState(p);
+ });
}
void SaveToBuffer(std::vector<u8>& buffer)
{
- bool wasUnpaused = Core::PauseAndLock(true);
-
- u8* ptr = nullptr;
- PointerWrap p(&ptr, PointerWrap::MODE_MEASURE);
+ Core::RunAsCPUThread([&] {
+ u8* ptr = nullptr;
+ PointerWrap p(&ptr, PointerWrap::MODE_MEASURE);
- DoState(p);
- const size_t buffer_size = reinterpret_cast<size_t>(ptr);
- buffer.resize(buffer_size);
-
- ptr = &buffer[0];
- p.SetMode(PointerWrap::MODE_WRITE);
- DoState(p);
+ DoState(p);
+ const size_t buffer_size = reinterpret_cast<size_t>(ptr);
+ buffer.resize(buffer_size);
- Core::PauseAndLock(false, wasUnpaused);
+ ptr = &buffer[0];
+ p.SetMode(PointerWrap::MODE_WRITE);
+ DoState(p);
+ });
}
void VerifyBuffer(std::vector<u8>& buffer)
{
- bool wasUnpaused = Core::PauseAndLock(true);
-
- u8* ptr = &buffer[0];
- PointerWrap p(&ptr, PointerWrap::MODE_VERIFY);
- DoState(p);
-
- Core::PauseAndLock(false, wasUnpaused);
+ Core::RunAsCPUThread([&] {
+ u8* ptr = &buffer[0];
+ PointerWrap p(&ptr, PointerWrap::MODE_VERIFY);
+ DoState(p);
+ });
}
// return state number not in map
@@ -399,48 +393,44 @@ static void CompressAndDumpState(CompressAndDumpState_args save_args)
void SaveAs(const std::string& filename, bool wait)
{
- // Pause the core while we save the state
- bool wasUnpaused = Core::PauseAndLock(true);
-
- // Measure the size of the buffer.
- u8* ptr = nullptr;
- PointerWrap p(&ptr, PointerWrap::MODE_MEASURE);
- DoState(p);
- const size_t buffer_size = reinterpret_cast<size_t>(ptr);
-
- // Then actually do the write.
- {
- std::lock_guard<std::mutex> lk(g_cs_current_buffer);
- g_current_buffer.resize(buffer_size);
- ptr = &g_current_buffer[0];
- p.SetMode(PointerWrap::MODE_WRITE);
+ Core::RunAsCPUThread([&] {
+ // Measure the size of the buffer.
+ u8* ptr = nullptr;
+ PointerWrap p(&ptr, PointerWrap::MODE_MEASURE);
DoState(p);
- }
+ const size_t buffer_size = reinterpret_cast<size_t>(ptr);
- if (p.GetMode() == PointerWrap::MODE_WRITE)
- {
- Core::DisplayMessage("Saving State...", 1000);
+ // Then actually do the write.
+ {
+ std::lock_guard<std::mutex> lk(g_cs_current_buffer);
+ g_current_buffer.resize(buffer_size);
+ ptr = &g_current_buffer[0];
+ p.SetMode(PointerWrap::MODE_WRITE);
+ DoState(p);
+ }
- CompressAndDumpState_args save_args;
- save_args.buffer_vector = &g_current_buffer;
- save_args.buffer_mutex = &g_cs_current_buffer;
- save_args.filename = filename;
- save_args.wait = wait;
+ if (p.GetMode() == PointerWrap::MODE_WRITE)
+ {
+ Core::DisplayMessage("Saving State...", 1000);
- Flush();
- g_save_thread = std::thread(CompressAndDumpState, save_args);
- g_compressAndDumpStateSyncEvent.Wait();
+ CompressAndDumpState_args save_args;
+ save_args.buffer_vector = &g_current_buffer;
+ save_args.buffer_mutex = &g_cs_current_buffer;
+ save_args.filename = filename;
+ save_args.wait = wait;
- g_last_filename = filename;
- }
- else
- {
- // someone aborted the save by changing the mode?
- Core::DisplayMessage("Unable to save: Internal DoState Error", 4000);
- }
+ Flush();
+ g_save_thread = std::thread(CompressAndDumpState, save_args);
+ g_compressAndDumpStateSyncEvent.Wait();
- // Resume the core and disable stepping
- Core::PauseAndLock(false, wasUnpaused);
+ g_last_filename = filename;
+ }
+ else
+ {
+ // someone aborted the save by changing the mode?
+ Core::DisplayMessage("Unable to save: Internal DoState Error", 4000);
+ }
+ });
}
bool ReadHeader(const std::string& filename, StateHeader& header)
@@ -549,72 +539,68 @@ void LoadAs(const std::string& filename)
return;
}
- // Stop the core while we load the state
- bool wasUnpaused = Core::PauseAndLock(true);
-
- g_loadDepth++;
-
- // Save temp buffer for undo load state
- if (!Movie::IsJustStartingRecordingInputFromSaveState())
- {
- std::lock_guard<std::mutex> lk(g_cs_undo_load_buffer);
- SaveToBuffer(g_undo_load_buffer);
- if (Movie::IsMovieActive())
- Movie::SaveRecording(File::GetUserPath(D_STATESAVES_IDX) + "undo.dtm");
- else if (File::Exists(File::GetUserPath(D_STATESAVES_IDX) + "undo.dtm"))
- File::Delete(File::GetUserPath(D_STATESAVES_IDX) + "undo.dtm");
- }
-
- bool loaded = false;
- bool loadedSuccessfully = false;
- std::string version_created_by;
+ Core::RunAsCPUThread([&] {
+ g_loadDepth++;
- // brackets here are so buffer gets freed ASAP
- {
- std::vector<u8> buffer;
- LoadFileStateData(filename, buffer);
-
- if (!buffer.empty())
+ // Save temp buffer for undo load state
+ if (!Movie::IsJustStartingRecordingInputFromSaveState())
{
- u8* ptr = &buffer[0];
- PointerWrap p(&ptr, PointerWrap::MODE_READ);
- version_created_by = DoState(p);
- loaded = true;
- loadedSuccessfully = (p.GetMode() == PointerWrap::MODE_READ);
+ std::lock_guard<std::mutex> lk(g_cs_undo_load_buffer);
+ SaveToBuffer(g_undo_load_buffer);
+ if (Movie::IsMovieActive())
+ Movie::SaveRecording(File::GetUserPath(D_STATESAVES_IDX) + "undo.dtm");
+ else if (File::Exists(File::GetUserPath(D_STATESAVES_IDX) + "undo.dtm"))
+ File::Delete(File::GetUserPath(D_STATESAVES_IDX) + "undo.dtm");
}
- }
- if (loaded)
- {
- if (loadedSuccessfully)
+ bool loaded = false;
+ bool loadedSuccessfully = false;
+ std::string version_created_by;
+
+ // brackets here are so buffer gets freed ASAP
{
- Core::DisplayMessage(StringFromFormat("Loaded state from %s", filename.c_str()), 2000);
- if (File::Exists(filename + ".dtm"))
- Movie::LoadInput(filename + ".dtm");
- else if (!Movie::IsJustStartingRecordingInputFromSaveState() &&
- !Movie::IsJustStartingPlayingInputFromSaveState())
- Movie::EndPlayInput(false);
+ std::vector<u8> buffer;
+ LoadFileStateData(filename, buffer);
+
+ if (!buffer.empty())
+ {
+ u8* ptr = &buffer[0];
+ PointerWrap p(&ptr, PointerWrap::MODE_READ);
+ version_created_by = DoState(p);
+ loaded = true;
+ loadedSuccessfully = (p.GetMode() == PointerWrap::MODE_READ);
+ }
}
- else
+
+ if (loaded)
{
- // failed to load
- Core::DisplayMessage("Unable to load: Can't load state from other versions!", 4000);
- if (!version_created_by.empty())
- Core::DisplayMessage("The savestate was created using " + version_created_by, 4000);
-
- // since we could be in an inconsistent state now (and might crash or whatever), undo.
- if (g_loadDepth < 2)
- UndoLoadState();
+ if (loadedSuccessfully)
+ {
+ Core::DisplayMessage(StringFromFormat("Loaded state from %s", filename.c_str()), 2000);
+ if (File::Exists(filename + ".dtm"))
+ Movie::LoadInput(filename + ".dtm");
+ else if (!Movie::IsJustStartingRecordingInputFromSaveState() &&
+ !Movie::IsJustStartingPlayingInputFromSaveState())
+ Movie::EndPlayInput(false);
+ }
+ else
+ {
+ // failed to load
+ Core::DisplayMessage("Unable to load: Can't load state from other versions!", 4000);
+ if (!version_created_by.empty())
+ Core::DisplayMessage("The savestate was created using " + version_created_by, 4000);
+
+ // since we could be in an inconsistent state now (and might crash or whatever), undo.
+ if (g_loadDepth < 2)
+ UndoLoadState();
+ }
}
- }
-
- if (s_on_after_load_callback)
- s_on_after_load_callback();
- g_loadDepth--;
+ if (s_on_after_load_callback)
+ s_on_after_load_callback();
- // resume dat core
- Core::PauseAndLock(false, wasUnpaused);
+ g_loadDepth--;
+ });
}
void SetOnAfterLoadCallback(AfterLoadCallbackFunc callback)
@@ -624,24 +610,22 @@ void SetOnAfterLoadCallback(AfterLoadCallbackFunc callback)
void VerifyAt(const std::string& filename)
{
- bool wasUnpaused = Core::PauseAndLock(true);
-
- std::vector<u8> buffer;
- LoadFileStateData(filename, buffer);
-
- if (!buffer.empty())
- {
- u8* ptr = &buffer[0];
- PointerWrap p(&ptr, PointerWrap::MODE_VERIFY);
- DoState(p);
+ Core::RunAsCPUThread([&] {
+ std::vector<u8> buffer;
+ LoadFileStateData(filename, buffer);
- if (p.GetMode() == PointerWrap::MODE_VERIFY)
- Core::DisplayMessage(StringFromFormat("Verified state at %s", filename.c_str()), 2000);
- else
- Core::DisplayMessage("Unable to Verify : Can't verify state from other revisions !", 4000);
- }
+ if (!buffer.empty())
+ {
+ u8* ptr = &buffer[0];
+ PointerWrap p(&ptr, PointerWrap::MODE_VERIFY);
+ DoState(p);
- Core::PauseAndLock(false, wasUnpaused);
+ if (p.GetMode() == PointerWrap::MODE_VERIFY)
+ Core::DisplayMessage(StringFromFormat("Verified state at %s", filename.c_str()), 2000);
+ else
+ Core::DisplayMessage("Unable to Verify : Can't verify state from other revisions !", 4000);
+ }
+ });
}
void Init()
diff --git a/Source/Core/DolphinNoGUI/MainNoGUI.cpp b/Source/Core/DolphinNoGUI/MainNoGUI.cpp
index b62cf0e22c..dc55d41ec6 100644
--- a/Source/Core/DolphinNoGUI/MainNoGUI.cpp
+++ b/Source/Core/DolphinNoGUI/MainNoGUI.cpp
@@ -137,13 +137,13 @@ void Host_ConnectWiimote(int wm_idx, bool connect)
const auto ios = IOS::HLE::GetIOS();
if (!ios || SConfig::GetInstance().m_bt_passthrough_enabled)
return;
- bool was_unpaused = Core::PauseAndLock(true);
- const auto bt = std::static_pointer_cast<IOS::HLE::Device::BluetoothEmu>(
- ios->GetDeviceByName("/dev/usb/oh1/57e/305"));
- if (bt)
- bt->AccessWiiMote(wm_idx | 0x100)->Activate(connect);
- Host_UpdateMainFrame();
- Core::PauseAndLock(false, was_unpaused);
+ Core::RunAsCPUThread([&] {
+ const auto bt = std::static_pointer_cast<IOS::HLE::Device::BluetoothEmu>(
+ ios->GetDeviceByName("/dev/usb/oh1/57e/305"));
+ if (bt)
+ bt->AccessWiiMote(wm_idx | 0x100)->Activate(connect);
+ Host_UpdateMainFrame();
+ });
});
}
diff --git a/Source/Core/DolphinQt2/Config/Mapping/IOWindow.cpp b/Source/Core/DolphinQt2/Config/Mapping/IOWindow.cpp
index ac2b22eb1d..16f0186cb2 100644
--- a/Source/Core/DolphinQt2/Config/Mapping/IOWindow.cpp
+++ b/Source/Core/DolphinQt2/Config/Mapping/IOWindow.cpp
@@ -237,25 +237,24 @@ void IOWindow::UpdateDeviceList()
m_block.Set(true);
m_devices_combo->clear();
- const bool paused = Core::PauseAndLock(true);
+ Core::RunAsCPUThread([&] {
+ g_controller_interface.RefreshDevices();
+ m_controller->UpdateReferences(g_controller_interface);
+ m_controller->UpdateDefaultDevice();
- g_controller_interface.RefreshDevices();
- m_controller->UpdateReferences(g_controller_interface);
- m_controller->UpdateDefaultDevice();
+ // Adding default device regardless if it's currently connected or not
+ const auto default_device = m_controller->default_device.ToString();
- // Adding default device regardless if it's currently connected or not
- const auto default_device = m_controller->default_device.ToString();
+ m_devices_combo->addItem(QString::fromStdString(default_device));
- m_devices_combo->addItem(QString::fromStdString(default_device));
-
- for (const auto& name : g_controller_interface.GetAllDeviceStrings())
- {
- if (name != default_device)
- m_devices_combo->addItem(QString::fromStdString(name));
- }
+ for (const auto& name : g_controller_interface.GetAllDeviceStrings())
+ {
+ if (name != default_device)
+ m_devices_combo->addItem(QString::fromStdString(name));
+ }
- m_devices_combo->setCurrentIndex(0);
+ m_devices_combo->setCurrentIndex(0);
+ });
- Core::PauseAndLock(false, paused);
m_block.Set(false);
}
diff --git a/Source/Core/DolphinQt2/Config/Mapping/MappingWindow.cpp b/Source/Core/DolphinQt2/Config/Mapping/MappingWindow.cpp
index f7406a5a8b..2885385f33 100644
--- a/Source/Core/DolphinQt2/Config/Mapping/MappingWindow.cpp
+++ b/Source/Core/DolphinQt2/Config/Mapping/MappingWindow.cpp
@@ -229,25 +229,23 @@ void MappingWindow::RefreshDevices()
{
m_devices_combo->clear();
- const bool paused = Core::PauseAndLock(true);
+ Core::RunAsCPUThread([&] {
+ g_controller_interface.RefreshDevices();
+ m_controller->UpdateReferences(g_controller_interface);
+ m_controller->UpdateDefaultDevice();
- g_controller_interface.RefreshDevices();
- m_controller->UpdateReferences(g_controller_interface);
- m_controller->UpdateDefaultDevice();
-
- const auto default_device = m_controller->default_device.ToString();
-
- m_devices_combo->addItem(QString::fromStdString(default_device));
+ const auto default_device = m_controller->default_device.ToString();
- for (const auto& name : g_controller_interface.GetAllDeviceStrings())
- {
- if (name != default_device)
- m_devices_combo->addItem(QString::fromStdString(name));
- }
+ m_devices_combo->addItem(QString::fromStdString(default_device));
- m_devices_combo->setCurrentIndex(0);
+ for (const auto& name : g_controller_interface.GetAllDeviceStrings())
+ {
+ if (name != default_device)
+ m_devices_combo->addItem(QString::fromStdString(name));
+ }
- Core::PauseAndLock(false, paused);
+ m_devices_combo->setCurrentIndex(0);
+ });
}
void MappingWindow::ChangeMappingType(MappingWindow::Type type)
diff --git a/Source/Core/DolphinWX/Config/GCAdapterConfigDiag.cpp b/Source/Core/DolphinWX/Config/GCAdapterConfigDiag.cpp
index 9cf3110e09..b5a862461d 100644
--- a/Source/Core/DolphinWX/Config/GCAdapterConfigDiag.cpp
+++ b/Source/Core/DolphinWX/Config/GCAdapterConfigDiag.cpp
@@ -71,12 +71,12 @@ void GCAdapterConfigDiag::ScheduleAdapterUpdate()
void GCAdapterConfigDiag::OnUpdateAdapter(wxCommandEvent& WXUNUSED(event))
{
- bool unpause = Core::PauseAndLock(true);
- if (GCAdapter::IsDetected())
- m_adapter_status->SetLabelText(_("Adapter Detected"));
- else
- m_adapter_status->SetLabelText(_("Adapter Not Detected"));
- Core::PauseAndLock(false, unpause);
+ Core::RunAsCPUThread([this] {
+ if (GCAdapter::IsDetected())
+ m_adapter_status->SetLabelText(_("Adapter Detected"));
+ else
+ m_adapter_status->SetLabelText(_("Adapter Not Detected"));
+ });
}
void GCAdapterConfigDiag::OnAdapterRumble(wxCommandEvent& event)
diff --git a/Source/Core/DolphinWX/Frame.cpp b/Source/Core/DolphinWX/Frame.cpp
index 29a7b526c3..fc5efddb34 100644
--- a/Source/Core/DolphinWX/Frame.cpp
+++ b/Source/Core/DolphinWX/Frame.cpp
@@ -1249,9 +1249,7 @@ void CFrame::DoExclusiveFullscreen(bool enable_fullscreen)
if (!g_renderer || g_renderer->IsFullscreen() == enable_fullscreen)
return;
- bool was_unpaused = Core::PauseAndLock(true);
- g_renderer->SetFullscreen(enable_fullscreen);
- Core::PauseAndLock(false, was_unpaused);
+ Core::RunAsCPUThread([enable_fullscreen] { g_renderer->SetFullscreen(enable_fullscreen); });
}
void CFrame::PollHotkeys(wxTimerEvent& event)
diff --git a/Source/Core/DolphinWX/FrameTools.cpp b/Source/Core/DolphinWX/FrameTools.cpp
index a403118000..d633561cfd 100644
--- a/Source/Core/DolphinWX/FrameTools.cpp
+++ b/Source/Core/DolphinWX/FrameTools.cpp
@@ -1411,19 +1411,19 @@ void CFrame::ConnectWiimote(int wm_idx, bool connect)
if (Core::IsRunning() && SConfig::GetInstance().bWii &&
!SConfig::GetInstance().m_bt_passthrough_enabled)
{
- bool was_unpaused = Core::PauseAndLock(true);
- const auto ios = IOS::HLE::GetIOS();
- if (!ios)
- return;
+ Core::RunAsCPUThread([&] {
+ const auto ios = IOS::HLE::GetIOS();
+ if (!ios)
+ return;
- const auto bt = std::static_pointer_cast<IOS::HLE::Device::BluetoothEmu>(
- ios->GetDeviceByName("/dev/usb/oh1/57e/305"));
- if (bt)
- bt->AccessWiiMote(wm_idx | 0x100)->Activate(connect);
- const char* message = connect ? "Wii Remote %i connected" : "Wii Remote %i disconnected";
- Core::DisplayMessage(StringFromFormat(message, wm_idx + 1), 3000);
- Host_UpdateMainFrame();
- Core::PauseAndLock(false, was_unpaused);
+ const auto bt = std::static_pointer_cast<IOS::HLE::Device::BluetoothEmu>(
+ ios->GetDeviceByName("/dev/usb/oh1/57e/305"));
+ if (bt)
+ bt->AccessWiiMote(wm_idx | 0x100)->Activate(connect);
+ const char* message = connect ? "Wii Remote %i connected" : "Wii Remote %i disconnected";
+ Core::DisplayMessage(StringFromFormat(message, wm_idx + 1), 3000);
+ Host_UpdateMainFrame();
+ });
}
}
@@ -1432,13 +1432,13 @@ void CFrame::OnConnectWiimote(wxCommandEvent& event)
const auto ios = IOS::HLE::GetIOS();
if (!ios || SConfig::GetInstance().m_bt_passthrough_enabled)
return;
- bool was_unpaused = Core::PauseAndLock(true);
- const auto bt = std::static_pointer_cast<IOS::HLE::Device::BluetoothEmu>(
- ios->GetDeviceByName("/dev/usb/oh1/57e/305"));
- const bool is_connected =
- bt && bt->AccessWiiMote((event.GetId() - IDM_CONNECT_WIIMOTE1) | 0x100)->IsConnected();
- ConnectWiimote(event.GetId() - IDM_CONNECT_WIIMOTE1, !is_connected);
- Core::PauseAndLock(false, was_unpaused);
+ Core::RunAsCPUThread([&] {
+ const auto bt = std::static_pointer_cast<IOS::HLE::Device::BluetoothEmu>(
+ ios->GetDeviceByName("/dev/usb/oh1/57e/305"));
+ const bool is_connected =
+ bt && bt->AccessWiiMote((event.GetId() - IDM_CONNECT_WIIMOTE1) | 0x100)->IsConnected();
+ ConnectWiimote(event.GetId() - IDM_CONNECT_WIIMOTE1, !is_connected);
+ });
}
// Toggle fullscreen. In Windows the fullscreen mode is accomplished by expanding the m_panel to
@@ -1603,15 +1603,15 @@ void CFrame::UpdateGUI()
GetMenuBar()->FindItem(IDM_CONNECT_BALANCEBOARD)->Enable(ShouldEnableWiimotes);
if (ShouldEnableWiimotes)
{
- bool was_unpaused = Core::PauseAndLock(true);
- GetMenuBar()->FindItem(IDM_CONNECT_WIIMOTE1)->Check(bt->AccessWiiMote(0x0100)->IsConnected());
- GetMenuBar()->FindItem(IDM_CONNECT_WIIMOTE2)->Check(bt->AccessWiiMote(0x0101)->IsConnected());
- GetMenuBar()->FindItem(IDM_CONNECT_WIIMOTE3)->Check(bt->AccessWiiMote(0x0102)->IsConnected());
- GetMenuBar()->FindItem(IDM_CONNECT_WIIMOTE4)->Check(bt->AccessWiiMote(0x0103)->IsConnected());
- GetMenuBar()
- ->FindItem(IDM_CONNECT_BALANCEBOARD)
- ->Check(bt->AccessWiiMote(0x0104)->IsConnected());
- Core::PauseAndLock(false, was_unpaused);
+ Core::RunAsCPUThread([&] {
+ GetMenuBar()->FindItem(IDM_CONNECT_WIIMOTE1)->Check(bt->AccessWiiMote(0x0100)->IsConnected());
+ GetMenuBar()->FindItem(IDM_CONNECT_WIIMOTE2)->Check(bt->AccessWiiMote(0x0101)->IsConnected());
+ GetMenuBar()->FindItem(IDM_CONNECT_WIIMOTE3)->Check(bt->AccessWiiMote(0x0102)->IsConnected());
+ GetMenuBar()->FindItem(IDM_CONNECT_WIIMOTE4)->Check(bt->AccessWiiMote(0x0103)->IsConnected());
+ GetMenuBar()
+ ->FindItem(IDM_CONNECT_BALANCEBOARD)
+ ->Check(bt->AccessWiiMote(0x0104)->IsConnected());
+ });
}
GetMenuBar()->FindItem(IDM_RECORD_READ_ONLY)->Enable(Running || Paused);
diff --git a/Source/Core/DolphinWX/Input/InputConfigDiag.cpp b/Source/Core/DolphinWX/Input/InputConfigDiag.cpp
index 15c213ac94..5d8bf9615e 100644
--- a/Source/Core/DolphinWX/Input/InputConfigDiag.cpp
+++ b/Source/Core/DolphinWX/Input/InputConfigDiag.cpp
@@ -915,25 +915,23 @@ void InputConfigDialog::UpdateDeviceComboBox()
void InputConfigDialog::RefreshDevices(wxCommandEvent&)
{
- bool was_unpaused = Core::PauseAndLock(true);
+ Core::RunAsCPUThread([&] {
+ // refresh devices
+ g_controller_interface.RefreshDevices();
- // refresh devices
- g_controller_interface.RefreshDevices();
+ // update all control references
+ UpdateControlReferences();
- // update all control references
- UpdateControlReferences();
+ // update device cbox
+ UpdateDeviceComboBox();
- // update device cbox
- UpdateDeviceComboBox();
+ Wiimote::LoadConfig();
+ Keyboard::LoadConfig();
+ Pad::LoadConfig();
+ HotkeyManagerEmu::LoadConfig();
- Wiimote::LoadConfig();
- Keyboard::LoadConfig();
- Pad::LoadConfig();
- HotkeyManagerEmu::LoadConfig();
-
- UpdateGUI();
-
- Core::PauseAndLock(false, was_unpaused);
+ UpdateGUI();
+ });
}
ControlGroupBox::~ControlGroupBox()