From 4b5e498185470c1fd6d1778ce0128174eb55dad7 Mon Sep 17 00:00:00 2001 From: acevest Date: Wed, 15 May 2024 19:59:48 +0800 Subject: [PATCH] =?utf8?q?=E6=B7=BB=E5=8A=A0=E5=87=8F=E7=BC=93=E7=B3=BB?= =?utf8?q?=E7=BB=9F=E8=BF=90=E8=A1=8C=E7=9A=84=E8=B0=83=E8=AF=95=E5=8A=9F?= =?utf8?q?=E8=83=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit --- Makefile | 1 + kernel/clock.c | 13 ++++-- kernel/irq.c | 106 ++++++++++++++++++++++++++++++++++--------------- kernel/sched.c | 24 +++++++++-- 4 files changed, 106 insertions(+), 38 deletions(-) diff --git a/Makefile b/Makefile index 533d351..b2c8ab4 100644 --- a/Makefile +++ b/Makefile @@ -31,6 +31,7 @@ CFLAGS += -fcf-protection=none CFLAGS += -DNR_TTYS=3 CFLAGS += -DFIXED_SYSENTER_ESP_MODE=1 CFLAGS += -DENABLE_BOOT_WAIT=0 +CFLAGS += -DENABLE_CLOCK_IRQ_WAIT=0 SYSTEMMAP = System.map KERNELBIN = KERNEL.ELF diff --git a/kernel/clock.c b/kernel/clock.c index 66b6764..97a16a5 100644 --- a/kernel/clock.c +++ b/kernel/clock.c @@ -25,10 +25,13 @@ void debug_print_all_tasks(); void dump_irq_nr_stack(); void clk_bh_handler(void *arg); +extern volatile bool enable_clock_irq_delay; + void clk_handler(unsigned int irq, pt_regs_t *regs, void *dev_id) { // if (jiffies % 100 == 0) { // printl(MPL_CLOCK, "clock irq: %d", jiffies); printlxy(MPL_IRQ, MPO_CLOCK, "CLK irq: %d", jiffies); + // printk("CLK irq %d\n", jiffies); // } jiffies++; @@ -46,6 +49,13 @@ void clk_handler(unsigned int irq, pt_regs_t *regs, void *dev_id) { return; } +#if ENABLE_CLOCK_IRQ_WAIT + if (enable_clock_irq_delay) { + return; + } + enable_clock_irq_delay = true; +#endif + current->ticks--; if (0 == current->ticks) { @@ -80,9 +90,6 @@ void clk_bh_handler(void *arg) { p->reason = "clk_bh"; } } - - // 此处调用这个还是有问题的 - debug_print_all_tasks(); } uint16_t read_i8254_counter(uint8_t counter_no) { diff --git a/kernel/irq.c b/kernel/irq.c index 74d6f47..d688d15 100644 --- a/kernel/irq.c +++ b/kernel/irq.c @@ -79,6 +79,8 @@ void schedule(); volatile int reenter_count = 0; +volatile uint32_t clk_irq_cnt = 0; + __attribute__((regparm(1))) void irq_handler(pt_regs_t *regs) { unsigned int irq = regs->irq; if (irq >= NR_IRQS) { @@ -100,6 +102,16 @@ __attribute__((regparm(1))) void irq_handler(pt_regs_t *regs) { // 发送EOI p->chip->ack(irq); +#if 0 + if (0x00 == irq) { + if ((clk_irq_cnt++ & 0xFU) != 0) { + reenter--; + p->chip->enable(irq); + return; + } + } +#endif + assert(current->magic == TASK_MAGIC); #if 1 @@ -150,54 +162,86 @@ __attribute__((regparm(1))) void irq_handler(pt_regs_t *regs) { } extern uint32_t jiffies; + +volatile bool enable_clock_irq_delay = false; + void irq_bh_handler() { uint32_t end = jiffies + 1; - while (true) { - irq_bh_action_t *action = NULL; + +// ENABLE_CLOCK_IRQ_WAIT是用来调试的 +// 是为了让时钟减缓进程的时间片更慢一点,以便于调试 +// 采用这种方式,而不是经过一定时钟数再减一次进程时间片的方法 +// 是因为这种方法只能让时间片减得慢,但会拉长进程的实际运行时间,效果不真实 +// 这种方法不会改变进程的运行时间 +#if ENABLE_CLOCK_IRQ_WAIT + uint32_t debug_end = jiffies + 20; + while (jiffies < debug_end) +#endif + { + while (true) { + irq_bh_action_t *action = NULL; #if 1 - disable_irq(); - action = irq_bh_actions; - if (action == NULL) { + disable_irq(); + action = irq_bh_actions; + if (action == NULL) { + enable_irq(); + break; + } + + irq_bh_actions = action->next; + if (irq_bh_actions == NULL) { + irq_bh_actions_end = NULL; + } enable_irq(); - break; - } - irq_bh_actions = action->next; - if (irq_bh_actions == NULL) { + action->handler(action->arg); + kfree(action); +#else + disable_irq(); + + action = irq_bh_actions; + irq_bh_actions = NULL; irq_bh_actions_end = NULL; - } - enable_irq(); - action->handler(action->arg); - kfree(action); -#else - disable_irq(); + enable_irq(); - action = irq_bh_actions; - irq_bh_actions = NULL; - irq_bh_actions_end = NULL; + if (action == NULL) { + break; + } - enable_irq(); + while (action != NULL) { + action->handler(action->arg); + irq_bh_action_t *p = action; + action = action->next; + kfree(p); + } +#endif + + if (jiffies >= end) { + break; + } - if (action == NULL) { - break; + // 这里可能存在有部分没处理完 } - while (action != NULL) { - action->handler(action->arg); - irq_bh_action_t *p = action; - action = action->next; - kfree(p); + void debug_print_all_tasks(); +#if ENABLE_CLOCK_IRQ_WAIT + debug_print_all_tasks(); + if (irq_bh_actions == NULL) { + asm("hlt;"); } -#endif - if (jiffies >= end) { - break; +#else + if (jiffies < end) { + debug_print_all_tasks(); } - - // 这里可能存在有部分没处理完 +#endif } +#if ENABLE_CLOCK_IRQ_WAIT + enable_clock_irq_delay = false; +#endif + // 这之后也可能存在再次被中断加入下半部处理请求 // 但这些都不会丢失 // 而是会延迟到这次中断返回后下一次的中断的下半部分处理逻辑 diff --git a/kernel/sched.c b/kernel/sched.c index b74cbe6..cace86f 100644 --- a/kernel/sched.c +++ b/kernel/sched.c @@ -154,7 +154,7 @@ task_t *find_task(pid_t pid) { const char *task_state(unsigned int state) { static const char s[][8] = { - " ERROR", "\x10RUN\x07\x07", " READY", " WAIT ", " INIT ", " EXIT ", + " ERROR", "\x10\x07RUN\x07", " READY", " WAIT ", " INIT ", " EXIT ", }; if (state >= TASK_END) { @@ -209,19 +209,35 @@ void schedule() { 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) 表示已经使用的量,越小越优先 - int64_t a = sel->jiffies - sel->priority + (sel->priority - sel->ticks); - int64_t b = p->jiffies - p->priority + (p->priority - p->ticks); - if (a > b) { + // 实际简化表达式为 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; } } +#endif } task_t *prev = current; -- 2.44.0