From 2d0c6ce1886d3fccfa99b8e1892465fd7dca5e3f Mon Sep 17 00:00:00 2001 From: acevest Date: Thu, 13 Aug 2026 18:22:27 +0800 Subject: [PATCH] =?utf8?q?=E9=87=8D=E5=86=99=E8=B6=85=E6=97=B6=E5=94=A4?= =?utf8?q?=E9=86=92=E9=80=BB=E8=BE=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit --- include/clock.h | 12 ++++++ include/sched.h | 1 - include/task.h | 12 ++---- include/timer.h | 33 ++++++++++++++++ kernel/clock.c | 23 +----------- kernel/fork.c | 6 +-- kernel/irq.c | 5 +-- kernel/sched.c | 15 +++++--- kernel/syscall.c | 27 ++++++++++---- kernel/timer.c | 97 ++++++++++++++++++++++++++++++++++++++++++++++++ 10 files changed, 179 insertions(+), 52 deletions(-) create mode 100644 include/clock.h create mode 100644 include/timer.h create mode 100644 kernel/timer.c diff --git a/include/clock.h b/include/clock.h new file mode 100644 index 0000000..8936631 --- /dev/null +++ b/include/clock.h @@ -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 diff --git a/include/sched.h b/include/sched.h index 0205dbc..47322ec 100644 --- a/include/sched.h +++ b/include/sched.h @@ -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; diff --git a/include/task.h b/include/task.h index 1232ffd..dcb263d 100644 --- a/include/task.h +++ b/include/task.h @@ -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 index 0000000..02e3cc6 --- /dev/null +++ b/include/timer.h @@ -0,0 +1,33 @@ +/* + * ------------------------------------------------------------------------ + * File Name: timer.h + * Author: Zhao Yanbai + * 2026-08-13 16:02:25 Thursday CST + * Description: none + * ------------------------------------------------------------------------ + */ + +#pragma once + +#include +#include + +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 diff --git a/kernel/clock.c b/kernel/clock.c index 779893e..ab1881e 100644 --- a/kernel/clock.c +++ b/kernel/clock.c @@ -14,13 +14,10 @@ #include #include #include +#include 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) { diff --git a/kernel/fork.c b/kernel/fork.c index 1d10cd1..962a1b0 100644 --- a/kernel/fork.c +++ b/kernel/fork.c @@ -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); diff --git a/kernel/irq.c b/kernel/irq.c index 48a5db1..4264233 100644 --- a/kernel/irq.c +++ b/kernel/irq.c @@ -20,6 +20,7 @@ #include #include #include +#include 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是用来调试的 // 是为了让时钟减缓进程的时间片更慢一点,以便于调试 diff --git a/kernel/sched.c b/kernel/sched.c index 45ad0a2..e4705d2 100644 --- a/kernel/sched.c +++ b/kernel/sched.c @@ -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 diff --git a/kernel/syscall.c b/kernel/syscall.c index fa0323a..8f8dcbb 100644 --- a/kernel/syscall.c +++ b/kernel/syscall.c @@ -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(¤t->pend)); - task_set_wait(current); - current->reason = "sysc_wait"; - current->delay_jiffies = jiffies + ticks; - list_add(¤t->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 index 0000000..852a233 --- /dev/null +++ b/kernel/timer.c @@ -0,0 +1,97 @@ +/* + * ------------------------------------------------------------------------ + * File Name: timer.c + * Author: Zhao Yanbai + * 2026-08-13 16:11:37 Thursday CST + * Description: none + * ------------------------------------------------------------------------ + */ + +#include +#include +#include +#include + +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 -- 2.47.0