From: acevest Date: Sun, 11 Jan 2026 02:01:38 +0000 (+0800) Subject: 时间片轮转调度 X-Git-Url: http://repos.zhaoyanbai.com/?a=commitdiff_plain;h=f123b175f3a31aafe20ec82d4eb828dd40e0ff4b;p=kernel.git 时间片轮转调度 --- diff --git a/include/task.h b/include/task.h index 8863461..729bcbc 100644 --- a/include/task.h +++ b/include/task.h @@ -57,9 +57,9 @@ typedef union task_union { uint32_t eip; int ticks; - uint32_t turn; // 时间片用完次数 - uint32_t priority; - uint64_t jiffies; + + int priority; + int64_t jiffies; volatile int need_resched; diff --git a/kernel/ap.c b/kernel/ap.c index 617ba76..f2a79aa 100644 --- a/kernel/ap.c +++ b/kernel/ap.c @@ -306,7 +306,7 @@ const char* task_state(unsigned int state) { void print_all_tasks() { extern task_t* monitor_tasks[]; - printl(MPL_TASK_TITLE, " NAME STATE TK/PI REASON SCHED KEEP TURN"); + printl(MPL_TASK_TITLE, " NAME STATE TK/PI REASON SCHED KEEP"); for (int i = 0; i < 10; i++) { task_t* p = monitor_tasks[i]; @@ -315,7 +315,7 @@ void print_all_tasks() { continue; } - printl(MPL_TASK_0 + p->pid, "a%08x %-6s:%u %s %02u/%02u %-10s %-9u %-9u %-9u", + printl(MPL_TASK_0 + p->pid, "%08x %-6s:%u %s %02d/%02u %-10s %-9u %-9u", p, // p->name, // p->pid, // @@ -324,8 +324,7 @@ void print_all_tasks() { p->priority, // p->reason, // p->sched_cnt, // - p->sched_keep_cnt, // - p->turn // + p->sched_keep_cnt // ); } } diff --git a/kernel/clock.c b/kernel/clock.c index 21fe47a..9ed4e5f 100644 --- a/kernel/clock.c +++ b/kernel/clock.c @@ -31,17 +31,6 @@ void clk_handler(unsigned int irq, pt_regs_t* regs, void* dev_id) { current->jiffies = jiffies; - // 中断目前虽然不能嵌套,但依然可以打断前一个中断的下半部分处理 - // 若前一个时钟中断将这个值减到0,会将该进程设置为need_resched,同时分配新的时间片值,以在下半部处理完后再重新调度就绪进程运行 - // 而如果其下半部分需要处理的事情很多,处理时间过长,两个时钟中断之间的时间还不足以处理完 - // 那么下一个时钟中断是完全可以打断还没处理完的下半部逻辑 - // 打断后该时钟中断不应该继续减少该进程的时间片,因为这会造成该进程在后续的调底中少了实际的运行时间 - if (1 == current->need_resched) { - // 这种情况必然已经发生了该时钟中断打断了下半部处理程序 - // 反之时钟中断打断了下半部处理程序不一定need_resched就为1 - return; - } - #if ENABLE_CLOCK_IRQ_WAIT if (enable_clock_irq_delay) { return; @@ -51,14 +40,6 @@ void clk_handler(unsigned int irq, pt_regs_t* regs, void* dev_id) { current->ticks--; - if (0 == current->ticks) { - current->need_resched = 1; - current->ticks = current->priority; - current->turn++; - } - - assert(current->ticks >= 0); // 防止ticks被减到0后再减溢出 - if (reenter == 0) { add_irq_bh_handler(clk_bh_handler, NULL); } diff --git a/kernel/fork.c b/kernel/fork.c index b11182b..278031b 100644 --- a/kernel/fork.c +++ b/kernel/fork.c @@ -84,7 +84,7 @@ int do_fork(pt_regs_t* regs, unsigned long flags) { tsk->ppid = current->pid; tsk->priority = current->priority; tsk->ticks = tsk->priority; - tsk->turn = 0; // + tsk->need_resched = 0; tsk->sched_cnt = 0; tsk->sched_keep_cnt = 0; diff --git a/kernel/irq.c b/kernel/irq.c index 3525f2d..95d27f2 100644 --- a/kernel/irq.c +++ b/kernel/irq.c @@ -88,9 +88,9 @@ __attribute__((regparm(1))) void irq_handler(pt_regs_t* regs) { reenter--; // 考察如果不需要调度程序,直接退出 - if (current->need_resched == 0) { - return; - } + // if (current->need_resched == 0) { + // return; + // } // if (irq != 0) { // return; diff --git a/kernel/sched.c b/kernel/sched.c index 279ced2..648b8f3 100644 --- a/kernel/sched.c +++ b/kernel/sched.c @@ -62,7 +62,6 @@ void init_root_task() { root_task.priority = 7; root_task.ticks = root_task.priority; root_task.vma_list = NULL; - root_task.turn = 0; root_task.need_resched = 0; root_task.sched_cnt = 0; root_task.sched_keep_cnt = 0; @@ -150,12 +149,11 @@ task_t* find_task(pid_t pid) { } void schedule() { - task_t* root = &root_task; + // task_t* root = &root_task; task_t* sel = 0; task_t* p = 0; list_head_t *pos = 0, *t = 0; - assert(current->ticks >= 0); assert(current->priority <= TASK_MAX_PRIORITY); unsigned long iflags; @@ -165,64 +163,40 @@ void schedule() { current->state = TASK_READY; } - list_for_each_safe(pos, t, &all_tasks) { + // task_t *head = current; + list_for_each_safe(pos, t, ¤t->list) { p = list_entry(pos, task_t, list); - - if (p == &root_task) { - continue; - } - - assert(p->state != TASK_RUN); - if (TASK_READY != p->state) { continue; } - - if (sel == 0) { - sel = p; + if (&root_task == p) { continue; } -#if 1 - if (p->priority > sel->priority) { - sel = p; - } else if (p->priority == sel->priority) { - int64_t a = p->jiffies + (p->priority - p->ticks); - int64_t b = sel->jiffies + (sel->priority - sel->ticks); - if (a < b) { - sel = p; - } - } -#endif -#if 0 - // 考察三个量 - // priority 越大越优先 - // jiffies 越小越优先 - // (priority - ticks) 表示已经使用的量,越小越优先 - // 实际简化表达式为 ticks - jiffies(选择最大的) - // 先这样写,后续可以在各项添加系数 - // 这个方法的缺点是对后面新加入的进程非常不友好 - int64_t a = sel->priority - sel->jiffies - (sel->priority - sel->ticks); - int64_t b = p->priority - p->jiffies - (p->priority - p->ticks); - if (a < b) { - sel = p; - } else if (a == b) { - if (sel->priority < p->priority) { - sel = p; - } + sel = p; + break; + } + + if (sel == 0) { + if (current->state != TASK_READY) { + sel = &root_task; + root_task.ticks = root_task.priority; + root_task.state = TASK_READY; + } else { + sel = current; } -#endif } task_t* prev = current; - task_t* next = sel != 0 ? sel : root; - - prev->need_resched = 0; + task_t* next = sel; next->state = TASK_RUN; next->reason = ""; if (prev != next) { + if (prev->ticks <= 0) { + prev->ticks = prev->priority; + } next->sched_cnt++; context_switch(prev, next); } else {