scheduler: Clean scheduler_common.h
scheduler_common.h is now meant for types, variables and functions used by both core scheduler code and implementations of scheduler modes. Functions like switch_thread() and update_thread_times() do not belong there anymore.
This commit is contained in:
@@ -1089,8 +1089,94 @@ update_cpu_performance(Thread* thread, int32 thisCore)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*! Switches the currently running thread.
|
||||||
|
This is a service function for scheduler implementations.
|
||||||
|
|
||||||
|
\param fromThread The currently running thread.
|
||||||
|
\param toThread The thread to switch to. Must be different from
|
||||||
|
\a fromThread.
|
||||||
|
*/
|
||||||
|
static inline void
|
||||||
|
switch_thread(Thread* fromThread, Thread* toThread)
|
||||||
|
{
|
||||||
|
// notify the user debugger code
|
||||||
|
if ((fromThread->flags & THREAD_FLAGS_DEBUGGER_INSTALLED) != 0)
|
||||||
|
user_debug_thread_unscheduled(fromThread);
|
||||||
|
|
||||||
|
// stop CPU time based user timers
|
||||||
|
acquire_spinlock(&fromThread->team->time_lock);
|
||||||
|
acquire_spinlock(&fromThread->time_lock);
|
||||||
|
if (fromThread->HasActiveCPUTimeUserTimers()
|
||||||
|
|| fromThread->team->HasActiveCPUTimeUserTimers()) {
|
||||||
|
user_timer_stop_cpu_timers(fromThread, toThread);
|
||||||
|
}
|
||||||
|
release_spinlock(&fromThread->time_lock);
|
||||||
|
release_spinlock(&fromThread->team->time_lock);
|
||||||
|
|
||||||
|
// update CPU and Thread structures and perform the context switch
|
||||||
|
cpu_ent* cpu = fromThread->cpu;
|
||||||
|
toThread->previous_cpu = toThread->cpu = cpu;
|
||||||
|
fromThread->cpu = NULL;
|
||||||
|
cpu->running_thread = toThread;
|
||||||
|
cpu->previous_thread = fromThread;
|
||||||
|
|
||||||
|
arch_thread_set_current_thread(toThread);
|
||||||
|
arch_thread_context_switch(fromThread, toThread);
|
||||||
|
|
||||||
|
release_spinlock(&fromThread->cpu->previous_thread->scheduler_lock);
|
||||||
|
|
||||||
|
// The use of fromThread below looks weird, but is correct. fromThread had
|
||||||
|
// been unscheduled earlier, but is back now. For a thread scheduled the
|
||||||
|
// first time the same is done in thread.cpp:common_thread_entry().
|
||||||
|
|
||||||
|
// continue CPU time based user timers
|
||||||
|
acquire_spinlock(&fromThread->team->time_lock);
|
||||||
|
acquire_spinlock(&fromThread->time_lock);
|
||||||
|
if (fromThread->HasActiveCPUTimeUserTimers()
|
||||||
|
|| fromThread->team->HasActiveCPUTimeUserTimers()) {
|
||||||
|
user_timer_continue_cpu_timers(fromThread, cpu->previous_thread);
|
||||||
|
}
|
||||||
|
release_spinlock(&fromThread->time_lock);
|
||||||
|
release_spinlock(&fromThread->team->time_lock);
|
||||||
|
|
||||||
|
// notify the user debugger code
|
||||||
|
if ((fromThread->flags & THREAD_FLAGS_DEBUGGER_INSTALLED) != 0)
|
||||||
|
user_debug_thread_scheduled(fromThread);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static inline void
|
||||||
|
update_thread_times(Thread* oldThread, Thread* nextThread)
|
||||||
|
{
|
||||||
|
bigtime_t now = system_time();
|
||||||
|
if (oldThread == nextThread) {
|
||||||
|
acquire_spinlock(&oldThread->time_lock);
|
||||||
|
oldThread->kernel_time += now - oldThread->last_time;
|
||||||
|
oldThread->last_time = now;
|
||||||
|
release_spinlock(&oldThread->time_lock);
|
||||||
|
} else {
|
||||||
|
acquire_spinlock(&oldThread->time_lock);
|
||||||
|
oldThread->kernel_time += now - oldThread->last_time;
|
||||||
|
oldThread->last_time = 0;
|
||||||
|
release_spinlock(&oldThread->time_lock);
|
||||||
|
|
||||||
|
acquire_spinlock(&nextThread->time_lock);
|
||||||
|
nextThread->last_time = now;
|
||||||
|
release_spinlock(&nextThread->time_lock);
|
||||||
|
}
|
||||||
|
|
||||||
|
// If the old thread's team has user time timers, check them now.
|
||||||
|
Team* team = oldThread->team;
|
||||||
|
|
||||||
|
acquire_spinlock(&team->time_lock);
|
||||||
|
if (team->HasActiveUserTimeUserTimers())
|
||||||
|
user_timer_check_team_user_timers(team);
|
||||||
|
release_spinlock(&team->time_lock);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
_scheduler_reschedule(void)
|
reschedule(void)
|
||||||
{
|
{
|
||||||
ASSERT(!are_interrupts_enabled());
|
ASSERT(!are_interrupts_enabled());
|
||||||
|
|
||||||
@@ -1206,7 +1292,7 @@ _scheduler_reschedule(void)
|
|||||||
compute_thread_load(nextThread);
|
compute_thread_load(nextThread);
|
||||||
|
|
||||||
// track kernel time (user time is tracked in thread_at_kernel_entry())
|
// track kernel time (user time is tracked in thread_at_kernel_entry())
|
||||||
scheduler_update_thread_times(oldThread, nextThread);
|
update_thread_times(oldThread, nextThread);
|
||||||
|
|
||||||
// track CPU activity
|
// track CPU activity
|
||||||
track_cpu_activity(oldThread, nextThread, thisCore);
|
track_cpu_activity(oldThread, nextThread, thisCore);
|
||||||
@@ -1235,7 +1321,7 @@ _scheduler_reschedule(void)
|
|||||||
|
|
||||||
modeLocker.Unlock();
|
modeLocker.Unlock();
|
||||||
if (nextThread != oldThread)
|
if (nextThread != oldThread)
|
||||||
scheduler_switch_thread(oldThread, nextThread);
|
switch_thread(oldThread, nextThread);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1253,7 +1339,7 @@ scheduler_reschedule(void)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
_scheduler_reschedule();
|
reschedule();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -1299,7 +1385,7 @@ scheduler_start(void)
|
|||||||
{
|
{
|
||||||
InterruptsSpinLocker _(thread_get_current_thread()->scheduler_lock);
|
InterruptsSpinLocker _(thread_get_current_thread()->scheduler_lock);
|
||||||
|
|
||||||
_scheduler_reschedule();
|
reschedule();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -184,90 +184,4 @@ get_core_load(struct Scheduler::CoreEntry* core)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*! Switches the currently running thread.
|
|
||||||
This is a service function for scheduler implementations.
|
|
||||||
|
|
||||||
\param fromThread The currently running thread.
|
|
||||||
\param toThread The thread to switch to. Must be different from
|
|
||||||
\a fromThread.
|
|
||||||
*/
|
|
||||||
static inline void
|
|
||||||
scheduler_switch_thread(Thread* fromThread, Thread* toThread)
|
|
||||||
{
|
|
||||||
// notify the user debugger code
|
|
||||||
if ((fromThread->flags & THREAD_FLAGS_DEBUGGER_INSTALLED) != 0)
|
|
||||||
user_debug_thread_unscheduled(fromThread);
|
|
||||||
|
|
||||||
// stop CPU time based user timers
|
|
||||||
acquire_spinlock(&fromThread->team->time_lock);
|
|
||||||
acquire_spinlock(&fromThread->time_lock);
|
|
||||||
if (fromThread->HasActiveCPUTimeUserTimers()
|
|
||||||
|| fromThread->team->HasActiveCPUTimeUserTimers()) {
|
|
||||||
user_timer_stop_cpu_timers(fromThread, toThread);
|
|
||||||
}
|
|
||||||
release_spinlock(&fromThread->time_lock);
|
|
||||||
release_spinlock(&fromThread->team->time_lock);
|
|
||||||
|
|
||||||
// update CPU and Thread structures and perform the context switch
|
|
||||||
cpu_ent* cpu = fromThread->cpu;
|
|
||||||
toThread->previous_cpu = toThread->cpu = cpu;
|
|
||||||
fromThread->cpu = NULL;
|
|
||||||
cpu->running_thread = toThread;
|
|
||||||
cpu->previous_thread = fromThread;
|
|
||||||
|
|
||||||
arch_thread_set_current_thread(toThread);
|
|
||||||
arch_thread_context_switch(fromThread, toThread);
|
|
||||||
|
|
||||||
release_spinlock(&fromThread->cpu->previous_thread->scheduler_lock);
|
|
||||||
|
|
||||||
// The use of fromThread below looks weird, but is correct. fromThread had
|
|
||||||
// been unscheduled earlier, but is back now. For a thread scheduled the
|
|
||||||
// first time the same is done in thread.cpp:common_thread_entry().
|
|
||||||
|
|
||||||
// continue CPU time based user timers
|
|
||||||
acquire_spinlock(&fromThread->team->time_lock);
|
|
||||||
acquire_spinlock(&fromThread->time_lock);
|
|
||||||
if (fromThread->HasActiveCPUTimeUserTimers()
|
|
||||||
|| fromThread->team->HasActiveCPUTimeUserTimers()) {
|
|
||||||
user_timer_continue_cpu_timers(fromThread, cpu->previous_thread);
|
|
||||||
}
|
|
||||||
release_spinlock(&fromThread->time_lock);
|
|
||||||
release_spinlock(&fromThread->team->time_lock);
|
|
||||||
|
|
||||||
// notify the user debugger code
|
|
||||||
if ((fromThread->flags & THREAD_FLAGS_DEBUGGER_INSTALLED) != 0)
|
|
||||||
user_debug_thread_scheduled(fromThread);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static inline void
|
|
||||||
scheduler_update_thread_times(Thread* oldThread, Thread* nextThread)
|
|
||||||
{
|
|
||||||
bigtime_t now = system_time();
|
|
||||||
if (oldThread == nextThread) {
|
|
||||||
acquire_spinlock(&oldThread->time_lock);
|
|
||||||
oldThread->kernel_time += now - oldThread->last_time;
|
|
||||||
oldThread->last_time = now;
|
|
||||||
release_spinlock(&oldThread->time_lock);
|
|
||||||
} else {
|
|
||||||
acquire_spinlock(&oldThread->time_lock);
|
|
||||||
oldThread->kernel_time += now - oldThread->last_time;
|
|
||||||
oldThread->last_time = 0;
|
|
||||||
release_spinlock(&oldThread->time_lock);
|
|
||||||
|
|
||||||
acquire_spinlock(&nextThread->time_lock);
|
|
||||||
nextThread->last_time = now;
|
|
||||||
release_spinlock(&nextThread->time_lock);
|
|
||||||
}
|
|
||||||
|
|
||||||
// If the old thread's team has user time timers, check them now.
|
|
||||||
Team* team = oldThread->team;
|
|
||||||
|
|
||||||
acquire_spinlock(&team->time_lock);
|
|
||||||
if (team->HasActiveUserTimeUserTimers())
|
|
||||||
user_timer_check_team_user_timers(team);
|
|
||||||
release_spinlock(&team->time_lock);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
#endif // KERNEL_SCHEDULER_COMMON_H
|
#endif // KERNEL_SCHEDULER_COMMON_H
|
||||||
|
|||||||
Reference in New Issue
Block a user