#include "SDL_internal.h"
#ifdef SDL_THREAD_N3DS
#include "../SDL_systhread.h"
#define N3DS_THREAD_STACK_SIZE_DEFAULT (80 * 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);
}
bool SDL_SYS_CreateThread(SDL_Thread *thread,
SDL_FunctionPointer pfnBeginThread,
SDL_FunctionPointer pfnEndThread)
{
s32 priority = 0x30;
int cpu = -1;
size_t stack_size = GetStackSize(thread->stacksize);
svcGetThreadPriority(&priority, CUR_THREAD_HANDLE);
if (thread->name && (SDL_strncmp(thread->name, "SDLAudioP", 9) == 0)) {
bool new3ds = false;
APT_CheckNew3DS(&new3ds);
if (new3ds && R_SUCCEEDED(APT_SetAppCpuTimeLimit(30))) {
cpu = 1;
}
}
thread->handle = threadCreate(ThreadEntry,
thread,
stack_size,
priority,
cpu,
false);
if (!thread->handle) {
return SDL_SetError("Couldn't create thread");
}
return true;
}
static size_t GetStackSize(size_t requested_size)
{
if (requested_size == 0) {
return N3DS_THREAD_STACK_SIZE_DEFAULT;
}
return requested_size;
}
void SDL_SYS_SetupThread(const char *name)
{
return;
}
SDL_ThreadID SDL_GetCurrentThreadID(void)
{
u32 thread_ID = 0;
svcGetThreadId(&thread_ID, CUR_THREAD_HANDLE);
return (SDL_ThreadID)thread_ID;
}
bool 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;
}
if (svcSetThreadPriority(CUR_THREAD_HANDLE, svc_priority) < 0) {
return SDL_SetError("svcSetThreadPriority failed");
}
return true;
}
void SDL_SYS_WaitThread(SDL_Thread *thread)
{
Result res = threadJoin(thread->handle, U64_MAX);
if (R_SUCCEEDED(res) && SDL_GetThreadState(thread) != SDL_THREAD_DETACHED) {
threadFree(thread->handle);
}
}
void SDL_SYS_DetachThread(SDL_Thread *thread)
{
threadDetach(thread->handle);
}
#endif