diff --git a/smp/condiction.c b/smp/condiction.c index 06e2886..d6ff53f 100644 --- a/smp/condiction.c +++ b/smp/condiction.c @@ -13,6 +13,7 @@ smp_Condition *smp_Condition_Create() { } void smp_Condition_Destroy(smp_Condition *c) { + smp_Condition_NotifyAll(c, (void *)UINTPTR_MAX); vector_Destroy(c->threads); kFree(c); } @@ -26,6 +27,7 @@ void *smp_Condition_Wait(smp_Condition *c) { INTERRUPT_RESTORE; smp_thread_Yield(); + return t->waitData; return 0; } @@ -40,17 +42,13 @@ bool smp_Condition_NotifyOne(smp_Condition *c, void *data) { __smp_Thread *last = *(__smp_Thread **)vector_At(c->threads, size - 1); last->waitCondition = NULL; + last->waitData = data; 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; @@ -63,6 +61,7 @@ int smp_Condition_NotifyAll(smp_Condition *c, void *data) { for (uintptr_t i = 0; i < size; i++) { __smp_Thread *t = *(__smp_Thread **)vector_At(c->threads, i); t->waitCondition = NULL; + t->waitData = data; } vector_Clear(c->threads); diff --git a/smp/internal.h b/smp/internal.h index 21ddc1d..6aa07d2 100644 --- a/smp/internal.h +++ b/smp/internal.h @@ -18,6 +18,7 @@ typedef struct { uint64_t lastTick; uint64_t sleepUntil; smp_Condition *waitCondition; + void * waitData; // Last-saved thread state after preemptive context switch smp_thread_State state;