scheduler: Allow mode to specify time slice length

This commit is contained in:
Pawel Dziepak
2013-11-29 05:11:44 +01:00
parent 7f8cf14b71
commit 0721899709
5 changed files with 45 additions and 20 deletions
@@ -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,
@@ -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,
+22 -15
View File
@@ -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);
}
@@ -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;
@@ -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);