Chinaunix首页 | 论坛 | 博客
  • 博客访问: 9495
  • 博文数量: 5
  • 博客积分: 10
  • 博客等级: 民兵
  • 技术积分: 60
  • 用 户 组: 普通用户
  • 注册时间: 2012-03-28 20:12
个人简介

在 CU 的博客

文章分类

全部博文(5)

文章存档

2015年(5)

我的朋友

分类: LINUX

2015-05-05 19:29:07

注: 内核版本4.0

4. vruntime 的计算
时钟中断产生后会调用update_process_times()

  1. /*
  2.  * Called from the timer interrupt handler to charge one tick to the current
  3.  * process. user_tick is 1 if the tick is user time, 0 for system.
  4.  */
  5.  void update_process_times(int user_tick)
  6.  {
  7.          struct task_struct *p = current;

  8.          /* Note: this timer irq context must be accounted for as well. */
  9.          account_process_tick(p, user_tick);
  10.          run_local_timers();
  11.          rcu_check_callbacks(user_tick);
  12.  #ifdef CONFIG_IRQ_WORK
  13.          if (in_irq())
  14.                  irq_work_tick();
  15.  #endif
  16.          scheduler_tick();
  17.          run_posix_cpu_timers(p);
  18.  }

在 scheduler_tick() 中有 curr->sched_class->task_tick(rq, curr, 0), 将调用 task_tick_fair(), 后者又调用 entity_tick(). 在 entity_tick() 中调用 update_curr() 和 check_preempt_tick().

可以看出 vruntime 的增量由 calc_delta_fair()计算, 这个函数的实现用到了一些移位操作, 但从函数前的注释可以看出其返回 delta * weight / lw.weight. 其中 weight 是当前进程的权重, lw.weight 是整个就绪队列总权重.

  1. /*
  2.  * Update the current task's runtime statistics.
  3.  */
  4.  static void update_curr(struct cfs_rq *cfs_rq)
  5.  {
  6.          …
  7.          delta_exec = now - curr->exec_start;
  8.          …
  9.          curr->sum_exec_runtime += delta_exec;/* 增加累计运行时间 */
  10.          …
  11.          curr->vruntime += calc_delta_fair(delta_exec, curr);
  12.          update_min_vruntime(cfs_rq);
  13.          …
  14. }

进程的权重 weight 由进程优先级 prio 决定, 实时进程的 prio 值是 [0, 99], 一般进程是 [100, 139], 对应 nice 值 [-20, 19].

prio 到 weight 的转换使用这张表:

  1. /*
  2.   * Nice levels are multiplicative, with a gentle 10% change for every
  3.   * nice level changed. I.e. when a CPU-bound task goes from nice 0 to
  4.   * nice 1, it will get ~10% less CPU time than another CPU-bound task
  5.   * that remained on nice 0.
  6.   *
  7.   * The "10% effect" is relative and cumulative: from _any_ nice level,
  8.   * if you go up 1 level, it's -10% CPU usage, if you go down 1 level
  9.   * it's +10% CPU usage. (to achieve that we use a multiplier of 1.25.
  10.   * If a task goes up by ~10% and another task goes down by ~10% then
  11.   * the relative distance between them is ~25%.)
  12.   */
  13.  static const int prio_to_weight[40] = {
  14.   /* -20 */ 88761, 71755, 56483, 46273, 36291,
  15.   /* -15 */ 29154, 23254, 18705, 14949, 11916,
  16.   /* -10 */ 9548, 7620, 6100, 4904, 3906,
  17.   /* -5 */ 3121, 2501, 1991, 1586, 1277,
  18.   /* 0 */ 1024, 820, 655, 526, 423,
  19.   /* 5 */ 335, 272, 215, 172, 137,
  20.   /* 10 */ 110, 87, 70, 56, 45,
  21.   /* 15 */ 36, 29, 23, 18, 15,
  22.  };
在 check_preempt_tick()中会比较 delta 和 ideal_runtime, delta 超过 ideal_runtime 的话就对当前进程设置重调度位.
阅读(437) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~