Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 356893
b: refs/heads/master
c: 7b270f6
h: refs/heads/master
i:
  356891: 24ddb83
v: v3
  • Loading branch information
Peter Zijlstra authored and Gleb Natapov committed Jan 29, 2013
1 parent ff16957 commit 8973c4d
Show file tree
Hide file tree
Showing 2 changed files with 20 additions and 7 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: c7c9c56ca26f7b9458711b2d78b60b60e0d38ba7
refs/heads/master: 7b270f609982f68f2433442bf167f735e7364b06
25 changes: 19 additions & 6 deletions trunk/kernel/sched/core.c
Original file line number Diff line number Diff line change
Expand Up @@ -4316,7 +4316,10 @@ EXPORT_SYMBOL(yield);
* It's the caller's job to ensure that the target task struct
* can't go away on us before we can do any checks.
*
* Returns true if we indeed boosted the target task.
* Returns:
* true (>0) if we indeed boosted the target task.
* false (0) if we failed to boost the target.
* -ESRCH if there's no task to yield to.
*/
bool __sched yield_to(struct task_struct *p, bool preempt)
{
Expand All @@ -4330,20 +4333,29 @@ bool __sched yield_to(struct task_struct *p, bool preempt)

again:
p_rq = task_rq(p);
/*
* If we're the only runnable task on the rq and target rq also
* has only one task, there's absolutely no point in yielding.
*/
if (rq->nr_running == 1 && p_rq->nr_running == 1) {
yielded = -ESRCH;
goto out_irq;
}

double_rq_lock(rq, p_rq);
while (task_rq(p) != p_rq) {
double_rq_unlock(rq, p_rq);
goto again;
}

if (!curr->sched_class->yield_to_task)
goto out;
goto out_unlock;

if (curr->sched_class != p->sched_class)
goto out;
goto out_unlock;

if (task_running(p_rq, p) || p->state)
goto out;
goto out_unlock;

yielded = curr->sched_class->yield_to_task(rq, p, preempt);
if (yielded) {
Expand All @@ -4356,11 +4368,12 @@ bool __sched yield_to(struct task_struct *p, bool preempt)
resched_task(p_rq->curr);
}

out:
out_unlock:
double_rq_unlock(rq, p_rq);
out_irq:
local_irq_restore(flags);

if (yielded)
if (yielded > 0)
schedule();

return yielded;
Expand Down

0 comments on commit 8973c4d

Please sign in to comment.