]> Zhao Yanbai Git Server - kernel.git/commitdiff
重写超时唤醒逻辑
authoracevest <zhaoyanbai@126.com>
Thu, 13 Aug 2026 10:22:27 +0000 (18:22 +0800)
committeracevest <zhaoyanbai@126.com>
Thu, 13 Aug 2026 10:22:38 +0000 (18:22 +0800)
include/clock.h [new file with mode: 0644]
include/sched.h
include/task.h
include/timer.h [new file with mode: 0644]
kernel/clock.c
kernel/fork.c
kernel/irq.c
kernel/sched.c
kernel/syscall.c
kernel/timer.c [new file with mode: 0644]

diff --git a/include/clock.h b/include/clock.h
new file mode 100644 (file)
index 0000000..8936631
--- /dev/null
@@ -0,0 +1,12 @@
+/*
+ * ------------------------------------------------------------------------
+ *   File Name: clock.h
+ *      Author: Zhao Yanbai
+ *              2026-08-13 18:13:37 Thursday CST
+ * Description: none
+ * ------------------------------------------------------------------------
+ */
+
+#pragma once
+
+extern volatile uint64_t jiffies;
\ No newline at end of file
index 0205dbcb7a96c311c292ea4e0d8449c9a704efa8..47322ec71fec4123d2a561eae0ad20482ca2f769 100644 (file)
@@ -30,4 +30,3 @@ extern task_t root_task;
 extern void load_cr3(task_t* tsk);
 
 extern list_head_t all_tasks;
-extern list_head_t delay_tasks;
index 1232ffd727ca2e63452471fe833e9a1ef7ee5c22..dcb263d3e39ef3ffd2543f0620bf8be17ece0940 100644 (file)
@@ -83,21 +83,13 @@ typedef union task_union {
 
         vm_area_t* vma_list;
 
-        list_head_t list;  // 所有进程串成一个链表
-
+        list_head_t list;        // 所有进程串成一个链表
         list_head_t ready_list;  // 就绪队列
-
         list_head_t waitq_list;
 
-        list_head_t pend;  // 某些条件串成一个链表
-
-        // list_head_t wait;
-
         uint32_t sched_cnt;       // 被调度换上CPU的次数
         uint32_t sched_keep_cnt;  // 时间片到了,但是没有被换出,又重新执行的次数
 
-        uint64_t delay_jiffies;  // debug only
-
         uint64_t magic;  // 栈溢出标志
     };
 
@@ -129,6 +121,8 @@ void task_set_run(task_t* t);
 void task_set_ready(task_t* t);
 void task_set_wait(task_t* t);
 
+void task_init_lists(task_t* t);
+
 #endif  // ASM
 
 #endif  //_TASK_H
diff --git a/include/timer.h b/include/timer.h
new file mode 100644 (file)
index 0000000..02e3cc6
--- /dev/null
@@ -0,0 +1,33 @@
+/*
+ * ------------------------------------------------------------------------
+ *   File Name: timer.h
+ *      Author: Zhao Yanbai
+ *              2026-08-13 16:02:25 Thursday CST
+ * Description: none
+ * ------------------------------------------------------------------------
+ */
+
+#pragma once
+
+#include <list.h>
+#include <types.h>
+
+typedef struct timer timer_t;
+
+typedef void (*timer_callback_t)(void* arg);
+
+struct timer {
+    list_head_t list;
+    uint64_t expires;
+
+    timer_callback_t callback;
+    void* callback_arg;
+};
+
+void timer_init(timer_t* timer, uint64_t expires, timer_callback_t callback, void* callback_arg);
+
+void timer_add(timer_t* timer);
+
+void timer_del(timer_t* timer);
+
+void timer_run_expired_timers();
\ No newline at end of file
index 779893ef7745ef16c0dbc9cea2903b9471c832a8..ab1881e82c0a21b2b4bca36870592ac427efc16c 100644 (file)
 #include <printk.h>
 #include <sched.h>
 #include <system.h>
+#include <timer.h>
 
 volatile uint64_t jiffies = 0;  // TODO uint64: undefined reference to `__umoddi3'
 
-unsigned int sys_clock() {
-    return jiffies;
-}
-
 void clk_bh_handler(void* arg);
 
 extern volatile bool enable_clock_irq_delay;
@@ -46,24 +43,8 @@ void clk_handler(unsigned int irq, pt_regs_t* regs, void* dev_id) {
 
 // 开中断执行这个函数
 // 后续放到一个内核任务中去做,需要先把禁止内核抢占做了
-const char* task_state(unsigned int state);
 void clk_bh_handler(void* arg) {
-    task_t* p = 0;
-    list_head_t* t = 0;
-    list_head_t* pos = 0;
-    list_for_each_safe(pos, t, &delay_tasks) {
-        p = list_entry(pos, task_t, pend);
-        // printk("%s state: %s\n", p->name, task_state(p->state));
-        assert(p->state == TASK_WAIT);
-        assert(p->delay_jiffies != 0);
-        if (p->delay_jiffies > 0 && jiffies > p->delay_jiffies) {
-            list_del_init(&p->pend);
-            p->delay_jiffies = 0;
-            // p->state = TASK_READY;
-            task_set_ready(p);
-            p->reason = "clk_bh";
-        }
-    }
+    timer_run_expired_timers();
 }
 
 uint16_t read_i8254_counter(uint8_t counter_no) {
index 1d10cd1d7e01ad4da50f07519f7d537e9c024900..962a1b07c48d0e0bff20b0cf6e97ef25f213c896 100644 (file)
@@ -31,10 +31,8 @@ int do_fork(pt_regs_t* regs, unsigned long flags) {
 
     tsk->state = TASK_INITING;
 
-    INIT_LIST_HEAD(&tsk->list);
-    INIT_LIST_HEAD(&tsk->ready_list);
-    INIT_LIST_HEAD(&tsk->waitq_list);
-    INIT_LIST_HEAD(&tsk->pend);
+    task_init_lists(tsk);
+
     unsigned long iflags;
     irq_save(iflags);
     list_add(&tsk->list, &all_tasks);
index 48a5db159d3e3599b80c7a4a350470b26d1b7987..4264233259bdd074d61af11a3a504e35140cd4d2 100644 (file)
@@ -20,6 +20,7 @@
 #include <irq.h>
 #include <system.h>
 #include <task.h>
+#include <clock.h>
 
 irq_desc_t irq_desc[NR_IRQS];
 irq_bh_action_t* irq_bh_actions = NULL;
@@ -107,12 +108,10 @@ __attribute__((regparm(1))) void irq_handler(pt_regs_t* regs) {
 #endif
 }
 
-extern uint32_t jiffies;
-
 volatile bool enable_clock_irq_delay = false;
 
 void irq_bh_handler() {
-    uint32_t end = jiffies + 1;
+    uint64_t end = jiffies + 1;
 
 // ENABLE_CLOCK_IRQ_WAIT是用来调试的
 // 是为了让时钟减缓进程的时间片更慢一点,以便于调试
index 45ad0a2de17f453bd1a1400442263f6a19efaa69..e4705d2302509f83a1319fdefd192bbd15dd9468 100644 (file)
@@ -46,7 +46,6 @@ extern pde_t __initdata init_pgd[PDECNT_PER_PAGE] __attribute__((__aligned__(PAG
 
 LIST_HEAD(all_tasks);
 LIST_HEAD(ready_tasks);
-LIST_HEAD(delay_tasks);
 
 void init_root_task() {
     int i;
@@ -64,10 +63,7 @@ void init_root_task() {
     root_task.magic = TASK_MAGIC;
     strcpy(root_task.name, "root");
 
-    INIT_LIST_HEAD(&root_task.list);
-    INIT_LIST_HEAD(&root_task.ready_list);
-    INIT_LIST_HEAD(&root_task.pend);
-    // INIT_LIST_HEAD(&root_task.next);
+    task_init_lists(&root_task);
 
     list_add(&root_task.list, &all_tasks);
 
@@ -92,7 +88,6 @@ kmem_cache_t* task_t_cache;
 void setup_tasks() {
     INIT_LIST_HEAD(&all_tasks);
     INIT_LIST_HEAD(&ready_tasks);
-    INIT_LIST_HEAD(&delay_tasks);
 
     init_root_task();
 
@@ -226,4 +221,12 @@ void task_set_wait(task_t* t) {
     t->state = TASK_WAIT;
 
     irq_restore(eflags);
+}
+
+void task_init_lists(task_t* t) {
+    assert(t != NULL);
+
+    INIT_LIST_HEAD(&t->list);
+    INIT_LIST_HEAD(&t->ready_list);
+    INIT_LIST_HEAD(&t->waitq_list);
 }
\ No newline at end of file
index fa0323ae92ea86e9990e6ff1fae9c4df18b28366..8f8dcbb47fb9ece324c92f18a11dddf01734dc02 100644 (file)
@@ -18,6 +18,8 @@
 #include "msr.h"
 #include "sched.h"
 #include "system.h"
+#include "timer.h"
+#include "clock.h"
 
 extern void syscall_entry();
 extern void init_sysc_handler_table();
@@ -39,7 +41,10 @@ int sysc_none() {
     return 0;
 }
 
-extern uint64_t jiffies;
+static void timer_waitq_wakeup_one_cb(void* arg) {
+    waitq_t* waitq = (waitq_t*)arg;
+    waitq_wakeup_one(waitq);
+}
 
 // 特别说明:如果想把这个函数的参数ticks改为int64_t
 // 那么就需要在编写用户级的系统调用库函数的时候注意
@@ -51,16 +56,22 @@ int sysc_wait(int ticks) {
     } else {
         unsigned long flags;
         irq_save(flags);
-        // current->state = TASK_WAIT;
         assert(current->state != TASK_WAIT);
-        assert(list_empty(&current->pend));
-        task_set_wait(current);
-        current->reason = "sysc_wait";
-        current->delay_jiffies = jiffies + ticks;
-        list_add(&current->pend, &delay_tasks);
+
+        waitq_t waitq;
+        waitq_init(&waitq);
+
+        timer_t timer;
+        timer_init(&timer, jiffies + ticks, timer_waitq_wakeup_one_cb, &waitq);
+        timer_add(&timer);
+
+        waitq_sleep(&waitq);
+
+        timer_del(&timer);
+
         irq_restore(flags);
     }
-    schedule();
+
     return 0;
 }
 
diff --git a/kernel/timer.c b/kernel/timer.c
new file mode 100644 (file)
index 0000000..852a233
--- /dev/null
@@ -0,0 +1,97 @@
+/*
+ * ------------------------------------------------------------------------
+ *   File Name: timer.c
+ *      Author: Zhao Yanbai
+ *              2026-08-13 16:11:37 Thursday CST
+ * Description: none
+ * ------------------------------------------------------------------------
+ */
+
+#include <timer.h>
+#include <irq.h>
+#include <assert.h>
+#include <clock.h>
+
+void timer_init(timer_t* timer, uint64_t expires, timer_callback_t callback, void* callback_arg) {
+    assert(timer != NULL);
+
+    list_init(&timer->list);
+    timer->expires = expires;
+    timer->callback = callback;
+    timer->callback_arg = callback_arg;
+}
+
+list_head_t g_timer_list = LIST_HEAD_INIT(g_timer_list);
+
+void timer_add(timer_t* timer) {
+    assert(timer != NULL);
+    assert(list_empty(&timer->list));
+
+    unsigned long eflags;
+    irq_save(eflags);
+
+    // 按expires升序添加到g_timer_list中
+    list_head_t* prev = &g_timer_list;
+    list_head_t* pos = NULL;
+    list_for_each(pos, &g_timer_list) {
+        timer_t* current_timer = list_entry(pos, timer_t, list);
+        if (timer->expires < current_timer->expires) {
+            break;
+        }
+
+        prev = pos;
+    }
+
+    assert(prev != NULL);
+    list_add(&timer->list, prev);
+
+    irq_restore(eflags);
+}
+
+void timer_del(timer_t* timer) {
+    assert(timer != NULL);
+
+    unsigned long eflags;
+    irq_save(eflags);
+
+    list_del_init(&timer->list);
+
+    irq_restore(eflags);
+}
+
+void timer_run_expired_timers() {
+    list_head_t expire_timers = LIST_HEAD_INIT(expire_timers);
+
+    // 关中断将到期的定时器添加到临时的expire_timers链表中
+    unsigned long eflags;
+    irq_save(eflags);
+
+    list_head_t* pos = NULL;
+    list_head_t* tmp = NULL;
+    list_for_each_safe(pos, tmp, &g_timer_list) {
+        timer_t* timer = list_entry(pos, timer_t, list);
+        if (timer->expires <= jiffies) {
+            list_del_init(pos);
+
+            list_add_tail(pos, &expire_timers);
+        } else {
+            break;
+        }
+    }
+
+    irq_restore(eflags);
+
+    // 执行到期的定时器回调函数
+    pos = NULL;
+    tmp = NULL;
+    list_for_each_safe(pos, tmp, &expire_timers) {
+        timer_t* timer = list_entry(pos, timer_t, list);
+        timer_callback_t callback = timer->callback;
+        void* callback_arg = timer->callback_arg;
+        assert(callback != NULL);
+
+        list_del_init(pos);
+
+        callback(callback_arg);
+    }
+}
\ No newline at end of file