summaryrefslogtreecommitdiff
path: root/source/3rd-party/SDL2/src/thread/pthread
diff options
context:
space:
mode:
Diffstat (limited to 'source/3rd-party/SDL2/src/thread/pthread')
-rw-r--r--source/3rd-party/SDL2/src/thread/pthread/SDL_syscond.c158
-rw-r--r--source/3rd-party/SDL2/src/thread/pthread/SDL_sysmutex.c195
-rw-r--r--source/3rd-party/SDL2/src/thread/pthread/SDL_sysmutex_c.h32
-rw-r--r--source/3rd-party/SDL2/src/thread/pthread/SDL_syssem.c209
-rw-r--r--source/3rd-party/SDL2/src/thread/pthread/SDL_systhread.c324
-rw-r--r--source/3rd-party/SDL2/src/thread/pthread/SDL_systhread_c.h27
-rw-r--r--source/3rd-party/SDL2/src/thread/pthread/SDL_systls.c70
7 files changed, 1015 insertions, 0 deletions
diff --git a/source/3rd-party/SDL2/src/thread/pthread/SDL_syscond.c b/source/3rd-party/SDL2/src/thread/pthread/SDL_syscond.c
new file mode 100644
index 0000000..d235780
--- /dev/null
+++ b/source/3rd-party/SDL2/src/thread/pthread/SDL_syscond.c
@@ -0,0 +1,158 @@
+/*
+ Simple DirectMedia Layer
+ Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
+
+ This software is provided 'as-is', without any express or implied
+ warranty. In no event will the authors be held liable for any damages
+ arising from the use of this software.
+
+ Permission is granted to anyone to use this software for any purpose,
+ including commercial applications, and to alter it and redistribute it
+ freely, subject to the following restrictions:
+
+ 1. The origin of this software must not be misrepresented; you must not
+ claim that you wrote the original software. If you use this software
+ in a product, an acknowledgment in the product documentation would be
+ appreciated but is not required.
+ 2. Altered source versions must be plainly marked as such, and must not be
+ misrepresented as being the original software.
+ 3. This notice may not be removed or altered from any source distribution.
+*/
+#include "../../SDL_internal.h"
+
+#include <sys/time.h>
+#include <time.h>
+#include <unistd.h>
+#include <errno.h>
+#include <pthread.h>
+
+#include "SDL_thread.h"
+#include "SDL_sysmutex_c.h"
+
+struct SDL_cond
+{
+ pthread_cond_t cond;
+};
+
+/* Create a condition variable */
+SDL_cond *
+SDL_CreateCond(void)
+{
+ SDL_cond *cond;
+
+ cond = (SDL_cond *) SDL_malloc(sizeof(SDL_cond));
+ if (cond) {
+ if (pthread_cond_init(&cond->cond, NULL) != 0) {
+ SDL_SetError("pthread_cond_init() failed");
+ SDL_free(cond);
+ cond = NULL;
+ }
+ }
+ return (cond);
+}
+
+/* Destroy a condition variable */
+void
+SDL_DestroyCond(SDL_cond * cond)
+{
+ if (cond) {
+ pthread_cond_destroy(&cond->cond);
+ SDL_free(cond);
+ }
+}
+
+/* Restart one of the threads that are waiting on the condition variable */
+int
+SDL_CondSignal(SDL_cond * cond)
+{
+ int retval;
+
+ if (!cond) {
+ return SDL_SetError("Passed a NULL condition variable");
+ }
+
+ retval = 0;
+ if (pthread_cond_signal(&cond->cond) != 0) {
+ return SDL_SetError("pthread_cond_signal() failed");
+ }
+ return retval;
+}
+
+/* Restart all threads that are waiting on the condition variable */
+int
+SDL_CondBroadcast(SDL_cond * cond)
+{
+ int retval;
+
+ if (!cond) {
+ return SDL_SetError("Passed a NULL condition variable");
+ }
+
+ retval = 0;
+ if (pthread_cond_broadcast(&cond->cond) != 0) {
+ return SDL_SetError("pthread_cond_broadcast() failed");
+ }
+ return retval;
+}
+
+int
+SDL_CondWaitTimeout(SDL_cond * cond, SDL_mutex * mutex, Uint32 ms)
+{
+ int retval;
+#ifndef HAVE_CLOCK_GETTIME
+ struct timeval delta;
+#endif
+ struct timespec abstime;
+
+ if (!cond) {
+ return SDL_SetError("Passed a NULL condition variable");
+ }
+
+#ifdef HAVE_CLOCK_GETTIME
+ clock_gettime(CLOCK_REALTIME, &abstime);
+
+ abstime.tv_nsec += (ms % 1000) * 1000000;
+ abstime.tv_sec += ms / 1000;
+#else
+ gettimeofday(&delta, NULL);
+
+ abstime.tv_sec = delta.tv_sec + (ms / 1000);
+ abstime.tv_nsec = (delta.tv_usec + (ms % 1000) * 1000) * 1000;
+#endif
+ if (abstime.tv_nsec > 1000000000) {
+ abstime.tv_sec += 1;
+ abstime.tv_nsec -= 1000000000;
+ }
+
+ tryagain:
+ retval = pthread_cond_timedwait(&cond->cond, &mutex->id, &abstime);
+ switch (retval) {
+ case EINTR:
+ goto tryagain;
+ /* break; -Wunreachable-code-break */
+ case ETIMEDOUT:
+ retval = SDL_MUTEX_TIMEDOUT;
+ break;
+ case 0:
+ break;
+ default:
+ retval = SDL_SetError("pthread_cond_timedwait() failed");
+ }
+ return retval;
+}
+
+/* Wait on the condition variable, unlocking the provided mutex.
+ The mutex must be locked before entering this function!
+ */
+int
+SDL_CondWait(SDL_cond * cond, SDL_mutex * mutex)
+{
+ if (!cond) {
+ return SDL_SetError("Passed a NULL condition variable");
+ } else if (pthread_cond_wait(&cond->cond, &mutex->id) != 0) {
+ return SDL_SetError("pthread_cond_wait() failed");
+ }
+ return 0;
+}
+
+/* vi: set ts=4 sw=4 expandtab: */
diff --git a/source/3rd-party/SDL2/src/thread/pthread/SDL_sysmutex.c b/source/3rd-party/SDL2/src/thread/pthread/SDL_sysmutex.c
new file mode 100644
index 0000000..e514778
--- /dev/null
+++ b/source/3rd-party/SDL2/src/thread/pthread/SDL_sysmutex.c
@@ -0,0 +1,195 @@
+/*
+ Simple DirectMedia Layer
+ Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
+
+ This software is provided 'as-is', without any express or implied
+ warranty. In no event will the authors be held liable for any damages
+ arising from the use of this software.
+
+ Permission is granted to anyone to use this software for any purpose,
+ including commercial applications, and to alter it and redistribute it
+ freely, subject to the following restrictions:
+
+ 1. The origin of this software must not be misrepresented; you must not
+ claim that you wrote the original software. If you use this software
+ in a product, an acknowledgment in the product documentation would be
+ appreciated but is not required.
+ 2. Altered source versions must be plainly marked as such, and must not be
+ misrepresented as being the original software.
+ 3. This notice may not be removed or altered from any source distribution.
+*/
+#include "../../SDL_internal.h"
+
+#include <errno.h>
+#include <pthread.h>
+
+#include "SDL_thread.h"
+
+#if !SDL_THREAD_PTHREAD_RECURSIVE_MUTEX && \
+ !SDL_THREAD_PTHREAD_RECURSIVE_MUTEX_NP
+#define FAKE_RECURSIVE_MUTEX 1
+#endif
+
+struct SDL_mutex
+{
+ pthread_mutex_t id;
+#if FAKE_RECURSIVE_MUTEX
+ int recursive;
+ pthread_t owner;
+#endif
+};
+
+SDL_mutex *
+SDL_CreateMutex(void)
+{
+ SDL_mutex *mutex;
+ pthread_mutexattr_t attr;
+
+ /* Allocate the structure */
+ mutex = (SDL_mutex *) SDL_calloc(1, sizeof(*mutex));
+ if (mutex) {
+ pthread_mutexattr_init(&attr);
+#if SDL_THREAD_PTHREAD_RECURSIVE_MUTEX
+ pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE);
+#elif SDL_THREAD_PTHREAD_RECURSIVE_MUTEX_NP
+ pthread_mutexattr_setkind_np(&attr, PTHREAD_MUTEX_RECURSIVE_NP);
+#else
+ /* No extra attributes necessary */
+#endif
+ if (pthread_mutex_init(&mutex->id, &attr) != 0) {
+ SDL_SetError("pthread_mutex_init() failed");
+ SDL_free(mutex);
+ mutex = NULL;
+ }
+ } else {
+ SDL_OutOfMemory();
+ }
+ return (mutex);
+}
+
+void
+SDL_DestroyMutex(SDL_mutex * mutex)
+{
+ if (mutex) {
+ pthread_mutex_destroy(&mutex->id);
+ SDL_free(mutex);
+ }
+}
+
+/* Lock the mutex */
+int
+SDL_LockMutex(SDL_mutex * mutex)
+{
+#if FAKE_RECURSIVE_MUTEX
+ pthread_t this_thread;
+#endif
+
+ if (mutex == NULL) {
+ return SDL_SetError("Passed a NULL mutex");
+ }
+
+#if FAKE_RECURSIVE_MUTEX
+ this_thread = pthread_self();
+ if (mutex->owner == this_thread) {
+ ++mutex->recursive;
+ } else {
+ /* The order of operations is important.
+ We set the locking thread id after we obtain the lock
+ so unlocks from other threads will fail.
+ */
+ if (pthread_mutex_lock(&mutex->id) == 0) {
+ mutex->owner = this_thread;
+ mutex->recursive = 0;
+ } else {
+ return SDL_SetError("pthread_mutex_lock() failed");
+ }
+ }
+#else
+ if (pthread_mutex_lock(&mutex->id) != 0) {
+ return SDL_SetError("pthread_mutex_lock() failed");
+ }
+#endif
+ return 0;
+}
+
+int
+SDL_TryLockMutex(SDL_mutex * mutex)
+{
+ int retval;
+ int result;
+#if FAKE_RECURSIVE_MUTEX
+ pthread_t this_thread;
+#endif
+
+ if (mutex == NULL) {
+ return SDL_SetError("Passed a NULL mutex");
+ }
+
+ retval = 0;
+#if FAKE_RECURSIVE_MUTEX
+ this_thread = pthread_self();
+ if (mutex->owner == this_thread) {
+ ++mutex->recursive;
+ } else {
+ /* The order of operations is important.
+ We set the locking thread id after we obtain the lock
+ so unlocks from other threads will fail.
+ */
+ result = pthread_mutex_trylock(&mutex->id);
+ if (result == 0) {
+ mutex->owner = this_thread;
+ mutex->recursive = 0;
+ } else if (result == EBUSY) {
+ retval = SDL_MUTEX_TIMEDOUT;
+ } else {
+ retval = SDL_SetError("pthread_mutex_trylock() failed");
+ }
+ }
+#else
+ result = pthread_mutex_trylock(&mutex->id);
+ if (result != 0) {
+ if (result == EBUSY) {
+ retval = SDL_MUTEX_TIMEDOUT;
+ } else {
+ retval = SDL_SetError("pthread_mutex_trylock() failed");
+ }
+ }
+#endif
+ return retval;
+}
+
+int
+SDL_UnlockMutex(SDL_mutex * mutex)
+{
+ if (mutex == NULL) {
+ return SDL_SetError("Passed a NULL mutex");
+ }
+
+#if FAKE_RECURSIVE_MUTEX
+ /* We can only unlock the mutex if we own it */
+ if (pthread_self() == mutex->owner) {
+ if (mutex->recursive) {
+ --mutex->recursive;
+ } else {
+ /* The order of operations is important.
+ First reset the owner so another thread doesn't lock
+ the mutex and set the ownership before we reset it,
+ then release the lock semaphore.
+ */
+ mutex->owner = 0;
+ pthread_mutex_unlock(&mutex->id);
+ }
+ } else {
+ return SDL_SetError("mutex not owned by this thread");
+ }
+
+#else
+ if (pthread_mutex_unlock(&mutex->id) != 0) {
+ return SDL_SetError("pthread_mutex_unlock() failed");
+ }
+#endif /* FAKE_RECURSIVE_MUTEX */
+
+ return 0;
+}
+
+/* vi: set ts=4 sw=4 expandtab: */
diff --git a/source/3rd-party/SDL2/src/thread/pthread/SDL_sysmutex_c.h b/source/3rd-party/SDL2/src/thread/pthread/SDL_sysmutex_c.h
new file mode 100644
index 0000000..27ac1da
--- /dev/null
+++ b/source/3rd-party/SDL2/src/thread/pthread/SDL_sysmutex_c.h
@@ -0,0 +1,32 @@
+/*
+ Simple DirectMedia Layer
+ Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
+
+ This software is provided 'as-is', without any express or implied
+ warranty. In no event will the authors be held liable for any damages
+ arising from the use of this software.
+
+ Permission is granted to anyone to use this software for any purpose,
+ including commercial applications, and to alter it and redistribute it
+ freely, subject to the following restrictions:
+
+ 1. The origin of this software must not be misrepresented; you must not
+ claim that you wrote the original software. If you use this software
+ in a product, an acknowledgment in the product documentation would be
+ appreciated but is not required.
+ 2. Altered source versions must be plainly marked as such, and must not be
+ misrepresented as being the original software.
+ 3. This notice may not be removed or altered from any source distribution.
+*/
+#include "../../SDL_internal.h"
+
+#ifndef SDL_mutex_c_h_
+#define SDL_mutex_c_h_
+
+struct SDL_mutex
+{
+ pthread_mutex_t id;
+};
+
+#endif /* SDL_mutex_c_h_ */
+/* vi: set ts=4 sw=4 expandtab: */
diff --git a/source/3rd-party/SDL2/src/thread/pthread/SDL_syssem.c b/source/3rd-party/SDL2/src/thread/pthread/SDL_syssem.c
new file mode 100644
index 0000000..bdebf13
--- /dev/null
+++ b/source/3rd-party/SDL2/src/thread/pthread/SDL_syssem.c
@@ -0,0 +1,209 @@
+/*
+ Simple DirectMedia Layer
+ Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
+
+ This software is provided 'as-is', without any express or implied
+ warranty. In no event will the authors be held liable for any damages
+ arising from the use of this software.
+
+ Permission is granted to anyone to use this software for any purpose,
+ including commercial applications, and to alter it and redistribute it
+ freely, subject to the following restrictions:
+
+ 1. The origin of this software must not be misrepresented; you must not
+ claim that you wrote the original software. If you use this software
+ in a product, an acknowledgment in the product documentation would be
+ appreciated but is not required.
+ 2. Altered source versions must be plainly marked as such, and must not be
+ misrepresented as being the original software.
+ 3. This notice may not be removed or altered from any source distribution.
+*/
+#include "../../SDL_internal.h"
+
+#include <errno.h>
+#include <pthread.h>
+#include <semaphore.h>
+#include <sys/time.h>
+#include <time.h>
+
+#include "SDL_thread.h"
+#include "SDL_timer.h"
+
+/* Wrapper around POSIX 1003.1b semaphores */
+
+#if defined(__MACOSX__) || defined(__IPHONEOS__)
+/* Mac OS X doesn't support sem_getvalue() as of version 10.4 */
+#include "../generic/SDL_syssem.c"
+#else
+
+struct SDL_semaphore
+{
+ sem_t sem;
+};
+
+/* Create a semaphore, initialized with value */
+SDL_sem *
+SDL_CreateSemaphore(Uint32 initial_value)
+{
+ SDL_sem *sem = (SDL_sem *) SDL_malloc(sizeof(SDL_sem));
+ if (sem) {
+ if (sem_init(&sem->sem, 0, initial_value) < 0) {
+ SDL_SetError("sem_init() failed");
+ SDL_free(sem);
+ sem = NULL;
+ }
+ } else {
+ SDL_OutOfMemory();
+ }
+ return sem;
+}
+
+void
+SDL_DestroySemaphore(SDL_sem * sem)
+{
+ if (sem) {
+ sem_destroy(&sem->sem);
+ SDL_free(sem);
+ }
+}
+
+int
+SDL_SemTryWait(SDL_sem * sem)
+{
+ int retval;
+
+ if (!sem) {
+ return SDL_SetError("Passed a NULL semaphore");
+ }
+ retval = SDL_MUTEX_TIMEDOUT;
+ if (sem_trywait(&sem->sem) == 0) {
+ retval = 0;
+ }
+ return retval;
+}
+
+int
+SDL_SemWait(SDL_sem * sem)
+{
+ int retval;
+
+ if (!sem) {
+ return SDL_SetError("Passed a NULL semaphore");
+ }
+
+ do {
+ retval = sem_wait(&sem->sem);
+ } while (retval < 0 && errno == EINTR);
+
+ if (retval < 0) {
+ retval = SDL_SetError("sem_wait() failed");
+ }
+ return retval;
+}
+
+int
+SDL_SemWaitTimeout(SDL_sem * sem, Uint32 timeout)
+{
+ int retval;
+#ifdef HAVE_SEM_TIMEDWAIT
+#ifndef HAVE_CLOCK_GETTIME
+ struct timeval now;
+#endif
+ struct timespec ts_timeout;
+#else
+ Uint32 end;
+#endif
+
+ if (!sem) {
+ return SDL_SetError("Passed a NULL semaphore");
+ }
+
+ /* Try the easy cases first */
+ if (timeout == 0) {
+ return SDL_SemTryWait(sem);
+ }
+ if (timeout == SDL_MUTEX_MAXWAIT) {
+ return SDL_SemWait(sem);
+ }
+
+#ifdef HAVE_SEM_TIMEDWAIT
+ /* Setup the timeout. sem_timedwait doesn't wait for
+ * a lapse of time, but until we reach a certain time.
+ * This time is now plus the timeout.
+ */
+#ifdef HAVE_CLOCK_GETTIME
+ clock_gettime(CLOCK_REALTIME, &ts_timeout);
+
+ /* Add our timeout to current time */
+ ts_timeout.tv_nsec += (timeout % 1000) * 1000000;
+ ts_timeout.tv_sec += timeout / 1000;
+#else
+ gettimeofday(&now, NULL);
+
+ /* Add our timeout to current time */
+ ts_timeout.tv_sec = now.tv_sec + (timeout / 1000);
+ ts_timeout.tv_nsec = (now.tv_usec + (timeout % 1000) * 1000) * 1000;
+#endif
+
+ /* Wrap the second if needed */
+ if (ts_timeout.tv_nsec > 1000000000) {
+ ts_timeout.tv_sec += 1;
+ ts_timeout.tv_nsec -= 1000000000;
+ }
+
+ /* Wait. */
+ do {
+ retval = sem_timedwait(&sem->sem, &ts_timeout);
+ } while (retval < 0 && errno == EINTR);
+
+ if (retval < 0) {
+ if (errno == ETIMEDOUT) {
+ retval = SDL_MUTEX_TIMEDOUT;
+ } else {
+ SDL_SetError("sem_timedwait returned an error: %s", strerror(errno));
+ }
+ }
+#else
+ end = SDL_GetTicks() + timeout;
+ while ((retval = SDL_SemTryWait(sem)) == SDL_MUTEX_TIMEDOUT) {
+ if (SDL_TICKS_PASSED(SDL_GetTicks(), end)) {
+ break;
+ }
+ SDL_Delay(1);
+ }
+#endif /* HAVE_SEM_TIMEDWAIT */
+
+ return retval;
+}
+
+Uint32
+SDL_SemValue(SDL_sem * sem)
+{
+ int ret = 0;
+ if (sem) {
+ sem_getvalue(&sem->sem, &ret);
+ if (ret < 0) {
+ ret = 0;
+ }
+ }
+ return (Uint32) ret;
+}
+
+int
+SDL_SemPost(SDL_sem * sem)
+{
+ int retval;
+
+ if (!sem) {
+ return SDL_SetError("Passed a NULL semaphore");
+ }
+
+ retval = sem_post(&sem->sem);
+ if (retval < 0) {
+ SDL_SetError("sem_post() failed");
+ }
+ return retval;
+}
+
+#endif /* __MACOSX__ */
+/* vi: set ts=4 sw=4 expandtab: */
diff --git a/source/3rd-party/SDL2/src/thread/pthread/SDL_systhread.c b/source/3rd-party/SDL2/src/thread/pthread/SDL_systhread.c
new file mode 100644
index 0000000..ec32937
--- /dev/null
+++ b/source/3rd-party/SDL2/src/thread/pthread/SDL_systhread.c
@@ -0,0 +1,324 @@
+/*
+ Simple DirectMedia Layer
+ Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
+
+ This software is provided 'as-is', without any express or implied
+ warranty. In no event will the authors be held liable for any damages
+ arising from the use of this software.
+
+ Permission is granted to anyone to use this software for any purpose,
+ including commercial applications, and to alter it and redistribute it
+ freely, subject to the following restrictions:
+
+ 1. The origin of this software must not be misrepresented; you must not
+ claim that you wrote the original software. If you use this software
+ in a product, an acknowledgment in the product documentation would be
+ appreciated but is not required.
+ 2. Altered source versions must be plainly marked as such, and must not be
+ misrepresented as being the original software.
+ 3. This notice may not be removed or altered from any source distribution.
+*/
+
+#include "../../SDL_internal.h"
+
+#include <pthread.h>
+
+#if HAVE_PTHREAD_NP_H
+#include <pthread_np.h>
+#endif
+
+#include <signal.h>
+
+#ifdef __LINUX__
+#include <sys/time.h>
+#include <sys/resource.h>
+#include <sys/syscall.h>
+#include <unistd.h>
+#include <errno.h>
+
+#include "../../core/linux/SDL_dbus.h"
+#endif /* __LINUX__ */
+
+#if defined(__LINUX__) || defined(__MACOSX__) || defined(__IPHONEOS__)
+#include <dlfcn.h>
+#ifndef RTLD_DEFAULT
+#define RTLD_DEFAULT NULL
+#endif
+#endif
+
+#include "SDL_log.h"
+#include "SDL_platform.h"
+#include "SDL_thread.h"
+#include "../SDL_thread_c.h"
+#include "../SDL_systhread.h"
+#ifdef __ANDROID__
+#include "../../core/android/SDL_android.h"
+#endif
+
+#ifdef __HAIKU__
+#include <kernel/OS.h>
+#endif
+
+#include "SDL_assert.h"
+
+#ifndef __NACL__
+/* List of signals to mask in the subthreads */
+static const int sig_list[] = {
+ SIGHUP, SIGINT, SIGQUIT, SIGPIPE, SIGALRM, SIGTERM, SIGCHLD, SIGWINCH,
+ SIGVTALRM, SIGPROF, 0
+};
+#endif
+
+static void *
+RunThread(void *data)
+{
+#ifdef __ANDROID__
+ Android_JNI_SetupThread();
+#endif
+ SDL_RunThread(data);
+ return NULL;
+}
+
+#if defined(__MACOSX__) || defined(__IPHONEOS__)
+static SDL_bool checked_setname = SDL_FALSE;
+static int (*ppthread_setname_np)(const char*) = NULL;
+#elif defined(__LINUX__)
+static SDL_bool checked_setname = SDL_FALSE;
+static int (*ppthread_setname_np)(pthread_t, const char*) = NULL;
+#endif
+int
+SDL_SYS_CreateThread(SDL_Thread * thread, void *args)
+{
+ pthread_attr_t type;
+
+ /* do this here before any threads exist, so there's no race condition. */
+ #if defined(__MACOSX__) || defined(__IPHONEOS__) || defined(__LINUX__)
+ if (!checked_setname) {
+ void *fn = dlsym(RTLD_DEFAULT, "pthread_setname_np");
+ #if defined(__MACOSX__) || defined(__IPHONEOS__)
+ ppthread_setname_np = (int(*)(const char*)) fn;
+ #elif defined(__LINUX__)
+ ppthread_setname_np = (int(*)(pthread_t, const char*)) fn;
+ #endif
+ checked_setname = SDL_TRUE;
+ }
+ #endif
+
+ /* Set the thread attributes */
+ if (pthread_attr_init(&type) != 0) {
+ return SDL_SetError("Couldn't initialize pthread attributes");
+ }
+ pthread_attr_setdetachstate(&type, PTHREAD_CREATE_JOINABLE);
+
+ /* Set caller-requested stack size. Otherwise: use the system default. */
+ if (thread->stacksize) {
+ pthread_attr_setstacksize(&type, (size_t) thread->stacksize);
+ }
+
+ /* Create the thread and go! */
+ if (pthread_create(&thread->handle, &type, RunThread, args) != 0) {
+ return SDL_SetError("Not enough resources to create thread");
+ }
+
+ return 0;
+}
+
+void
+SDL_SYS_SetupThread(const char *name)
+{
+#if !defined(__NACL__)
+ int i;
+ sigset_t mask;
+#endif /* !__NACL__ */
+
+ if (name != NULL) {
+ #if defined(__MACOSX__) || defined(__IPHONEOS__) || defined(__LINUX__)
+ SDL_assert(checked_setname);
+ if (ppthread_setname_np != NULL) {
+ #if defined(__MACOSX__) || defined(__IPHONEOS__)
+ ppthread_setname_np(name);
+ #elif defined(__LINUX__)
+ ppthread_setname_np(pthread_self(), name);
+ #endif
+ }
+ #elif HAVE_PTHREAD_SETNAME_NP
+ #if defined(__NETBSD__)
+ pthread_setname_np(pthread_self(), "%s", name);
+ #else
+ pthread_setname_np(pthread_self(), name);
+ #endif
+ #elif HAVE_PTHREAD_SET_NAME_NP
+ pthread_set_name_np(pthread_self(), name);
+ #elif defined(__HAIKU__)
+ /* The docs say the thread name can't be longer than B_OS_NAME_LENGTH. */
+ char namebuf[B_OS_NAME_LENGTH];
+ SDL_snprintf(namebuf, sizeof (namebuf), "%s", name);
+ namebuf[sizeof (namebuf) - 1] = '\0';
+ rename_thread(find_thread(NULL), namebuf);
+ #endif
+ }
+
+ /* NativeClient does not yet support signals.*/
+#if !defined(__NACL__)
+ /* Mask asynchronous signals for this thread */
+ sigemptyset(&mask);
+ for (i = 0; sig_list[i]; ++i) {
+ sigaddset(&mask, sig_list[i]);
+ }
+ pthread_sigmask(SIG_BLOCK, &mask, 0);
+#endif /* !__NACL__ */
+
+
+#ifdef PTHREAD_CANCEL_ASYNCHRONOUS
+ /* Allow ourselves to be asynchronously cancelled */
+ {
+ int oldstate;
+ pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, &oldstate);
+ }
+#endif
+}
+
+SDL_threadID
+SDL_ThreadID(void)
+{
+ return ((SDL_threadID) pthread_self());
+}
+
+#if __LINUX__
+/* d-bus queries to org.freedesktop.RealtimeKit1. */
+#if SDL_USE_LIBDBUS
+
+#define RTKIT_DBUS_NODE "org.freedesktop.RealtimeKit1"
+#define RTKIT_DBUS_PATH "/org/freedesktop/RealtimeKit1"
+#define RTKIT_DBUS_INTERFACE "org.freedesktop.RealtimeKit1"
+
+static pthread_once_t rtkit_initialize_once = PTHREAD_ONCE_INIT;
+static Sint32 rtkit_min_nice_level = -20;
+
+static void
+rtkit_initialize()
+{
+ SDL_DBusContext *dbus = SDL_DBus_GetContext();
+
+ /* Try getting minimum nice level: this is often greater than PRIO_MIN (-20). */
+ if (!dbus || !SDL_DBus_QueryPropertyOnConnection(dbus->system_conn, RTKIT_DBUS_NODE, RTKIT_DBUS_PATH, RTKIT_DBUS_INTERFACE, "MinNiceLevel",
+ DBUS_TYPE_INT32, &rtkit_min_nice_level)) {
+ rtkit_min_nice_level = -20;
+ }
+}
+
+static SDL_bool
+rtkit_setpriority(pid_t thread, int nice_level)
+{
+ Uint64 ui64 = (Uint64)thread;
+ Sint32 si32 = (Sint32)nice_level;
+ SDL_DBusContext *dbus = SDL_DBus_GetContext();
+
+ pthread_once(&rtkit_initialize_once, rtkit_initialize);
+
+ if (si32 < rtkit_min_nice_level)
+ si32 = rtkit_min_nice_level;
+
+ if (!dbus || !SDL_DBus_CallMethodOnConnection(dbus->system_conn,
+ RTKIT_DBUS_NODE, RTKIT_DBUS_PATH, RTKIT_DBUS_INTERFACE, "MakeThreadHighPriority",
+ DBUS_TYPE_UINT64, &ui64, DBUS_TYPE_INT32, &si32, DBUS_TYPE_INVALID,
+ DBUS_TYPE_INVALID)) {
+ return SDL_FALSE;
+ }
+ return SDL_TRUE;
+}
+
+#else
+
+static SDL_bool
+rtkit_setpriority(pid_t thread, int nice_level)
+{
+ return SDL_FALSE;
+}
+
+#endif /* !SDL_USE_LIBDBUS */
+
+int
+SDL_LinuxSetThreadPriority(Sint64 threadID, int priority)
+{
+ if (setpriority(PRIO_PROCESS, (id_t)threadID, priority) < 0) {
+ /* Note that this fails if you're trying to set high priority
+ and you don't have root permission. BUT DON'T RUN AS ROOT!
+
+ You can grant the ability to increase thread priority by
+ running the following command on your application binary:
+ sudo setcap 'cap_sys_nice=eip' <application>
+
+ Let's try setting priority with RealtimeKit...
+
+ README and sample code at:
+ http://git.0pointer.net/rtkit.git
+ */
+ if (rtkit_setpriority((pid_t)threadID, priority) == SDL_FALSE) {
+ return SDL_SetError("setpriority() failed");
+ }
+ }
+ return 0;
+}
+#endif /* __LINUX__ */
+
+int
+SDL_SYS_SetThreadPriority(SDL_ThreadPriority priority)
+{
+#if __NACL__
+ /* FIXME: Setting thread priority does not seem to be supported in NACL */
+ return 0;
+#elif __LINUX__
+ int value;
+ pid_t thread = syscall(SYS_gettid);
+
+ if (priority == SDL_THREAD_PRIORITY_LOW) {
+ value = 19;
+ } else if (priority == SDL_THREAD_PRIORITY_HIGH) {
+ value = -10;
+ } else if (priority == SDL_THREAD_PRIORITY_TIME_CRITICAL) {
+ value = -20;
+ } else {
+ value = 0;
+ }
+ return SDL_LinuxSetThreadPriority(thread, value);
+#else
+ struct sched_param sched;
+ int policy;
+ pthread_t thread = pthread_self();
+
+ if (pthread_getschedparam(thread, &policy, &sched) != 0) {
+ return SDL_SetError("pthread_getschedparam() failed");
+ }
+ if (priority == SDL_THREAD_PRIORITY_LOW) {
+ sched.sched_priority = sched_get_priority_min(policy);
+ } else if (priority == SDL_THREAD_PRIORITY_TIME_CRITICAL) {
+ sched.sched_priority = sched_get_priority_max(policy);
+ } else {
+ int min_priority = sched_get_priority_min(policy);
+ int max_priority = sched_get_priority_max(policy);
+ sched.sched_priority = (min_priority + (max_priority - min_priority) / 2);
+ if (priority == SDL_THREAD_PRIORITY_HIGH) {
+ sched.sched_priority += ((max_priority - min_priority) / 4);
+ }
+ }
+ if (pthread_setschedparam(thread, policy, &sched) != 0) {
+ return SDL_SetError("pthread_setschedparam() failed");
+ }
+ return 0;
+#endif /* linux */
+}
+
+void
+SDL_SYS_WaitThread(SDL_Thread * thread)
+{
+ pthread_join(thread->handle, 0);
+}
+
+void
+SDL_SYS_DetachThread(SDL_Thread * thread)
+{
+ pthread_detach(thread->handle);
+}
+
+/* vi: set ts=4 sw=4 expandtab: */
diff --git a/source/3rd-party/SDL2/src/thread/pthread/SDL_systhread_c.h b/source/3rd-party/SDL2/src/thread/pthread/SDL_systhread_c.h
new file mode 100644
index 0000000..898c219
--- /dev/null
+++ b/source/3rd-party/SDL2/src/thread/pthread/SDL_systhread_c.h
@@ -0,0 +1,27 @@
+/*
+ Simple DirectMedia Layer
+ Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
+
+ This software is provided 'as-is', without any express or implied
+ warranty. In no event will the authors be held liable for any damages
+ arising from the use of this software.
+
+ Permission is granted to anyone to use this software for any purpose,
+ including commercial applications, and to alter it and redistribute it
+ freely, subject to the following restrictions:
+
+ 1. The origin of this software must not be misrepresented; you must not
+ claim that you wrote the original software. If you use this software
+ in a product, an acknowledgment in the product documentation would be
+ appreciated but is not required.
+ 2. Altered source versions must be plainly marked as such, and must not be
+ misrepresented as being the original software.
+ 3. This notice may not be removed or altered from any source distribution.
+*/
+#include "../../SDL_internal.h"
+
+#include <pthread.h>
+
+typedef pthread_t SYS_ThreadHandle;
+
+/* vi: set ts=4 sw=4 expandtab: */
diff --git a/source/3rd-party/SDL2/src/thread/pthread/SDL_systls.c b/source/3rd-party/SDL2/src/thread/pthread/SDL_systls.c
new file mode 100644
index 0000000..c580595
--- /dev/null
+++ b/source/3rd-party/SDL2/src/thread/pthread/SDL_systls.c
@@ -0,0 +1,70 @@
+/*
+ Simple DirectMedia Layer
+ Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
+
+ This software is provided 'as-is', without any express or implied
+ warranty. In no event will the authors be held liable for any damages
+ arising from the use of this software.
+
+ Permission is granted to anyone to use this software for any purpose,
+ including commercial applications, and to alter it and redistribute it
+ freely, subject to the following restrictions:
+
+ 1. The origin of this software must not be misrepresented; you must not
+ claim that you wrote the original software. If you use this software
+ in a product, an acknowledgment in the product documentation would be
+ appreciated but is not required.
+ 2. Altered source versions must be plainly marked as such, and must not be
+ misrepresented as being the original software.
+ 3. This notice may not be removed or altered from any source distribution.
+*/
+#include "../../SDL_internal.h"
+#include "SDL_thread.h"
+#include "../SDL_systhread.h"
+#include "../SDL_thread_c.h"
+
+#include <pthread.h>
+
+
+#define INVALID_PTHREAD_KEY ((pthread_key_t)-1)
+
+static pthread_key_t thread_local_storage = INVALID_PTHREAD_KEY;
+static SDL_bool generic_local_storage = SDL_FALSE;
+
+SDL_TLSData *
+SDL_SYS_GetTLSData(void)
+{
+ if (thread_local_storage == INVALID_PTHREAD_KEY && !generic_local_storage) {
+ static SDL_SpinLock lock;
+ SDL_AtomicLock(&lock);
+ if (thread_local_storage == INVALID_PTHREAD_KEY && !generic_local_storage) {
+ pthread_key_t storage;
+ if (pthread_key_create(&storage, NULL) == 0) {
+ SDL_MemoryBarrierRelease();
+ thread_local_storage = storage;
+ } else {
+ generic_local_storage = SDL_TRUE;
+ }
+ }
+ SDL_AtomicUnlock(&lock);
+ }
+ if (generic_local_storage) {
+ return SDL_Generic_GetTLSData();
+ }
+ SDL_MemoryBarrierAcquire();
+ return (SDL_TLSData *)pthread_getspecific(thread_local_storage);
+}
+
+int
+SDL_SYS_SetTLSData(SDL_TLSData *data)
+{
+ if (generic_local_storage) {
+ return SDL_Generic_SetTLSData(data);
+ }
+ if (pthread_setspecific(thread_local_storage, data) != 0) {
+ return SDL_SetError("pthread_setspecific() failed");
+ }
+ return 0;
+}
+
+/* vi: set ts=4 sw=4 expandtab: */