From e943ac262fcfdb390684619336a9f501c82b2555 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Francisco=20Jos=C3=A9=20Garc=C3=ADa=20Garc=C3=ADa?= Date: Sun, 15 Nov 2020 09:41:37 +0100 Subject: [PATCH 1/2] [VITA] Remove old threading workaround --- bootstrap/vita/threading.c | 229 -------------------------------- frontend/drivers/platform_psp.c | 1 - 2 files changed, 230 deletions(-) delete mode 100644 bootstrap/vita/threading.c diff --git a/bootstrap/vita/threading.c b/bootstrap/vita/threading.c deleted file mode 100644 index 8b0d10aa2a..0000000000 --- a/bootstrap/vita/threading.c +++ /dev/null @@ -1,229 +0,0 @@ -// This provides support for __getreent() as well as implementation of our thread-related wrappers - -#include -#include -#include - -#include -#include - -#define MAX_THREADS 256 - -typedef struct reent_for_thread { - int thread_id; - int needs_reclaim; - void *tls_data_ext; - void *pthread_data_ext; - struct _reent reent; -} reent_for_thread; - -static reent_for_thread reent_list[MAX_THREADS]; -static int _newlib_reent_mutex; -static struct _reent _newlib_global_reent; - -#define TLS_REENT_THID_PTR(thid) sceKernelGetThreadTLSAddr(thid, 0x88) -#define TLS_REENT_PTR sceKernelGetTLSAddr(0x88) - -#define list_entry(ptr, type, member) \ - ((type *)((char *)(ptr)-(unsigned long)(&((type *)0)->member))) - -int __vita_delete_thread_reent(int thid) -{ - struct reent_for_thread *for_thread; - - // We only need to cleanup if reent is allocated, i.e. if it's on our TLS - // We also don't need to clean up the global reent - struct _reent **on_tls = NULL; - - if (thid == 0) - on_tls = TLS_REENT_PTR; - else - on_tls = TLS_REENT_THID_PTR(thid); - - if (!*on_tls || *on_tls == &_newlib_global_reent) - return 0; - - for_thread = list_entry(*on_tls, struct reent_for_thread, reent); - - // Remove from TLS - *on_tls = 0; - - // Set thread id to zero, which means the reent is free - for_thread->thread_id = 0; - - // We can't reclaim it here, will be done later in __getreent - for_thread->needs_reclaim = 1; - - return 1; -} - -int vitasdk_delete_thread_reent(int thid) -{ - int res = 0; - // Lock the list because we'll be modifying it - sceKernelLockMutex(_newlib_reent_mutex, 1, NULL); - - res = __vita_delete_thread_reent(thid); - - sceKernelUnlockMutex(_newlib_reent_mutex, 1); - return res; -} - -int _exit_thread_common(int exit_status, int (*exit_func)(int)) { - int res = 0; - int ret = 0; - int thid = sceKernelGetThreadId(); - - // Lock the list because we'll be modifying it - sceKernelLockMutex(_newlib_reent_mutex, 1, NULL); - - res = __vita_delete_thread_reent(0); - - ret = exit_func(exit_status); - - if (res) - { - struct _reent **on_tls = TLS_REENT_PTR; - struct reent_for_thread *for_thread = list_entry(*on_tls, struct reent_for_thread, reent); - - for_thread->thread_id = thid; - - // And put it back on TLS - *on_tls = &for_thread->reent; - } - - sceKernelUnlockMutex(_newlib_reent_mutex, 1); - return ret; -} - -int vita_exit_thread(int exit_status) { - return _exit_thread_common(exit_status, sceKernelExitThread); -} - -int vita_exit_delete_thread(int exit_status) { - return _exit_thread_common(exit_status, sceKernelExitDeleteThread); -} - -static inline void __vita_clean_reent(void) -{ - int i; - SceKernelThreadInfo info; - - for (i = 0; i < MAX_THREADS; ++i) - { - info.size = sizeof(SceKernelThreadInfo); - - if (sceKernelGetThreadInfo(reent_list[i].thread_id, &info) < 0) - { - reent_list[i].thread_id = 0; - reent_list[i].needs_reclaim = 1; - } - } -} - -static inline struct reent_for_thread *__vita_allocate_reent(void) -{ - int i; - struct reent_for_thread *free_reent = 0; - - for (i = 0; i < MAX_THREADS; ++i) - if (reent_list[i].thread_id == 0) { - free_reent = &reent_list[i]; - break; - } - - return free_reent; -} - -struct _reent *__getreent_for_thread(int thid) { - struct reent_for_thread *free_reent = 0; - struct _reent *returned_reent = 0; - - // A pointer to our reent should be on the TLS - struct _reent **on_tls = NULL; - - if (thid == 0) - on_tls = TLS_REENT_PTR; - else - on_tls = TLS_REENT_THID_PTR(thid); - - if (*on_tls) { - return *on_tls; - } - - sceKernelLockMutex(_newlib_reent_mutex, 1, 0); - - // If it's not on the TLS this means the thread doesn't have a reent allocated yet - // We allocate one and put a pointer to it on the TLS - free_reent = __vita_allocate_reent(); - - if (!free_reent) { - // clean any hanging thread references - __vita_clean_reent(); - - free_reent = __vita_allocate_reent(); - - if (!free_reent) { - // we've exhausted all our resources - __builtin_trap(); - } - } else { - // First, check if it needs to be cleaned up (if it came from another thread) - if (free_reent->needs_reclaim) { - _reclaim_reent(&free_reent->reent); - free_reent->needs_reclaim = 0; - } - - memset(free_reent, 0, sizeof(struct reent_for_thread)); - - // Set it up - if(thid==0){ - thid = sceKernelGetThreadId(); - } - free_reent->thread_id = thid; - _REENT_INIT_PTR(&free_reent->reent); - returned_reent = &free_reent->reent; - } - - // Put it on TLS for faster access time - *on_tls = returned_reent; - - sceKernelUnlockMutex(_newlib_reent_mutex, 1); - return returned_reent; -} - -struct _reent *__getreent(void) { - return __getreent_for_thread(0); -} - -void *vitasdk_get_tls_data(SceUID thid) -{ - struct reent_for_thread *for_thread; - struct _reent *reent = __getreent_for_thread(thid); - - for_thread = list_entry(reent, struct reent_for_thread, reent); - return &for_thread->tls_data_ext; -} - -void *vitasdk_get_pthread_data(SceUID thid) -{ - struct reent_for_thread *for_thread; - struct _reent *reent = __getreent_for_thread(thid); - - for_thread = list_entry(reent, struct reent_for_thread, reent); - return &for_thread->pthread_data_ext; -} - -// Called from _start to set up the main thread reentrancy structure -void _init_vita_reent(void) { - memset(reent_list, 0, sizeof(reent_list)); - _newlib_reent_mutex = sceKernelCreateMutex("reent list access mutex", 0, 0, 0); - reent_list[0].thread_id = sceKernelGetThreadId(); - _REENT_INIT_PTR(&reent_list[0].reent); - *(struct _reent **)(TLS_REENT_PTR) = &reent_list[0].reent; - _REENT_INIT_PTR(&_newlib_global_reent); -} - -void _free_vita_reent(void) { - sceKernelDeleteMutex(_newlib_reent_mutex); -} diff --git a/frontend/drivers/platform_psp.c b/frontend/drivers/platform_psp.c index 8072c3ce33..32ca6af71e 100644 --- a/frontend/drivers/platform_psp.c +++ b/frontend/drivers/platform_psp.c @@ -30,7 +30,6 @@ #include #include "../../bootstrap/vita/sbrk.c" -#include "../../bootstrap/vita/threading.c" #else #include From c5f2375254d4d4936dbda792211e182a7c6fa245 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Francisco=20Jos=C3=A9=20Garc=C3=ADa=20Garc=C3=ADa?= Date: Sun, 15 Nov 2020 10:23:58 +0100 Subject: [PATCH 2/2] [VITA] Remove pthread workaround --- Makefile.vita | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Makefile.vita b/Makefile.vita index dd94ba0282..b447a6fa22 100644 --- a/Makefile.vita +++ b/Makefile.vita @@ -95,7 +95,7 @@ AR := $(PREFIX)ar OBJCOPY := $(PREFIX)objcopy STRIP := $(PREFIX)strip NM := $(PREFIX)nm -LD := $(CC) +LD := $(CXX) LIBDIRS := -L. @@ -132,7 +132,7 @@ CXXFLAGS := $(CFLAGS) -fno-rtti -fno-exceptions VITA_LIBS := -lSceDisplay_stub -lSceGxm_stub -lSceNet_stub -lSceNetCtl_stub -lSceAppUtil_stub \ -lSceSysmodule_stub -lSceCtrl_stub -lSceHid_stub -lSceTouch_stub -lSceAudio_stub \ -lScePower_stub -lSceRtc_stub -lSceCommonDialog_stub -lScePgf_stub -lSceMotion_stub \ - -lSceFiber_stub -lSceMotion_stub -lSceAppMgr_stub -lstdc++ -lpthread -lpng -lz -lvitaGL -lvitashark -lSceShaccCg_stub + -lSceFiber_stub -lSceMotion_stub -lSceAppMgr_stub -lpthread -lpng -lz -lvitaGL -lvitashark -lSceShaccCg_stub LIBS := $(WHOLE_START) -lretro_vita $(WHOLE_END) $(VITA_LIBS) -lm -lc