mirror of https://github.com/encounter/SDL.git
switch: use c11 threads
This commit is contained in:
parent
063a1c9265
commit
6748b87af8
|
@ -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 */
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -20,5 +20,6 @@
|
|||
*/
|
||||
|
||||
#include <switch.h>
|
||||
#include <threads.h>
|
||||
|
||||
typedef Thread SYS_ThreadHandle;
|
||||
typedef thrd_t SYS_ThreadHandle;
|
||||
|
|
Loading…
Reference in New Issue