helos1/smp/condiction.c

72 lines
1.4 KiB
C
Raw Normal View History

#include "condiction.h"
#include "kthread.h"
#include "internal.h"
#include "../interrupt/interrupt.h"
#include "../memory/memory.h"
smp_Condition *smp_Condition_Create() {
smp_Condition *c = kMalloc(sizeof(smp_Condition));
c->threads = vector_Create(sizeof(__smp_Thread *));
return c;
}
void smp_Condition_Destroy(smp_Condition *c) {
vector_Destroy(c->threads);
kFree(c);
}
void *smp_Condition_Wait(smp_Condition *c) {
INTERRUPT_DISABLE;
__smp_Thread *t = __smp_Current[0];
t->waitCondition = c;
vector_Push(c->threads, &t);
INTERRUPT_RESTORE;
smp_thread_Yield();
return 0;
}
bool smp_Condition_NotifyOne(smp_Condition *c, void *data) {
INTERRUPT_DISABLE;
uintptr_t size = vector_Size(c->threads);
if (size == 0) {
INTERRUPT_RESTORE;
return false;
}
__smp_Thread *last = *(__smp_Thread **)vector_At(c->threads, size - 1);
last->waitCondition = NULL;
vector_Resize(c->threads, size - 1);
INTERRUPT_RESTORE;
return true;
}
// NotifyAll unblocks all waiting threads.
//
// The data is (for now) not sent.
//
// Returns the number of threads unblocked.
int smp_Condition_NotifyAll(smp_Condition *c, void *data) {
INTERRUPT_DISABLE;
uintptr_t size = vector_Size(c->threads);
if (size == 0) {
INTERRUPT_RESTORE;
return size;
}
for (uintptr_t i = 0; i < size; i++) {
__smp_Thread *t = *(__smp_Thread **)vector_At(c->threads, i);
t->waitCondition = NULL;
}
vector_Clear(c->threads);
INTERRUPT_RESTORE;
return true;
}