Merge pull request #3821 from heuripedes/tls

Add TLS support
This commit is contained in:
Twinaphex 2016-10-18 02:26:52 +02:00 committed by GitHub
commit 5c938320ed
7 changed files with 120 additions and 4 deletions

View File

@ -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

View File

@ -36,6 +36,10 @@ 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:
* @start_routine : thread entry callback function
@ -178,6 +182,48 @@ int scond_broadcast(scond_t *cond);
**/
void scond_signal(scond_t *cond);
#ifdef HAVE_THREAD_STORAGE
/**
* @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);
#endif
RETRO_END_DECLS
#endif

View File

@ -474,3 +474,41 @@ bool scond_wait_timeout(scond_t *cond, slock_t *lock, int64_t timeout_us)
return (ret == 0);
#endif
}
#ifdef HAVE_THREAD_STORAGE
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
}
#endif

View File

@ -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

View File

@ -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

View File

@ -42,7 +42,7 @@
#include <retro_stat.h>
#include <retro_assert.h>
#include <retro_miscellaneous.h>
#include <rthreads/rthreads.h>
#include <features/features_cpu.h>
#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_THREAD_STORAGE
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_THREAD_STORAGE
sthread_tls_delete(&rarch_tls);
#endif
break;
case RARCH_CTL_INIT:
rarch_ctl(RARCH_CTL_DEINIT, NULL);
#ifdef HAVE_THREAD_STORAGE
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_THREAD_STORAGE
return sthread_tls_get(&rarch_tls) == MAGIC_POINTER;
#else
return true;
#endif
case RARCH_CTL_NONE:
default:
return false;

View File

@ -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