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