]> Zhao Yanbai Git Server - kernel.git/commitdiff
引入TASK_RUNNING状态
authoracevest <zhaoyanbai@126.com>
Wed, 24 May 2023 06:11:30 +0000 (14:11 +0800)
committeracevest <zhaoyanbai@126.com>
Wed, 24 May 2023 06:11:30 +0000 (14:11 +0800)
17 files changed:
drivers/ide.c
include/irq.h
include/printk.h
include/sched.h
include/system.h
include/task.h
include/wait.h
kernel/assert.c
kernel/clock.c
kernel/fork.c
kernel/interrupts.S
kernel/irq.c
kernel/sched.c
kernel/syscall.c
kernel/task_root.c
kernel/task_user.c
kernel/wait.c

index 04d0b61da48281397bac21f294f9381b25bf9f5a..da78c5cf3915975a1d1c92be8784e45b8ea2f6e8 100644 (file)
@@ -558,7 +558,7 @@ volatile uint32_t disk_inter_cnt = 0;
 void ide_irq_handler(unsigned int irq, pt_regs_t *regs, void *devid) {
     // printk("ide irq handler %d \n", irq);
 
-    printk("ide irq %d handler pci status after interrupt: %x\n", irq, ata_pci_bus_status());
+    printk("ide irq %d handler pci status: 0x%02x\n", irq, ata_pci_bus_status());
 
 #if 1
     disk_inter_cnt++;
index f59b7764b26b4449f8c64bd56c725b19f19f24b0..fc704c71e9995ba57b2a574770d89da448f07fe5 100644 (file)
@@ -59,6 +59,8 @@ int close_irq(unsigned int irq);
 
 #define irq_save(x) __asm__ __volatile__("pushfl; popl %0; cli" : "=g"(x)::"memory")
 
+bool irq_enabled();
+
 #define irq_restore(x)                                                     \
     do {                                                                   \
         typecheck(unsigned long, x);                                       \
index e60bf5b65a87a5017a9ea6076e9b8fa33752cb6f..7337ed4e322cc9481108633826fa1f39e3e62ca5 100644 (file)
@@ -36,7 +36,7 @@ enum {
     MPL_TEST,
     MPL_X,
     MPL_DEBUG,
-    MPL_ROOT,
+    MPL_TASK_TITLE,
     MPL_TASK_0,
     MPL_TASK_1,
     MPL_TASK_2,
index c0197dc93e3c8b4965d998519bb7b7885647a2b2..73883e3fdadc9d2b409baf1cdf3cba5fe0e8da96 100644 (file)
@@ -23,7 +23,7 @@
 #define FORK_USER 0
 #define FORK_KRNL 1
 
-unsigned long schedule();
+void schedule();
 
 void wake_up(wait_queue_head_t *wqh);
 
index 2721475c98e445664ec2c31665d9576a543d10cf..e54d77d7ce4827daa3a970883960873d70b74be8 100644 (file)
@@ -60,6 +60,8 @@ void kfree(void *addr);
 #define panic(msg, ...)                                                                                         \
     do {                                                                                                        \
         asm("cli;");                                                                                            \
+        printl(MPL_DEBUG, "PANIC:" msg " file:%s function:%s line:%d\n", ##__VA_ARGS__, __FILE__, __FUNCTION__, \
+               __LINE__);                                                                                       \
         printk("PANIC:" msg " file:%s function:%s line:%d\n", ##__VA_ARGS__, __FILE__, __FUNCTION__, __LINE__); \
         while (1) {                                                                                             \
             asm("hlt");                                                                                         \
index 2f39bb3ac2a7ff9894da984d0d6d39461ccccf3d..2e9509745aefe0f37f5d3b0d380397c3f1e1f613 100644 (file)
@@ -26,6 +26,7 @@
 
 enum {
     TASK_UNUSED,
+    TASK_RUNNING,
     TASK_READY,
     TASK_WAIT,
     TASK_INITING,
@@ -35,6 +36,8 @@ enum {
 
 #define TASK_NAME_SIZE 32
 
+#define TASK_MAX_PRIORITY 200
+
 typedef union task_union {
     struct {
         unsigned long esp0; /* kernel stack */
@@ -44,8 +47,9 @@ typedef union task_union {
         unsigned long eip;
 
         uint32_t ticks;
+        uint32_t turn;  // 时间片用完次数
         uint32_t priority;
-        uint32_t jiffies;
+        uint64_t jiffies;
 
         pid_t pid;
         pid_t ppid;
@@ -63,9 +67,10 @@ typedef union task_union {
 
         wait_queue_head_t wait;
 
-        unsigned int sched_cnt;
+        uint32_t sched_cnt;       // 被调度换上CPU的次数
+        uint32_t sched_keep_cnt;  // 时间片到了,但是没有被换出,又重新执行的次数
 
-        int delay_cnt;  // debug only
+        uint64_t delay_jiffies;  // debug only
     };
 
     unsigned char stack[TASK_SIZE];
index f985f9a263596deef2e025a12d611dc85ed19976..c54c0142312596d8ef232b6613eb2440aa7d0663 100644 (file)
@@ -48,7 +48,7 @@ void __end_wait(wait_queue_head_t *head, wait_queue_t *wq);
 void sleep_on(wait_queue_head_t *head);
 void wake_up(wait_queue_head_t *head);
 
-unsigned long schedule();
+void schedule();
 #define __wait_event(head, condition)                  \
     do {                                               \
         DECLARE_WAIT_QUEUE(__wait, current);           \
index 0de5c407358b7fcd2f6d94caa4a1081422523ba6..639a202773b28856a5d6cb6d67b7c88fa4690eeb 100644 (file)
@@ -13,8 +13,9 @@
 #include <printk.h>
 
 void assert_fail(char *exp, char *file, unsigned int line, const char *func) {
+    printl(MPL_DEBUG, "%s:%d: %s: Assertion \'%s\' failed.\n", file, line, func, exp);
     printk("%s:%d: %s: Assertion \'%s\' failed.\n", file, line, func, exp);
-
-    while (1)
-        ;
+    while (1) {
+        asm("cli;hlt;");
+    }
 }
index 432bcd8fd8d8af60ee4bf8318f2fd07952dcf8e2..f2ce282341891528b528b4a50b7ad42597991202 100644 (file)
@@ -31,14 +31,15 @@ void clk_handler(unsigned int irq, pt_regs_t *regs, void *dev_id) {
 
     current->jiffies = jiffies;
     current->ticks--;
+    assert(current->ticks <= TASK_MAX_PRIORITY);  // 防止ticks被减到0后再减溢出
 
     task_union *p = 0;
     list_head_t *t = 0;
     list_head_t *pos = 0;
     list_for_each_safe(pos, t, &all_tasks) {
         p = list_entry(pos, task_union, list);
-        if (0 != p->delay_cnt && jiffies > p->delay_cnt && p->state == TASK_WAIT) {
-            p->delay_cnt = 0;
+        if (0 != p->delay_jiffies && jiffies > p->delay_jiffies && p->state == TASK_WAIT) {
+            p->delay_jiffies = 0;
             p->state = TASK_READY;
         }
     }
index 3b430d1c7ef36ecfdc1dedc7dbe2576c8cac068f..6893710f40fadfdc41eec2895db4f842f20fa194 100644 (file)
@@ -87,6 +87,9 @@ 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;  //
+    root_task.sched_cnt = 0;
+    root_task.sched_keep_cnt = 0;
 
     pt_regs_t *child_regs = ((pt_regs_t *)(TASK_SIZE + (unsigned long)tsk)) - 1;
 
index 2c68da2f8a0f4641d5fc32e092fed8139bbd90f8..9be5a2457fe6d11fee5cf2990a0affb41e96989e 100644 (file)
@@ -53,7 +53,7 @@ DEF_IRQ(0,F)
 .global _irq_handler
 .extern irq_handler
 .extern schedule
-.extern try_to_reschedule
+.extern irq_reenter
 _irq_handler:
     SAVE_REGS
 
@@ -70,8 +70,9 @@ _irq_handler:
     movl    %esp, %eax
     call    irq_handler
 
-
-    call    try_to_reschedule
+    cmpl    $0, (irq_reenter)
+    jnz     restore_regs
+    call    schedule
 
 restore_regs:
     RESTORE_REGS
index 073ee2ce20fa69feaa398ceb4854437a40c3b539..0dfb65c6c293c21c0db36a39025d92d4fd211d9e 100644 (file)
@@ -114,3 +114,14 @@ int request_irq(unsigned int irq, void (*handler)(unsigned int, pt_regs_t *, voi
 int open_irq(unsigned int irq) { return irq_desc[irq].chip->enable(irq); }
 
 int close_irq(unsigned int irq) { return irq_desc[irq].chip->disable(irq); }
+
+bool irq_enabled() {
+    uint32_t flags;
+    __asm__ __volatile__("pushfl; popl %0;" : "=a"(flags));
+
+    if ((flags & (1 << 9)) != 0) {
+        return true;
+    }
+
+    return false;
+}
\ No newline at end of file
index 9f1fb61fbcb2c4101b36c8649387c5abf08f67b6..4094b956177a94114cb94b477b5997cf5d0821f9 100644 (file)
@@ -58,6 +58,9 @@ void init_root_task() {
     root_task.state = TASK_READY;
     root_task.priority = 7;
     root_task.ticks = root_task.priority;
+    root_task.turn = 0;
+    root_task.sched_cnt = 0;
+    root_task.sched_keep_cnt = 0;
     strcpy(root_task.name, "root");
 
     list_add(&root_task.list, &all_tasks);
@@ -148,7 +151,7 @@ task_union *find_task(pid_t pid) {
 
 static const char *task_state(unsigned int state) {
     static const char s[][16] = {
-        "  ERROR", "READY", " WAIT", " INIT", " EXIT",
+        "  ERROR", "RUNNING", "  READY", "   WAIT", "   INIT", "   EXIT",
     };
 
     if (state >= TASK_END) {
@@ -162,133 +165,91 @@ extern uint32_t disk_request_cnt;
 extern uint32_t disk_handled_cnt;
 extern uint32_t disk_inter_cnt;
 
-unsigned long schedule() {
+void schedule() {
     task_union *root = &root_task;
     task_union *sel = 0;
     task_union *p = 0;
     list_head_t *pos = 0, *t = 0;
 
+    printl(MPL_X, "disk req %u consumed %u irq %u", disk_request_cnt, disk_handled_cnt, disk_inter_cnt);
+
+    assert(current->ticks <= TASK_MAX_PRIORITY);
+    assert(current->priority <= TASK_MAX_PRIORITY);
+
     unsigned long iflags;
     irq_save(iflags);
-    // printl(MPL_ROOT, "root:%d [%08x] cnt %u", root_task.pid, &root_task, root_task.cnt);
 
-    printl(MPL_X, "disk req %u consumed %u irq %u", disk_request_cnt, disk_handled_cnt, disk_inter_cnt);
+    if (TASK_RUNNING == current->state) {
+        if (0 == current->ticks) {
+            current->turn++;
+            current->ticks = current->priority;
+            current->state = TASK_READY;
+        } else {
+            irq_restore(iflags);
+            return;
+        }
+    }
 
-#if 1
     list_for_each_safe(pos, t, &all_tasks) {
         p = list_entry(pos, task_union, list);
+
+        assert(p->state != TASK_RUNNING);
+
         if (p == &root_task) {
             continue;
         }
-        if (p->state != TASK_READY) {
+
+        if (TASK_READY != p->state) {
             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;
-            }
-        }
-    }
-
-    sel = sel != 0 ? sel : root;
-
-    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 (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) {
-        p = list_entry(pos, task_union, list);
-        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;
-            }
-            p->weight = 0;
-        }
-    }
-
-    list_for_each_safe(pos, t, &all_tasks) {
-        p = list_entry(pos, task_union, list);
 
-        if (p->state != TASK_READY) {
+        if (sel->jiffies < p->jiffies) {
             continue;
         }
 
-        // 貌似在Mac的M1上的qemu执行这一句会有问题
-        // 所以暂时把这整个逻辑注释掉,写了个简单的替代算法
-        float ratio = (float)(p->weight * 1.0) / (p->priority * 1.0);
-        if (ratio < min_ratio) {
-            sel = p;
-            min_ratio = ratio;
+        uint64_t delta = sel->jiffies - p->jiffies;
+
+        if (sel->priority <= p->priority) {
+            if (delta > (1 * p->ticks)) {
+                sel = p;
+            }
+        } else if (sel->priority > p->priority) {
+            if (delta > (5 * p->ticks)) {
+                sel = p;
+            }
         }
     }
 
-    irq_restore(iflags);
-    sel->sched_cnt++;
-    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;
+    task_union *next = sel != 0 ? sel : root;
 
+    next->state = TASK_RUNNING;
     if (prev != next) {
-        // printk("switch to: %s:%d\n", next->name, next->pid);
+        next->sched_cnt++;
+
+        printl(MPL_TASK_TITLE, "         NAME     STATE TK/PI TURN       SCHED      KEEP");
         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 %03d sched %u", next == p ? ">" : " ",
-                   p->name, p->pid, p, task_state(p->state), p->ticks, p->priority, p->sched_cnt);
+            printl(MPL_TASK_0 + p->pid, "%08x%s%4s:%d %s %02u/%02d %-10u %-10u %-10u", p, next == p ? ">" : " ",
+                   p->name, p->pid, task_state(p->state), p->ticks, p->priority, p->turn, p->sched_cnt,
+                   p->sched_keep_cnt);
         }
-        context_switch(prev, next);
-    }
-#endif
-}
 
-// 必需在关中断的情况下调用
-void try_to_reschedule() {
-    if (irq_reenter != 0) {
-        return;
+        context_switch(prev, next);
+    } else {
+        // 这里可能是的情况是任务把时间片ticks用完了
+        // 被设置成READY
+        // 重新高度,还是选中了该任务
+        next->sched_keep_cnt++;
     }
 
-    if (0 == current->ticks) {
-        current->ticks = current->priority;
-        schedule();
-    }
+    assert(current->state == TASK_RUNNING);
+    irq_restore(iflags);
 }
 
 void debug_sched() {
index 7749781ccb058737268bfc1e283d32aa3dcdd691..8292f19d76a573e2fae773934254c523d501af00 100644 (file)
@@ -58,7 +58,7 @@ int sysc_test() {
             return 0;
         }
 
-        current->delay_cnt = root_task.sched_cnt % 40;
+        current->delay_jiffies = root_task.sched_cnt % 40;
 
         unsigned long iflags;
         irq_save(iflags);
index 6fb8360f6595a988289965f067e88a3d0c08e49c..7c454875062b32bdf61e16886932ae1fc6d55d99 100644 (file)
@@ -141,7 +141,7 @@ void taskC_entry() {
     while (1) {
         sysc_wait(2);
 
-        for (int i = 0; i < 2; i++) {
+        for (int i = 0; i < 7; i++) {
             asm("hlt;");
         }
     }
@@ -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;");
index bcbcda1b2bf7e3f99534eb9b592ec1d8d94dd9e4..1545db92a5c1e19edaf40d6824ce7988c62348b4 100644 (file)
@@ -43,12 +43,13 @@ void __ring3text__ __attribute__((__aligned__(PAGE_SIZE))) ring3_entry() {
                             // 共享代码会利用保存在栈上的地址返回到sysexit_return_address处
             "pushl $0;"
             "pushl $0;"
+            "movl $2, %%ebx;"
             "pushl %%ebp;"
             "movl  %%esp, %%ebp;"
             "sysenter;"
             "sysexit_return_address:"
             : "=a"(__sysc_ret__)
-            : "a"(SYSC_TEST), "c"(ring3_entry));
+            : "a"(SYSC_WAIT), "c"(ring3_entry));
     }
 }
 
index e3d2df59097ddfbdff8a4381a85d52e1322ce7b9..acbc179cbec039b23e77406942cfb1bea804f54e 100644 (file)
@@ -129,7 +129,8 @@ int sysc_wait(unsigned long cnt) {
     unsigned long flags;
     irq_save(flags);
     current->state = TASK_WAIT;
-    current->delay_cnt = jiffies + cnt;
+    current->delay_jiffies = jiffies + cnt;
+
     irq_restore(flags);
 
     schedule();