From 4d1053dd6d12556206045c4f0e6c4603cf0c4f01 Mon Sep 17 00:00:00 2001 From: acevest Date: Wed, 24 May 2023 00:44:08 +0800 Subject: [PATCH] =?utf8?q?=E6=96=B0=E7=9A=84=E8=B0=83=E5=BA=A6=E9=80=BB?= =?utf8?q?=E8=BE=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit --- Makefile | 5 +++ boot/reboot.S | 2 +- include/task.h | 7 ++-- kernel/clock.c | 9 +++-- kernel/fork.c | 3 +- kernel/interrupts.S | 6 ++-- kernel/sched.c | 84 ++++++++++++++++++++++++++------------------- kernel/task_init.c | 3 +- kernel/task_root.c | 9 ++--- kernel/task_user.c | 2 +- 10 files changed, 76 insertions(+), 54 deletions(-) diff --git a/Makefile b/Makefile index f6e3e65..e295b1f 100644 --- a/Makefile +++ b/Makefile @@ -50,13 +50,16 @@ ${KERNELBIN}: ${OBJS} %.c.o: %.c ${HEADER_FILES} ${CC} ${CFLAGS} $< -o $@ +.PHONY: c c: rm -f $(KERNELBIN) +.PHONY: clean clean: rm -f $(OBJS) rm -f $(KERNELBIN) $(SYSTEMMAP) +.PHONY: install install: cp -p KERNEL.BIN /boot/ sync @@ -65,6 +68,8 @@ install: mkdir -p /kernel/bin/ cp bin/hello /kernel/bin/ cp bin/shell /kernel/bin/ + +.PHONY: cp cp: cd bin && make clean cd bin && make diff --git a/boot/reboot.S b/boot/reboot.S index ac1fa26..aabea79 100644 --- a/boot/reboot.S +++ b/boot/reboot.S @@ -159,4 +159,4 @@ Code16End: msg_reboot: .asciz "\nREBOOTING...........\n" -msg_poweroff: .asciz "\nSHUTDOWN SYSTEM NOW......\n" \ No newline at end of file +msg_poweroff: .asciz "\nSHUTDOWN SYSTEM NOW......\n" diff --git a/include/task.h b/include/task.h index 6b8e1d9..2f39bb3 100644 --- a/include/task.h +++ b/include/task.h @@ -43,8 +43,9 @@ typedef union task_union { unsigned long esp; unsigned long eip; - long weight; - long priority; + uint32_t ticks; + uint32_t priority; + uint32_t jiffies; pid_t pid; pid_t ppid; @@ -86,7 +87,7 @@ task_union *find_task(pid_t pid); #define ROOT_TSK_PID (0) -#define TASK_INIT_WEIGHT 0 +// #define TASK_INIT_WEIGHT 0 #define get_tsk_from_list(p) list_entry((p), Task, list) #define del_tsk_from_list(tsk) list_del((&tsk->list)) diff --git a/kernel/clock.c b/kernel/clock.c index a759d3a..432bcd8 100644 --- a/kernel/clock.c +++ b/kernel/clock.c @@ -15,13 +15,11 @@ #include #include -volatile unsigned int jiffies = 0; +volatile uint32_t jiffies = 0; unsigned int sys_clock() { return jiffies; } void clk_handler(unsigned int irq, pt_regs_t *regs, void *dev_id) { - jiffies++; - if (jiffies % 100 == 0) { printl(MPL_CLOCK, "clock irq: %d", jiffies); } @@ -29,6 +27,11 @@ void clk_handler(unsigned int irq, pt_regs_t *regs, void *dev_id) { unsigned long iflags; irq_save(iflags); + jiffies++; + + current->jiffies = jiffies; + current->ticks--; + task_union *p = 0; list_head_t *t = 0; list_head_t *pos = 0; diff --git a/kernel/fork.c b/kernel/fork.c index 057fcc9..3b430d1 100644 --- a/kernel/fork.c +++ b/kernel/fork.c @@ -85,6 +85,8 @@ int do_fork(pt_regs_t *regs, unsigned long flags) { tsk->pid = get_next_pid(); tsk->ppid = current->pid; + tsk->priority = current->priority; + tsk->ticks = tsk->priority; pt_regs_t *child_regs = ((pt_regs_t *)(TASK_SIZE + (unsigned long)tsk)) - 1; @@ -105,7 +107,6 @@ int do_fork(pt_regs_t *regs, unsigned long flags) { printk("tsk %08x child_regs esp %08x esp0 %08x\n", tsk, tsk->esp, tsk->esp0); tsk->state = TASK_INITING; - tsk->weight = TASK_INIT_WEIGHT; INIT_LIST_HEAD(&tsk->list); unsigned long iflags; diff --git a/kernel/interrupts.S b/kernel/interrupts.S index f86f75e..2c68da2 100644 --- a/kernel/interrupts.S +++ b/kernel/interrupts.S @@ -53,7 +53,7 @@ DEF_IRQ(0,F) .global _irq_handler .extern irq_handler .extern schedule -.extern irq_reenter +.extern try_to_reschedule _irq_handler: SAVE_REGS @@ -70,10 +70,8 @@ _irq_handler: movl %esp, %eax call irq_handler - cmpl $0, (irq_reenter) - jnz restore_regs - call schedule + call try_to_reschedule restore_regs: RESTORE_REGS diff --git a/kernel/sched.c b/kernel/sched.c index c97b1ea..9f1fb61 100644 --- a/kernel/sched.c +++ b/kernel/sched.c @@ -56,8 +56,8 @@ void init_root_task() { root_task.pid = get_next_pid(); root_task.ppid = 0; root_task.state = TASK_READY; - root_task.weight = TASK_INIT_WEIGHT; - root_task.priority = 100; + root_task.priority = 7; + root_task.ticks = root_task.priority; strcpy(root_task.name, "root"); list_add(&root_task.list, &all_tasks); @@ -163,7 +163,8 @@ extern uint32_t disk_handled_cnt; extern uint32_t disk_inter_cnt; unsigned long schedule() { - task_union *sel = &root_task; + task_union *root = &root_task; + task_union *sel = 0; task_union *p = 0; list_head_t *pos = 0, *t = 0; @@ -174,52 +175,51 @@ unsigned long schedule() { printl(MPL_X, "disk req %u consumed %u irq %u", disk_request_cnt, disk_handled_cnt, disk_inter_cnt); #if 1 - bool need_reset_weight = true; list_for_each_safe(pos, t, &all_tasks) { p = list_entry(pos, task_union, list); - if (p == &root_task) { continue; } - if (p->state != TASK_READY) { continue; } - if (p->weight < p->priority) { - need_reset_weight = false; - break; - } - } - - if (need_reset_weight) { - list_for_each_safe(pos, t, &all_tasks) { - p = list_entry(pos, task_union, list); - if (p->state != TASK_READY) { - continue; + if (sel == 0) { + sel = p; + } else if (sel->jiffies >= p->jiffies) { + uint32_t delta = sel->jiffies - p->jiffies; + if (delta > 3 * p->ticks) { + sel = p; } - p->weight = 0; } } - list_for_each_safe(pos, t, &all_tasks) { - p = list_entry(pos, task_union, list); - if (p == &root_task) { - continue; - } - if (p->state != TASK_READY) { - continue; - } + sel = sel != 0 ? sel : root; - if (p->weight > p->priority) { - continue; - } + irq_restore(iflags); + sel->sched_cnt++; + // printk("%08x %s ticks %d state: %s\n", sel, sel->name, sel->ticks, task_state(sel->state)); + task_union *prev = current; + task_union *next = sel; - if (p->weight < sel->weight) { - sel = p; + if (prev != next) { + // printk("switch to: %s:%d\n", next->name, next->pid); + list_for_each_safe(pos, t, &all_tasks) { + p = list_entry(pos, task_union, list); + printl(MPL_TASK_0 + p->pid, " "); // 清掉上一次显示的 '>' + printl(MPL_TASK_0 + p->pid, "%s%4s:%d [%08x] state %s ticks %03d %02d sched %u", next == p ? ">" : " ", + p->name, p->pid, p, task_state(p->state), p->ticks, p->priority, p->sched_cnt); } + context_switch(prev, next); } #else + task_union *sel = &root_task; + task_union *p = 0; + list_head_t *pos = 0, *t = 0; + + unsigned long iflags; + irq_save(iflags); + float min_ratio = 1.0; bool need_reset_weight = true; list_for_each_safe(pos, t, &all_tasks) { @@ -258,12 +258,11 @@ unsigned long schedule() { min_ratio = ratio; } } -#endif irq_restore(iflags); sel->sched_cnt++; - sel->weight += 13; - // printk("%08x %s weight %d state: %s\n", sel, sel->name, sel->weight, task_state(sel->state)); + sel->ticks += 13; + // printk("%08x %s ticks %d state: %s\n", sel, sel->name, sel->ticks, task_state(sel->state)); task_union *prev = current; task_union *next = sel; @@ -272,11 +271,24 @@ unsigned long schedule() { list_for_each_safe(pos, t, &all_tasks) { p = list_entry(pos, task_union, list); printl(MPL_TASK_0 + p->pid, " "); // 清掉上一次显示的 '>' - printl(MPL_TASK_0 + p->pid, "%s%4s:%d [%08x] state %s weight %03d %03d sched %u", next == p ? ">" : " ", - p->name, p->pid, p, task_state(p->state), p->weight, p->priority, p->sched_cnt); + printl(MPL_TASK_0 + p->pid, "%s%4s:%d [%08x] state %s ticks %03d %03d sched %u", next == p ? ">" : " ", + p->name, p->pid, p, task_state(p->state), p->ticks, p->priority, p->sched_cnt); } context_switch(prev, next); } +#endif +} + +// 必需在关中断的情况下调用 +void try_to_reschedule() { + if (irq_reenter != 0) { + return; + } + + if (0 == current->ticks) { + current->ticks = current->priority; + schedule(); + } } void debug_sched() { diff --git a/kernel/task_init.c b/kernel/task_init.c index b46df5e..3e5e9bd 100644 --- a/kernel/task_init.c +++ b/kernel/task_init.c @@ -11,7 +11,7 @@ #include void init_task_entry() { - current->priority = 100; + current->priority = 10; // 继续内核未完成的初始化 // 这些初始化在开中断的情况下完成 @@ -20,5 +20,6 @@ void init_task_entry() { while (1) { asm("hlt;"); + sysc_wait(2); } } diff --git a/kernel/task_root.c b/kernel/task_root.c index 13835b7..6fb8360 100644 --- a/kernel/task_root.c +++ b/kernel/task_root.c @@ -90,7 +90,7 @@ u16 disk_buf1[256]; u16 disk_buf2[256]; void taskA_entry() { - current->priority = 99; + current->priority = 9; while (1) { sysc_wait(7); @@ -114,7 +114,7 @@ void taskA_entry() { } void taskB_entry() { - current->priority = 99; + current->priority = 9; while (1) { sysc_wait(10); @@ -136,7 +136,7 @@ void taskB_entry() { } void taskC_entry() { - current->priority = 99; + current->priority = 19; while (1) { sysc_wait(2); @@ -163,7 +163,7 @@ void root_task_entry() { kernel_task("init", init_task_entry); kernel_task("disk", disk_task_entry); - kernel_task("user", user_task_entry); + // kernel_task("user", user_task_entry); // for (int i = 0; i < 100; i++) { // asm("hlt;"); @@ -173,6 +173,7 @@ void root_task_entry() { kernel_task("tskB", taskB_entry); kernel_task("tskC", taskC_entry); + current->priority = 1; while (1) { asm("hlt;"); } diff --git a/kernel/task_user.c b/kernel/task_user.c index 288f67a..bcbcda1 100644 --- a/kernel/task_user.c +++ b/kernel/task_user.c @@ -53,7 +53,7 @@ void __ring3text__ __attribute__((__aligned__(PAGE_SIZE))) ring3_entry() { } void user_task_entry() { - current->priority = 90; + current->priority = 7; unsigned long ring3_text_page = va2pa(ring3_entry); unsigned long ring3_bss_page = va2pa(alloc_one_page(0)); -- 2.44.0