]> Zhao Yanbai Git Server - kernel.git/commitdiff
新的调度逻辑
authoracevest <zhaoyanbai@126.com>
Tue, 23 May 2023 16:44:08 +0000 (00:44 +0800)
committeracevest <zhaoyanbai@126.com>
Tue, 23 May 2023 16:44:08 +0000 (00:44 +0800)
Makefile
boot/reboot.S
include/task.h
kernel/clock.c
kernel/fork.c
kernel/interrupts.S
kernel/sched.c
kernel/task_init.c
kernel/task_root.c
kernel/task_user.c

index f6e3e653294a5fbef3500d22ba9230c905666f37..e295b1f537da0eae288b5df2b18c472e9ca7e1cb 100644 (file)
--- 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
index ac1fa26767ac4166511a75d03d7bde96acf133ff..aabea799fd4b0e8e69f6da5d10689025c642015d 100644 (file)
@@ -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"
index 6b8e1d995f28eee116a572148ceeaa8ca973899a..2f39bb3ac2a7ff9894da984d0d6d39461ccccf3d 100644 (file)
@@ -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))
index a759d3ab4742bd95eb642c9651793a826cd579be..432bcd8fd8d8af60ee4bf8318f2fd07952dcf8e2 100644 (file)
 #include <system.h>
 #include <wait.h>
 
-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;
index 057fcc94416986a1c7d838bb81f9ff86d4f73fd4..3b430d1c7ef36ecfdc1dedc7dbe2576c8cac068f 100644 (file)
@@ -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;
index f86f75e234b07f273a322be1b8ba548bc60cbe18..2c68da2f8a0f4641d5fc32e092fed8139bbd90f8 100644 (file)
@@ -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
index c97b1ea5cd0a3f9711e49b43abdc25a076185785..9f1fb61fbcb2c4101b36c8649387c5abf08f67b6 100644 (file)
@@ -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() {
index b46df5e528484f15f629fedbf9bc1c142eb9ce53..3e5e9bd2014b6323d6e4a51d6a0c2a8aab4f0daf 100644 (file)
@@ -11,7 +11,7 @@
 #include <types.h>
 
 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);
     }
 }
index 13835b7dc09eaca22c083b355881e4460fe6ffe0..6fb8360f6595a988289965f067e88a3d0c08e49c 100644 (file)
@@ -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;");
     }
index 288f67a72abd0eae92bb5c35d2dd34e9c5bd8348..bcbcda1b2bf7e3f99534eb9b592ec1d8d94dd9e4 100644 (file)
@@ -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));