当前位置: 技术问答>linux和unix
求助:分析linux的一段代码-课程设计及用
来源: 互联网 发布时间:2015-03-21
本文导语: 进程调度: asmlinkage void schedule(void) { struct task_struct prev,next,*p; /*prev表示调度之前的进程,next表示调度之后的进程*/ struct list_head *tmp; int this_cpu,c; if (!current->active_mm) BUG(); /*如果当前进程的active_mm为空,...
进程调度:
asmlinkage void schedule(void)
{
struct task_struct prev,next,*p; /*prev表示调度之前的进程,next表示调度之后的进程*/
struct list_head *tmp;
int this_cpu,c;
if (!current->active_mm) BUG(); /*如果当前进程的active_mm为空,出错*/
need_resched_back;
prev=current; /*让prev成为当前进程*/
this_cpu=prev->processor;
if (in_interrupt()) {
/*如果schedule是在中断服务程序内部执行,就说明发生了错误*/
printk(“Scheduling in interruptn”);
BUG();
}
release_kernel_lock(prev,this_cpu); /*释放全局内核锁,并开this_cpu的中断*/
spin_lock_irq(&runqueue_lock); /*锁住运行队列,并且同时关中断*/
if (prev_>policy = = SCHED_RR) /*将一个时间片用完的SCHED_RR实时进程放到队列的末尾*/
goto move_rr_last;
move_rr_back:
switch(prev->state) {
/*根据prev的状态做相应的处理*/
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;
if (prev->state= =TASK_RUNNING)
still_running_back:
list_for_each(tmp,&runqueue_head) {
/*遍历运行队列*/
p=list_entry(tmp,struct tadk_struct,run_list);
if (can_schedule(p,this_cpu)) {
/*单cpu中,该函数总返回1*/
int weight=goodness(p,this_cpu,prev->active_mm);
if (weight,next=p;
)
}
/*如果c为0,说明运行队列中所有进程的权值都为0,也就是分配给各个进程的时间片都已用完,需重新计算各个进程的时间片*/
if (!c) {
struct tadk_struct *p;
spin_unlock_irq(&runqueue_lock); /*锁住运行队列*/
read_lock(&tasklist_lock); /*锁住进程的双向链表*/
for_each_task(p) /*对系统中的每个进程*/
p->counter=(p->counter>>1)+NICE_TO_TICKS(p->nice);
read_unlock(&tasklist_lock);
spin_lock_irq(&runqueue_lock);
goto repeat_schedule;
}
apin_unlock_irq(&runqueue_lock); /*对运行队列解锁,并开中断*/
if (prev= =next) {
/*如果选中的进程就是原来的进程*/
prev-?policy &= ~SCHED_YIELD;
goto same_process;
}
/*下面开始进行进程切换*/
kstat.context_swtch++; /*统计上下问切换的次数*/
{
struct mm_struct *mm=next->mm;
struct mm_struct *oldmm=prev->active_mm;
if (!mm) {
/*如果是内核线程,则借用prev的地址空间*/
if (next->active_mm) BUG();
next->active_mm=oldmm;
}
else {
/*如果是一般进程,则切换到next的用户空间*/
if (next->active_mm!=MM) BUG();
switch_mm(oldmm,mm,next,this_cpu);
}
if (!prev->mm) {
/*如果切换出去的是内核线程*/
prev->active_mm=NULL;/*归还它所借用的地址空间*/
mmdrop(oldmm); /*mm_struct中的共享计数减1*/
}
}
switch_to (prev,next,prevc); /*进程的真正切换,即堆栈的切换*/
_schedule_tail(prev); /*置prev->policy的SCHED——YIELD为0*/
same_process:
reacquire_kernel_lock(current); /*针对SMP*/
if (current->need_resched) /*如果调度标志被置位*/
goto need_resched_back; /*重新开始调度*/
return;
}
asmlinkage void schedule(void)
{
struct task_struct prev,next,*p; /*prev表示调度之前的进程,next表示调度之后的进程*/
struct list_head *tmp;
int this_cpu,c;
if (!current->active_mm) BUG(); /*如果当前进程的active_mm为空,出错*/
need_resched_back;
prev=current; /*让prev成为当前进程*/
this_cpu=prev->processor;
if (in_interrupt()) {
/*如果schedule是在中断服务程序内部执行,就说明发生了错误*/
printk(“Scheduling in interruptn”);
BUG();
}
release_kernel_lock(prev,this_cpu); /*释放全局内核锁,并开this_cpu的中断*/
spin_lock_irq(&runqueue_lock); /*锁住运行队列,并且同时关中断*/
if (prev_>policy = = SCHED_RR) /*将一个时间片用完的SCHED_RR实时进程放到队列的末尾*/
goto move_rr_last;
move_rr_back:
switch(prev->state) {
/*根据prev的状态做相应的处理*/
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;
if (prev->state= =TASK_RUNNING)
still_running_back:
list_for_each(tmp,&runqueue_head) {
/*遍历运行队列*/
p=list_entry(tmp,struct tadk_struct,run_list);
if (can_schedule(p,this_cpu)) {
/*单cpu中,该函数总返回1*/
int weight=goodness(p,this_cpu,prev->active_mm);
if (weight,next=p;
)
}
/*如果c为0,说明运行队列中所有进程的权值都为0,也就是分配给各个进程的时间片都已用完,需重新计算各个进程的时间片*/
if (!c) {
struct tadk_struct *p;
spin_unlock_irq(&runqueue_lock); /*锁住运行队列*/
read_lock(&tasklist_lock); /*锁住进程的双向链表*/
for_each_task(p) /*对系统中的每个进程*/
p->counter=(p->counter>>1)+NICE_TO_TICKS(p->nice);
read_unlock(&tasklist_lock);
spin_lock_irq(&runqueue_lock);
goto repeat_schedule;
}
apin_unlock_irq(&runqueue_lock); /*对运行队列解锁,并开中断*/
if (prev= =next) {
/*如果选中的进程就是原来的进程*/
prev-?policy &= ~SCHED_YIELD;
goto same_process;
}
/*下面开始进行进程切换*/
kstat.context_swtch++; /*统计上下问切换的次数*/
{
struct mm_struct *mm=next->mm;
struct mm_struct *oldmm=prev->active_mm;
if (!mm) {
/*如果是内核线程,则借用prev的地址空间*/
if (next->active_mm) BUG();
next->active_mm=oldmm;
}
else {
/*如果是一般进程,则切换到next的用户空间*/
if (next->active_mm!=MM) BUG();
switch_mm(oldmm,mm,next,this_cpu);
}
if (!prev->mm) {
/*如果切换出去的是内核线程*/
prev->active_mm=NULL;/*归还它所借用的地址空间*/
mmdrop(oldmm); /*mm_struct中的共享计数减1*/
}
}
switch_to (prev,next,prevc); /*进程的真正切换,即堆栈的切换*/
_schedule_tail(prev); /*置prev->policy的SCHED——YIELD为0*/
same_process:
reacquire_kernel_lock(current); /*针对SMP*/
if (current->need_resched) /*如果调度标志被置位*/
goto need_resched_back; /*重新开始调度*/
return;
}
|
为甚么不到Linux/Unix开发版里去发贴呢???
|
www.linuxaid.com.cn
www.linuxforum.net
www.linuxforum.net
|
建议你去看机械工业出版社的《Linux 2.4源代码分析大全》,此外还有人民邮电出版社的《深入分析Linux源代码》等等。