kernel: Introduce scheduler modes of operation
This commit is contained in:
parent
4b446279e6
commit
cd8d4e39fd
@ -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);
|
||||
|
@ -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,
|
||||
|
@ -720,6 +720,7 @@ static scheduler_ops kSimpleOps = {
|
||||
simple_on_thread_init,
|
||||
simple_on_thread_destroy,
|
||||
simple_start,
|
||||
NULL,
|
||||
simple_dump_thread_data
|
||||
};
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user