mirror of
https://github.com/izzy2lost/ppsspp.git
synced 2026-03-10 12:43:04 -07:00
Try to get a bit better at detaching threads that have used JNI from the VM.
This commit is contained in:
@@ -44,6 +44,7 @@ struct ThreadContext {
|
||||
std::atomic<bool> cancelled;
|
||||
std::atomic<Task *> private_single;
|
||||
std::deque<Task *> private_queue;
|
||||
char name[16];
|
||||
};
|
||||
|
||||
ThreadManager::ThreadManager() : global_(new GlobalThreadContext()) {
|
||||
@@ -124,14 +125,13 @@ bool ThreadManager::TeardownTask(Task *task, bool enqueue) {
|
||||
}
|
||||
|
||||
static void WorkerThreadFunc(GlobalThreadContext *global, ThreadContext *thread) {
|
||||
char threadName[16];
|
||||
if (thread->type == TaskType::CPU_COMPUTE) {
|
||||
snprintf(threadName, sizeof(threadName), "PoolWorker %d", thread->index);
|
||||
snprintf(thread->name, sizeof(thread->name), "PoolWorker %d", thread->index);
|
||||
} else {
|
||||
_assert_(thread->type == TaskType::IO_BLOCKING);
|
||||
snprintf(threadName, sizeof(threadName), "PoolWorkerIO %d", thread->index);
|
||||
snprintf(thread->name, sizeof(thread->name), "PoolWorkerIO %d", thread->index);
|
||||
}
|
||||
SetCurrentThreadName(threadName);
|
||||
SetCurrentThreadName(thread->name);
|
||||
|
||||
const bool isCompute = thread->type == TaskType::CPU_COMPUTE;
|
||||
const auto global_queue_size = [isCompute, &global]() -> int {
|
||||
@@ -185,6 +185,9 @@ static void WorkerThreadFunc(GlobalThreadContext *global, ThreadContext *thread)
|
||||
thread->queue_size--;
|
||||
}
|
||||
}
|
||||
|
||||
// In case it got attached to JNI, detach it. Don't think this has any side effects if called redundantly.
|
||||
DetachThreadFromJNI();
|
||||
}
|
||||
|
||||
void ThreadManager::Init(int numRealCores, int numLogicalCoresPerCpu) {
|
||||
|
||||
@@ -12,10 +12,15 @@
|
||||
|
||||
#elif defined(__ANDROID__)
|
||||
|
||||
#include "android/jni/app-android.h"
|
||||
|
||||
#define TLS_SUPPORTED
|
||||
|
||||
#endif
|
||||
|
||||
// TODO: Many other platforms also support TLS, in fact probably nearly all that we support
|
||||
// these days.
|
||||
|
||||
#include <cstring>
|
||||
#include <cstdint>
|
||||
|
||||
@@ -62,6 +67,13 @@ static EXCEPTION_DISPOSITION NTAPI ignore_handler(EXCEPTION_RECORD *rec,
|
||||
}
|
||||
#endif
|
||||
|
||||
void DetachThreadFromJNI() {
|
||||
#if PPSSPP_PLATFORM(ANDROID)
|
||||
Android_DetachThreadFromJNI();
|
||||
#else
|
||||
// Do nothing
|
||||
#endif
|
||||
}
|
||||
|
||||
#if PPSSPP_PLATFORM(WINDOWS) && !PPSSPP_PLATFORM(UWP)
|
||||
typedef HRESULT (WINAPI *TSetThreadDescription)(HANDLE, PCWSTR);
|
||||
@@ -90,7 +102,15 @@ static void InitializeSetThreadDescription() {
|
||||
void SetCurrentThreadNameThroughException(const char *threadName);
|
||||
#endif
|
||||
|
||||
void SetCurrentThreadName(const char* threadName) {
|
||||
const char *GetCurrentThreadName() {
|
||||
#ifdef TLS_SUPPORTED
|
||||
return curThreadName;
|
||||
#else
|
||||
return "";
|
||||
#endif
|
||||
}
|
||||
|
||||
void SetCurrentThreadName(const char *threadName) {
|
||||
#if PPSSPP_PLATFORM(WINDOWS) && !PPSSPP_PLATFORM(UWP)
|
||||
InitializeSetThreadDescription();
|
||||
if (g_pSetThreadDescription) {
|
||||
|
||||
@@ -2,11 +2,26 @@
|
||||
|
||||
#include <mutex>
|
||||
|
||||
// Note that name must be a global string that lives until the end of the process,
|
||||
// Note that the string pointed to must be have a lifetime until the end of the thread,
|
||||
// for AssertCurrentThreadName to work.
|
||||
void SetCurrentThreadName(const char *threadName);
|
||||
void AssertCurrentThreadName(const char *threadName);
|
||||
|
||||
// If TLS is not supported, this will return an empty string.
|
||||
const char *GetCurrentThreadName();
|
||||
|
||||
// Just gets a cheap thread identifier so that you can see different threads in debug output,
|
||||
// exactly what it is is badly specified and not useful for anything.
|
||||
int GetCurrentThreadIdForDebug();
|
||||
|
||||
// Call when leaving threads. On Android, calls DetachCurrentThread.
|
||||
// Threads that use scoped storage I/O end up attached as JNI threads, and will thus
|
||||
// need this in order to follow the rules correctly. Some devices seem to enforce this.
|
||||
void DetachThreadFromJNI();
|
||||
|
||||
class AndroidJNIThreadContext {
|
||||
public:
|
||||
~AndroidJNIThreadContext() {
|
||||
DetachThreadFromJNI();
|
||||
}
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user