libnx/nx/source/kernel/barrier.c
Juan Antonio Hernández Cánovas 3903f7a3e3 whoops
2018-08-25 01:17:28 +02:00

50 lines
1.4 KiB
C

#include "kernel/barrier.h"
#include "../internal.h"
void barrierInit(Barrier* b) {
mutexInit(&b->mutex);
mutexLock(&b->mutex);
listInit(&b->threads_registered);
listInit(&b->threads_waiting);
mutexUnlock(&b->mutex);
}
void barrierFree(Barrier* b) {
mutexLock(&b->mutex);
listFree(&b->threads_registered);
listFree(&b->threads_waiting);
mutexUnlock(&b->mutex);
}
void barrierRegister(Barrier* b, Thread* thread) {
if(listIsInserted(&b->threads_registered, (void*)thread)) {
return;
}
listInsertLast(&b->threads_registered, (void*)thread);
}
void barrierUnregister(Barrier* b, Thread* thread) {
listDelete(&b->threads_registered, (void*)thread);
}
void barrierWait(Barrier* b) {
Thread* thread = getThreadVars()->thread_ptr;
if(!listIsInserted(&b->threads_registered, (void*)thread)) {
return;
}
mutexLock(&b->mutex);
if(listGetNumNodes(&b->threads_registered) == listGetNumNodes(&b->threads_waiting)+1) {
while(listGetNumNodes(&b->threads_waiting) > 0) {
Thread* current_thread = listGetItem(&b->threads_waiting, 0);
svcSetThreadActivity(current_thread->handle, 0);
listDelete(&b->threads_waiting, (void*)current_thread);
}
mutexUnlock(&b->mutex);
}
else {
listInsertLast(&b->threads_waiting, (void*)thread);
mutexUnlock(&b->mutex);
svcSleepThread(0);
}
}