void ide_ata_init();
ide_ata_init();
- request_irq(0x0E, ide_irq_handler, "hard", "IDE");
+ request_irq(0x0E, ide_irq_handler, NULL, "hard", "IDE");
// init_pci_controller(0x0106);
init_pci_controller(0x0101);
typedef struct irqaction {
// void (*handler)(pt_regs_t * regs, unsigned int irq);
void (*handler)(unsigned int irq, pt_regs_t *regs, void *dev_id);
+ void (*bh_handler)();
const char *dev_name;
void *dev_id;
struct irqaction *next;
extern irq_desc_t no_irq_desc;
int request_irq(unsigned int irq,
// void (*handler)(pt_regs_t *, unsigned int),
- void (*handler)(unsigned int, pt_regs_t *, void *), const char *devname, void *dev_id);
+ void (*handler)(unsigned int, pt_regs_t *, void *), void (*bh_handler)(), const char *devname,
+ void *dev_id);
int open_irq(unsigned int irq);
int close_irq(unsigned int irq);
#define irq_save(x) __asm__ __volatile__("pushfl; popl %0; cli" : "=g"(x)::"memory")
bool irq_enabled();
+bool irq_disabled();
#define irq_restore(x) \
do { \
MPL_IDE,
MPL_IDE_INTR,
MPL_CURRENT,
- MPL_FUCK,
+ MPL_TEST0,
MPL_TEST,
MPL_X,
MPL_DEBUG,
extern void load_cr3(task_union *tsk);
extern list_head_t all_tasks;
+extern list_head_t delay_tasks;
#define set_current_state(st) \
do { \
void disk_task_entry();
void user_task_entry();
-extern volatile int irq_reenter;
+extern volatile int reenter;
#endif
#endif //_SYSTEM_H
uint32_t priority;
uint64_t jiffies;
+ volatile int need_resched;
+
pid_t pid;
pid_t ppid;
volatile unsigned int state;
printl(MPL_CLOCK, "clock irq: %d", jiffies);
}
+#if 0
unsigned long iflags;
irq_save(iflags);
-
+#endif
jiffies++;
current->jiffies = jiffies;
- // 若clk_handler嵌套在其它中断函数中执行
- // 那么这个变量减到0时,再退出中clk_handler并不会引起调度
- //
- current->ticks--;
+ // 中断目前虽然不能嵌套,但依然可以打断前一个中断的下半部分处理
+ // 若前一个时钟中断将这个值减到0
+ // 同时其下半部分处理时间过长,直到这个时钟中断还没处理完
+ // 那么这个时钟中断是完全可以打断它,且在这里把这个ticks从0减到负数
+ // 而这个是uint32_t型,因此会溢出成0xFFFFFFFF
+ volatile uint32_t ticks;
+
+ ticks = current->ticks;
+ if (current->ticks > 0) {
+ current->ticks--;
+ }
+ ticks = current->ticks;
+
+#if 0
if (current->ticks > TASK_MAX_PRIORITY) {
printl(MPL_X, "current %08x ticks %u", current, current->ticks);
printk("DIE: ");
dump_irq_nr_stack();
}
+#endif
+
assert(current->ticks <= TASK_MAX_PRIORITY); // 防止ticks被减到0后再减溢出
+#if 0
task_union *p = 0;
list_head_t *t = 0;
list_head_t *pos = 0;
p->state = TASK_READY;
}
}
+#endif
+#if 0
debug_print_all_tasks();
debug_print_all_tasks();
debug_print_all_tasks();
debug_print_all_tasks();
+#endif
+#if 0
irq_restore(iflags);
+#endif
}
+
+// 开中断执行这个函数
+const char *task_state(unsigned int state);
+void clk_bh_handler() {
+ unsigned long iflags;
+ irq_save(iflags);
+ task_union *p = 0;
+ list_head_t *t = 0;
+ list_head_t *pos = 0;
+ list_for_each_safe(pos, t, &delay_tasks) {
+ p = list_entry(pos, task_union, pend);
+ // printk("%s state: %s\n", p->name, task_state(p->state));
+ assert(p->state == TASK_WAIT);
+ assert(p->delay_jiffies != 0);
+ if (jiffies > p->delay_jiffies) {
+ list_del(&p->pend);
+ p->delay_jiffies = 0;
+ p->state = TASK_READY;
+ }
+ }
+
+ // 此处调用这个还是有问题的
+ debug_print_all_tasks();
+ irq_restore(iflags);
+}
\ No newline at end of file
tsk->priority = current->priority;
tsk->ticks = tsk->priority;
tsk->turn = 0; //
+ tsk->need_resched = 0;
tsk->sched_cnt = 0;
tsk->sched_keep_cnt = 0;
assert(tsk->magic == TASK_MAGIC);
.global _irq_handler
.extern irq_handler
-.extern schedule
-.extern irq_reenter
_irq_handler:
SAVE_REGS
movl %esp, %eax
call irq_handler
-
- cmpl $0, (irq_reenter)
- jnz restore_regs
-
-
- call schedule
-
- RESTORE_REGS
- addl $4, %esp
- iret
-
-restore_regs:
+
RESTORE_REGS
addl $4, %esp
- iret
+ iret
\ No newline at end of file
void dump_irq_nr_stack() {
if (irq_nr_stack_pos == 0) {
printl(MPL_TEST, "irq nr stack empty");
- return 0;
+ return;
}
- printl(MPL_FUCK, "irq nr stack pos %u", irq_nr_stack_pos);
+ printl(MPL_TEST0, "irq nr stack pos %u", irq_nr_stack_pos);
char buf[128];
__attribute__((regparm(1))) void irq_handler(pt_regs_t *regs) {
unsigned int irq = regs->irq;
if (irq >= NR_IRQS) {
- printk("invalid irq %d\n", irq);
- return;
+ panic("invalid irq %d\n", irq);
}
irq_desc_t *p = irq_desc + irq;
irq_action_t *action = p->action;
+ assert(irq_disabled());
+ reenter++;
+
// 屏蔽当前中断
p->chip->disable(irq);
// 发送EOI
p->chip->ack(irq);
- if (irq_reenter == 0) {
- // 可以切换到中断栈
- }
-
- irq_reenter++;
-
assert(current->magic == TASK_MAGIC);
+#if 0
push_irq_nr_stack(irq);
// if (irq_nr_stack_pos >= 2) {
dump_irq_nr_stack();
// panic("sdfasd");
// }
+#endif
+
+#if 0
// 开中断执行中断处理函数
enable_irq();
+#endif
+
+#if 1
unsigned long esp;
asm("movl %%esp, %%eax" : "=a"(esp));
- printl(MPL_CURRENT, "current %08x cr3 %08x reenter %d esp %08x", current, current->cr3, irq_reenter, esp);
- printk("2: %d r %d t %d\n", irq, irq_reenter, current->ticks);
+ printl(MPL_CURRENT, "current %08x cr3 %08x reenter %d esp %08x %u", current, current->cr3, reenter, esp,
+ current->ticks);
+#endif
+
while (action && action->handler) {
- if (irq == 14) {
- printk("a: %d r %d t %d \n", irq, irq_reenter, current->ticks);
- }
action->handler(irq, regs, action->dev_id);
- if (irq == 14) {
- printk("b: %d r %d t %d \n", irq, irq_reenter, current->ticks);
- }
action = action->next;
}
+#if 0
// 关全局中断
- if (irq == 14) {
- printk("c: %d r %d t %d \n", irq, irq_reenter, current->ticks);
- }
disable_irq();
+#endif
+
+#if 0
pop_irq_nr_stack();
- irq_reenter--;
- if (irq == 14) {
- printk("d: %d r %d t %d \n", irq, irq_reenter, current->ticks);
- }
+#endif
+
// 解除屏蔽当前中断
p->chip->enable(irq);
- printk("x: %d r %d t %d \n", irq, irq_reenter, current->ticks);
+ // 代表当前中断程序打断了前一个中断程序的“开中断处理的底半部分逻辑”
+ // 即前一个中断处理尚未完全完成
+ assert(irq_disabled());
+ if (reenter != 0) {
+ reenter--;
+ return;
+ }
+ // --以上逻辑CPU处于中断禁止状态--------------------------
+
+ // 此处执行中断函数的下半部分逻辑,开中断执行
+ {
+ enable_irq();
+
+ action = p->action;
+ while (action) {
+ if (action->bh_handler != NULL) {
+ action->bh_handler();
+ }
+ action = action->next;
+ }
+
+ disable_irq();
+ }
+
+ // --以下逻辑CPU处于中断禁止状态--------------------------
+ assert(irq_disabled());
+ assert(reenter == 0);
+ reenter--;
+ assert(reenter == -1);
+
+ // 考察如果不需要调度程序,直接退出
+ if (current->ticks != 0) {
+ return;
+ }
+
+ // 如果需要调度程序
+ schedule();
}
-int request_irq(unsigned int irq, void (*handler)(unsigned int, pt_regs_t *, void *), const char *devname,
- void *dev_id) {
+int request_irq(unsigned int irq, void (*handler)(unsigned int, pt_regs_t *, void *), void (*bh_handler)(),
+ const char *devname, void *dev_id) {
irq_action_t *p;
if (irq >= NR_IRQS) {
p->dev_name = devname;
p->dev_id = dev_id;
p->handler = handler;
+ p->bh_handler = bh_handler;
p->next = NULL;
if (irq_desc[irq].action != NULL) {
p->next = irq_desc[irq].action;
}
return false;
-}
\ No newline at end of file
+}
+
+bool irq_disabled() { return !irq_enabled(); }
\ No newline at end of file
root_task.priority = 7;
root_task.ticks = root_task.priority;
root_task.turn = 0;
+ root_task.need_resched = 0;
root_task.sched_cnt = 0;
root_task.sched_keep_cnt = 0;
root_task.magic = TASK_MAGIC;
return p;
}
-static const char *task_state(unsigned int state) {
+const char *task_state(unsigned int state) {
static const char s[][16] = {
" ERROR", "RUNNING", " READY", " WAIT", " INIT", " EXIT",
};
task_union *sel = 0;
task_union *p = 0;
list_head_t *pos = 0, *t = 0;
- printk("*");
printl(MPL_X, "disk req %u consumed %u irq %u", disk_request_cnt, disk_handled_cnt, disk_inter_cnt);
unsigned long iflags;
irq_save(iflags);
- 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 (0 == current->ticks) {
+ current->turn++;
+ current->ticks = current->priority;
+ current->state = TASK_READY;
}
+ // printk("-----\n");
list_for_each_safe(pos, t, &all_tasks) {
p = list_entry(pos, task_union, list);
- assert(p->state != TASK_RUNNING);
+ // printk("%s state: %s ticks %u\n", current->name, task_state(current->state), current->ticks);
+ // printk("%s state: %s\n", p->name, task_state(p->state));
if (p == &root_task) {
continue;
}
+ assert(p->state != TASK_RUNNING);
+
if (TASK_READY != p->state) {
continue;
}
.global syscall_entry
.global ret_from_fork_user
.global ret_from_fork_krnl
+.extern reenter
//.global syscall_exit
syscall_entry:
#if FIX_SYSENTER_ESP_MODE
movl (%esp),%esp
#endif
-
+
// sysenter have cleared IF, and sysexit will not set IF.
sti
void kbd_handler(unsigned int irq, pt_regs_t *regs, void *dev_id);
void clk_handler(unsigned int irq, pt_regs_t *regs, void *dev_id);
+ void clk_bh_handler();
- request_irq(0x00, clk_handler, "Intel 8254", "Clock Chip");
- request_irq(0x01, kbd_handler, "Intel 8042", "PS/2 Keyboard");
+ request_irq(0x00, clk_handler, clk_bh_handler, "Intel 8254", "Clock Chip");
+ request_irq(0x01, kbd_handler, NULL, "Intel 8042", "PS/2 Keyboard");
// request_irq(0x0E, default_ide_irq_handler, "hard", "IDE");
for (int i = 0; i < 16; i++) {
if (i != 0 && i != 1 && i != 10 && i != 14) {
- request_irq(i, default_irq_handler, "default", "default");
+ request_irq(i, default_irq_handler, NULL, "default", "default");
}
}
char gdtr[6] __attribute__((__aligned__(4)));
char idtr[6] __attribute__((__aligned__(4)));
-volatile int irq_reenter = 0x00;
\ No newline at end of file
+volatile int reenter = -1;
\ No newline at end of file
setup_under_irq();
while (1) {
- asm("hlt;");
+ asm("sti;hlt;");
sysc_wait(2);
}
}
irq_save(flags);
current->state = TASK_WAIT;
current->delay_jiffies = jiffies + cnt;
-
+ list_add(¤t->pend, &delay_tasks);
irq_restore(flags);
schedule();