diff options
author | Michael Sevakis <jethead71@rockbox.org> | 2008-02-28 17:40:18 +0000 |
---|---|---|
committer | Michael Sevakis <jethead71@rockbox.org> | 2008-02-28 17:40:18 +0000 |
commit | bbe3f1f61c50e950015aa76f6c80050adeaf167d (patch) | |
tree | d7cb64eaf76a95bd8d01694b49d3344c78432cbd /firmware/thread.c | |
parent | 7cbf70cbf2c49543b1871ac72ab9c2a1059bd66e (diff) |
Fix a very subtle bug that would cause a yielding thread to be scheduled twice in a row even if others were woken and one of them should be selected. Evaluate next thread _after_ waking checks to keep fairness.
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@16444 a1c6a512-1295-4272-9138-f99709370657
Diffstat (limited to 'firmware/thread.c')
-rw-r--r-- | firmware/thread.c | 17 |
1 files changed, 11 insertions, 6 deletions
diff --git a/firmware/thread.c b/firmware/thread.c index 63f8405cf3..b144e97403 100644 --- a/firmware/thread.c +++ b/firmware/thread.c @@ -1590,14 +1590,10 @@ void switch_thread(struct thread_entry *old) { const unsigned int core = CURRENT_CORE; struct thread_entry *thread = cores[core].running; + struct thread_entry *block = old; - if (old == NULL) - { - /* Move to next thread */ + if (block == NULL) old = thread; - cores[core].running = old->l.next; - } - /* else running list is already at next thread */ #ifdef RB_PROFILE profile_thread_stopped(old - threads); @@ -1625,6 +1621,9 @@ void switch_thread(struct thread_entry *old) #ifdef HAVE_PRIORITY_SCHEDULING /* Select the new task based on priorities and the last time a process * got CPU time. */ + if (block == NULL) + thread = thread->l.next; + for (;;) { int priority = thread->priority; @@ -1645,6 +1644,12 @@ void switch_thread(struct thread_entry *old) /* Reset the value of thread's last running time to the current time. */ thread->last_run = current_tick; +#else + if (block == NULL) + { + thread = thread->l.next; + cores[core].running = thread; + } #endif /* HAVE_PRIORITY_SCHEDULING */ /* And finally give control to the next thread. */ |