1 #include <lunaix/ds/waitq.h>
2 #include <lunaix/process.h>
3 #include <lunaix/sched.h>
4 #include <lunaix/spike.h>
5 #include <lunaix/kpreempt.h>
7 static inline void must_inline
8 __try_wait(bool check_stall)
11 waitq_t* current_wq = ¤t_thread->waitqueue;
12 if (waitq_empty(current_wq)) {
16 block_current_thread();
19 // if we are not checking stall, we give up voluntarily
22 // otherwise, treat it as being preempted by kernel
26 // In case of SIGINT-forced awaken
27 llist_delete(¤t_wq->waiters);
30 static inline void must_inline
31 __pwait(waitq_t* queue, bool check_stall)
33 // prevent race condition.
36 prepare_to_wait(queue);
37 __try_wait(check_stall);
45 __pwait(queue, false);
49 pwait_check_stall(waitq_t* queue)
55 pwake_one(waitq_t* queue)
57 if (waitq_empty(queue)) {
61 waitq_t* wq = list_entry(queue->waiters.next, waitq_t, waiters);
62 struct thread* thread = container_of(wq, struct thread, waitqueue);
64 assert(thread->state == PS_BLOCKED);
65 thread->state = PS_READY;
66 llist_delete(&wq->waiters);
70 pwake_all(waitq_t* queue)
72 if (waitq_empty(queue)) {
76 struct thread* thread;
78 llist_for_each(pos, n, &queue->waiters, waiters)
80 thread = container_of(pos, struct thread, waitqueue);
82 if (thread->state == PS_BLOCKED) {
83 thread->state = PS_READY;
86 // already awaken or killed by other event, just remove it
87 llist_delete(&pos->waiters);
92 prepare_to_wait(waitq_t* queue)
94 assert(current_thread);
96 waitq_t* current_wq = ¤t_thread->waitqueue;
97 assert(llist_empty(¤t_wq->waiters));
99 llist_append(&queue->waiters, ¤t_wq->waiters);
109 try_wait_check_stall()