void print_all_tasks() {
extern task_t* monitor_tasks[];
- printl(MPL_TASK_TITLE, " NAME STATE TK/PI REASON SCHED KEEP TURN");
+ printl(MPL_TASK_TITLE, " NAME STATE TK/PI REASON SCHED KEEP");
for (int i = 0; i < 10; i++) {
task_t* p = monitor_tasks[i];
continue;
}
- printl(MPL_TASK_0 + p->pid, "a%08x %-6s:%u %s %02u/%02u %-10s %-9u %-9u %-9u",
+ printl(MPL_TASK_0 + p->pid, "%08x %-6s:%u %s %02d/%02u %-10s %-9u %-9u",
p, //
p->name, //
p->pid, //
p->priority, //
p->reason, //
p->sched_cnt, //
- p->sched_keep_cnt, //
- p->turn //
+ p->sched_keep_cnt //
);
}
}
current->jiffies = jiffies;
- // 中断目前虽然不能嵌套,但依然可以打断前一个中断的下半部分处理
- // 若前一个时钟中断将这个值减到0,会将该进程设置为need_resched,同时分配新的时间片值,以在下半部处理完后再重新调度就绪进程运行
- // 而如果其下半部分需要处理的事情很多,处理时间过长,两个时钟中断之间的时间还不足以处理完
- // 那么下一个时钟中断是完全可以打断还没处理完的下半部逻辑
- // 打断后该时钟中断不应该继续减少该进程的时间片,因为这会造成该进程在后续的调底中少了实际的运行时间
- if (1 == current->need_resched) {
- // 这种情况必然已经发生了该时钟中断打断了下半部处理程序
- // 反之时钟中断打断了下半部处理程序不一定need_resched就为1
- return;
- }
-
#if ENABLE_CLOCK_IRQ_WAIT
if (enable_clock_irq_delay) {
return;
current->ticks--;
- if (0 == current->ticks) {
- current->need_resched = 1;
- current->ticks = current->priority;
- current->turn++;
- }
-
- assert(current->ticks >= 0); // 防止ticks被减到0后再减溢出
-
if (reenter == 0) {
add_irq_bh_handler(clk_bh_handler, NULL);
}
root_task.priority = 7;
root_task.ticks = root_task.priority;
root_task.vma_list = NULL;
- root_task.turn = 0;
root_task.need_resched = 0;
root_task.sched_cnt = 0;
root_task.sched_keep_cnt = 0;
}
void schedule() {
- task_t* root = &root_task;
+ // task_t* root = &root_task;
task_t* sel = 0;
task_t* p = 0;
list_head_t *pos = 0, *t = 0;
- assert(current->ticks >= 0);
assert(current->priority <= TASK_MAX_PRIORITY);
unsigned long iflags;
current->state = TASK_READY;
}
- list_for_each_safe(pos, t, &all_tasks) {
+ // task_t *head = current;
+ list_for_each_safe(pos, t, ¤t->list) {
p = list_entry(pos, task_t, list);
-
- if (p == &root_task) {
- continue;
- }
-
- assert(p->state != TASK_RUN);
-
if (TASK_READY != p->state) {
continue;
}
-
- if (sel == 0) {
- sel = p;
+ if (&root_task == p) {
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) 表示已经使用的量,越小越优先
- // 实际简化表达式为 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;
- }
+ sel = p;
+ break;
+ }
+
+ if (sel == 0) {
+ if (current->state != TASK_READY) {
+ sel = &root_task;
+ root_task.ticks = root_task.priority;
+ root_task.state = TASK_READY;
+ } else {
+ sel = current;
}
-#endif
}
task_t* prev = current;
- task_t* next = sel != 0 ? sel : root;
-
- prev->need_resched = 0;
+ task_t* next = sel;
next->state = TASK_RUN;
next->reason = "";
if (prev != next) {
+ if (prev->ticks <= 0) {
+ prev->ticks = prev->priority;
+ }
next->sched_cnt++;
context_switch(prev, next);
} else {