From: acevest Date: Fri, 14 Aug 2026 00:29:45 +0000 (+0800) Subject: 重写检查是否需要调度;新增系统调用返回前检查是否需要重新调度;新增waitq唤醒任务的时候标记需要重新调度 X-Git-Url: http://repos.zhaoyanbai.com/?a=commitdiff_plain;h=ac2388fa05fe8eb47cb924b7cc7226a35751f07c;p=kernel.git 重写检查是否需要调度;新增系统调用返回前检查是否需要重新调度;新增waitq唤醒任务的时候标记需要重新调度 --- diff --git a/include/sched.h b/include/sched.h index 47322ec..edb4945 100644 --- a/include/sched.h +++ b/include/sched.h @@ -25,6 +25,10 @@ void schedule(); +void set_need_schedule(); +void clear_need_schedule(); +bool need_schedule(); + extern task_t root_task; extern void load_cr3(task_t* tsk); diff --git a/include/task.h b/include/task.h index dcb263d..5b1d604 100644 --- a/include/task.h +++ b/include/task.h @@ -59,9 +59,6 @@ typedef union task_union { int ticks; int priority; - int64_t jiffies; - - volatile int need_resched; pid_t pid; pid_t ppid; diff --git a/kernel/clock.c b/kernel/clock.c index ab1881e..209deea 100644 --- a/kernel/clock.c +++ b/kernel/clock.c @@ -25,8 +25,6 @@ extern volatile bool enable_clock_irq_delay; void clk_handler(unsigned int irq, pt_regs_t* regs, void* dev_id) { jiffies++; - current->jiffies = jiffies; - #if ENABLE_CLOCK_IRQ_WAIT if (enable_clock_irq_delay) { return; @@ -36,6 +34,10 @@ void clk_handler(unsigned int irq, pt_regs_t* regs, void* dev_id) { current->ticks--; + if (current->ticks <= 0) { + set_need_schedule(); + } + if (reenter == 0) { add_irq_bh_handler(clk_bh_handler, NULL); } diff --git a/kernel/fork.c b/kernel/fork.c index 962a1b0..5f80536 100644 --- a/kernel/fork.c +++ b/kernel/fork.c @@ -85,7 +85,6 @@ int do_fork(pt_regs_t* regs, unsigned long flags) { tsk->priority = current->priority; tsk->ticks = tsk->priority; - tsk->need_resched = 0; tsk->sched_cnt = 0; tsk->sched_keep_cnt = 0; diff --git a/kernel/irq.c b/kernel/irq.c index 4264233..5100c9d 100644 --- a/kernel/irq.c +++ b/kernel/irq.c @@ -21,6 +21,7 @@ #include #include #include +#include irq_desc_t irq_desc[NR_IRQS]; irq_bh_action_t* irq_bh_actions = NULL; @@ -91,13 +92,9 @@ __attribute__((regparm(1))) void irq_handler(pt_regs_t* regs) { reenter--; // 考察如果不需要调度程序,直接退出 - // if (current->need_resched == 0) { - // return; - // } - - // if (irq != 0) { - // return; - // } + if (!need_schedule()) { + return; + } enable_irq(); diff --git a/kernel/sched.c b/kernel/sched.c index e4705d2..bdafccc 100644 --- a/kernel/sched.c +++ b/kernel/sched.c @@ -57,7 +57,6 @@ void init_root_task() { root_task.priority = 7; root_task.ticks = root_task.priority; root_task.vma_list = NULL; - root_task.need_resched = 0; root_task.sched_cnt = 0; root_task.sched_keep_cnt = 0; root_task.magic = TASK_MAGIC; @@ -134,6 +133,7 @@ void schedule() { unsigned long eflags; irq_save(eflags); + // 把自己挂到就绪队列尾部 if (prev->state == TASK_READY || prev->state == TASK_RUN) { task_set_ready(prev); } @@ -156,6 +156,8 @@ end: prev->ticks = prev->priority; } + clear_need_schedule(); + if (prev != next) { next->sched_cnt++; context_switch(prev, next); @@ -176,10 +178,10 @@ void add_task_for_monitor(task_t* tsk) { void task_set_run(task_t* t) { assert(t != NULL); - if (t == &root_task) { - t->state = TASK_RUN; - return; - } + // if (t == &root_task) { + // t->state = TASK_RUN; + // return; + // } assert(t->state == TASK_READY); @@ -229,4 +231,20 @@ void task_init_lists(task_t* t) { INIT_LIST_HEAD(&t->list); INIT_LIST_HEAD(&t->ready_list); INIT_LIST_HEAD(&t->waitq_list); +} + +/// + +static volatile bool _need_schedule = false; + +void set_need_schedule() { + _need_schedule = true; +} + +void clear_need_schedule() { + _need_schedule = false; +} + +bool need_schedule() { + return _need_schedule; } \ No newline at end of file diff --git a/kernel/syscall.S b/kernel/syscall.S index a1fce55..657e4e5 100644 --- a/kernel/syscall.S +++ b/kernel/syscall.S @@ -27,6 +27,7 @@ .global syscall_entry .global ret_from_fork_krnl .extern reenter +.extern sysc_check_resched //.global syscall_exit syscall_entry: @@ -72,6 +73,8 @@ syscall_entry: // 保存返回值 movl %eax, PT_REGS_EAX(%esp) + call sysc_check_resched + RESTORE_REGS diff --git a/kernel/syscall.c b/kernel/syscall.c index 8f8dcbb..0dfb2ce 100644 --- a/kernel/syscall.c +++ b/kernel/syscall.c @@ -129,3 +129,14 @@ int sysc_bad_nr() { return -1; } + +void sysc_check_resched() { + unsigned long eflags; + irq_save(eflags); + if (need_schedule()) { + if (!IN_CRITICAL_ZONE()) { + schedule(); + } + } + irq_restore(eflags); +} \ No newline at end of file diff --git a/kernel/waitq.c b/kernel/waitq.c index ad8ea70..1502fe2 100644 --- a/kernel/waitq.c +++ b/kernel/waitq.c @@ -32,6 +32,9 @@ void waitq_wakeup(waitq_t* waitq, int cnt) { assert(waitq != NULL); assert(cnt >= 0); + // 是否唤醒了任务,如果唤醒了任务就将当前任务标记为需要调度,以便新任务更快可以被调度 + bool woken_task = false; + for (int i = 0; ((i < cnt) || (cnt == 0)); i++) { if (list_empty(&waitq->list)) { break; @@ -44,6 +47,12 @@ void waitq_wakeup(waitq_t* waitq, int cnt) { list_del_init(&task->waitq_list); task_set_ready(task); + + woken_task = true; + } + + if (woken_task) { + set_need_schedule(); } }