From 471ff4a9998aed7b5b9a25217d35c458b1f86d2f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Higor=20Eur=C3=ADpedes?= Date: Mon, 17 Oct 2016 20:49:37 -0300 Subject: [PATCH 1/3] (libretro-common) Add thread local storage --- libretro-common/include/rthreads/rthreads.h | 41 +++++++++++++++++++++ libretro-common/rthreads/rthreads.c | 36 ++++++++++++++++++ 2 files changed, 77 insertions(+) diff --git a/libretro-common/include/rthreads/rthreads.h b/libretro-common/include/rthreads/rthreads.h index a960d7f8ec..86d1fde8b0 100644 --- a/libretro-common/include/rthreads/rthreads.h +++ b/libretro-common/include/rthreads/rthreads.h @@ -35,6 +35,7 @@ RETRO_BEGIN_DECLS typedef struct sthread sthread_t; typedef struct slock slock_t; typedef struct scond scond_t; +typedef unsigned sthread_tls_t; /** * sthread_create: @@ -178,6 +179,46 @@ int scond_broadcast(scond_t *cond); **/ void scond_signal(scond_t *cond); +/** + * @brief Creates a thread local storage key + * + * This function shall create thread-specific data key visible to all threads in + * the process. The same key can be used by multiple threads to store + * thread-local data. + * + * When the key is created NULL shall be associated with it in all active + * threads. Whenever a new thread is spawned the all defined keys will be + * associated with NULL on that thread. + * + * @param tls + * @return whether the operation suceeded or not + */ +bool sthread_tls_create(sthread_tls_t *tls); + +/** + * @brief Deletes a thread local storage + * @param tls + * @return whether the operation suceeded or not + */ +bool sthread_tls_delete(sthread_tls_t *tls); + +/** + * @brief Retrieves thread specific data associated with a key + * + * There is no way to tell whether this function failed. + * + * @param tls + * @return + */ +void *sthread_tls_get(sthread_tls_t *tls); + +/** + * @brief Binds thread specific data to a key + * @param tls + * @return whether the operation suceeded or not + */ +bool sthread_tls_set(sthread_tls_t *tls, const void *data); + RETRO_END_DECLS #endif diff --git a/libretro-common/rthreads/rthreads.c b/libretro-common/rthreads/rthreads.c index 1c17d650b7..aca3bd1e88 100644 --- a/libretro-common/rthreads/rthreads.c +++ b/libretro-common/rthreads/rthreads.c @@ -474,3 +474,39 @@ bool scond_wait_timeout(scond_t *cond, slock_t *lock, int64_t timeout_us) return (ret == 0); #endif } + +bool sthread_tls_create(sthread_tls_t *tls) +{ +#ifdef USE_WIN32_THREADS + return (*tls = TlsAlloc()) != TLS_OUT_OF_INDEXES; +#else + return pthread_key_create(tls, NULL) == 0; +#endif +} + +bool sthread_tls_delete(sthread_tls_t *tls) +{ +#ifdef USE_WIN32_THREADS + return TlsFree(*tls) != 0; +#else + return pthread_key_delete(*tls) == 0; +#endif +} + +void *sthread_tls_get(sthread_tls_t *tls) +{ +#ifdef USE_WIN32_THREADS + return TlsGetValue(*tls); +#else + return pthread_getspecific(*tls); +#endif +} + +bool sthread_tls_set(sthread_tls_t *tls, const void *data) +{ +#ifdef USE_WIN32_THREADS + return TlsSetValue(*tls, (void*)data) != 0; +#else + return pthread_setspecific(*tls, data) == 0; +#endif +} From dd36cff1745f90eb566ecd6362b07280d5f9b69e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Higor=20Eur=C3=ADpedes?= Date: Mon, 17 Oct 2016 20:50:19 -0300 Subject: [PATCH 2/3] (retroarch.c) Add RARCH_CTL_IS_MAIN_THREAD --- retroarch.c | 20 +++++++++++++++++++- retroarch.h | 3 ++- 2 files changed, 21 insertions(+), 2 deletions(-) diff --git a/retroarch.c b/retroarch.c index f544a67ff2..558172462b 100644 --- a/retroarch.c +++ b/retroarch.c @@ -42,7 +42,7 @@ #include #include #include - +#include #include #ifdef HAVE_CONFIG_H @@ -1108,6 +1108,10 @@ bool rarch_ctl(enum rarch_ctl_state state, void *data) static bool rarch_ips_pref = false; static bool rarch_patch_blocked = false; settings_t *settings = config_get_ptr(); +#ifdef HAVE_THREADS + static sthread_tls_t rarch_tls; + const void *MAGIC_POINTER = (void*)0xB16B00B5; +#endif switch(state) { @@ -1218,9 +1222,17 @@ bool rarch_ctl(enum rarch_ctl_state state, void *data) path_deinit_savefile(); rarch_ctl(RARCH_CTL_UNSET_INITED, NULL); + +#ifdef HAVE_THREADS + sthread_tls_delete(&rarch_tls); +#endif break; case RARCH_CTL_INIT: rarch_ctl(RARCH_CTL_DEINIT, NULL); +#ifdef HAVE_THREADS + sthread_tls_create(&rarch_tls); + sthread_tls_set(&rarch_tls, MAGIC_POINTER); +#endif retroarch_init_state(); { unsigned i; @@ -1306,6 +1318,12 @@ bool rarch_ctl(enum rarch_ctl_state state, void *data) command_event(CMD_EVENT_OVERLAY_INIT, NULL); #endif break; + case RARCH_CTL_IS_MAIN_THREAD: +#ifdef HAVE_THREADS + return sthread_tls_get(&rarch_tls) == MAGIC_POINTER; +#else + return true; +#endif case RARCH_CTL_NONE: default: return false; diff --git a/retroarch.h b/retroarch.h index e8fb374033..15799c69fd 100644 --- a/retroarch.h +++ b/retroarch.h @@ -106,8 +106,9 @@ enum rarch_ctl_state /* Username */ RARCH_CTL_HAS_SET_USERNAME, RARCH_CTL_USERNAME_SET, - RARCH_CTL_USERNAME_UNSET + RARCH_CTL_USERNAME_UNSET, + RARCH_CTL_IS_MAIN_THREAD }; enum rarch_capabilities From 330a8d7594d262750c0801cc1379748c47367848 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Higor=20Eur=C3=ADpedes?= Date: Mon, 17 Oct 2016 21:21:51 -0300 Subject: [PATCH 3/3] Make thread local storage optional --- Makefile.common | 6 +++++- libretro-common/include/rthreads/rthreads.h | 5 +++++ libretro-common/rthreads/rthreads.c | 2 ++ qb/config.libs.sh | 8 ++++++++ qb/config.params.sh | 3 ++- retroarch.c | 8 ++++---- 6 files changed, 26 insertions(+), 6 deletions(-) diff --git a/Makefile.common b/Makefile.common index 76ed5fe6af..b04e7e22dc 100644 --- a/Makefile.common +++ b/Makefile.common @@ -575,6 +575,10 @@ ifeq ($(HAVE_THREADS), 1) endif endif +ifeq ($(HAVE_THREAD_STORAGE), 1) + DEFINES += -DHAVE_THREAD_STORAGE +endif + ifeq ($(HAVE_WAYLAND), 1) OBJ += gfx/drivers_context/wayland_ctx.o DEFINES += $(WAYLAND_CFLAGS) @@ -1064,7 +1068,7 @@ OBJ += $(ZLIB_OBJS) endif endif -# Video4Linux 2 +# Video4Linux 2 ifeq ($(HAVE_V4L2),1) OBJ += camera/drivers/video4linux2.o diff --git a/libretro-common/include/rthreads/rthreads.h b/libretro-common/include/rthreads/rthreads.h index 86d1fde8b0..9af41fd301 100644 --- a/libretro-common/include/rthreads/rthreads.h +++ b/libretro-common/include/rthreads/rthreads.h @@ -35,7 +35,10 @@ RETRO_BEGIN_DECLS typedef struct sthread sthread_t; typedef struct slock slock_t; typedef struct scond scond_t; + +#ifdef HAVE_THREAD_STORAGE typedef unsigned sthread_tls_t; +#endif /** * sthread_create: @@ -179,6 +182,7 @@ int scond_broadcast(scond_t *cond); **/ void scond_signal(scond_t *cond); +#ifdef HAVE_THREAD_STORAGE /** * @brief Creates a thread local storage key * @@ -218,6 +222,7 @@ void *sthread_tls_get(sthread_tls_t *tls); * @return whether the operation suceeded or not */ bool sthread_tls_set(sthread_tls_t *tls, const void *data); +#endif RETRO_END_DECLS diff --git a/libretro-common/rthreads/rthreads.c b/libretro-common/rthreads/rthreads.c index aca3bd1e88..f8ea548be9 100644 --- a/libretro-common/rthreads/rthreads.c +++ b/libretro-common/rthreads/rthreads.c @@ -475,6 +475,7 @@ bool scond_wait_timeout(scond_t *cond, slock_t *lock, int64_t timeout_us) #endif } +#ifdef HAVE_THREAD_STORAGE bool sthread_tls_create(sthread_tls_t *tls) { #ifdef USE_WIN32_THREADS @@ -510,3 +511,4 @@ bool sthread_tls_set(sthread_tls_t *tls, const void *data) return pthread_setspecific(*tls, data) == 0; #endif } +#endif diff --git a/qb/config.libs.sh b/qb/config.libs.sh index 3cf24ece08..c60c9a0218 100644 --- a/qb/config.libs.sh +++ b/qb/config.libs.sh @@ -150,9 +150,17 @@ fi if [ "$OS" = 'Win32' ]; then HAVE_THREADS=yes + HAVE_THREAD_STORAGE=yes HAVE_DYLIB=yes else check_lib THREADS "$PTHREADLIB" pthread_create + + if [ "$HAVE_THREADS" = 'yes' ]; then + check_lib THREAD_STORAGE "$PTHREADLIB" pthread_key_create + else + HAVE_THREAD_STORAGE=no + fi + check_lib DYLIB "$DYLIB" dlopen fi diff --git a/qb/config.params.sh b/qb/config.params.sh index a5d1d57481..61d5a41861 100644 --- a/qb/config.params.sh +++ b/qb/config.params.sh @@ -1,6 +1,6 @@ HAVE_LIBRETRODB=yes # Libretrodb support HAVE_RGUI=yes # RGUI menu -HAVE_MATERIALUI=auto # MaterialUI menu +HAVE_MATERIALUI=auto # MaterialUI menu HAVE_XMB=auto # XMB menu HAVE_ZARCH=no # Zarch menu HAVE_NUKLEAR=no # Nuklear menu @@ -20,6 +20,7 @@ HAVE_MAN_DIR= # Manpage install directory HAVE_OPENGLES_LIBS= # Link flags for custom GLES library HAVE_OPENGLES_CFLAGS= # C-flags for custom GLES library HAVE_THREADS=auto # Threading support +HAVE_THREAD_STORAGE=auto # Thread Local Storage support HAVE_FFMPEG=auto # FFmpeg recording support C89_FFMPEG=no HAVE_SSA=auto # SSA/ASS for FFmpeg subtitle support diff --git a/retroarch.c b/retroarch.c index 558172462b..2c8effecb5 100644 --- a/retroarch.c +++ b/retroarch.c @@ -1108,7 +1108,7 @@ bool rarch_ctl(enum rarch_ctl_state state, void *data) static bool rarch_ips_pref = false; static bool rarch_patch_blocked = false; settings_t *settings = config_get_ptr(); -#ifdef HAVE_THREADS +#ifdef HAVE_THREAD_STORAGE static sthread_tls_t rarch_tls; const void *MAGIC_POINTER = (void*)0xB16B00B5; #endif @@ -1223,13 +1223,13 @@ bool rarch_ctl(enum rarch_ctl_state state, void *data) rarch_ctl(RARCH_CTL_UNSET_INITED, NULL); -#ifdef HAVE_THREADS +#ifdef HAVE_THREAD_STORAGE sthread_tls_delete(&rarch_tls); #endif break; case RARCH_CTL_INIT: rarch_ctl(RARCH_CTL_DEINIT, NULL); -#ifdef HAVE_THREADS +#ifdef HAVE_THREAD_STORAGE sthread_tls_create(&rarch_tls); sthread_tls_set(&rarch_tls, MAGIC_POINTER); #endif @@ -1319,7 +1319,7 @@ bool rarch_ctl(enum rarch_ctl_state state, void *data) #endif break; case RARCH_CTL_IS_MAIN_THREAD: -#ifdef HAVE_THREADS +#ifdef HAVE_THREAD_STORAGE return sthread_tls_get(&rarch_tls) == MAGIC_POINTER; #else return true;