forked from len0rd/rockbox
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
This commit is contained in:
parent
7cbf70cbf2
commit
bbe3f1f61c
1 changed files with 11 additions and 6 deletions
|
|
@ -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. */
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue