From cd8d4e39fd92e1886821dcb21ff08f81f1227317 Mon Sep 17 00:00:00 2001 From: Pawel Dziepak Date: Mon, 21 Oct 2013 02:17:00 +0200 Subject: [PATCH] kernel: Introduce scheduler modes of operation --- headers/private/kernel/kscheduler.h | 11 +++ .../kernel/scheduler/scheduler_affine.cpp | 73 ++++++++++++++++++- .../kernel/scheduler/scheduler_simple.cpp | 1 + 3 files changed, 83 insertions(+), 2 deletions(-) diff --git a/headers/private/kernel/kscheduler.h b/headers/private/kernel/kscheduler.h index 2c399b1b50..7746222f38 100644 --- a/headers/private/kernel/kscheduler.h +++ b/headers/private/kernel/kscheduler.h @@ -17,6 +17,13 @@ struct scheduling_analysis; struct SchedulerListener; +typedef enum scheduler_mode { + SCHEDULER_MODE_PERFORMANCE, + SCHEDULER_MODE_POWER_SAVING, + // ... + SCHEDULER_MODE_COUNT +} scheduler_mode; + struct scheduler_ops { /*! Enqueues the thread in the ready-to-run queue. The caller must hold the scheduler lock (with disabled interrupts). @@ -68,6 +75,10 @@ struct scheduler_ops { */ void (*start)(void); + /*! Sets scheduler operation mode. + */ + status_t (*set_operation_mode)(scheduler_mode mode); + /*! Dumps scheduler specific thread information. */ void (*dump_thread_data)(Thread* thread); diff --git a/src/system/kernel/scheduler/scheduler_affine.cpp b/src/system/kernel/scheduler/scheduler_affine.cpp index 4f4c1be9b8..96aa692d21 100644 --- a/src/system/kernel/scheduler/scheduler_affine.cpp +++ b/src/system/kernel/scheduler/scheduler_affine.cpp @@ -49,6 +49,11 @@ const bigtime_t kMinThreadQuantum = 3000; const bigtime_t kMaxThreadQuantum = 10000; +static scheduler_mode sSchedulerMode; + +static int32 (*sChooseCore)(void); + + // Heaps in sCPUPriorityHeaps are used for load balancing on a core the logical // processors in the heap belong to. Since there are no cache affinity issues // at this level and the run queue is shared among all logical processors on @@ -523,8 +528,8 @@ affine_update_priority_heaps(int32 cpu, int32 priority) } -static inline int32 -affine_choose_core(void) +static int32 +affine_choose_core_performance(void) { CoreEntry* entry; @@ -546,6 +551,37 @@ affine_choose_core(void) } +static int32 +affine_choose_core_power_saving(void) +{ + CoreEntry* entry; + + // TODO: small tasks packing + if (sPackageUsageHeap->PeekMinimum() != NULL) { + // wake new core + PackageEntry* package = sPackageUsageHeap->PeekMinimum(); + entry = package->fIdleCores.Last(); + } else if (sIdlePackageList->Last() != NULL) { + // wake new package + PackageEntry* package = sIdlePackageList->Last(); + entry = package->fIdleCores.Last(); + } else { + // no idle cores, use least occupied core + entry = sCorePriorityHeap->PeekRoot(); + } + + ASSERT(entry != NULL); + return entry->fCoreID; +} + + +static inline int32 +affine_choose_core(void) +{ + return sChooseCore(); +} + + static inline int32 affine_choose_cpu(int32 core) { @@ -1092,6 +1128,37 @@ affine_start(void) } +static status_t +affine_set_operation_mode(scheduler_mode mode) +{ + if (mode != SCHEDULER_MODE_PERFORMANCE + && mode != SCHEDULER_MODE_POWER_SAVING) { + return B_BAD_VALUE; + } + +#ifdef TRACE_SCHEDULER + const char* modeNames = { "performance", "power saving" }; +#endif + TRACE("switching scheduler to %s mode\n", modeNames[mode]); + + sSchedulerMode = mode; + switch (mode) { + case SCHEDULER_MODE_PERFORMANCE: + sChooseCore = affine_choose_core_performance; + break; + + case SCHEDULER_MODE_POWER_SAVING: + sChooseCore = affine_choose_core_power_saving; + break; + + default: + break; + } + + return B_OK; +} + + static scheduler_ops kAffineOps = { affine_enqueue_in_run_queue, affine_reschedule, @@ -1101,6 +1168,7 @@ static scheduler_ops kAffineOps = { affine_on_thread_init, affine_on_thread_destroy, affine_start, + affine_set_operation_mode, affine_dump_thread_data }; @@ -1278,6 +1346,7 @@ scheduler_affine_init() return result; } + affine_set_operation_mode(SCHEDULER_MODE_PERFORMANCE); gScheduler = &kAffineOps; add_debugger_command_etc("run_queue", &dump_run_queue, diff --git a/src/system/kernel/scheduler/scheduler_simple.cpp b/src/system/kernel/scheduler/scheduler_simple.cpp index 951994e2dd..e02f4d34c2 100644 --- a/src/system/kernel/scheduler/scheduler_simple.cpp +++ b/src/system/kernel/scheduler/scheduler_simple.cpp @@ -720,6 +720,7 @@ static scheduler_ops kSimpleOps = { simple_on_thread_init, simple_on_thread_destroy, simple_start, + NULL, simple_dump_thread_data };