#include "../../SDL_internal.h"
#ifdef SDL_THREAD_N3DS
#include "../SDL_systhread.h"
#define N3DS_THREAD_STACK_SIZE_MAX (16 * 1024)
#define N3DS_THREAD_STACK_SIZE_DEFAULT (4 * 1024)
#define N3DS_THREAD_PRIORITY_LOW 0x3F
#define N3DS_THREAD_PRIORITY_MEDIUM 0x2F
#define N3DS_THREAD_PRIORITY_HIGH 0x19
#define N3DS_THREAD_PRIORITY_TIME_CRITICAL 0x18
static size_t GetStackSize(size_t requested_size);
static void
ThreadEntry(void *arg)
{
SDL_RunThread((SDL_Thread *) arg);
threadExit(0);
}
#ifdef SDL_PASSED_BEGINTHREAD_ENDTHREAD
#error "SDL_PASSED_BEGINTHREAD_ENDTHREAD is not supported on N3DS"
#endif
int
SDL_SYS_CreateThread(SDL_Thread *thread)
{
s32 priority = N3DS_THREAD_PRIORITY_MEDIUM;
size_t stack_size = GetStackSize(thread->stacksize);
thread->handle = threadCreate(ThreadEntry,
thread,
stack_size,
priority,
-1,
false);
if (thread->handle == NULL) {
return SDL_SetError("Couldn't create thread");
}
return 0;
}
static size_t
GetStackSize(size_t requested_size)
{
if (requested_size == 0) {
return N3DS_THREAD_STACK_SIZE_DEFAULT;
}
if (requested_size > N3DS_THREAD_STACK_SIZE_MAX) {
SDL_LogWarn(SDL_LOG_CATEGORY_SYSTEM,
"Requested a thread size of %zu,"
" falling back to the maximum supported of %zu\n",
requested_size,
N3DS_THREAD_STACK_SIZE_MAX);
requested_size = N3DS_THREAD_STACK_SIZE_MAX;
}
return requested_size;
}
void
SDL_SYS_SetupThread(const char *name)
{
return;
}
SDL_threadID
SDL_ThreadID(void)
{
u32 thread_ID = 0;
svcGetThreadId(&thread_ID, CUR_THREAD_HANDLE);
return (SDL_threadID) thread_ID;
}
int
SDL_SYS_SetThreadPriority(SDL_ThreadPriority sdl_priority)
{
s32 svc_priority;
switch (sdl_priority) {
case SDL_THREAD_PRIORITY_LOW:
svc_priority = N3DS_THREAD_PRIORITY_LOW;
break;
case SDL_THREAD_PRIORITY_NORMAL:
svc_priority = N3DS_THREAD_PRIORITY_MEDIUM;
break;
case SDL_THREAD_PRIORITY_HIGH:
svc_priority = N3DS_THREAD_PRIORITY_HIGH;
break;
case SDL_THREAD_PRIORITY_TIME_CRITICAL:
svc_priority = N3DS_THREAD_PRIORITY_TIME_CRITICAL;
break;
default:
svc_priority = N3DS_THREAD_PRIORITY_MEDIUM;
}
return (int) svcSetThreadPriority(CUR_THREAD_HANDLE, svc_priority);
}
void
SDL_SYS_WaitThread(SDL_Thread *thread)
{
Result res = threadJoin(thread->handle, U64_MAX);
if (R_SUCCEEDED(res) && SDL_AtomicGet(&thread->state) != SDL_THREAD_STATE_DETACHED) {
threadFree(thread->handle);
}
}
void
SDL_SYS_DetachThread(SDL_Thread *thread)
{
threadDetach(thread->handle);
}
#endif