diff --git a/src/system/kernel/scheduler/low_latency.cpp b/src/system/kernel/scheduler/low_latency.cpp index 3e4365768b..6adfe4e6fb 100644 --- a/src/system/kernel/scheduler/low_latency.cpp +++ b/src/system/kernel/scheduler/low_latency.cpp @@ -13,6 +13,9 @@ using namespace Scheduler; +const bigtime_t kCacheExpire = 100000; + + static void switch_to_mode(void) { @@ -182,6 +185,12 @@ scheduler_mode_operations gSchedulerLowLatencyMode = { true, + 2000, + 700, + { 2, 30 }, + + 60000, + switch_to_mode, set_cpu_enabled, has_cache_expired, diff --git a/src/system/kernel/scheduler/power_saving.cpp b/src/system/kernel/scheduler/power_saving.cpp index aa960e49cd..9613a356ce 100644 --- a/src/system/kernel/scheduler/power_saving.cpp +++ b/src/system/kernel/scheduler/power_saving.cpp @@ -13,6 +13,8 @@ using namespace Scheduler; +const bigtime_t kCacheExpire = 100000; + static int32 sSmallTaskCore; @@ -243,6 +245,12 @@ scheduler_mode_operations gSchedulerPowerSavingMode = { false, + 3000, + 1000, + { 3, 60 }, + + 200000, + switch_to_mode, set_cpu_enabled, has_cache_expired, diff --git a/src/system/kernel/scheduler/scheduler.cpp b/src/system/kernel/scheduler/scheduler.cpp index 9ec5d217d2..ba13a2e54e 100644 --- a/src/system/kernel/scheduler/scheduler.cpp +++ b/src/system/kernel/scheduler/scheduler.cpp @@ -611,7 +611,7 @@ should_cancel_penalty(Thread* thread) return atomic_get(&gCoreEntries[core].fStarvationCounter) != thread->scheduler_data->went_sleep_count && system_time() - thread->scheduler_data->went_sleep - > kThreadQuantum; + > sCurrentMode->base_quantum; } @@ -845,7 +845,9 @@ quantum_ended(Thread* thread, bool wasPreempted, bool hasYielded) schedulerThreadData->time_left = max_c(0, schedulerThreadData->time_left); // too little time left, it's better make the next quantum a bit longer - if (wasPreempted || schedulerThreadData->time_left <= kThreadQuantum / 50) { + if (wasPreempted + || schedulerThreadData->time_left <= sCurrentMode->minimal_quantum) { + schedulerThreadData->stolen_time += schedulerThreadData->time_left; schedulerThreadData->time_left = 0; } @@ -872,15 +874,21 @@ get_base_quantum(Thread* thread) { int32 priority = get_effective_priority(thread); + const bigtime_t kQuantum0 = sCurrentMode->base_quantum; if (priority >= B_URGENT_DISPLAY_PRIORITY) - return kThreadQuantum; + return kQuantum0; + + const bigtime_t kQuantum1 + = kQuantum0 * sCurrentMode->quantum_multipliers[0]; if (priority > B_NORMAL_PRIORITY) { - return quantum_linear_interpolation(kThreadQuantum * 2, - kThreadQuantum, B_URGENT_DISPLAY_PRIORITY, B_NORMAL_PRIORITY, - priority); + return quantum_linear_interpolation(kQuantum1, kQuantum0, + B_URGENT_DISPLAY_PRIORITY, B_NORMAL_PRIORITY, priority); } - return quantum_linear_interpolation(kThreadQuantum * 30, - kThreadQuantum * 2, B_NORMAL_PRIORITY, B_IDLE_PRIORITY, priority); + + const bigtime_t kQuantum2 + = kQuantum0 * sCurrentMode->quantum_multipliers[1]; + return quantum_linear_interpolation(kQuantum2, kQuantum1, B_NORMAL_PRIORITY, + B_IDLE_PRIORITY, priority); } @@ -902,10 +910,8 @@ compute_quantum(Thread* thread) == gCPUToCore[smp_get_current_cpu()]); CoreEntry* core = &gCoreEntries[schedulerThreadData->previous_core]; int32 threadCount = (core->fThreadCount + 1) / core->fCPUCount; - if (threadCount > 1) { - quantum = max_c(min_c(kMaximumLatency / threadCount, quantum), - kThreadQuantum / 3); - } + quantum = max_c(min_c(sCurrentMode->maximum_latency / threadCount, quantum), + sCurrentMode->minimal_quantum); schedulerThreadData->time_left = quantum; schedulerThreadData->quantum_start = system_time(); @@ -1312,7 +1318,7 @@ scheduler_on_thread_init(Thread* thread) if (thread_is_idle_thread(thread)) { static int32 sIdleThreadsID; - int32 cpu = atomic_add(&gIdleThreadsID, 1); + int32 cpu = atomic_add(&sIdleThreadsID, 1); thread->previous_cpu = &gCPU[cpu]; thread->pinned_to_cpu = 1; @@ -1421,7 +1427,6 @@ scheduler_set_cpu_enabled(int32 cpu, bool enabled) // core has been disabled ASSERT(!enabled); - int32 load = CoreLoadHeap::GetKey(core); if (core->fHighLoad) { gCoreHighLoadHeap->ModifyKey(core, -1); ASSERT(gCoreHighLoadHeap->PeekMinimum() == core); @@ -1833,7 +1838,9 @@ _user_estimate_max_scheduling_latency(thread_id id) / get_effective_priority(thread); } - return max_c(threadCount * kThreadQuantum, kThreadQuantum / 5); + return min_c(max_c(threadCount * sCurrentMode->base_quantum, + sCurrentMode->minimal_quantum), + sCurrentMode->maximum_latency); } diff --git a/src/system/kernel/scheduler/scheduler_common.h b/src/system/kernel/scheduler/scheduler_common.h index 4c63c9fe9b..3069fffa5a 100644 --- a/src/system/kernel/scheduler/scheduler_common.h +++ b/src/system/kernel/scheduler/scheduler_common.h @@ -29,11 +29,6 @@ namespace Scheduler { -const bigtime_t kThreadQuantum = 2000; -const bigtime_t kMaximumLatency = 600000; - -const bigtime_t kCacheExpire = 100000; - const int kLowLoad = kMaxLoad * 20 / 100; const int kTargetLoad = kMaxLoad * 55 / 100; const int kHighLoad = kMaxLoad * 70 / 100; diff --git a/src/system/kernel/scheduler/scheduler_modes.h b/src/system/kernel/scheduler/scheduler_modes.h index b413a6bdba..2d790a3967 100644 --- a/src/system/kernel/scheduler/scheduler_modes.h +++ b/src/system/kernel/scheduler/scheduler_modes.h @@ -15,6 +15,12 @@ struct scheduler_mode_operations { bool avoid_boost; + bigtime_t base_quantum; + bigtime_t minimal_quantum; + bigtime_t quantum_multipliers[2]; + + bigtime_t maximum_latency; + void (*switch_to_mode)(void); void (*set_cpu_enabled)(int32 cpu, bool enabled); bool (*has_cache_expired)(Thread* thread);