Android: Pin emu thread to exclusive cores where supported
This commit is contained in:
parent
700f916a34
commit
35dc530b9a
|
@ -22,6 +22,8 @@
|
||||||
#include "scmversion/scmversion.h"
|
#include "scmversion/scmversion.h"
|
||||||
#include <android/native_window_jni.h>
|
#include <android/native_window_jni.h>
|
||||||
#include <cmath>
|
#include <cmath>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <sched.h>
|
||||||
#include <imgui.h>
|
#include <imgui.h>
|
||||||
Log_SetChannel(AndroidHostInterface);
|
Log_SetChannel(AndroidHostInterface);
|
||||||
|
|
||||||
|
@ -952,6 +954,31 @@ DEFINE_JNI_ARGS_METHOD(jstring, AndroidHostInterface_getFullScmVersion, jobject
|
||||||
g_scm_branch_str, __DATE__, __TIME__));
|
g_scm_branch_str, __DATE__, __TIME__));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
DEFINE_JNI_ARGS_METHOD(void, AndroidHostInterface_setThreadAffinity, jobject unused, jintArray cores)
|
||||||
|
{
|
||||||
|
// https://github.com/googlearchive/android-audio-high-performance/blob/c232c21bf35d3bfea16537b781c526b8abdcc3cf/SimpleSynth/app/src/main/cpp/audio_player.cc
|
||||||
|
int length = env->GetArrayLength(cores);
|
||||||
|
int* p_cores = env->GetIntArrayElements(cores, nullptr);
|
||||||
|
|
||||||
|
pid_t current_thread_id = gettid();
|
||||||
|
cpu_set_t cpu_set;
|
||||||
|
CPU_ZERO(&cpu_set);
|
||||||
|
for (int i = 0; i < length; i++)
|
||||||
|
{
|
||||||
|
Log_InfoPrintf("Binding to CPU %d", p_cores[i]);
|
||||||
|
CPU_SET(p_cores[i], &cpu_set);
|
||||||
|
}
|
||||||
|
|
||||||
|
int result = sched_setaffinity(current_thread_id, sizeof(cpu_set_t), &cpu_set);
|
||||||
|
if (result != 0)
|
||||||
|
Log_InfoPrintf("Thread affinity set.");
|
||||||
|
else
|
||||||
|
Log_ErrorPrintf("Error setting thread affinity: %d", result);
|
||||||
|
|
||||||
|
env->ReleaseIntArrayElements(cores, p_cores, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
DEFINE_JNI_ARGS_METHOD(jobject, AndroidHostInterface_create, jobject unused, jobject context_object,
|
DEFINE_JNI_ARGS_METHOD(jobject, AndroidHostInterface_create, jobject unused, jobject context_object,
|
||||||
jstring user_directory)
|
jstring user_directory)
|
||||||
{
|
{
|
||||||
|
|
|
@ -45,6 +45,8 @@ public class AndroidHostInterface {
|
||||||
|
|
||||||
static public native String getFullScmVersion();
|
static public native String getFullScmVersion();
|
||||||
|
|
||||||
|
static public native boolean setThreadAffinity(int[] cpus);
|
||||||
|
|
||||||
static public native AndroidHostInterface create(Context context, String userDirectory);
|
static public native AndroidHostInterface create(Context context, String userDirectory);
|
||||||
|
|
||||||
public native boolean isEmulationThreadRunning();
|
public native boolean isEmulationThreadRunning();
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
package com.github.stenzek.duckstation;
|
package com.github.stenzek.duckstation;
|
||||||
|
|
||||||
|
import android.os.Build;
|
||||||
import android.os.Process;
|
import android.os.Process;
|
||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
import android.view.Surface;
|
import android.view.Surface;
|
||||||
|
@ -28,10 +29,25 @@ public class EmulationThread extends Thread {
|
||||||
return thread;
|
return thread;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void setExclusiveCores() {
|
||||||
|
try {
|
||||||
|
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
|
||||||
|
int[] cores = Process.getExclusiveCores();
|
||||||
|
if (cores == null || cores.length == 0)
|
||||||
|
throw new Exception("Invalid return value from getExclusiveCores()");
|
||||||
|
|
||||||
|
AndroidHostInterface.setThreadAffinity(cores);
|
||||||
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
Log.e("EmulationThread", "getExclusiveCores() failed");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void run() {
|
public void run() {
|
||||||
try {
|
try {
|
||||||
Process.setThreadPriority(Process.THREAD_PRIORITY_MORE_FAVORABLE);
|
Process.setThreadPriority(Process.THREAD_PRIORITY_MORE_FAVORABLE);
|
||||||
|
setExclusiveCores();
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
Log.i("EmulationThread", "Failed to set priority for emulation thread: " + e.getMessage());
|
Log.i("EmulationThread", "Failed to set priority for emulation thread: " + e.getMessage());
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue