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++;
return;
}
+#if ENABLE_CLOCK_IRQ_WAIT
+ if (enable_clock_irq_delay) {
+ return;
+ }
+ enable_clock_irq_delay = true;
+#endif
+
current->ticks--;
if (0 == current->ticks) {
p->reason = "clk_bh";
}
}
-
- // 此处调用这个还是有问题的
- debug_print_all_tasks();
}
uint16_t read_i8254_counter(uint8_t counter_no) {
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) {
// 发送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
}
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
+
// 这之后也可能存在再次被中断加入下半部处理请求
// 但这些都不会丢失
// 而是会延迟到这次中断返回后下一次的中断的下半部分处理逻辑
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) {
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;