From d135f6d2ee8f4d19c4bc5ed13b86496ea293528d Mon Sep 17 00:00:00 2001 From: notaz Date: Tue, 15 Oct 2024 01:49:22 +0300 Subject: [PATCH] 3ds: customize thread creation --- Makefile | 2 +- frontend/3ds/3ds_utils.h | 3 +- frontend/3ds/pthread.h | 3 + frontend/libretro-rthreads.c | 96 +++++++++++++++++++++++++++++--- frontend/libretro-rthreads.h | 18 +++++- frontend/libretro.c | 12 ++++ frontend/libretro_core_options.h | 24 ++++++++ frontend/main.c | 8 +-- libpcsxcore/cdrom-async.c | 3 +- libpcsxcore/new_dynarec/emu_if.c | 2 +- 10 files changed, 151 insertions(+), 20 deletions(-) diff --git a/Makefile b/Makefile index f30816fa..69b7ab3d 100644 --- a/Makefile +++ b/Makefile @@ -369,7 +369,7 @@ endif # $(PLATFORM) == "libretro" ifeq "$(USE_RTHREADS)" "1" OBJS += frontend/libretro-rthreads.o OBJS += deps/libretro-common/features/features_cpu.o -frontend/main.o: CFLAGS += -DHAVE_CPU_FEATURES +frontend/main.o: CFLAGS += -DHAVE_RTHREADS INC_LIBRETRO_COMMON := 1 endif ifeq "$(INC_LIBRETRO_COMMON)" "1" diff --git a/frontend/3ds/3ds_utils.h b/frontend/3ds/3ds_utils.h index 75ab63b9..f7c8ddc2 100644 --- a/frontend/3ds/3ds_utils.h +++ b/frontend/3ds/3ds_utils.h @@ -3,7 +3,8 @@ #include #include -#include <3ds.h> +#include <3ds/os.h> +#include <3ds/svc.h> #ifdef OS_HEAP_AREA_BEGIN // defined in libctru 2.0+ #define USE_CTRULIB_2 1 diff --git a/frontend/3ds/pthread.h b/frontend/3ds/pthread.h index 76f1681c..63afa32c 100644 --- a/frontend/3ds/pthread.h +++ b/frontend/3ds/pthread.h @@ -23,8 +23,11 @@ #ifndef _CTR_PTHREAD_WRAP_CTR_ #define _CTR_PTHREAD_WRAP_CTR_ +#include <3ds/thread.h> +#include <3ds/services/apt.h> #include "3ds_utils.h" +#include #include #include diff --git a/frontend/libretro-rthreads.c b/frontend/libretro-rthreads.c index 72784d4d..24507508 100644 --- a/frontend/libretro-rthreads.c +++ b/frontend/libretro-rthreads.c @@ -1,20 +1,98 @@ -// temporary(?) workaround: -// https://github.com/libretro/libretro-common/pull/216 +#ifndef _GNU_SOURCE +#define _GNU_SOURCE // *_np +#endif #ifdef _3DS #include <3ds/svc.h> +#include <3ds/os.h> #include <3ds/services/apt.h> #include #endif #include "../deps/libretro-common/rthreads/rthreads.c" +#include "features/features_cpu.h" +#include "libretro-rthreads.h" + +// pcsxr "extensions" +extern void SysPrintf(const char *fmt, ...); + +#ifdef _3DS +static bool is_new_3ds; +#endif -// an "extension" -int sthread_set_name(sthread_t *thread, const char *name) +void pcsxr_sthread_init(void) { -#if defined(__GLIBC__) || defined(__MACH__) || \ - (defined(__ANDROID_API__) && __ANDROID_API__ >= 26) - if (thread) - return pthread_setname_np(thread->id, name); + SysPrintf("%d cpu core(s) detected\n", cpu_features_get_core_amount()); +#ifdef _3DS + int64_t version = 0; + APT_CheckNew3DS(&is_new_3ds); + svcGetSystemInfo(&version, 0x10000, 0); + + APT_SetAppCpuTimeLimit(35); + u32 percent = -1; + APT_GetAppCpuTimeLimit(&percent); + + SysPrintf("%s3ds detected, v%d.%d, AppCpuTimeLimit=%ld\n", + is_new_3ds ? "new" : "old", (int)GET_VERSION_MAJOR(version), + (int)GET_VERSION_MINOR(version), percent); +#endif +} + +sthread_t *pcsxr_sthread_create(void (*thread_func)(void *), + enum pcsxr_thread_type type) +{ + sthread_t *h = NULL; +#ifdef _3DS + Thread ctr_thread; + int core_id = 0; + s32 prio = 0x30; + + h = calloc(1, sizeof(*h)); + if (!h) + return NULL; + + svcGetThreadPriority(&prio, CUR_THREAD_HANDLE); + + switch (type) { + case PCSXRT_CDR: + case PCSXRT_SPU: + core_id = 1; + break; + case PCSXRT_DRC: + case PCSXRT_GPU: + core_id = is_new_3ds ? 2 : 1; + break; + case PCSXRT_COUNT: + break; + } + + ctr_thread = threadCreate(thread_func, NULL, STACKSIZE, prio, core_id, false); + if (!ctr_thread) { + if (core_id == 1) { + SysPrintf("threadCreate pcsxt %d core %d failed\n", + type, core_id); + core_id = is_new_3ds ? 2 : -1; + ctr_thread = threadCreate(thread_func, NULL, STACKSIZE, + prio, core_id, false); + } + } + if (!ctr_thread) { + SysPrintf("threadCreate pcsxt %d core %d failed\n", type, core_id); + free(h); + return NULL; + } + h->id = (pthread_t)ctr_thread; +#else + h = sthread_create(thread_func, NULL); + #if defined(__GLIBC__) || defined(__MACH__) || \ + (defined(__ANDROID_API__) && __ANDROID_API__ >= 26) + if (h && (unsigned int)type < (unsigned int)PCSXRT_COUNT) + { + const char * const pcsxr_tnames[PCSXRT_COUNT] = { + "pcsxr-cdrom", "pcsxr-drc", "pcsxr-gpu", "pcsxr-spu" + }; + pthread_setname_np(h->id, pcsxr_tnames[type]); + } + #endif #endif - return -1; + return h; } diff --git a/frontend/libretro-rthreads.h b/frontend/libretro-rthreads.h index 851d448e..6a2d004b 100644 --- a/frontend/libretro-rthreads.h +++ b/frontend/libretro-rthreads.h @@ -1,3 +1,19 @@ +#ifndef __LIBRETRO_PCSXR_RTHREADS_H__ +#define __LIBRETRO_PCSXR_RTHREADS_H__ + #include "rthreads/rthreads.h" -int sthread_set_name(sthread_t *thread, const char *name); +enum pcsxr_thread_type +{ + PCSXRT_CDR = 0, + PCSXRT_DRC, + PCSXRT_GPU, + PCSXRT_SPU, + PCSXRT_COUNT // must be last +}; + +void pcsxr_sthread_init(void); +sthread_t *pcsxr_sthread_create(void (*thread_func)(void*), + enum pcsxr_thread_type type); + +#endif // __LIBRETRO_PCSXR_RTHREADS_H__ diff --git a/frontend/libretro.c b/frontend/libretro.c index f7eb64cd..ce0e7427 100644 --- a/frontend/libretro.c +++ b/frontend/libretro.c @@ -50,6 +50,9 @@ #endif #ifdef _3DS +#include <3ds/svc.h> +#include <3ds/services/apt.h> +#include <3ds/allocator/linear.h> #include "3ds/3ds_utils.h" #endif @@ -2778,6 +2781,15 @@ static void update_variables(bool in_flight) mouse_sensitivity = atof(var.value); } +#ifdef _3DS + var.value = NULL; + var.key = "pcsx_rearmed_3ds_appcputime"; + if (environ_cb(RETRO_ENVIRONMENT_GET_VARIABLE, &var) && var.value) + { + APT_SetAppCpuTimeLimit(strtol(var.value, NULL, 10)); + } +#endif + if (found_bios) { var.value = NULL; diff --git a/frontend/libretro_core_options.h b/frontend/libretro_core_options.h index a4ead77e..8910ad23 100644 --- a/frontend/libretro_core_options.h +++ b/frontend/libretro_core_options.h @@ -1612,6 +1612,30 @@ struct retro_core_option_v2_definition option_defs_us[] = { }, "disabled", }, +#ifdef _3DS +#define V(x) { #x, NULL } + { + "pcsx_rearmed_3ds_appcputime", + "3DS AppCpuTimeLimit", + NULL, + "% of syscore (core #1) CPU time allocated to the emulator", + NULL, + "speed_hack", + { + V( 5), V(10), + V(15), V(20), + V(25), V(30), + V(35), V(40), + V(45), V(50), + V(55), V(60), + V(65), V(70), + V(75), V(80), + { NULL, NULL}, + }, + "35", + }, +#undef V +#endif // _3DS { "pcsx_rearmed_cd_turbo", "Turbo CD", diff --git a/frontend/main.c b/frontend/main.c index 0bb4a6df..949ba65b 100644 --- a/frontend/main.c +++ b/frontend/main.c @@ -14,8 +14,8 @@ #if !defined(_WIN32) && !defined(NO_DYLIB) #include #endif -#ifdef HAVE_CPU_FEATURES -#include "features/features_cpu.h" +#ifdef HAVE_RTHREADS +#include "../frontend/libretro-rthreads.h" #endif #include "main.h" @@ -513,10 +513,8 @@ int emu_core_preinit(void) int emu_core_init(void) { SysPrintf("Starting PCSX-ReARMed " REV "%s\n", get_build_info()); -#ifdef HAVE_CPU_FEATURES - SysPrintf("%d cpu core(s) detected\n", cpu_features_get_core_amount()); -#endif + pcsxr_sthread_init(); #ifndef NO_FRONTEND check_profile(); check_memcards(); diff --git a/libpcsxcore/cdrom-async.c b/libpcsxcore/cdrom-async.c index 4da0f374..81b2e12a 100644 --- a/libpcsxcore/cdrom-async.c +++ b/libpcsxcore/cdrom-async.c @@ -268,12 +268,11 @@ static void cdra_start_thread(void) if (acdrom.buf_cache && acdrom.buf_lock && acdrom.read_lock && acdrom.cond) { int i; - acdrom.thread = sthread_create(cdra_prefetch_thread, NULL); + acdrom.thread = pcsxr_sthread_create(cdra_prefetch_thread, PCSXRT_CDR); for (i = 0; i < acdrom.buf_cnt; i++) acdrom.buf_cache[i].lba = ~0; } if (acdrom.thread) { - sthread_set_name(acdrom.thread, "pcsxr-cdrom"); SysPrintf("cdrom precache: %d buffers%s\n", acdrom.buf_cnt, acdrom.have_subchannel ? " +sub" : ""); } diff --git a/libpcsxcore/new_dynarec/emu_if.c b/libpcsxcore/new_dynarec/emu_if.c index e4958018..57fe663d 100644 --- a/libpcsxcore/new_dynarec/emu_if.c +++ b/libpcsxcore/new_dynarec/emu_if.c @@ -499,7 +499,7 @@ static void ari64_thread_init(void) ndrc_g.thread.cond = scond_new(); } if (ndrc_g.thread.lock && ndrc_g.thread.cond) - ndrc_g.thread.handle = sthread_create(ari64_compile_thread, NULL); + ndrc_g.thread.handle = pcsxr_sthread_create(ari64_compile_thread, PCSXRT_DRC); if (ndrc_g.thread.handle) { psxRec.Execute = ari64_execute_threaded; psxRec.ExecuteBlock = ari64_execute_threaded_block; -- 2.39.5