From 679b71e250ce6557f05b57882747029ab6af7edc Mon Sep 17 00:00:00 2001 From: Justin Weiss Date: Fri, 21 Feb 2020 21:17:31 -0800 Subject: Add async CD access --- frontend/3ds/3ds_utils.h | 14 +++++++ frontend/3ds/pthread.h | 81 +++++++++++++++++++++++++++++++++++++++- frontend/libretro.c | 12 ++++++ frontend/libretro_core_options.h | 14 ++++++- 4 files changed, 118 insertions(+), 3 deletions(-) (limited to 'frontend') diff --git a/frontend/3ds/3ds_utils.h b/frontend/3ds/3ds_utils.h index cad4cbe..c9b9d7f 100644 --- a/frontend/3ds/3ds_utils.h +++ b/frontend/3ds/3ds_utils.h @@ -24,6 +24,20 @@ void threadFree(int32_t thread); void threadExit(int32_t rc) __attribute__((noreturn)); int32_t svcGetSystemInfo(int64_t* out, uint32_t type, int32_t param); + +int32_t svcCreateSemaphore(uint32_t *sem, int32_t initial_count, uint32_t max_count); +int32_t svcReleaseSemaphore(int32_t *count, uint32_t sem, int32_t release_count); +int32_t svcWaitSynchronization(uint32_t handle, int64_t nanoseconds); + +typedef int32_t LightLock; + +void LightLock_Init(LightLock* lock); +void LightLock_Lock(LightLock* lock); +int LightLock_TryLock(LightLock* lock); +void LightLock_Unlock(LightLock* lock); + +int32_t APT_CheckNew3DS(bool *out); + int32_t svcBackdoor(int32_t (*callback)(void)); #define DEBUG_HOLD() do{printf("%s@%s:%d.\n",__FUNCTION__, __FILE__, __LINE__);fflush(stdout);wait_for_input();}while(0) diff --git a/frontend/3ds/pthread.h b/frontend/3ds/pthread.h index 9f43707..cc3c965 100644 --- a/frontend/3ds/pthread.h +++ b/frontend/3ds/pthread.h @@ -9,15 +9,34 @@ #include "3ds_utils.h" #define CTR_PTHREAD_STACK_SIZE 0x10000 +#define FALSE 0 typedef int32_t pthread_t; typedef int pthread_attr_t; +typedef LightLock pthread_mutex_t; +typedef int pthread_mutexattr_t; + +typedef struct { + uint32_t semaphore; + LightLock lock; + uint32_t waiting; +} pthread_cond_t; + +typedef int pthread_condattr_t; + static inline int pthread_create(pthread_t *thread, const pthread_attr_t *attr, void *(*start_routine)(void*), void *arg) { - thread = threadCreate(start_routine, arg, CTR_PTHREAD_STACK_SIZE, 0x25, -2, FALSE); - return 1; + int procnum = -2; // use default cpu + bool isNew3DS; + APT_CheckNew3DS(&isNew3DS); + + if (isNew3DS) + procnum = 2; + + *thread = threadCreate(start_routine, arg, CTR_PTHREAD_STACK_SIZE, 0x25, procnum, FALSE); + return 0; } @@ -41,6 +60,64 @@ static inline void pthread_exit(void *retval) threadExit(0); } +static inline int pthread_mutex_init(pthread_mutex_t *mutex, const pthread_mutexattr_t *attr) { + LightLock_Init(mutex); + return 0; +} + +static inline int pthread_mutex_lock(pthread_mutex_t *mutex) { + LightLock_Lock(mutex); + return 0; +} + +static inline int pthread_mutex_unlock(pthread_mutex_t *mutex) { + LightLock_Unlock(mutex); + return 0; +} + +static inline int pthread_mutex_destroy(pthread_mutex_t *mutex) { + return 0; +} + +static inline int pthread_cond_init(pthread_cond_t *cond, const pthread_condattr_t *attr) { + if (svcCreateSemaphore(&cond->semaphore, 0, 1)) + goto error; + + LightLock_Init(&cond->lock); + cond->waiting = 0; + return 0; + + error: + svcCloseHandle(cond->semaphore); + return -1; +} + +static inline int pthread_cond_signal(pthread_cond_t *cond) { + int32_t count; + LightLock_Lock(&cond->lock); + if (cond->waiting) { + cond->waiting--; + svcReleaseSemaphore(&count, cond->semaphore, 1); + } + LightLock_Unlock(&cond->lock); + return 0; +} + +static inline int pthread_cond_wait(pthread_cond_t *cond, pthread_mutex_t *lock) { + LightLock_Lock(&cond->lock); + cond->waiting++; + LightLock_Unlock(lock); + LightLock_Unlock(&cond->lock); + svcWaitSynchronization(cond->semaphore, INT64_MAX); + LightLock_Lock(lock); + return 0; +} + +static inline int pthread_cond_destroy(pthread_cond_t *cond) { + svcCloseHandle(cond->semaphore); + return 0; +} + #endif //_3DS_PTHREAD_WRAP__ diff --git a/frontend/libretro.c b/frontend/libretro.c index cc443fe..bd7dc43 100644 --- a/frontend/libretro.c +++ b/frontend/libretro.c @@ -1852,6 +1852,18 @@ static void update_variables(bool in_flight) Config.VSyncWA = 1; } +#ifndef _WIN32 + var.value = NULL; + var.key = "pcsx_rearmed_async_cd"; + if (environ_cb(RETRO_ENVIRONMENT_GET_VARIABLE, &var) || var.value) + { + if (strcmp(var.value, "async") == 0) + Config.AsyncCD = 1; + else + Config.AsyncCD = 0; + } +#endif + var.value = NULL; var.key = "pcsx_rearmed_noxadecoding"; if (environ_cb(RETRO_ENVIRONMENT_GET_VARIABLE, &var) || var.value) diff --git a/frontend/libretro_core_options.h b/frontend/libretro_core_options.h index badd856..6f26c71 100644 --- a/frontend/libretro_core_options.h +++ b/frontend/libretro_core_options.h @@ -961,7 +961,19 @@ struct retro_core_option_definition option_defs_us[] = { }, "disabled", }, - +#ifndef _WIN32 + { + "pcsx_rearmed_async_cd", + "CD Access Method (Restart)", + "Select method used to read data from content disk images. 'Synchronous' mimics original hardware. 'Asynchronous' can reduce stuttering on devices with slow storage.", + { + { "sync", "Synchronous" }, + { "async", "Asynchronous" }, + { NULL, NULL}, + }, + "sync", + }, +#endif /* ADVANCED OPTIONS */ { "pcsx_rearmed_noxadecoding", -- cgit v1.2.3