scheduler: Send reschedule ICI after enqueueing the thread

This commit is contained in:
Pawel Dziepak
2013-11-26 03:03:41 +01:00
parent 7db89e8dc3
commit 35153d1c49
+25 -30
View File
@@ -548,7 +548,7 @@ choose_cpu(int32 core)
} }
static bool static void
choose_core_and_cpu(Thread* thread, int32& targetCore, int32& targetCPU) choose_core_and_cpu(Thread* thread, int32& targetCore, int32& targetCPU)
{ {
if (targetCore == -1 && targetCPU != -1) if (targetCore == -1 && targetCPU != -1)
@@ -562,19 +562,6 @@ choose_core_and_cpu(Thread* thread, int32& targetCore, int32& targetCPU)
ASSERT(targetCore >= 0 && targetCore < gRunQueueCount); ASSERT(targetCore >= 0 && targetCore < gRunQueueCount);
ASSERT(targetCPU >= 0 && targetCPU < smp_get_num_cpus()); ASSERT(targetCPU >= 0 && targetCPU < smp_get_num_cpus());
int32 targetPriority = gCPUEntries[targetCPU].fPriority;
int32 threadPriority = get_effective_priority(thread);
if (threadPriority > targetPriority) {
// It is possible that another CPU schedules the thread before the
// target CPU. However, since the target CPU is sent an ICI it will
// reschedule anyway and update its heap key to the correct value.
update_cpu_priority(targetCPU, threadPriority);
return true;
}
return false;
} }
@@ -716,7 +703,7 @@ enqueue(Thread* thread, bool newOne)
targetCore = schedulerThreadData->previous_core; targetCore = schedulerThreadData->previous_core;
} }
bool shouldReschedule = choose_core_and_cpu(thread, targetCore, targetCPU); choose_core_and_cpu(thread, targetCore, targetCPU);
schedulerThreadData->previous_core = targetCore; schedulerThreadData->previous_core = targetCore;
TRACE("enqueueing thread %ld with priority %ld on CPU %ld (core %ld)\n", TRACE("enqueueing thread %ld with priority %ld on CPU %ld (core %ld)\n",
@@ -734,7 +721,14 @@ enqueue(Thread* thread, bool newOne)
NotifySchedulerListeners(&SchedulerListener::ThreadEnqueuedInRunQueue, NotifySchedulerListeners(&SchedulerListener::ThreadEnqueuedInRunQueue,
thread); thread);
if (shouldReschedule) { int32 targetPriority = gCPUEntries[targetCPU].fPriority;
if (threadPriority > targetPriority) {
// It is possible that another CPU schedules the thread before the
// target CPU. However, since the target CPU is sent an ICI it will
// reschedule anyway and update its heap key to the correct value.
update_cpu_priority(targetCPU, threadPriority);
if (targetCPU == smp_get_current_cpu()) if (targetCPU == smp_get_current_cpu())
gCPU[targetCPU].invoke_scheduler = true; gCPU[targetCPU].invoke_scheduler = true;
else { else {
@@ -1638,7 +1632,7 @@ create_debug_heaps()
static status_t static status_t
_scheduler_init() init()
{ {
// create logical processor to core and package mappings // create logical processor to core and package mappings
int32 cpuCount, coreCount, packageCount; int32 cpuCount, coreCount, packageCount;
@@ -1751,18 +1745,6 @@ _scheduler_init()
if (result != B_OK) if (result != B_OK)
return result; return result;
scheduler_set_operation_mode(SCHEDULER_MODE_LOW_LATENCY);
add_debugger_command_etc("run_queue", &dump_run_queue,
"List threads in run queue", "\nLists threads in run queue", 0);
add_debugger_command_etc("cpu_heap", &dump_cpu_heap,
"List CPUs in CPU priority heap", "\nList CPUs in CPU priority heap",
0);
if (!gSingleCore) {
add_debugger_command_etc("idle_cores", &dump_idle_cores,
"List idle cores", "\nList idle cores", 0);
}
runQueuesDeleter.Detach(); runQueuesDeleter.Detach();
pinnedRunQueuesDeleter.Detach(); pinnedRunQueuesDeleter.Detach();
coreHighLoadHeapDeleter.Detach(); coreHighLoadHeapDeleter.Detach();
@@ -1784,10 +1766,22 @@ scheduler_init(void)
" cache level%s\n", cpuCount, cpuCount != 1 ? "s" : "", " cache level%s\n", cpuCount, cpuCount != 1 ? "s" : "",
gCPUCacheLevelCount, gCPUCacheLevelCount != 1 ? "s" : ""); gCPUCacheLevelCount, gCPUCacheLevelCount != 1 ? "s" : "");
status_t result = _scheduler_init(); status_t result = init();
if (result != B_OK) if (result != B_OK)
panic("scheduler_init: failed to initialize scheduler\n"); panic("scheduler_init: failed to initialize scheduler\n");
scheduler_set_operation_mode(SCHEDULER_MODE_LOW_LATENCY);
add_debugger_command_etc("run_queue", &dump_run_queue,
"List threads in run queue", "\nLists threads in run queue", 0);
add_debugger_command_etc("cpu_heap", &dump_cpu_heap,
"List CPUs in CPU priority heap", "\nList CPUs in CPU priority heap",
0);
if (!gSingleCore) {
add_debugger_command_etc("idle_cores", &dump_idle_cores,
"List idle cores", "\nList idle cores", 0);
}
#if SCHEDULER_TRACING #if SCHEDULER_TRACING
add_debugger_command_etc("scheduler", &cmd_scheduler, add_debugger_command_etc("scheduler", &cmd_scheduler,
"Analyze scheduler tracing information", "Analyze scheduler tracing information",
@@ -1883,3 +1877,4 @@ _user_get_scheduler_mode(void)
{ {
return sCurrentModeID; return sCurrentModeID;
} }