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.
|
3. This notice may not be removed or altered from any source distribution.
|
||||||
*/
|
*/
|
||||||
#include <switch.h>
|
#include <switch.h>
|
||||||
|
#include <threads.h>
|
||||||
#include "../../SDL_internal.h"
|
#include "../../SDL_internal.h"
|
||||||
|
|
||||||
#if SDL_THREAD_SWITCH
|
#if SDL_THREAD_SWITCH
|
||||||
|
@ -33,23 +34,26 @@
|
||||||
|
|
||||||
struct SDL_cond
|
struct SDL_cond
|
||||||
{
|
{
|
||||||
CondVar var;
|
cnd_t cnd;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct SDL_mutex
|
struct SDL_mutex
|
||||||
{
|
{
|
||||||
RMutex mtx;
|
mtx_t mtx;
|
||||||
};
|
};
|
||||||
|
|
||||||
/* Create a condition variable */
|
/* Create a condition variable */
|
||||||
SDL_cond *
|
SDL_cond *
|
||||||
SDL_CreateCond(void)
|
SDL_CreateCond(void)
|
||||||
{
|
{
|
||||||
SDL_cond *cond;
|
SDL_cond *cond = NULL;
|
||||||
|
|
||||||
cond = (SDL_cond *) SDL_malloc(sizeof(SDL_cond));
|
cond = (SDL_cond *) SDL_malloc(sizeof(SDL_cond));
|
||||||
if (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 {
|
else {
|
||||||
SDL_OutOfMemory();
|
SDL_OutOfMemory();
|
||||||
|
@ -62,6 +66,7 @@ void
|
||||||
SDL_DestroyCond(SDL_cond *cond)
|
SDL_DestroyCond(SDL_cond *cond)
|
||||||
{
|
{
|
||||||
if (cond) {
|
if (cond) {
|
||||||
|
cnd_destroy(&cond->cnd);
|
||||||
SDL_free(cond);
|
SDL_free(cond);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -70,11 +75,16 @@ SDL_DestroyCond(SDL_cond *cond)
|
||||||
int
|
int
|
||||||
SDL_CondSignal(SDL_cond *cond)
|
SDL_CondSignal(SDL_cond *cond)
|
||||||
{
|
{
|
||||||
|
int res;
|
||||||
|
|
||||||
if (!cond) {
|
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;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -83,11 +93,16 @@ SDL_CondSignal(SDL_cond *cond)
|
||||||
int
|
int
|
||||||
SDL_CondBroadcast(SDL_cond *cond)
|
SDL_CondBroadcast(SDL_cond *cond)
|
||||||
{
|
{
|
||||||
|
int res;
|
||||||
|
|
||||||
if (!cond) {
|
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;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -116,22 +131,19 @@ Thread B:
|
||||||
int
|
int
|
||||||
SDL_CondWaitTimeout(SDL_cond *cond, SDL_mutex *mutex, Uint32 ms)
|
SDL_CondWaitTimeout(SDL_cond *cond, SDL_mutex *mutex, Uint32 ms)
|
||||||
{
|
{
|
||||||
uint32_t mutex_state[2];
|
struct timespec ts;
|
||||||
|
int res;
|
||||||
|
|
||||||
if (!cond) {
|
if (!cond || !mutex) {
|
||||||
return SDL_SetError("Passed a NULL condition variable");
|
return SDL_SetError("SDL_CondWaitTimeout: passed a NULL cond/mutex");
|
||||||
}
|
}
|
||||||
|
|
||||||
// backup mutex state
|
ts.tv_sec = ms / 1000;
|
||||||
mutex_state[0] = mutex->mtx.thread_tag;
|
ts.tv_nsec = (ms % 1000) * 1000000;
|
||||||
mutex_state[1] = mutex->mtx.counter;
|
res = cnd_timedwait(&cond->cnd, &mutex->mtx, &ts);
|
||||||
mutex->mtx.thread_tag = 0;
|
if (res != thrd_success) {
|
||||||
mutex->mtx.counter = 0;
|
return SDL_SetError("SDL_CondWaitTimeout::cnd_timedwait failed: %i", res);
|
||||||
|
}
|
||||||
condvarWaitTimeout(&cond->var, &mutex->mtx.lock, ms * 1000000);
|
|
||||||
|
|
||||||
mutex->mtx.thread_tag = mutex_state[0];
|
|
||||||
mutex->mtx.counter = mutex_state[1];
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -140,7 +152,18 @@ SDL_CondWaitTimeout(SDL_cond *cond, SDL_mutex *mutex, Uint32 ms)
|
||||||
int
|
int
|
||||||
SDL_CondWait(SDL_cond *cond, SDL_mutex *mutex)
|
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 */
|
#endif /* SDL_THREAD_SWITCH */
|
||||||
|
|
|
@ -22,14 +22,14 @@
|
||||||
|
|
||||||
#if SDL_THREAD_SWITCH
|
#if SDL_THREAD_SWITCH
|
||||||
|
|
||||||
/* An implementation of mutexes using semaphores */
|
/* An implementation of mutexes */
|
||||||
|
|
||||||
#include "SDL_thread.h"
|
#include "SDL_thread.h"
|
||||||
#include "SDL_systhread_c.h"
|
#include "SDL_systhread_c.h"
|
||||||
|
|
||||||
struct SDL_mutex
|
struct SDL_mutex
|
||||||
{
|
{
|
||||||
RMutex mtx;
|
mtx_t mtx;
|
||||||
};
|
};
|
||||||
|
|
||||||
/* Create a mutex */
|
/* Create a mutex */
|
||||||
|
@ -38,7 +38,7 @@ SDL_CreateMutex(void)
|
||||||
{
|
{
|
||||||
SDL_mutex *mutex = (SDL_mutex *) SDL_malloc(sizeof(*mutex));
|
SDL_mutex *mutex = (SDL_mutex *) SDL_malloc(sizeof(*mutex));
|
||||||
if (mutex) {
|
if (mutex) {
|
||||||
rmutexInit(&mutex->mtx);
|
mtx_init(&mutex->mtx, mtx_plain | mtx_recursive);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
SDL_OutOfMemory();
|
SDL_OutOfMemory();
|
||||||
|
@ -52,11 +52,12 @@ void
|
||||||
SDL_DestroyMutex(SDL_mutex *mutex)
|
SDL_DestroyMutex(SDL_mutex *mutex)
|
||||||
{
|
{
|
||||||
if (mutex) {
|
if (mutex) {
|
||||||
|
mtx_destroy(&mutex->mtx);
|
||||||
SDL_free(mutex);
|
SDL_free(mutex);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Lock the semaphore */
|
/* Lock the mutex */
|
||||||
int
|
int
|
||||||
SDL_mutexP(SDL_mutex *mutex)
|
SDL_mutexP(SDL_mutex *mutex)
|
||||||
{
|
{
|
||||||
|
@ -64,7 +65,7 @@ SDL_mutexP(SDL_mutex *mutex)
|
||||||
return SDL_SetError("Passed a NULL mutex");
|
return SDL_SetError("Passed a NULL mutex");
|
||||||
}
|
}
|
||||||
|
|
||||||
rmutexLock(&mutex->mtx);
|
mtx_lock(&mutex->mtx);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -77,7 +78,7 @@ SDL_mutexV(SDL_mutex *mutex)
|
||||||
return SDL_SetError("Passed a NULL mutex");
|
return SDL_SetError("Passed a NULL mutex");
|
||||||
}
|
}
|
||||||
|
|
||||||
rmutexUnlock(&mutex->mtx);
|
mtx_unlock(&mutex->mtx);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -31,39 +31,18 @@
|
||||||
#include "SDL_thread.h"
|
#include "SDL_thread.h"
|
||||||
#include "../SDL_systhread.h"
|
#include "../SDL_systhread.h"
|
||||||
|
|
||||||
#define STACK_SIZE 0x20000
|
static int
|
||||||
|
|
||||||
static void
|
|
||||||
SDL_SYS_RunThread(void *data)
|
SDL_SYS_RunThread(void *data)
|
||||||
{
|
{
|
||||||
SDL_RunThread(data);
|
SDL_RunThread(data);
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int SDL_SYS_CreateThread(SDL_Thread *thread, void *args)
|
int SDL_SYS_CreateThread(SDL_Thread *thread, void *args)
|
||||||
{
|
{
|
||||||
Result res;
|
int res = thrd_create(&thread->handle, SDL_SYS_RunThread, args);
|
||||||
u64 core_mask = 0;
|
if (res != thrd_success) {
|
||||||
|
return SDL_SetError("SDL_SYS_CreateThread failed: %i", res);
|
||||||
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);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -71,45 +50,39 @@ int SDL_SYS_CreateThread(SDL_Thread *thread, void *args)
|
||||||
|
|
||||||
void SDL_SYS_SetupThread(const char *name)
|
void SDL_SYS_SetupThread(const char *name)
|
||||||
{
|
{
|
||||||
/* Do nothing. */
|
|
||||||
}
|
}
|
||||||
|
|
||||||
SDL_threadID SDL_ThreadID(void)
|
SDL_threadID SDL_ThreadID(void)
|
||||||
{
|
{
|
||||||
u64 tid = 0;
|
return (SDL_threadID) thrd_current();
|
||||||
|
|
||||||
svcGetThreadId(&tid, CUR_THREAD_HANDLE);
|
|
||||||
|
|
||||||
return (SDL_threadID) tid;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void SDL_SYS_WaitThread(SDL_Thread *thread)
|
void SDL_SYS_WaitThread(SDL_Thread *thread)
|
||||||
{
|
{
|
||||||
if (thread && thread->handle.handle) {
|
if (thread) {
|
||||||
threadWaitForExit(&thread->handle);
|
thrd_join(thread->handle, NULL);
|
||||||
threadClose(&thread->handle);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void SDL_SYS_DetachThread(SDL_Thread *thread)
|
void SDL_SYS_DetachThread(SDL_Thread *thread)
|
||||||
{
|
{
|
||||||
if (thread && thread->handle.handle) {
|
|
||||||
threadClose(&thread->handle);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int SDL_SYS_SetThreadPriority(SDL_ThreadPriority priority)
|
int SDL_SYS_SetThreadPriority(SDL_ThreadPriority priority)
|
||||||
{
|
{
|
||||||
u32 value = 0x2C;
|
Result res;
|
||||||
|
|
||||||
if (priority == SDL_THREAD_PRIORITY_LOW) {
|
if (priority == SDL_THREAD_PRIORITY_HIGH) {
|
||||||
value = 0x2D;
|
res = svcSetThreadPriority(CUR_THREAD_HANDLE, 0x1C);
|
||||||
}
|
}
|
||||||
else if (priority == SDL_THREAD_PRIORITY_HIGH) {
|
else {
|
||||||
value = 0x1C;
|
// 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;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -20,5 +20,6 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <switch.h>
|
#include <switch.h>
|
||||||
|
#include <threads.h>
|
||||||
|
|
||||||
typedef Thread SYS_ThreadHandle;
|
typedef thrd_t SYS_ThreadHandle;
|
||||||
|
|
Loading…
Reference in New Issue