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

我们先来说下进程管理的相关初始化,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
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值