Chinaunix首页 | 论坛 | 博客
  • 博客访问: 353270
  • 博文数量: 197
  • 博客积分: 0
  • 博客等级: 民兵
  • 技术积分: 303
  • 用 户 组: 普通用户
  • 注册时间: 2013-09-02 14:21
文章分类

全部博文(197)

文章存档

2014年(89)

2013年(108)

我的朋友

分类: LINUX

2013-11-14 17:59:20

6. 唤醒进程

时间过的很快,十二月份了。十二月份的南京已经颇冷,蚊子也没有了。但天气着实冷,晚上睡不安稳。后来垫上厚褥子,盖上两层被子。厚实的保护下,寒气也无从侵入,终于能睡安稳了。在这个起床靠鞭子抽的季节里,联想起进程的唤醒和休眠也无非如此罢了。进程休眠的时候,自己找个安稳的休眠队列往上一躺,设置一个标志,调用sched函数就休眠了。而唤醒就不是进程自己能办到的了,需要借助外力,这就好比冬天起床的过程,没个闹钟你能起来吗?北方有暖气的除外,那个环境起床一点困难的没有,暖气开足了还闹流鼻血。闲话少扯,唤醒进程的外力就是try_to_wake_up函数了

wps_clip_image-2728

try_to_wake_up函数首先调用update_rq_clock更新一下cfs调度队列上的clock时间。如果该进程已经是TASK_RUNNING状态,直接退出该函数,如果这个进程在运行队列上,就直接跳到check_preempt_curr函数就可以了。如果确实是刚唤醒的进程,调用active_task,这个函数主要的作用就是调整taskvruntime,进程在休眠的时候vruntime是不会一直更新的,所以等唤醒进程的时候必须更新这个变量。之后将task放入到运行队列上去。

 
/*
* activate_task - move a task to the runqueue.
*/ 
static void activate_task(struct rq *rq, struct task_struct *p, int wakeup)
{
    if (task_contributes_to_load(p))
        rq->nr_uninterruptible--;
 
    enqueue_task(rq, p, wakeup);
    inc_nr_running(rq);
}
 

 
/*
* The enqueue_task method is called before nr_running is
* increased. Here we update the fair scheduling stats and
* then put the task into the rbtree:
*/ 
static void enqueue_task_fair(struct rq *rq, struct task_struct *p, int wakeup)
{
    struct cfs_rq *cfs_rq;
    struct sched_entity *se = &p->se;
 
    for_each_sched_entity(se)
    {
        if (se->on_rq)
            break;
        cfs_rq = cfs_rq_of(se);
        enqueue_entity(cfs_rq, se, wakeup);
        wakeup = 1;
    }
 
    hrtick_update(rq);
}

 
static void 
enqueue_entity(struct cfs_rq *cfs_rq, struct sched_entity *se, int wakeup)
{
    /*
     * Update run-time statistics of the 'current'.
     */ 
    update_curr(cfs_rq);
    account_entity_enqueue(cfs_rq, se);
 
    if (wakeup)
    {
        place_entity(cfs_rq, se, 0);
        enqueue_sleeper(cfs_rq, se);
    }
 
    update_stats_enqueue(cfs_rq, se);
    check_spread(cfs_rq, se);
    if (se != cfs_rq->curr)
        __enqueue_entity(cfs_rq, se);
}
 

wps_clip_image-26677

Activate_task最主要的工作还是将task放入到运行队列中去,但是,需要注意到是place_entity操作,对于被唤醒的进程,系统试着奖励一点运行时间(vruntime -= thresh;)

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