wait_queue.c 2.2 KB

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