summaryrefslogtreecommitdiff
path: root/firmware/thread.c
diff options
context:
space:
mode:
authorMichael Sevakis <jethead71@rockbox.org>2008-02-28 17:40:18 +0000
committerMichael Sevakis <jethead71@rockbox.org>2008-02-28 17:40:18 +0000
commitbbe3f1f61c50e950015aa76f6c80050adeaf167d (patch)
treed7cb64eaf76a95bd8d01694b49d3344c78432cbd /firmware/thread.c
parent7cbf70cbf2c49543b1871ac72ab9c2a1059bd66e (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.c17
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. */