Skip to content
Permalink
Browse files

Merge pull request #3794 from EmptyChaos/frame-advance-race

Core: Add synchronization to state changes (Fix Frame Step and FIFO Player -  Issue 8718)
  • Loading branch information...
lioncash committed May 22, 2016
2 parents ff4bc5f + c1944f6 commit 08d45b9fea67714610cc6fdbe41e7bf1262816df
Showing with 976 additions and 399 deletions.
  1. +45 −3 Source/Android/jni/MainAndroid.cpp
  2. +0 −9 Source/Core/AudioCommon/Mixer.cpp
  3. +1 −0 Source/Core/Common/Common.h
  4. +2 −4 Source/Core/Common/Event.h
  5. +155 −26 Source/Core/Core/Core.cpp
  6. +21 −3 Source/Core/Core/Core.h
  7. +3 −4 Source/Core/Core/Debugger/PPCDebugInterface.cpp
  8. +83 −33 Source/Core/Core/FifoPlayer/FifoPlayer.cpp
  9. +12 −2 Source/Core/Core/FifoPlayer/FifoPlayer.h
  10. +2 −1 Source/Core/Core/HLE/HLE_Misc.cpp
  11. +239 −87 Source/Core/Core/HW/CPU.cpp
  12. +35 −11 Source/Core/Core/HW/CPU.h
  13. +3 −4 Source/Core/Core/HW/DVDInterface.cpp
  14. +1 −1 Source/Core/Core/HW/DVDInterface.h
  15. +132 −71 Source/Core/Core/Movie.cpp
  16. +2 −4 Source/Core/Core/PowerPC/CachedInterpreter.cpp
  17. +1 −4 Source/Core/Core/PowerPC/Interpreter/Interpreter.cpp
  18. +6 −3 Source/Core/Core/PowerPC/Jit64/Jit.cpp
  19. +4 −8 Source/Core/Core/PowerPC/Jit64/JitAsm.cpp
  20. +2 −1 Source/Core/Core/PowerPC/Jit64/Jit_LoadStore.cpp
  21. +2 −1 Source/Core/Core/PowerPC/Jit64IL/IR_X86.cpp
  22. +5 −2 Source/Core/Core/PowerPC/Jit64IL/JitIL.cpp
  23. +2 −5 Source/Core/Core/PowerPC/JitArm64/JitAsm.cpp
  24. +2 −1 Source/Core/Core/PowerPC/JitCommon/JitBase.cpp
  25. +2 −1 Source/Core/Core/PowerPC/JitILCommon/JitILBase_LoadStore.cpp
  26. +60 −68 Source/Core/Core/PowerPC/PowerPC.cpp
  27. +15 −17 Source/Core/Core/PowerPC/PowerPC.h
  28. +10 −0 Source/Core/DolphinQt2/Host.cpp
  29. +7 −0 Source/Core/DolphinQt2/Main.cpp
  30. +2 −0 Source/Core/DolphinWX/Debugger/CodeWindow.cpp
  31. +4 −3 Source/Core/DolphinWX/Debugger/WatchView.cpp
  32. +13 −0 Source/Core/DolphinWX/Main.cpp
  33. +1 −0 Source/Core/DolphinWX/Main.h
  34. +26 −10 Source/Core/DolphinWX/MainNoGUI.cpp
  35. +72 −12 Source/Core/DolphinWX/TASInputDlg.cpp
  36. +4 −0 Source/Core/DolphinWX/TASInputDlg.h
@@ -7,6 +7,8 @@
#include <cstdlib>
#include <jni.h>
#include <memory>
#include <mutex>
#include <thread>
#include <android/log.h>
#include <android/native_window_jni.h>
#include <EGL/egl.h>
@@ -29,7 +31,6 @@
#include "Core/HW/Wiimote.h"
#include "Core/HW/WiimoteReal/WiimoteReal.h"
#include "Core/PowerPC/JitInterface.h"
#include "Core/PowerPC/PowerPC.h"
#include "Core/PowerPC/Profiler.h"

#include "DiscIO/Volume.h"
@@ -65,9 +66,24 @@ jint JNI_OnLoad(JavaVM* vm, void* reserved)
void Host_NotifyMapLoaded() {}
void Host_RefreshDSPDebuggerWindow() {}

// The Core only supports using a single Host thread.
// If multiple threads want to call host functions then they need to queue
// sequentially for access.
static std::mutex s_host_identity_lock;
Common::Event updateMainFrameEvent;
static bool s_have_wm_user_stop = false;
void Host_Message(int Id)
{
if (Id == WM_USER_JOB_DISPATCH)
{
updateMainFrameEvent.Set();
}
else if (Id == WM_USER_STOP)
{
s_have_wm_user_stop = true;
if (Core::IsRunning())
Core::QueueHostJob(&Core::Stop);
}
}

void* Host_GetRenderHandle()
@@ -388,15 +404,18 @@ JNIEXPORT void JNICALL Java_org_dolphinemu_dolphinemu_NativeLibrary_SurfaceDestr

JNIEXPORT void JNICALL Java_org_dolphinemu_dolphinemu_NativeLibrary_UnPauseEmulation(JNIEnv *env, jobject obj)
{
std::lock_guard<std::mutex> guard(s_host_identity_lock);
Core::SetState(Core::CORE_RUN);
}
JNIEXPORT void JNICALL Java_org_dolphinemu_dolphinemu_NativeLibrary_PauseEmulation(JNIEnv *env, jobject obj)
{
std::lock_guard<std::mutex> guard(s_host_identity_lock);
Core::SetState(Core::CORE_PAUSE);
}

JNIEXPORT void JNICALL Java_org_dolphinemu_dolphinemu_NativeLibrary_StopEmulation(JNIEnv *env, jobject obj)
{
std::lock_guard<std::mutex> guard(s_host_identity_lock);
Core::SaveScreenShot("thumb");
Renderer::s_screenshotCompleted.WaitFor(std::chrono::seconds(2));
Core::Stop();
@@ -485,6 +504,7 @@ JNIEXPORT jboolean JNICALL Java_org_dolphinemu_dolphinemu_NativeLibrary_Supports

JNIEXPORT void JNICALL Java_org_dolphinemu_dolphinemu_NativeLibrary_SaveScreenShot(JNIEnv *env, jobject obj)
{
std::lock_guard<std::mutex> guard(s_host_identity_lock);
Core::SaveScreenShot();
}

@@ -529,11 +549,13 @@ JNIEXPORT void JNICALL Java_org_dolphinemu_dolphinemu_NativeLibrary_SetFilename(

JNIEXPORT void JNICALL Java_org_dolphinemu_dolphinemu_NativeLibrary_SaveState(JNIEnv *env, jobject obj, jint slot)
{
std::lock_guard<std::mutex> guard(s_host_identity_lock);
State::Save(slot);
}

JNIEXPORT void JNICALL Java_org_dolphinemu_dolphinemu_NativeLibrary_LoadState(JNIEnv *env, jobject obj, jint slot)
{
std::lock_guard<std::mutex> guard(s_host_identity_lock);
State::Load(slot);
}

@@ -560,6 +582,7 @@ JNIEXPORT void JNICALL Java_org_dolphinemu_dolphinemu_NativeLibrary_CreateUserFo

JNIEXPORT void JNICALL Java_org_dolphinemu_dolphinemu_NativeLibrary_SetUserDirectory(JNIEnv *env, jobject obj, jstring jDirectory)
{
std::lock_guard<std::mutex> guard(s_host_identity_lock);
std::string directory = GetJString(env, jDirectory);
g_set_userpath = directory;
UICommon::SetUserDirectory(directory);
@@ -572,6 +595,7 @@ JNIEXPORT jstring JNICALL Java_org_dolphinemu_dolphinemu_NativeLibrary_GetUserDi

JNIEXPORT void JNICALL Java_org_dolphinemu_dolphinemu_NativeLibrary_SetProfiling(JNIEnv *env, jobject obj, jboolean enable)
{
std::lock_guard<std::mutex> guard(s_host_identity_lock);
Core::SetState(Core::CORE_PAUSE);
JitInterface::ClearCache();
Profiler::g_ProfileBlocks = enable;
@@ -580,6 +604,7 @@ JNIEXPORT void JNICALL Java_org_dolphinemu_dolphinemu_NativeLibrary_SetProfiling

JNIEXPORT void JNICALL Java_org_dolphinemu_dolphinemu_NativeLibrary_WriteProfileResults(JNIEnv *env, jobject obj)
{
std::lock_guard<std::mutex> guard(s_host_identity_lock);
std::string filename = File::GetUserPath(D_DUMP_IDX) + "Debug/profiler.txt";
File::CreateFullPath(filename);
JitInterface::WriteProfileResults(filename);
@@ -638,6 +663,7 @@ JNIEXPORT void JNICALL Java_org_dolphinemu_dolphinemu_NativeLibrary_SurfaceDestr
}
JNIEXPORT void JNICALL Java_org_dolphinemu_dolphinemu_NativeLibrary_RefreshWiimotes(JNIEnv *env, jobject obj)
{
std::lock_guard<std::mutex> guard(s_host_identity_lock);
WiimoteReal::Refresh();
}

@@ -651,21 +677,37 @@ JNIEXPORT void JNICALL Java_org_dolphinemu_dolphinemu_NativeLibrary_Run(JNIEnv *

RegisterMsgAlertHandler(&MsgAlert);

std::unique_lock<std::mutex> guard(s_host_identity_lock);
UICommon::SetUserDirectory(g_set_userpath);
UICommon::Init();

WiimoteReal::InitAdapterClass();

// No use running the loop when booting fails
s_have_wm_user_stop = false;
if ( BootManager::BootCore( g_filename.c_str() ) )
{
PowerPC::Start();
while (PowerPC::GetState() != PowerPC::CPU_POWERDOWN)
static constexpr int TIMEOUT = 10000;
static constexpr int WAIT_STEP = 25;
int time_waited = 0;
// A Core::CORE_ERROR state would be helpful here.
while (!Core::IsRunning() && time_waited < TIMEOUT && !s_have_wm_user_stop)
{
std::this_thread::sleep_for(std::chrono::milliseconds(WAIT_STEP));
time_waited += WAIT_STEP;
}
while (Core::IsRunning())
{
guard.unlock();
updateMainFrameEvent.Wait();
guard.lock();
Core::HostDispatchJobs();
}
}

Core::Shutdown();
UICommon::Shutdown();
guard.unlock();

if (surf)
{
@@ -12,9 +12,6 @@
#include "Common/Logging/Log.h"
#include "Core/ConfigManager.h"

// UGLINESS
#include "Core/PowerPC/PowerPC.h"

#if _M_SSE >= 0x301 && !(defined __GNUC__ && !defined __SSSE3__)
#include <tmmintrin.h>
#endif
@@ -121,12 +118,6 @@ unsigned int CMixer::Mix(short* samples, unsigned int num_samples, bool consider

memset(samples, 0, num_samples * 2 * sizeof(short));

if (PowerPC::GetState() != PowerPC::CPU_RUNNING)
{
// Silence
return num_samples;
}

m_dma_mixer.Mix(samples, num_samples, consider_framelimit);
m_streaming_mixer.Mix(samples, num_samples, consider_framelimit);
m_wiimote_speaker_mixer.Mix(samples, num_samples, consider_framelimit);
@@ -83,6 +83,7 @@ enum HOST_COMM
WM_USER_STOP = 10,
WM_USER_CREATE,
WM_USER_SETCURSOR,
WM_USER_JOB_DISPATCH,
};

// Used for notification on emulation state
@@ -42,8 +42,7 @@ class Event final
return;

std::unique_lock<std::mutex> lk(m_mutex);
m_condvar.wait(lk, [&]{ return m_flag.IsSet(); });
m_flag.Clear();
m_condvar.wait(lk, [&]{ return m_flag.TestAndClear(); });
}

template<class Rep, class Period>
@@ -54,8 +53,7 @@ class Event final

std::unique_lock<std::mutex> lk(m_mutex);
bool signaled = m_condvar.wait_for(lk, rel_time,
[&]{ return m_flag.IsSet(); });
m_flag.Clear();
[&]{ return m_flag.TestAndClear(); });

return signaled;
}
Oops, something went wrong.

0 comments on commit 08d45b9

Please sign in to comment.
You can’t perform that action at this time.