72 lines
1.4 KiB
C
72 lines
1.4 KiB
C
|
|
||
|
#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;
|
||
|
}
|