diff --git a/core/synchro.c b/core/synchro.c index 993c439..f1c9ad0 100644 --- a/core/synchro.c +++ b/core/synchro.c @@ -1,6 +1,6 @@ -#include "assert.h" #include "synchro.h" #include "alloc.h" +#include "assert.h" #include "irq.h" #include "klibc.h" #include "list.h" @@ -59,12 +59,7 @@ int mutexLock(struct mutex *m) disable_IRQs(flags); current = getCurrenThread(); assert(m->owner != current); - while (m->owner) { - kthreadUnsched(current); - list_add_tail(m->wait->thread, current); - current->state = WAITING; - kthreadSaveAndYield(current); - } + wait_event(m->wait, m->owner == NULL); m->owner = current; restore_IRQs(flags); @@ -74,17 +69,14 @@ int mutexLock(struct mutex *m) int mutexUnlock(struct mutex *m) { - struct kthread *th; uint32_t flags; disable_IRQs(flags); assert(m->owner == getCurrenThread()); m->owner = NULL; - - list_collapse(m->wait->thread, th){ - kthreadAddThread(th); - } + + wake_up(m->wait); restore_IRQs(flags); diff --git a/core/wait.c b/core/wait.c new file mode 100644 index 0000000..dccf354 --- /dev/null +++ b/core/wait.c @@ -0,0 +1,37 @@ +#include "wait.h" +#include "irq.h" +#include "kthread.h" +#include "list.h" + +int wake_up(struct wait_queue *wq) +{ + struct kthread *th; + uint32_t flags; + + disable_IRQs(flags); + list_collapse(wq->thread, th) + { + kthreadAddThread(th); + } + + restore_IRQs(flags); + + return 0; +} + +int wait(struct wait_queue *wq) +{ + struct kthread *current; + uint32_t flags; + + disable_IRQs(flags); + + current = getCurrenThread(); + kthreadUnsched(current); + list_add_tail(wq->thread, current); + current->state = WAITING; + kthreadSaveAndYield(current); + + restore_IRQs(flags); + return 0; +} diff --git a/core/wait.h b/core/wait.h index 8a4b82c..1b77bec 100644 --- a/core/wait.h +++ b/core/wait.h @@ -8,12 +8,22 @@ struct wait_queue { struct wait_queue *prev; }; +int wait(struct wait_queue *); +int wake_up(struct wait_queue *); + +#define wait_event(wq, condition) \ + do { \ + if (condition) \ + break; \ + wait(wq); \ + } while (1) + struct semaphore { - int count; - struct wait_queue *wait; + int count; + struct wait_queue *wait; }; struct mutex { - struct kthread *owner; - struct wait_queue *wait; + struct kthread *owner; + struct wait_queue *wait; };