scheduler: Reduce scheduler mode lock cache bouncing
This commit is contained in:
@@ -43,7 +43,6 @@ static bool sSchedulerEnabled;
|
|||||||
SchedulerListenerList gSchedulerListeners;
|
SchedulerListenerList gSchedulerListeners;
|
||||||
spinlock gSchedulerListenersLock = B_SPINLOCK_INITIALIZER;
|
spinlock gSchedulerListenersLock = B_SPINLOCK_INITIALIZER;
|
||||||
|
|
||||||
static rw_spinlock sSchedulerModeLock = B_RW_SPINLOCK_INITIALIZER;
|
|
||||||
static struct scheduler_mode_operations* sCurrentMode;
|
static struct scheduler_mode_operations* sCurrentMode;
|
||||||
static struct scheduler_mode_operations* sSchedulerModes[] = {
|
static struct scheduler_mode_operations* sSchedulerModes[] = {
|
||||||
&gSchedulerLowLatencyMode,
|
&gSchedulerLowLatencyMode,
|
||||||
@@ -74,6 +73,29 @@ int32 gRunQueueCount;
|
|||||||
int32* gCPUToCore;
|
int32* gCPUToCore;
|
||||||
int32* gCPUToPackage;
|
int32* gCPUToPackage;
|
||||||
|
|
||||||
|
class SchedulerModeLocker : public ReadSpinLocker {
|
||||||
|
public:
|
||||||
|
inline SchedulerModeLocker(bool alreadyLocked = false,
|
||||||
|
bool lockIfNotLocked = true)
|
||||||
|
:
|
||||||
|
ReadSpinLocker(gCPUEntries[smp_get_current_cpu()].fSchedulerModeLock,
|
||||||
|
alreadyLocked, lockIfNotLocked)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
class InterruptsSchedulerModeLocker : public InterruptsReadSpinLocker {
|
||||||
|
public:
|
||||||
|
inline InterruptsSchedulerModeLocker(bool alreadyLocked = false,
|
||||||
|
bool lockIfNotLocked = true)
|
||||||
|
:
|
||||||
|
InterruptsReadSpinLocker(
|
||||||
|
gCPUEntries[smp_get_current_cpu()].fSchedulerModeLock,
|
||||||
|
alreadyLocked, lockIfNotLocked)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
} // namespace Scheduler
|
} // namespace Scheduler
|
||||||
|
|
||||||
|
|
||||||
@@ -84,6 +106,7 @@ CPUEntry::CPUEntry()
|
|||||||
fMeasureTime(0),
|
fMeasureTime(0),
|
||||||
fLoad(0)
|
fLoad(0)
|
||||||
{
|
{
|
||||||
|
B_INITIALIZE_RW_SPINLOCK(&fSchedulerModeLock);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -784,7 +807,7 @@ enqueue(Thread* thread, bool newOne)
|
|||||||
void
|
void
|
||||||
scheduler_enqueue_in_run_queue(Thread *thread)
|
scheduler_enqueue_in_run_queue(Thread *thread)
|
||||||
{
|
{
|
||||||
InterruptsReadSpinLocker modeLocker(sSchedulerModeLock);
|
InterruptsSchedulerModeLocker _;
|
||||||
|
|
||||||
TRACE("enqueueing new thread %ld with static priority %ld\n", thread->id,
|
TRACE("enqueueing new thread %ld with static priority %ld\n", thread->id,
|
||||||
thread->priority);
|
thread->priority);
|
||||||
@@ -833,7 +856,7 @@ int32
|
|||||||
scheduler_set_thread_priority(Thread *thread, int32 priority)
|
scheduler_set_thread_priority(Thread *thread, int32 priority)
|
||||||
{
|
{
|
||||||
InterruptsSpinLocker _(thread->scheduler_lock);
|
InterruptsSpinLocker _(thread->scheduler_lock);
|
||||||
InterruptsReadSpinLocker modeLocker(sSchedulerModeLock);
|
SchedulerModeLocker modeLocker;
|
||||||
|
|
||||||
int32 oldPriority = thread->priority;
|
int32 oldPriority = thread->priority;
|
||||||
|
|
||||||
@@ -1127,7 +1150,9 @@ update_cpu_performance(Thread* thread, int32 thisCore)
|
|||||||
static void
|
static void
|
||||||
_scheduler_reschedule(void)
|
_scheduler_reschedule(void)
|
||||||
{
|
{
|
||||||
InterruptsReadSpinLocker modeLocker(sSchedulerModeLock);
|
ASSERT(!are_interrupts_enabled());
|
||||||
|
|
||||||
|
SchedulerModeLocker modeLocker;
|
||||||
|
|
||||||
Thread* oldThread = thread_get_current_thread();
|
Thread* oldThread = thread_get_current_thread();
|
||||||
|
|
||||||
@@ -1324,10 +1349,16 @@ scheduler_set_operation_mode(scheduler_mode mode)
|
|||||||
|
|
||||||
dprintf("scheduler: switching to %s mode\n", sSchedulerModes[mode]->name);
|
dprintf("scheduler: switching to %s mode\n", sSchedulerModes[mode]->name);
|
||||||
|
|
||||||
InterruptsWriteSpinLocker _(sSchedulerModeLock);
|
InterruptsLocker _;
|
||||||
|
for (int32_t i = 0; i < smp_get_num_cpus(); i++)
|
||||||
|
acquire_write_spinlock(&gCPUEntries[i].fSchedulerModeLock);
|
||||||
|
|
||||||
sCurrentMode = sSchedulerModes[mode];
|
sCurrentMode = sSchedulerModes[mode];
|
||||||
sCurrentMode->switch_to_mode();
|
sCurrentMode->switch_to_mode();
|
||||||
|
|
||||||
|
for (int32_t i = 0; i < smp_get_num_cpus(); i++)
|
||||||
|
release_write_spinlock(&gCPUEntries[i].fSchedulerModeLock);
|
||||||
|
|
||||||
return B_OK;
|
return B_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -65,6 +65,8 @@ struct CPUEntry : public MinMaxHeapLinkImpl<CPUEntry, int32> {
|
|||||||
bigtime_t fMeasureTime;
|
bigtime_t fMeasureTime;
|
||||||
|
|
||||||
int32 fLoad;
|
int32 fLoad;
|
||||||
|
|
||||||
|
rw_spinlock fSchedulerModeLock;
|
||||||
} CACHE_LINE_ALIGN;
|
} CACHE_LINE_ALIGN;
|
||||||
typedef MinMaxHeap<CPUEntry, int32> CPUHeap CACHE_LINE_ALIGN;
|
typedef MinMaxHeap<CPUEntry, int32> CPUHeap CACHE_LINE_ALIGN;
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user