merge latest rthreads.c from libretro-common, and improve sthread_isself to null check argument (fixes crash in winport's single-core codepaths when lua window is open)

This commit is contained in:
zeromus 2017-01-09 16:50:44 -06:00
parent 9c573370f3
commit 522a4e25d1
1 changed files with 626 additions and 572 deletions

View File

@ -43,11 +43,18 @@
#include "gx_pthread.h"
#elif defined(PSP)
#include "psp_pthread.h"
#elif defined(__CELLOS_LV2__)
#include <pthread.h>
#include <sys/sys_time.h>
#else
#include <pthread.h>
#include <time.h>
#endif
#if defined(VITA)
#include <sys/time.h>
#endif
#ifdef __MACH__
#include <mach/clock.h>
#include <mach/mach.h>
@ -154,8 +161,15 @@ sthread_t *sthread_create(void (*thread_func)(void*), void *userdata)
#ifdef USE_WIN32_THREADS
thread->thread = CreateThread(NULL, 0, thread_wrap, data, 0, NULL);
thread_created = !!thread->thread;
#else
#if defined(VITA)
pthread_attr_t thread_attr;
pthread_attr_init(&thread_attr);
pthread_attr_setstacksize(&thread_attr , 0x10000 );
thread_created = pthread_create(&thread->id, &thread_attr, thread_wrap, data) == 0;
#else
thread_created = pthread_create(&thread->id, NULL, thread_wrap, data) == 0;
#endif
#endif
if (!thread_created)
@ -218,15 +232,13 @@ void sthread_join(sthread_t *thread)
* sthread_isself:
* @thread : pointer to thread object
*
* Join with a terminated thread. Waits for the thread specified by
* @thread to terminate. If that thread has already terminated, then
* it will return immediately. The thread specified by @thread must
* be joinable.
*
* Returns: true (1) if calling thread is the specified thread
*/
bool sthread_isself(sthread_t *thread)
{
/* This thread can't possibly be a null thread */
if (!thread) return false;
#ifdef USE_WIN32_THREADS
return GetCurrentThread() == thread->thread;
#else
@ -295,6 +307,8 @@ void slock_free(slock_t *lock)
**/
void slock_lock(slock_t *lock)
{
if (!lock)
return;
#ifdef USE_WIN32_THREADS
WaitForSingleObject(lock->lock, INFINITE);
#else
@ -310,6 +324,8 @@ void slock_lock(slock_t *lock)
**/
void slock_unlock(slock_t *lock)
{
if (!lock)
return;
#ifdef USE_WIN32_THREADS
ReleaseMutex(lock->lock);
#else
@ -547,7 +563,7 @@ bool scond_wait_timeout(scond_t *cond, slock_t *lock, int64_t timeout_us)
sys_time_get_current_time(&s, &n);
now.tv_sec = s;
now.tv_nsec = n;
#elif defined(__mips__)
#elif defined(__mips__) || defined(VITA)
struct timeval tm;
gettimeofday(&tm, NULL);
@ -570,3 +586,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((pthread_key_t*)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