libnx/nx/source/kernel/thread.c

78 lines
1.8 KiB
C

// Copyright 2017 plutoo
#include <switch.h>
#include <malloc.h>
static void _EntryWrap(Thread* t) {
t->entry(t->arg);
svcExitThread();
}
Result threadCreate(
Thread* t, ThreadFunc entry, void* arg, size_t stack_sz, int prio,
int cpuid)
{
Result rc = 0;
void* stack = memalign(0x1000, stack_sz);
if (stack == NULL) {
rc = MAKERESULT(MODULE_LIBNX, LIBNX_OUTOFMEM);
}
else {
// todo: svcMapMemory returns 0xDC01
void* stack_mirror = stack;//virtmemReserveMap(stack_sz);
//rc = svcMapMemory(stack_mirror, stack, stack_sz);
if (R_SUCCEEDED(rc))
{
u64 stack_top = ((u64)stack_mirror) + t->stack_sz;
Handle handle;
rc = svcCreateThread(
&handle, (ThreadFunc) &_EntryWrap, (void*) t, (void*) stack_top,
prio, cpuid);
if (R_SUCCEEDED(rc))
{
t->handle = handle;
t->entry = entry;
t->arg = arg;
t->stack_mem = stack;
t->stack_mirror = stack_mirror;
t->stack_sz = stack_sz;
}
if (R_FAILED(rc)) {
svcUnmapMemory(stack_mirror, stack, stack_sz);
}
}
if (R_FAILED(rc)) {
virtmemFreeMap(stack_mirror, stack_sz);
free(stack);
}
}
return rc;
}
Result threadStart(Thread* t) {
return svcStartThread(t->handle);
}
Result threadWaitForExit(Thread* t) {
Handle handle = t->handle;
s32 idx = 0;
return svcWaitSynchronization(&idx, &handle, 1, -1);
}
Result threadClose(Thread* t) {
Result rc;
rc = svcUnmapMemory(t->stack_mirror, t->stack_mem, t->stack_sz);
virtmemFreeMap(t->stack_mirror, t->stack_sz);
free(t->stack_mem);
svcCloseHandle(t->handle);
return rc;
}