]> Zhao Yanbai Git Server - kernel.git/commitdiff
添加wait_event用于替换sleep_on
authoracevest <zhaoyanbai@126.com>
Wed, 17 Nov 2021 15:59:30 +0000 (23:59 +0800)
committeracevest <zhaoyanbai@126.com>
Wed, 17 Nov 2021 15:59:39 +0000 (23:59 +0800)
include/sched.h
include/system.h
include/wait.h
kernel/sched.c
kernel/wait.c

index c2abf48e9078b587a785b0437788f714151094c3..6be62034d5e3fbc05a4a7f118bf95bf23cde32ea 100644 (file)
@@ -16,8 +16,9 @@
 
 #pragma once
 
+#include <irq.h>
+#include <system.h>
 #include <task.h>
-#include <wait.h>
 
 #define FORK_USER 0
 #define FORK_KRNL 1
@@ -31,4 +32,10 @@ extern task_union root_task;
 extern void load_cr3(task_union *tsk);
 
 extern list_head_t all_tasks;
-extern list_head_t delay_tasks;
\ No newline at end of file
+extern list_head_t delay_tasks;
+
+#define set_current_state(st)  \
+    do {                       \
+        current->state = (st); \
+        mb();                  \
+    } while (0)
index a301f3b8b4683c0c1967d22eb32d4e0a1ecd64c2..7aa46f4c4ceacd4da30e9189f6fe3660b5fc3419 100644 (file)
@@ -76,6 +76,7 @@ extern char gdtr[6], idtr[6];
 #define cli() __asm__ __volatile__("cli")
 #define sti() __asm__ __volatile__("sti")
 #define nop() asm volatile("nop")
+#define mb() asm volatile("" ::: "memory")
 #define disableIRQ() cli()
 #define enableIRQ() sti()
 
index 2f79426084c92f76138f34983edf21d2ab20c841..7fe371a9538890f92085a899252300c4eafa9ce4 100644 (file)
@@ -32,8 +32,30 @@ typedef struct {
 #define DECLARE_WAIT_QUEUE(name, tsk) wait_queue_t name = WAIT_QUEUE_INITIALIZER(name, tsk)
 
 void init_wait_queue_head(wait_queue_head_t *wqh);
-void add_wait_queue(wait_queue_head_t *wqh, wait_queue_t *wq);
-void del_wait_queue(wait_queue_head_t *wqh, wait_queue_t *wq);
+void add_wait_queue(wait_queue_head_t *head, wait_queue_t *wq);
+void del_wait_queue(wait_queue_head_t *head, wait_queue_t *wq);
+void __do_wait(wait_queue_head_t *head, wait_queue_t *wq, unsigned int state);
+void __end_wait(wait_queue_head_t *head, wait_queue_t *wq);
 
 void sleep_on(wait_queue_head_t *head);
 void wake_up(wait_queue_head_t *head);
+
+#define __wait_event(head, condition)        \
+    do {                                     \
+        DECLARE_WAIT_QUEUE(__wait, current); \
+        while (1) {                          \
+            __do_wait(head, wa, TASK_WAIT);  \
+            if ((condition)) {               \
+                break;                       \
+            }                                \
+            schedule();                      \
+        }                                    \
+        __end_wait(head, &__wait);           \
+    } while (0)
+
+#define wait_event(head, condition)          \
+    do {                                     \
+        if (!(condition)) {                  \
+            __wait_event(head, (condition)); \
+        }                                    \
+    } while (0)
index 8b445b1a6138ee6917f526084c98ac9a8b613692..798fd7656d63945a4f1eb1d0084fed110ce8c334 100644 (file)
 
 #include "sched.h"
 
+#include <wait.h>
+
 #include "assert.h"
 #include "linkage.h"
 #include "mm.h"
 #include "msr.h"
-#include "system.h"
 
 task_union root_task __attribute__((__aligned__(PAGE_SIZE)));
 
index 1c50eb2366db76a740b663f9c9c12d1ea83dd062..bc59197437ee6e59887df8f2d051a70e35885637 100644 (file)
@@ -28,6 +28,24 @@ void del_wait_queue(wait_queue_head_t *head, wait_queue_t *wq) {
     irq_restore(flags);
 }
 
+void __do_wait(wait_queue_head_t *head, wait_queue_t *wq, unsigned int state) {
+    unsigned long flags;
+    irq_save(flags);
+    if (list_empty(&wq->task_list)) {
+        list_add_tail(&wq->task_list, &head->task_list);
+    }
+    set_current_state(state);
+    irq_restore(flags);
+}
+
+void __end_wait(wait_queue_head_t *head, wait_queue_t *wq) {
+    set_current_state(TASK_RUNNING);
+    unsigned long flags;
+    irq_save(flags);
+    list_del_init(&wq->task_list);
+    irq_restore(flags);
+}
+
 void sleep_on(wait_queue_head_t *head) {
     DECLARE_WAIT_QUEUE(wait, current);