《操作系统》的实验代码。
Ви не можете вибрати більше 25 тем Теми мають розпочинатися з літери або цифри, можуть містити дефіси (-) і не повинні перевищувати 35 символів.

122 рядки
3.0 KiB

10 роки тому
  1. #include <defs.h>
  2. #include <list.h>
  3. #include <sync.h>
  4. #include <wait.h>
  5. #include <proc.h>
  6. void
  7. wait_init(wait_t *wait, struct proc_struct *proc) {
  8. wait->proc = proc;
  9. wait->wakeup_flags = WT_INTERRUPTED;
  10. list_init(&(wait->wait_link));
  11. }
  12. void
  13. wait_queue_init(wait_queue_t *queue) {
  14. list_init(&(queue->wait_head));
  15. }
  16. void
  17. wait_queue_add(wait_queue_t *queue, wait_t *wait) {
  18. assert(list_empty(&(wait->wait_link)) && wait->proc != NULL);
  19. wait->wait_queue = queue;
  20. list_add_before(&(queue->wait_head), &(wait->wait_link));
  21. }
  22. void
  23. wait_queue_del(wait_queue_t *queue, wait_t *wait) {
  24. assert(!list_empty(&(wait->wait_link)) && wait->wait_queue == queue);
  25. list_del_init(&(wait->wait_link));
  26. }
  27. wait_t *
  28. wait_queue_next(wait_queue_t *queue, wait_t *wait) {
  29. assert(!list_empty(&(wait->wait_link)) && wait->wait_queue == queue);
  30. list_entry_t *le = list_next(&(wait->wait_link));
  31. if (le != &(queue->wait_head)) {
  32. return le2wait(le, wait_link);
  33. }
  34. return NULL;
  35. }
  36. wait_t *
  37. wait_queue_prev(wait_queue_t *queue, wait_t *wait) {
  38. assert(!list_empty(&(wait->wait_link)) && wait->wait_queue == queue);
  39. list_entry_t *le = list_prev(&(wait->wait_link));
  40. if (le != &(queue->wait_head)) {
  41. return le2wait(le, wait_link);
  42. }
  43. return NULL;
  44. }
  45. wait_t *
  46. wait_queue_first(wait_queue_t *queue) {
  47. list_entry_t *le = list_next(&(queue->wait_head));
  48. if (le != &(queue->wait_head)) {
  49. return le2wait(le, wait_link);
  50. }
  51. return NULL;
  52. }
  53. wait_t *
  54. wait_queue_last(wait_queue_t *queue) {
  55. list_entry_t *le = list_prev(&(queue->wait_head));
  56. if (le != &(queue->wait_head)) {
  57. return le2wait(le, wait_link);
  58. }
  59. return NULL;
  60. }
  61. bool
  62. wait_queue_empty(wait_queue_t *queue) {
  63. return list_empty(&(queue->wait_head));
  64. }
  65. bool
  66. wait_in_queue(wait_t *wait) {
  67. return !list_empty(&(wait->wait_link));
  68. }
  69. void
  70. wakeup_wait(wait_queue_t *queue, wait_t *wait, uint32_t wakeup_flags, bool del) {
  71. if (del) {
  72. wait_queue_del(queue, wait);
  73. }
  74. wait->wakeup_flags = wakeup_flags;
  75. wakeup_proc(wait->proc);
  76. }
  77. void
  78. wakeup_first(wait_queue_t *queue, uint32_t wakeup_flags, bool del) {
  79. wait_t *wait;
  80. if ((wait = wait_queue_first(queue)) != NULL) {
  81. wakeup_wait(queue, wait, wakeup_flags, del);
  82. }
  83. }
  84. void
  85. wakeup_queue(wait_queue_t *queue, uint32_t wakeup_flags, bool del) {
  86. wait_t *wait;
  87. if ((wait = wait_queue_first(queue)) != NULL) {
  88. if (del) {
  89. do {
  90. wakeup_wait(queue, wait, wakeup_flags, 1);
  91. } while ((wait = wait_queue_first(queue)) != NULL);
  92. }
  93. else {
  94. do {
  95. wakeup_wait(queue, wait, wakeup_flags, 0);
  96. } while ((wait = wait_queue_next(queue, wait)) != NULL);
  97. }
  98. }
  99. }
  100. void
  101. wait_current_set(wait_queue_t *queue, wait_t *wait, uint32_t wait_state) {
  102. assert(current != NULL);
  103. wait_init(wait, current);
  104. current->state = PROC_SLEEPING;
  105. current->wait_state = wait_state;
  106. wait_queue_add(queue, wait);
  107. }