Chinaunix首页 | 论坛 | 博客
  • 博客访问: 208385
  • 博文数量: 102
  • 博客积分: 0
  • 博客等级: 民兵
  • 技术积分: 1015
  • 用 户 组: 普通用户
  • 注册时间: 2013-06-05 16:45
文章存档

2014年(73)

2013年(29)

我的朋友

分类: LINUX

2013-11-21 21:20:37

国嵌内核驱动进阶班-5-2(LINUX进程调度)


点击(此处)折叠或打开

  1. //sched.c(kernel)
  2. /*
  3.  * schedule() is the main scheduler function.
  4.  */
  5. asmlinkage void __sched schedule(void)
  6. {
  7.     struct task_struct *prev, *next;
  8.     unsigned long *switch_count;
  9.     struct rq *rq;
  10.     int cpu;

  11. need_resched:
  12.     preempt_disable();
  13.     cpu = smp_processor_id();
  14.     rq = cpu_rq(cpu);
  15.     rcu_sched_qs(cpu);
  16.     prev = rq->curr;
  17.     switch_count = &prev->nivcsw;

  18.     release_kernel_lock(prev);
  19. need_resched_nonpreemptible:

  20.     schedule_debug(prev);

  21.     if (sched_feat(HRTICK))
  22.         hrtick_clear(rq);

  23.     spin_lock_irq(&rq->lock);
  24.     update_rq_clock(rq);
  25.     clear_tsk_need_resched(prev);

  26.     if (prev->state && !(preempt_count() & PREEMPT_ACTIVE)) {
  27.         if (unlikely(signal_pending_state(prev->state, prev)))
  28.             prev->state = TASK_RUNNING;
  29.         else
  30.             deactivate_task(rq, prev, 1);
  31.         switch_count = &prev->nvcsw;
  32.     }

  33.     pre_schedule(rq, prev);

  34.     if (unlikely(!rq->nr_running))
  35.         idle_balance(cpu, rq);

  36.     put_prev_task(rq, prev);
  37.     next = pick_next_task(rq);

  38.     if (likely(prev != next)) {
  39.         sched_info_switch(prev, next);
  40.         perf_event_task_sched_out(prev, next, cpu);

  41.         rq->nr_switches++;
  42.         rq->curr = next;
  43.         ++*switch_count;

  44.         context_switch(rq, prev, next); /* unlocks the rq */
  45.         /*
  46.          * the context switch might have flipped the stack from under
  47.          * us, hence refresh the local variables.
  48.          */
  49.         cpu = smp_processor_id();
  50.         rq = cpu_rq(cpu);
  51.     } else
  52.         spin_unlock_irq(&rq->lock);

  53.     post_schedule(rq);

  54.     if (unlikely(reacquire_kernel_lock(current) < 0))
  55.         goto need_resched_nonpreemptible;

  56.     preempt_enable_no_resched();
  57.     if (need_resched())
  58.         goto need_resched;
  59. }
  60. EXPORT_SYMBOL(schedule);



调度只从TASK_RUNNING状态的进程



 Preempt  vt. 先占;先取;以先买权获得





点击(此处)折叠或打开

  1. /*
  2.  * Pick up the highest-prio task:
  3.  */
  4. static inline struct task_struct *
  5. pick_next_task(struct rq *rq)
  6. {
  7.     const struct sched_class *class;
  8.     struct task_struct *p;

  9.     /*
  10.      * Optimization: we know that if all tasks are in
  11.      * the fair class we can call that function directly:
  12.      */
  13.     if (likely(rq->nr_running == rq->cfs.nr_running)) {
  14.         p = fair_sched_class.pick_next_task(rq);
  15.         if (likely(p))
  16.             return p;
  17.     }

  18.     class = sched_class_highest;
  19.     for ( ; ; ) {
  20.         p = class->pick_next_task(rq);
  21.         if (p)
  22.             return p;
  23.         /*
  24.          * Will never be NULL as the idle class always
  25.          * returns a non-NULL p:
  26.          */
  27.         class = class->next;
  28.     }
  29. }



阅读(1048) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~