- 论坛徽章:
- 6
|
回复 3# Mr__key
进程睡眠后相当于自动放弃了cpu资源,再接下来的进程管理调度会根据该进程其优先级及平均睡眠时间重新分配其时间片。
不知道你看的那个版本的代码???
刚才看了一下2.6.32的内核代码:
如果进程在还有时间片的情况下调用sleep,那么对应的在内核通过alarm系统调用,将当前进程放到等待队列上,调用schedule()。
当睡眠时间到了以后,timer触发default_wake_function,最后对应的函数是try_to_wake_up()。
try_to_wake_up函数- /***
- * try_to_wake_up - wake up a thread
- * @p: the to-be-woken-up thread
- * @state: the mask of task states that can be woken
- * @sync: do a synchronous wakeup?
- *
- * Put it on the run-queue if it's not already there. The "current"
- * thread is always on the run-queue (except when the actual
- * re-schedule is in progress), and as such you're allowed to do
- * the simpler "current->state = TASK_RUNNING" to mark yourself
- * runnable without the overhead of this.
- *
- * returns failure only if the task is already active.
- */
- static int try_to_wake_up(struct task_struct *p, unsigned int state,
- int wake_flags)
- {
- int cpu, orig_cpu, this_cpu, success = 0;
- unsigned long flags;
- struct rq *rq, *orig_rq;
- if (!sched_feat(SYNC_WAKEUPS))
- wake_flags &= ~WF_SYNC;
- this_cpu = get_cpu();
- smp_wmb();
- rq = orig_rq = task_rq_lock(p, &flags);
- update_rq_clock(rq);
- if (!(p->state & state))
- goto out;
- if (p->se.on_rq)
- goto out_running;
- cpu = task_cpu(p);
- orig_cpu = cpu;
- #ifdef CONFIG_SMP
- if (unlikely(task_running(rq, p)))
- goto out_activate;
- /*
- * In order to handle concurrent wakeups and release the rq->lock
- * we put the task in TASK_WAKING state.
- *
- * First fix up the nr_uninterruptible count:
- */
- if (task_contributes_to_load(p))
- rq->nr_uninterruptible--;
- p->state = TASK_WAKING;
- task_rq_unlock(rq, &flags);
- cpu = p->sched_class->select_task_rq(p, SD_BALANCE_WAKE, wake_flags);
- if (cpu != orig_cpu)
- set_task_cpu(p, cpu);
- rq = task_rq_lock(p, &flags);
- if (rq != orig_rq)
- update_rq_clock(rq);
- WARN_ON(p->state != TASK_WAKING);
- cpu = task_cpu(p);
- #ifdef CONFIG_SCHEDSTATS
- schedstat_inc(rq, ttwu_count);
- if (cpu == this_cpu)
- schedstat_inc(rq, ttwu_local);
- else {
- struct sched_domain *sd;
- for_each_domain(this_cpu, sd) {
- if (cpumask_test_cpu(cpu, sched_domain_span(sd))) {
- schedstat_inc(sd, ttwu_wake_remote);
- break;
- }
- }
- }
- #endif /* CONFIG_SCHEDSTATS */
- out_activate:
- #endif /* CONFIG_SMP */
- schedstat_inc(p, se.nr_wakeups);
- if (wake_flags & WF_SYNC)
- schedstat_inc(p, se.nr_wakeups_sync);
- if (orig_cpu != cpu)
- schedstat_inc(p, se.nr_wakeups_migrate);
- if (cpu == this_cpu)
- schedstat_inc(p, se.nr_wakeups_local);
- else
- schedstat_inc(p, se.nr_wakeups_remote);
- activate_task(rq, p, 1);
- success = 1;
- /*
- * Only attribute actual wakeups done by this task.
- */
- if (!in_interrupt()) {
- struct sched_entity *se = ¤t->se;
- u64 sample = se->sum_exec_runtime;
- if (se->last_wakeup)
- sample -= se->last_wakeup;
- else
- sample -= se->start_runtime;
- update_avg(&se->avg_wakeup, sample);
- se->last_wakeup = se->sum_exec_runtime;
- }
- out_running:
- trace_sched_wakeup(rq, p, success);
- check_preempt_curr(rq, p, wake_flags);
- p->state = TASK_RUNNING;
- #ifdef CONFIG_SMP
- if (p->sched_class->task_wake_up)
- p->sched_class->task_wake_up(rq, p);
- if (unlikely(rq->idle_stamp)) {
- u64 delta = rq->clock - rq->idle_stamp;
- u64 max = 2*sysctl_sched_migration_cost;
- if (delta > max)
- rq->avg_idle = max;
- else
- update_avg(&rq->avg_idle, delta);
- rq->idle_stamp = 0;
- }
- #endif
- out:
- task_rq_unlock(rq, &flags);
- put_cpu();
- return success;
- }
复制代码 该函数将进程的状态设置为TASK_RUNNING,并将进程插入本地CPU队列,不会修改时间片,顶多会根据平均睡眠时间修改优先级。
|
|