uClinux进程调度器的实现分析
(4)当唤醒一个睡眠进程时,发现被唤醒的进程比当前进程优先级更高。www.51kaifa.com
(5)一个进程通过执行系统调用来改变调度策略或降低自身的优先级,从而引起调度。
4 Schedule调度程序核心部分源代码分析[3]
该调度程序的目标是选择下一个要执行的进程:首先对所有进程进行检测,唤醒任何一个得到信号的进程,即改变进程的state属性;然后根据时间片和优先级调度机制来计算处于就绪队列中每个进程的综合优先级,其计算方法由goodness( )函数实现;接着选择综合优先级最高的进程作为随后要执行的进程,若就绪队列中没有可调度的,则重新分配时间片,即改变进程的counter属性值,并利用switch_to( )函数进行进程切换。
asmlinkage void schedule(void){
struct schedule_data * sched_data;
/*描述进程的数据结构,
包含指向所运行CPU的属性。*/
struct task_struct *prev, *next, *p;
struct list_head *tmp;
int this_cpu, c;
spin_lock_prefetch(runqueue_lock);
need_resched_back:
prev = current;
this_cpu = prev->processor;
if (unlikely(in_interrupt())) {
/*判断是否在中断服务程序中*/
printk("Scheduling in interruptn"); www.51kaifa.com
/*是的话则打印错误提示,退出调度器*/
BUG();
}
release_kernel_lock(prev, this_cpu); /*释放全局内核锁和全局中断锁*/
sched_data=aligned_data[this_cpu].schedule_data;
if (unlikely(prev->policy == SCHED_RR))
if (!prev->counter) {
prev->counter= NICE_TO_TICKS(prev->nice);
move_last_runqueue(prev);
}
switch (prev->state) {
case TASK_INTERRUPTIBLE:
/*此状态表明进程可以被信号中断*/
if (signal_pending(prev)) {
/*如果该进程有未处理的信号*/
prev->state= TASK_RUNNING; break;
}
default:
del_from_runqueue(prev);
case TASK_RUNNING:;
}
prev->need_resched = 0;
repeat_schedule: /*缺省选择空闲进程*/
next = idle_task(this_cpu);
c = -1000;
list_for_each(tmp, runqueue_head) {
p = list_entry(tmp, struct task_struct, run_list);
if (can_schedule(p, this_cpu)) {
/*寻找优先级最高的那个进程*/
int weight=
goodness(p, this_cpu, prev->active_mm);
if (weight > c)
c = weight, next = p;
}
}
评论