1 #include <common/spinlock.h>
2 #include <common/wait_queue.h>
3 #include <mm/slab.h>
4 #include <process/process.h>
5 #include <sched/sched.h>
6
7 /**
8 * @brief 初始化等待队列
9 *
10 * @param wait_queue 等待队列
11 * @param pcb pcb
12 */
wait_queue_init(wait_queue_node_t * wait_queue,struct process_control_block * pcb)13 void wait_queue_init(wait_queue_node_t *wait_queue, struct process_control_block *pcb)
14 {
15 list_init(&wait_queue->wait_list);
16 wait_queue->pcb = pcb;
17 }
18
19 /**
20 * @brief 在等待队列上进行等待
21 *
22 * @param wait_queue_head 队列头指针
23 */
wait_queue_sleep_on(wait_queue_node_t * wait_queue_head)24 void wait_queue_sleep_on(wait_queue_node_t *wait_queue_head)
25 {
26 wait_queue_node_t *wait = (wait_queue_node_t *)kzalloc(sizeof(wait_queue_node_t), 0);
27 wait_queue_init(wait, current_pcb);
28 current_pcb->state = PROC_UNINTERRUPTIBLE;
29 list_append(&wait_queue_head->wait_list, &wait->wait_list);
30
31 sched();
32 }
33
34 /**
35 * @brief 在等待队列上进行等待,同时释放自旋锁
36 *
37 * @param wait_queue_head 队列头指针
38 */
wait_queue_sleep_on_unlock(wait_queue_node_t * wait_queue_head,void * lock)39 void wait_queue_sleep_on_unlock(wait_queue_node_t *wait_queue_head,
40 void *lock)
41 {
42 wait_queue_node_t *wait = (wait_queue_node_t *)kzalloc(sizeof(wait_queue_node_t), 0);
43 wait_queue_init(wait, current_pcb);
44 current_pcb->state = PROC_UNINTERRUPTIBLE;
45 list_append(&wait_queue_head->wait_list, &wait->wait_list);
46 spin_unlock((spinlock_t *)lock);
47 sched();
48 }
49
50 /**
51 * @brief 在等待队列上进行等待(允许中断)
52 *
53 * @param wait_queue_head 队列头指针
54 */
wait_queue_sleep_on_interriptible(wait_queue_node_t * wait_queue_head)55 void wait_queue_sleep_on_interriptible(wait_queue_node_t *wait_queue_head)
56 {
57 wait_queue_node_t *wait = (wait_queue_node_t *)kzalloc(sizeof(wait_queue_node_t), 0);
58 wait_queue_init(wait, current_pcb);
59 current_pcb->state = PROC_INTERRUPTIBLE;
60 list_append(&wait_queue_head->wait_list, &wait->wait_list);
61
62 sched();
63 }
64
65 /**
66 * @brief 唤醒在等待队列的头部的进程
67 *
68 * @param wait_queue_head
69 * @param state
70 */
wait_queue_wakeup(wait_queue_node_t * wait_queue_head,int64_t state)71 void wait_queue_wakeup(wait_queue_node_t *wait_queue_head, int64_t state)
72 {
73 if (list_empty(&wait_queue_head->wait_list))
74 return;
75 wait_queue_node_t *wait = container_of(list_next(&wait_queue_head->wait_list), wait_queue_node_t, wait_list);
76
77 // 符合唤醒条件
78 if (wait->pcb->state & state)
79 {
80 list_del(&wait->wait_list);
81 process_wakeup(wait->pcb);
82 kfree(wait);
83 }
84 }