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
|
||||
_scheduler_reschedule(void)
|
||||
reschedule(void)
|
||||
{
|
||||
ASSERT(!are_interrupts_enabled());
|
||||
|
||||
@@ -1206,7 +1292,7 @@ _scheduler_reschedule(void)
|
||||
compute_thread_load(nextThread);
|
||||
|
||||
// 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(oldThread, nextThread, thisCore);
|
||||
@@ -1235,7 +1321,7 @@ _scheduler_reschedule(void)
|
||||
|
||||
modeLocker.Unlock();
|
||||
if (nextThread != oldThread)
|
||||
scheduler_switch_thread(oldThread, nextThread);
|
||||
switch_thread(oldThread, nextThread);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1253,7 +1339,7 @@ scheduler_reschedule(void)
|
||||
return;
|
||||
}
|
||||
|
||||
_scheduler_reschedule();
|
||||
reschedule();
|
||||
}
|
||||
|
||||
|
||||
@@ -1299,7 +1385,7 @@ scheduler_start(void)
|
||||
{
|
||||
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
|
||||
|
||||
Reference in New Issue
Block a user