From ac2388fa05fe8eb47cb924b7cc7226a35751f07c Mon Sep 17 00:00:00 2001 From: acevest Date: Fri, 14 Aug 2026 08:29:45 +0800 Subject: [PATCH] =?utf8?q?=E9=87=8D=E5=86=99=E6=A3=80=E6=9F=A5=E6=98=AF?= =?utf8?q?=E5=90=A6=E9=9C=80=E8=A6=81=E8=B0=83=E5=BA=A6;=E6=96=B0=E5=A2=9E?= =?utf8?q?=E7=B3=BB=E7=BB=9F=E8=B0=83=E7=94=A8=E8=BF=94=E5=9B=9E=E5=89=8D?= =?utf8?q?=E6=A3=80=E6=9F=A5=E6=98=AF=E5=90=A6=E9=9C=80=E8=A6=81=E9=87=8D?= =?utf8?q?=E6=96=B0=E8=B0=83=E5=BA=A6;=E6=96=B0=E5=A2=9Ewaitq=E5=94=A4?= =?utf8?q?=E9=86=92=E4=BB=BB=E5=8A=A1=E7=9A=84=E6=97=B6=E5=80=99=E6=A0=87?= =?utf8?q?=E8=AE=B0=E9=9C=80=E8=A6=81=E9=87=8D=E6=96=B0=E8=B0=83=E5=BA=A6?= MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit --- include/sched.h | 4 ++++ include/task.h | 3 --- kernel/clock.c | 6 ++++-- kernel/fork.c | 1 - kernel/irq.c | 11 ++++------- kernel/sched.c | 28 +++++++++++++++++++++++----- kernel/syscall.S | 3 +++ kernel/syscall.c | 11 +++++++++++ kernel/waitq.c | 9 +++++++++ 9 files changed, 58 insertions(+), 18 deletions(-) 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(); } } -- 2.47.0