added 3 changesets to branch 'refs/remotes/pdziepak-github/scheduler' old head: c4292aceb9febae7f5880a1903f405abadfb95cd new head: 667617ad043a4587d8d366d5192d9ad291cfa37a overview: https://github.com/pdziepak/Haiku/compare/c4292ac...667617a ---------------------------------------------------------------------------- 391d1b3: scheduler: Disable load tracking when not needed 5b9e5d3: kernel: Remove cpu_info::load This field forces kernel to track each CPU load all the time. It is not a problem with the current scheduler on a multicore systems, but on single core machnies or with any other future scheduler this field may become just an unnecessary burden. It isn't difficult for an application to compute CPU load by itself when it needs it. 667617a: scheduler: SCHEDULER_EXIT_FUNCTION() is not needed [ Pawel Dziepak <pdziepak@xxxxxxxxxxx> ] ---------------------------------------------------------------------------- 9 files changed, 36 insertions(+), 37 deletions(-) headers/os/kernel/OS.h | 1 - headers/private/kernel/kscheduler.h | 2 -- src/system/kernel/scheduler/scheduler.cpp | 22 ++++++++++---------- src/system/kernel/scheduler/scheduler_common.h | 2 ++ src/system/kernel/scheduler/scheduler_cpu.cpp | 6 ++++-- src/system/kernel/scheduler/scheduler_profiler.h | 4 ---- src/system/kernel/scheduler/scheduler_thread.cpp | 18 ++++++++++++++++ src/system/kernel/scheduler/scheduler_thread.h | 17 +-------------- src/system/kernel/system_info.cpp | 1 - ############################################################################ Commit: 391d1b326c0cb2ef4faba8f32da89f366985b9f7 Author: Pawel Dziepak <pdziepak@xxxxxxxxxxx> Date: Fri Jan 3 18:34:25 2014 UTC scheduler: Disable load tracking when not needed ---------------------------------------------------------------------------- diff --git a/src/system/kernel/scheduler/scheduler.cpp b/src/system/kernel/scheduler/scheduler.cpp index 41546f0..bb3caa8 100644 --- a/src/system/kernel/scheduler/scheduler.cpp +++ b/src/system/kernel/scheduler/scheduler.cpp @@ -136,6 +136,8 @@ scheduler_mode gCurrentModeID; scheduler_mode_operations* gCurrentMode; bool gSingleCore; +bool gCPUFrequencyManagement; +bool gTrackLoad; CPUEntry* gCPUEntries; @@ -533,7 +535,6 @@ reschedule(int32 nextState) Thread* nextThread = nextThreadData->GetThread(); ASSERT(!gCPU[thisCPU].disabled || thread_is_idle_thread(nextThread)); - // update CPU heap CoreCPUHeapLocker cpuLocker(core); cpu->UpdatePriority(nextThreadData->GetEffectivePriority()); @@ -803,8 +804,16 @@ init() if (result != B_OK) return result; - gCoreCount = coreCount; + // disable parts of the scheduler logic that are not needed gSingleCore = coreCount == 1; + gCPUFrequencyManagement = increase_cpu_performance(0) == B_OK; + gTrackLoad = !gSingleCore || gCPUFrequencyManagement; + dprintf("scheduler switches: single core: %s, cpufreq: %s, load tracking:" + " %s\n", gSingleCore ? "true" : "false", + gCPUFrequencyManagement ? "true" : "false", + gTrackLoad ? "true" : "false"); + + gCoreCount = coreCount; gPackageCount = packageCount; gCPUEntries = new(std::nothrow) CPUEntry[cpuCount]; diff --git a/src/system/kernel/scheduler/scheduler_common.h b/src/system/kernel/scheduler/scheduler_common.h index 02c9691..812fb7d 100644 --- a/src/system/kernel/scheduler/scheduler_common.h +++ b/src/system/kernel/scheduler/scheduler_common.h @@ -43,6 +43,8 @@ const int kVeryHighLoad = (kMaxLoad + kHighLoad) / 2; const int kLoadDifference = kMaxLoad * 20 / 100; extern bool gSingleCore; +extern bool gCPUFrequencyManagement; +extern bool gTrackLoad; void init_debug_commands(); diff --git a/src/system/kernel/scheduler/scheduler_cpu.cpp b/src/system/kernel/scheduler/scheduler_cpu.cpp index 08987fd..a88c041 100644 --- a/src/system/kernel/scheduler/scheduler_cpu.cpp +++ b/src/system/kernel/scheduler/scheduler_cpu.cpp @@ -164,7 +164,6 @@ CPUEntry::ComputeLoad() { SCHEDULER_ENTER_FUNCTION(); - ASSERT(!gSingleCore); ASSERT(fCPUNumber == smp_get_current_cpu()); int oldLoad = compute_load(fMeasureTime, fMeasureActiveTime, fLoad); @@ -247,7 +246,7 @@ CPUEntry::TrackActivity(ThreadData* oldThreadData, ThreadData* nextThreadData) oldThreadData->ComputeLoad(); nextThreadData->ComputeLoad(); - if (!gSingleCore && !cpuEntry->disabled) + if (gTrackLoad && !cpuEntry->disabled) ComputeLoad(); Thread* nextThread = nextThreadData->GetThread(); @@ -267,6 +266,9 @@ CPUEntry::_RequestPerformanceLevel(ThreadData* threadData) { SCHEDULER_ENTER_FUNCTION(); + if (!gCPUFrequencyManagement) + return; + if (gCPU[fCPUNumber].disabled) { decrease_cpu_performance(kCPUPerformanceScaleMax); return; diff --git a/src/system/kernel/scheduler/scheduler_thread.cpp b/src/system/kernel/scheduler/scheduler_thread.cpp index 4d5ea19..ec84ee4 100644 --- a/src/system/kernel/scheduler/scheduler_thread.cpp +++ b/src/system/kernel/scheduler/scheduler_thread.cpp @@ -115,6 +115,24 @@ ThreadData::ChooseCoreAndCPU(CoreEntry*& targetCore, CPUEntry*& targetCPU) } +void +ThreadData::ComputeLoad() +{ + SCHEDULER_ENTER_FUNCTION(); + + if (!gTrackLoad) + return; + + if (fLastInterruptTime > 0) { + bigtime_t interruptTime = gCPU[smp_get_current_cpu()].interrupt_time; + interruptTime -= fLastInterruptTime; + fMeasureActiveTime -= interruptTime; + } + + compute_load(fMeasureTime, fMeasureActiveTime, fLoad); +} + + bigtime_t ThreadData::ComputeQuantum() { diff --git a/src/system/kernel/scheduler/scheduler_thread.h b/src/system/kernel/scheduler/scheduler_thread.h index 98cc660..debcf2d 100644 --- a/src/system/kernel/scheduler/scheduler_thread.h +++ b/src/system/kernel/scheduler/scheduler_thread.h @@ -56,7 +56,7 @@ public: inline bool Dequeue(); inline void UpdateActivity(bigtime_t active); - inline void ComputeLoad(); + void ComputeLoad(); inline bool HasQuantumEnded(bool wasPreempted, bool hasYielded); bigtime_t ComputeQuantum(); @@ -318,21 +318,6 @@ ThreadData::UpdateActivity(bigtime_t active) } -inline void -ThreadData::ComputeLoad() -{ - SCHEDULER_ENTER_FUNCTION(); - - if (fLastInterruptTime > 0) { - bigtime_t interruptTime = gCPU[smp_get_current_cpu()].interrupt_time; - interruptTime -= fLastInterruptTime; - fMeasureActiveTime -= interruptTime; - } - - compute_load(fMeasureTime, fMeasureActiveTime, fLoad); -} - - inline bool ThreadData::HasQuantumEnded(bool wasPreempted, bool hasYielded) { ############################################################################ Commit: 5b9e5d33fe35590524da7a631fded8f87bfb5b38 Author: Pawel Dziepak <pdziepak@xxxxxxxxxxx> Date: Fri Jan 3 18:38:05 2014 UTC kernel: Remove cpu_info::load This field forces kernel to track each CPU load all the time. It is not a problem with the current scheduler on a multicore systems, but on single core machnies or with any other future scheduler this field may become just an unnecessary burden. It isn't difficult for an application to compute CPU load by itself when it needs it. ---------------------------------------------------------------------------- diff --git a/headers/os/kernel/OS.h b/headers/os/kernel/OS.h index 66131ee..dce55f0 100644 --- a/headers/os/kernel/OS.h +++ b/headers/os/kernel/OS.h @@ -422,7 +422,6 @@ extern void ktrace_vprintf(const char *format, va_list args); typedef struct { bigtime_t active_time; /* usec of doing useful work since boot */ - int32 load; bool enabled; } cpu_info; diff --git a/headers/private/kernel/kscheduler.h b/headers/private/kernel/kscheduler.h index b3328a6..bfc6e02 100644 --- a/headers/private/kernel/kscheduler.h +++ b/headers/private/kernel/kscheduler.h @@ -81,8 +81,6 @@ void scheduler_new_thread_entry(Thread* thread); void scheduler_set_cpu_enabled(int32 cpu, bool enabled); -int scheduler_get_cpu_load(int32 cpu); - void scheduler_add_listener(struct SchedulerListener* listener); void scheduler_remove_listener(struct SchedulerListener* listener); diff --git a/src/system/kernel/scheduler/scheduler.cpp b/src/system/kernel/scheduler/scheduler.cpp index bb3caa8..04827d8 100644 --- a/src/system/kernel/scheduler/scheduler.cpp +++ b/src/system/kernel/scheduler/scheduler.cpp @@ -723,13 +723,6 @@ scheduler_set_cpu_enabled(int32 cpuID, bool enabled) } -int -scheduler_get_cpu_load(int32 cpu) -{ - return CPUEntry::GetCPU(cpu)->GetLoad() / 10; -} - - static void traverse_topology_tree(const cpu_topology_node* node, int packageID, int coreID) { diff --git a/src/system/kernel/system_info.cpp b/src/system/kernel/system_info.cpp index 9f22a90..5fa1664 100644 --- a/src/system/kernel/system_info.cpp +++ b/src/system/kernel/system_info.cpp @@ -452,7 +452,6 @@ get_cpu_info(uint32 firstCPU, uint32 cpuCount, cpu_info* info) memset(info, 0, sizeof(cpu_info) * count); for (uint32 i = 0; i < count; i++) { info[i].active_time = cpu_get_active_time(firstCPU + i); - info[i].load = scheduler_get_cpu_load(firstCPU + i); info[i].enabled = !gCPU[firstCPU + i].disabled; } ############################################################################ Commit: 667617ad043a4587d8d366d5192d9ad291cfa37a Author: Pawel Dziepak <pdziepak@xxxxxxxxxxx> Date: Fri Jan 3 19:09:43 2014 UTC scheduler: SCHEDULER_EXIT_FUNCTION() is not needed ---------------------------------------------------------------------------- diff --git a/src/system/kernel/scheduler/scheduler.cpp b/src/system/kernel/scheduler/scheduler.cpp index 04827d8..de6a49f 100644 --- a/src/system/kernel/scheduler/scheduler.cpp +++ b/src/system/kernel/scheduler/scheduler.cpp @@ -585,8 +585,6 @@ reschedule(int32 nextState) modeLocker.Unlock(); - SCHEDULER_EXIT_FUNCTION(); - if (nextThread != oldThread) switch_thread(oldThread, nextThread); } diff --git a/src/system/kernel/scheduler/scheduler_profiler.h b/src/system/kernel/scheduler/scheduler_profiler.h index d2c1bfc..e6c95b5 100644 --- a/src/system/kernel/scheduler/scheduler_profiler.h +++ b/src/system/kernel/scheduler/scheduler_profiler.h @@ -16,9 +16,6 @@ #define SCHEDULER_ENTER_FUNCTION() \ Scheduler::Profiling::Function schedulerProfiler(__PRETTY_FUNCTION__) -#define SCHEDULER_EXIT_FUNCTION() \ - schedulerProfiler.Exit() - namespace Scheduler { @@ -127,7 +124,6 @@ Function::Exit() #else // SCHEDULER_PROFILING #define SCHEDULER_ENTER_FUNCTION() (void)0 -#define SCHEDULER_EXIT_FUNCTION() (void)0 #endif // !SCHEDULER_PROFILING