switch: use c11 threads

This commit is contained in:
Cpasjuste 2018-12-13 09:39:43 +01:00 committed by Dave Murphy
parent 063a1c9265
commit 6748b87af8
4 changed files with 71 additions and 73 deletions

View File

@ -19,6 +19,7 @@
3. This notice may not be removed or altered from any source distribution.
*/
#include <switch.h>
#include <threads.h>
#include "../../SDL_internal.h"
#if SDL_THREAD_SWITCH
@ -33,23 +34,26 @@
struct SDL_cond
{
CondVar var;
cnd_t cnd;
};
struct SDL_mutex
{
RMutex mtx;
mtx_t mtx;
};
/* Create a condition variable */
SDL_cond *
SDL_CreateCond(void)
{
SDL_cond *cond;
SDL_cond *cond = NULL;
cond = (SDL_cond *) SDL_malloc(sizeof(SDL_cond));
if (cond) {
condvarInit(&cond->var);
int res = cnd_init(&cond->cnd);
if (res != thrd_success) {
printf("SDL_CreateCond::cnd_init failed: %i\n", res);
}
}
else {
SDL_OutOfMemory();
@ -62,6 +66,7 @@ void
SDL_DestroyCond(SDL_cond *cond)
{
if (cond) {
cnd_destroy(&cond->cnd);
SDL_free(cond);
}
}
@ -70,11 +75,16 @@ SDL_DestroyCond(SDL_cond *cond)
int
SDL_CondSignal(SDL_cond *cond)
{
int res;
if (!cond) {
return SDL_SetError("Passed a NULL condition variable");
return SDL_SetError("Passed a NULL cond");
}
condvarWakeOne(&cond->var);
res = cnd_signal(&cond->cnd);
if (res != thrd_success) {
return SDL_SetError("SDL_CondSignal::cnd_signal failed: %i", res);
}
return 0;
}
@ -83,11 +93,16 @@ SDL_CondSignal(SDL_cond *cond)
int
SDL_CondBroadcast(SDL_cond *cond)
{
int res;
if (!cond) {
return SDL_SetError("Passed a NULL condition variable");
return SDL_SetError("Passed a NULL cond");
}
condvarWakeAll(&cond->var);
res = cnd_broadcast(&cond->cnd);
if (res != thrd_success) {
return SDL_SetError("SDL_CondBroadcast::cnd_broadcast failed: %i", res);
}
return 0;
}
@ -116,22 +131,19 @@ Thread B:
int
SDL_CondWaitTimeout(SDL_cond *cond, SDL_mutex *mutex, Uint32 ms)
{
uint32_t mutex_state[2];
struct timespec ts;
int res;
if (!cond) {
return SDL_SetError("Passed a NULL condition variable");
if (!cond || !mutex) {
return SDL_SetError("SDL_CondWaitTimeout: passed a NULL cond/mutex");
}
// backup mutex state
mutex_state[0] = mutex->mtx.thread_tag;
mutex_state[1] = mutex->mtx.counter;
mutex->mtx.thread_tag = 0;
mutex->mtx.counter = 0;
condvarWaitTimeout(&cond->var, &mutex->mtx.lock, ms * 1000000);
mutex->mtx.thread_tag = mutex_state[0];
mutex->mtx.counter = mutex_state[1];
ts.tv_sec = ms / 1000;
ts.tv_nsec = (ms % 1000) * 1000000;
res = cnd_timedwait(&cond->cnd, &mutex->mtx, &ts);
if (res != thrd_success) {
return SDL_SetError("SDL_CondWaitTimeout::cnd_timedwait failed: %i", res);
}
return 0;
}
@ -140,7 +152,18 @@ SDL_CondWaitTimeout(SDL_cond *cond, SDL_mutex *mutex, Uint32 ms)
int
SDL_CondWait(SDL_cond *cond, SDL_mutex *mutex)
{
return SDL_CondWaitTimeout(cond, mutex, SDL_MUTEX_MAXWAIT);
int res;
if (!cond || !mutex) {
return SDL_SetError("SDL_CondWaitTimeout: passed a NULL cond/mutex");
}
res = cnd_wait(&cond->cnd, &mutex->mtx);
if (res != thrd_success) {
return SDL_SetError("SDL_CondWait::cnd_wait failed: %i", res);
}
return 0;
}
#endif /* SDL_THREAD_SWITCH */

View File

@ -22,14 +22,14 @@
#if SDL_THREAD_SWITCH
/* An implementation of mutexes using semaphores */
/* An implementation of mutexes */
#include "SDL_thread.h"
#include "SDL_systhread_c.h"
struct SDL_mutex
{
RMutex mtx;
mtx_t mtx;
};
/* Create a mutex */
@ -38,7 +38,7 @@ SDL_CreateMutex(void)
{
SDL_mutex *mutex = (SDL_mutex *) SDL_malloc(sizeof(*mutex));
if (mutex) {
rmutexInit(&mutex->mtx);
mtx_init(&mutex->mtx, mtx_plain | mtx_recursive);
}
else {
SDL_OutOfMemory();
@ -52,11 +52,12 @@ void
SDL_DestroyMutex(SDL_mutex *mutex)
{
if (mutex) {
mtx_destroy(&mutex->mtx);
SDL_free(mutex);
}
}
/* Lock the semaphore */
/* Lock the mutex */
int
SDL_mutexP(SDL_mutex *mutex)
{
@ -64,7 +65,7 @@ SDL_mutexP(SDL_mutex *mutex)
return SDL_SetError("Passed a NULL mutex");
}
rmutexLock(&mutex->mtx);
mtx_lock(&mutex->mtx);
return 0;
}
@ -77,7 +78,7 @@ SDL_mutexV(SDL_mutex *mutex)
return SDL_SetError("Passed a NULL mutex");
}
rmutexUnlock(&mutex->mtx);
mtx_unlock(&mutex->mtx);
return 0;
}

View File

@ -31,39 +31,18 @@
#include "SDL_thread.h"
#include "../SDL_systhread.h"
#define STACK_SIZE 0x20000
static void
static int
SDL_SYS_RunThread(void *data)
{
SDL_RunThread(data);
return 0;
}
int SDL_SYS_CreateThread(SDL_Thread *thread, void *args)
{
Result res;
u64 core_mask = 0;
res = svcGetInfo(&core_mask, 0, CUR_PROCESS_HANDLE, 0);
if (R_FAILED(res)) {
return SDL_SetError("svcGetInfo() failed: 0x%08X", res);
}
res = threadCreate(&thread->handle, SDL_SYS_RunThread, args, STACK_SIZE, 0x2C, -2);
if (R_FAILED(res)) {
return SDL_SetError("threadCreate() failed: 0x%08X", res);
}
res = svcSetThreadCoreMask(thread->handle.handle, -1, (u32) core_mask);
if (R_FAILED(res)) {
threadClose(&thread->handle);
return SDL_SetError("threadCreate() failed: 0x%08X", res);
}
res = threadStart(&thread->handle);
if (R_FAILED(res)) {
threadClose(&thread->handle);
return SDL_SetError("threadStart() failed: 0x%08X", res);
int res = thrd_create(&thread->handle, SDL_SYS_RunThread, args);
if (res != thrd_success) {
return SDL_SetError("SDL_SYS_CreateThread failed: %i", res);
}
return 0;
@ -71,45 +50,39 @@ int SDL_SYS_CreateThread(SDL_Thread *thread, void *args)
void SDL_SYS_SetupThread(const char *name)
{
/* Do nothing. */
}
SDL_threadID SDL_ThreadID(void)
{
u64 tid = 0;
svcGetThreadId(&tid, CUR_THREAD_HANDLE);
return (SDL_threadID) tid;
return (SDL_threadID) thrd_current();
}
void SDL_SYS_WaitThread(SDL_Thread *thread)
{
if (thread && thread->handle.handle) {
threadWaitForExit(&thread->handle);
threadClose(&thread->handle);
if (thread) {
thrd_join(thread->handle, NULL);
}
}
void SDL_SYS_DetachThread(SDL_Thread *thread)
{
if (thread && thread->handle.handle) {
threadClose(&thread->handle);
}
}
int SDL_SYS_SetThreadPriority(SDL_ThreadPriority priority)
{
u32 value = 0x2C;
Result res;
if (priority == SDL_THREAD_PRIORITY_LOW) {
value = 0x2D;
if (priority == SDL_THREAD_PRIORITY_HIGH) {
res = svcSetThreadPriority(CUR_THREAD_HANDLE, 0x1C);
}
else if (priority == SDL_THREAD_PRIORITY_HIGH) {
value = 0x1C;
else {
// 0x3B = preemptive threading
res = svcSetThreadPriority(CUR_THREAD_HANDLE, 0x3B);
}
svcSetThreadPriority(CUR_THREAD_HANDLE, value);
if(R_FAILED(res)) {
return SDL_SetError("SDL_SYS_SetThreadPriority failed: %i", res);
}
return 0;
}

View File

@ -20,5 +20,6 @@
*/
#include <switch.h>
#include <threads.h>
typedef Thread SYS_ThreadHandle;
typedef thrd_t SYS_ThreadHandle;