summaryrefslogtreecommitdiff
path: root/Source/Android/jni/MainAndroid.cpp
diff options
context:
space:
mode:
authorMat M <mathew1800@gmail.com>2016-05-22 15:19:16 -0400
committerMat M <mathew1800@gmail.com>2016-05-22 15:19:16 -0400
commit08d45b9fea67714610cc6fdbe41e7bf1262816df (patch)
treebd873fe49b79ecd9152523a98688749825f0b047 /Source/Android/jni/MainAndroid.cpp
parentff4bc5f33d6bfaab38d651b0706c77d705cf6c5c (diff)
parentc1944f623b5918ab45152795dea9e49f57878138 (diff)
Merge pull request #3794 from EmptyChaos/frame-advance-race
Core: Add synchronization to state changes (Fix Frame Step and FIFO Player - Issue 8718)
Diffstat (limited to 'Source/Android/jni/MainAndroid.cpp')
-rw-r--r--Source/Android/jni/MainAndroid.cpp48
1 files changed, 45 insertions, 3 deletions
diff --git a/Source/Android/jni/MainAndroid.cpp b/Source/Android/jni/MainAndroid.cpp
index d9b8a61fba..6b30bc5409 100644
--- a/Source/Android/jni/MainAndroid.cpp
+++ b/Source/Android/jni/MainAndroid.cpp
@@ -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)
{