1
0
Fork 0
forked from len0rd/rockbox

Trim a little bulk off the scheduler for dual core. Shouldn't change bin size on single except for a small function call avoidance.

git-svn-id: svn://svn.rockbox.org/rockbox/trunk@14075 a1c6a512-1295-4272-9138-f99709370657
This commit is contained in:
Michael Sevakis 2007-07-30 16:44:36 +00:00
parent 0df8d1f295
commit a690ebb1d1

View file

@ -388,12 +388,11 @@ static void remove_from_list(struct thread_entry **list,
static void check_sleepers(void) __attribute__ ((noinline)); static void check_sleepers(void) __attribute__ ((noinline));
static void check_sleepers(void) static void check_sleepers(void)
{ {
const unsigned int core = CURRENT_CORE;
struct thread_entry *current, *next; struct thread_entry *current, *next;
/* Check sleeping threads. */ /* Check sleeping threads. */
current = cores[CURRENT_CORE].sleeping; current = cores[core].sleeping;
if (current == NULL)
return ;
for (;;) for (;;)
{ {
@ -403,12 +402,12 @@ static void check_sleepers(void)
{ {
/* Sleep timeout has been reached so bring the thread /* Sleep timeout has been reached so bring the thread
* back to life again. */ * back to life again. */
remove_from_list(&cores[CURRENT_CORE].sleeping, current); remove_from_list(&cores[core].sleeping, current);
add_to_list(&cores[CURRENT_CORE].running, current); add_to_list(&cores[core].running, current);
current->statearg = 0; current->statearg = 0;
/* If there is no more processes in the list, break the loop. */ /* If there is no more processes in the list, break the loop. */
if (cores[CURRENT_CORE].sleeping == NULL) if (cores[core].sleeping == NULL)
break; break;
current = next; current = next;
@ -419,7 +418,7 @@ static void check_sleepers(void)
/* Break the loop once we have walked through the list of all /* Break the loop once we have walked through the list of all
* sleeping processes. */ * sleeping processes. */
if (current == cores[CURRENT_CORE].sleeping) if (current == cores[core].sleeping)
break; break;
} }
} }
@ -429,14 +428,15 @@ static void check_sleepers(void)
static void wake_list_awaken(void) __attribute__ ((noinline)); static void wake_list_awaken(void) __attribute__ ((noinline));
static void wake_list_awaken(void) static void wake_list_awaken(void)
{ {
const unsigned int core = CURRENT_CORE;
int oldlevel = set_irq_level(HIGHEST_IRQ_LEVEL); int oldlevel = set_irq_level(HIGHEST_IRQ_LEVEL);
/* No need for another check in the IRQ lock since IRQs are allowed /* No need for another check in the IRQ lock since IRQs are allowed
only to add threads to the waking list. They won't be adding more only to add threads to the waking list. They won't be adding more
until we're done here though. */ until we're done here though. */
struct thread_entry *waking = cores[CURRENT_CORE].waking; struct thread_entry *waking = cores[core].waking;
struct thread_entry *running = cores[CURRENT_CORE].running; struct thread_entry *running = cores[core].running;
if (running != NULL) if (running != NULL)
{ {
@ -452,33 +452,36 @@ static void wake_list_awaken(void)
{ {
/* Just transfer the list as-is - just came out of a core /* Just transfer the list as-is - just came out of a core
* sleep. */ * sleep. */
cores[CURRENT_CORE].running = waking; cores[core].running = waking;
} }
/* Done with waking list */ /* Done with waking list */
cores[CURRENT_CORE].waking = NULL; cores[core].waking = NULL;
set_irq_level(oldlevel); set_irq_level(oldlevel);
} }
static inline void sleep_core(void) static inline void sleep_core(void)
{ {
const unsigned int core = CURRENT_CORE;
for (;;) for (;;)
{ {
/* We want to do these ASAP as it may change the decision to sleep /* We want to do these ASAP as it may change the decision to sleep
the core or the core has woken because an interrupt occurred the core or the core has woken because an interrupt occurred
and posted a message to a queue. */ and posted a message to a queue. */
if (cores[CURRENT_CORE].waking != NULL) if (cores[core].waking != NULL)
wake_list_awaken(); wake_list_awaken();
if (cores[CURRENT_CORE].last_tick != current_tick) if (cores[core].last_tick != current_tick)
{ {
if (cores[core].sleeping != NULL)
check_sleepers(); check_sleepers();
cores[CURRENT_CORE].last_tick = current_tick; cores[core].last_tick = current_tick;
} }
/* We must sleep until there is at least one process in the list /* We must sleep until there is at least one process in the list
* of running processes. */ * of running processes. */
if (cores[CURRENT_CORE].running != NULL) if (cores[core].running != NULL)
break; break;
/* Enter sleep mode to reduce power usage, woken up on interrupt */ /* Enter sleep mode to reduce power usage, woken up on interrupt */
@ -508,34 +511,35 @@ void profile_thread(void) {
static void change_thread_state(struct thread_entry **blocked_list) __attribute__ ((noinline)); static void change_thread_state(struct thread_entry **blocked_list) __attribute__ ((noinline));
static void change_thread_state(struct thread_entry **blocked_list) static void change_thread_state(struct thread_entry **blocked_list)
{ {
const unsigned int core = CURRENT_CORE;
struct thread_entry *old; struct thread_entry *old;
unsigned long new_state; unsigned long new_state;
/* Remove the thread from the list of running threads. */ /* Remove the thread from the list of running threads. */
old = cores[CURRENT_CORE].running; old = cores[core].running;
new_state = GET_STATE(old->statearg); new_state = GET_STATE(old->statearg);
/* Check if a thread state change has been requested. */ /* Check if a thread state change has been requested. */
if (new_state) if (new_state)
{ {
/* Change running thread state and switch to next thread. */ /* Change running thread state and switch to next thread. */
remove_from_list(&cores[CURRENT_CORE].running, old); remove_from_list(&cores[core].running, old);
/* And put the thread into a new list of inactive threads. */ /* And put the thread into a new list of inactive threads. */
if (new_state == STATE_BLOCKED) if (new_state == STATE_BLOCKED)
add_to_list(blocked_list, old); add_to_list(blocked_list, old);
else else
add_to_list(&cores[CURRENT_CORE].sleeping, old); add_to_list(&cores[core].sleeping, old);
#ifdef HAVE_PRIORITY_SCHEDULING #ifdef HAVE_PRIORITY_SCHEDULING
/* Reset priorities */ /* Reset priorities */
if (old->priority == cores[CURRENT_CORE].highest_priority) if (old->priority == cores[core].highest_priority)
cores[CURRENT_CORE].highest_priority = 100; cores[core].highest_priority = 100;
#endif #endif
} }
else else
/* Switch to the next running thread. */ /* Switch to the next running thread. */
cores[CURRENT_CORE].running = old->next; cores[core].running = old->next;
} }
/*--------------------------------------------------------------------------- /*---------------------------------------------------------------------------
@ -544,8 +548,10 @@ static void change_thread_state(struct thread_entry **blocked_list)
*/ */
void switch_thread(bool save_context, struct thread_entry **blocked_list) void switch_thread(bool save_context, struct thread_entry **blocked_list)
{ {
const unsigned int core = CURRENT_CORE;
#ifdef RB_PROFILE #ifdef RB_PROFILE
profile_thread_stopped(get_threadnum(cores[CURRENT_CORE].running)); profile_thread_stopped(get_threadnum(cores[core].running));
#endif #endif
unsigned int *stackptr; unsigned int *stackptr;
@ -560,13 +566,13 @@ void switch_thread(bool save_context, struct thread_entry **blocked_list)
* to this call. */ * to this call. */
if (save_context) if (save_context)
{ {
store_context(&cores[CURRENT_CORE].running->context); store_context(&cores[core].running->context);
/* Check if the current thread stack is overflown */ /* Check if the current thread stack is overflown */
stackptr = cores[CURRENT_CORE].running->stack; stackptr = cores[core].running->stack;
if(stackptr[0] != DEADBEEF) if(stackptr[0] != DEADBEEF)
#ifdef THREAD_EXTRA_CHECKS #ifdef THREAD_EXTRA_CHECKS
thread_panicf("Stkov", cores[CURRENT_CORE].running, NULL); thread_panicf("Stkov", cores[core].running, NULL);
#else #else
thread_stkov(); thread_stkov();
#endif #endif
@ -577,10 +583,10 @@ void switch_thread(bool save_context, struct thread_entry **blocked_list)
/* This has to be done after the scheduler is finished with the /* This has to be done after the scheduler is finished with the
blocked_list pointer so that an IRQ can't kill us by attempting blocked_list pointer so that an IRQ can't kill us by attempting
a wake but before attempting any core sleep. */ a wake but before attempting any core sleep. */
if (cores[CURRENT_CORE].switch_to_irq_level != STAY_IRQ_LEVEL) if (cores[core].switch_to_irq_level != STAY_IRQ_LEVEL)
{ {
int level = cores[CURRENT_CORE].switch_to_irq_level; int level = cores[core].switch_to_irq_level;
cores[CURRENT_CORE].switch_to_irq_level = STAY_IRQ_LEVEL; cores[core].switch_to_irq_level = STAY_IRQ_LEVEL;
set_irq_level(level); set_irq_level(level);
} }
} }
@ -595,34 +601,34 @@ void switch_thread(bool save_context, struct thread_entry **blocked_list)
* got CPU time. */ * got CPU time. */
for (;;) for (;;)
{ {
int priority = cores[CURRENT_CORE].running->priority; int priority = cores[core].running->priority;
if (priority < cores[CURRENT_CORE].highest_priority) if (priority < cores[core].highest_priority)
cores[CURRENT_CORE].highest_priority = priority; cores[core].highest_priority = priority;
if (priority == cores[CURRENT_CORE].highest_priority || if (priority == cores[core].highest_priority ||
(current_tick - cores[CURRENT_CORE].running->last_run > (current_tick - cores[core].running->last_run >
priority * 8) || priority * 8) ||
cores[CURRENT_CORE].running->priority_x != 0) cores[core].running->priority_x != 0)
{ {
break; break;
} }
cores[CURRENT_CORE].running = cores[CURRENT_CORE].running->next; cores[core].running = cores[core].running->next;
} }
/* Reset the value of thread's last running time to the current time. */ /* Reset the value of thread's last running time to the current time. */
cores[CURRENT_CORE].running->last_run = current_tick; cores[core].running->last_run = current_tick;
#endif #endif
#endif #endif
unlock_cores(); unlock_cores();
/* And finally give control to the next thread. */ /* And finally give control to the next thread. */
load_context(&cores[CURRENT_CORE].running->context); load_context(&cores[core].running->context);
#ifdef RB_PROFILE #ifdef RB_PROFILE
profile_thread_started(get_threadnum(cores[CURRENT_CORE].running)); profile_thread_started(get_threadnum(cores[core].running));
#endif #endif
} }
@ -995,7 +1001,7 @@ struct thread_entry * thread_get_current(void)
void init_threads(void) void init_threads(void)
{ {
unsigned int core = CURRENT_CORE; const unsigned int core = CURRENT_CORE;
int slot; int slot;
/* Let main CPU initialize first. */ /* Let main CPU initialize first. */