improve wait_queue api

This commit is contained in:
Mathieu Maret 2020-08-15 23:31:35 +02:00
parent 36734ae6e6
commit 6922f6dfa4
3 changed files with 55 additions and 16 deletions

View File

@ -1,6 +1,6 @@
#include "assert.h"
#include "synchro.h" #include "synchro.h"
#include "alloc.h" #include "alloc.h"
#include "assert.h"
#include "irq.h" #include "irq.h"
#include "klibc.h" #include "klibc.h"
#include "list.h" #include "list.h"
@ -59,12 +59,7 @@ int mutexLock(struct mutex *m)
disable_IRQs(flags); disable_IRQs(flags);
current = getCurrenThread(); current = getCurrenThread();
assert(m->owner != current); assert(m->owner != current);
while (m->owner) { wait_event(m->wait, m->owner == NULL);
kthreadUnsched(current);
list_add_tail(m->wait->thread, current);
current->state = WAITING;
kthreadSaveAndYield(current);
}
m->owner = current; m->owner = current;
restore_IRQs(flags); restore_IRQs(flags);
@ -74,17 +69,14 @@ int mutexLock(struct mutex *m)
int mutexUnlock(struct mutex *m) int mutexUnlock(struct mutex *m)
{ {
struct kthread *th;
uint32_t flags; uint32_t flags;
disable_IRQs(flags); disable_IRQs(flags);
assert(m->owner == getCurrenThread()); assert(m->owner == getCurrenThread());
m->owner = NULL; m->owner = NULL;
list_collapse(m->wait->thread, th){ wake_up(m->wait);
kthreadAddThread(th);
}
restore_IRQs(flags); restore_IRQs(flags);

37
core/wait.c Normal file
View File

@ -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;
}

View File

@ -8,12 +8,22 @@ struct wait_queue {
struct wait_queue *prev; 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 { struct semaphore {
int count; int count;
struct wait_queue *wait; struct wait_queue *wait;
}; };
struct mutex { struct mutex {
struct kthread *owner; struct kthread *owner;
struct wait_queue *wait; struct wait_queue *wait;
}; };