您的位置:首页 > 其它

进程管理相关初始化(一)

2010-03-26 19:12 190 查看
我们先来说下进程管理的相关初始化,sched_init()是调度相关初始化,以下是它的具体代码:

void __init sched_init(void)
{
runqueue_t *rq;//这个结构体的原型就是struct runqueue我们在后续会把它称为运行队列结构体。
int i, j, k;

for (i = 0; i < NR_CPUS; i++) {//NR_CPUS表示系统一共有多少个cpu。
prio_array_t *array;//这个类型的原型是struct prio_array我们在后面称之为优先级阵列结构体。

rq = cpu_rq(i);//或缺i号处理器对应的运行队列,
spin_lock_init(&rq->lock);//初始化运行队列的锁。
rq->active = rq->arrays;//rq->arrays是struct prio_array结构类型数组,我们然运行队列的活动优先级阵列指向数组的第一个单元。
rq->expired = rq->arrays + 1;//运行队列的期满优先级阵列指向数组的第二个单元。
rq->best_expired_prio = MAX_PRIO;//当系统要设置优先级为某某时的进程为满期,那么首选是best_expired_prio所指优先级进程。

#ifdef CONFIG_SMP//由于这个和多处理器有关,我们主要面向arm,所以这里就不强调了。
rq->sd = &sched_domain_dummy;
rq->cpu_load = 0;
rq->active_balance = 0;
rq->push_cpu = 0;
rq->migration_thread = NULL;
INIT_LIST_HEAD(&rq->migration_queue);
#endif
atomic_set(&rq->nr_iowait, 0);//nr_iowait是表示进程I/O结束的进程计数器。

for (j = 0; j < 2; j++) {//这里是要遍历rq->arrays数组中的全部成员。对每个成员做一些初始化。
array = rq->arrays + j;//这样我们就可以得到struct prio_array结构体指针。
for (k = 0; k < MAX_PRIO; k++) {//由于优先级阵列里面的queue代表一个数组,我们就要遍历完这个数组的每个成员。
INIT_LIST_HEAD(array->queue + k);//array->queue是struct list_head类型,换句话来说这是一个链表数组。每个成员代表一个链表,相同优先级的进程都会挂在对应的链表上的。这里就是初始化这些链表。
__clear_bit(k, array->bitmap);//array->bitmap是unsigned long类型,这是个位码表,其每一位代表一个优先级。这个函数的作用就是把相应位清零。
}
__set_bit(MAX_PRIO, array->bitmap);//这里就是把优先级为MAX_PRIO对应的那一位置1.
}
}

atomic_inc(&init_mm.mm_count);//init_mm全局变量的mm_count成员加1,它是一个计数器,该结构被引用的进程数。
enter_lazy_tlb(&init_mm, current);
init_idle(current, smp_processor_id());//这个函数就是初始化当前处理器的0号进程。current是struct task_struct结构类型。它是一个全局变量。0号进程是所有进程的父进程。
}
void __devinit init_idle(task_t *idle, int cpu)
{
runqueue_t *rq = cpu_rq(cpu);//cpu_rq()这个函数我们上面才刚将过。
unsigned long flags;

idle->sleep_avg = 0;//sleep_avg是进程等待时间与运行时间的差值,这个差值越大,优先级就越大。这是计算动态优先级的关键因子。
idle->interactive_credit = 0;//interactive_credit是表示交互程度,如果超过了CREDIT_LIMIT(100)话,表示进程是交互进程。
idle->array = NULL;//array是进程的活动优先级阵列指针。
idle->prio = MAX_PRIO;//prio是动态优先级,数值越大,说明优先级越小。
idle->state = TASK_RUNNING;//这个是进程的状态。
set_task_cpu(idle, cpu);//将idle->thread_info->cpu设置为cpu(记得我们调用这个函数时,第二个参数是当前cpu号),这个表示这个进程是由哪个cpu创建和运行的。

spin_lock_irqsave(&rq->lock, flags);//获得运行队列的锁,同时把当前cpsr的值保存在flags中,同时禁止irq。
rq->curr = rq->idle = idle;//curr和idle都是struct task_struct结构,前者表示该队列中的当前运行的进程,后者表示队列中的0号进程。
set_tsk_need_resched(idle);//将idle->thread_info->flags或上TIF_NEED_RESCHED,表示必须执行调度程序。
spin_unlock_irqrestore(&rq->lock, flags);//解锁,允许irq中断,把flags内容返回cpsr中。

/* Set the preempt count _outside_ the spinlocks! */
#ifdef CONFIG_PREEMPT//如果系统允许进程被抢占
idle->thread_info->preempt_count = (idle->lock_depth >= 0);//这里分为两种情况,第一就是如果括号内为1是说明idle->lock_depth>=0,就是说进程被锁了,这个时候不允许抢占。第二就是idle->lock_depth<0说-明进程没锁,这是idle->thread_info->preempt_count=0,表示进程可以被抢占。
#else//如果系统不支持进程被抢占。
idle->thread_info->preempt_count = 0;
#endif
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: