Unifying the Lunaix's Physical Memory Model (#28)
[lunaix-os.git] / lunaix-os / kernel / ds / waitq.c
1 #include <lunaix/ds/waitq.h>
2 #include <lunaix/process.h>
3 #include <lunaix/sched.h>
4 #include <lunaix/spike.h>
5
6 void
7 pwait(waitq_t* queue)
8 {
9     assert(current_thread);
10     // prevent race condition.
11     cpu_disable_interrupt();
12
13     waitq_t* current_wq = &current_thread->waitqueue;
14     assert(llist_empty(&current_wq->waiters));
15
16     llist_append(&queue->waiters, &current_wq->waiters);
17
18     block_current_thread();
19     sched_pass();
20
21     cpu_enable_interrupt();
22 }
23
24 void
25 pwake_one(waitq_t* queue)
26 {
27     if (llist_empty(&queue->waiters)) {
28         return;
29     }
30
31     waitq_t* wq = list_entry(queue->waiters.next, waitq_t, waiters);
32     struct thread* thread = container_of(wq, struct thread, waitqueue);
33
34     assert(thread->state == PS_BLOCKED);
35     thread->state = PS_READY;
36     llist_delete(&wq->waiters);
37 }
38
39 void
40 pwake_all(waitq_t* queue)
41 {
42     if (llist_empty(&queue->waiters)) {
43         return;
44     }
45
46     struct thread* thread;
47     waitq_t *pos, *n;
48     llist_for_each(pos, n, &queue->waiters, waiters)
49     {
50         thread = container_of(pos, struct thread, waitqueue);
51
52         assert(thread->state == PS_BLOCKED);
53         thread->state = PS_READY;
54         llist_delete(&pos->waiters);
55     }
56 }