From ad6b9a1df8ccdb1093c4b122764f8692d6f7ca2c Mon Sep 17 00:00:00 2001 From: Pawel Dziepak Date: Fri, 20 Dec 2013 02:18:44 +0100 Subject: [PATCH] scheduler: Use sequential locks instead of atomic 64 bit access --- headers/os/drivers/KernelExport.h | 6 +++--- src/system/kernel/scheduler/low_latency.cpp | 12 ++++++++++-- src/system/kernel/scheduler/scheduler_cpu.cpp | 1 + src/system/kernel/scheduler/scheduler_cpu.h | 1 + src/system/kernel/scheduler/scheduler_thread.h | 12 ++++++++++-- 5 files changed, 25 insertions(+), 7 deletions(-) diff --git a/headers/os/drivers/KernelExport.h b/headers/os/drivers/KernelExport.h index 4f7e8e2969..ffdbb245ea 100644 --- a/headers/os/drivers/KernelExport.h +++ b/headers/os/drivers/KernelExport.h @@ -59,9 +59,9 @@ typedef struct { } seqlock; #define B_SEQLOCK_INITIALIZER { B_SPINLOCK_INITIALIZER, 0 } -#define B_INITIALIZE_SEQLOCK(seqlock) do { \ - B_INITIALIZE_SPINLOCK((seqlock)->lock); \ - (seqlock)->count = 0; \ +#define B_INITIALIZE_SEQLOCK(seqlock) do { \ + B_INITIALIZE_SPINLOCK(&(seqlock)->lock); \ + (seqlock)->count = 0; \ } while (false) /* interrupt handling support for device drivers */ diff --git a/src/system/kernel/scheduler/low_latency.cpp b/src/system/kernel/scheduler/low_latency.cpp index a272f53214..409699792f 100644 --- a/src/system/kernel/scheduler/low_latency.cpp +++ b/src/system/kernel/scheduler/low_latency.cpp @@ -35,8 +35,16 @@ has_cache_expired(const ThreadData* threadData) { ASSERT(!gSingleCore); - return atomic_get64(&threadData->GetCore()->fActiveTime) - - threadData->fWentSleepActive > kCacheExpire; + CoreEntry* core = threadData->GetCore(); + + bigtime_t activeTime; + uint32 count; + do { + count = acquire_read_seqlock(&core->fActiveTimeLock); + activeTime = core->fActiveTime; + } while (!release_read_seqlock(&core->fActiveTimeLock, count)); + + return activeTime - threadData->fWentSleepActive > kCacheExpire; } diff --git a/src/system/kernel/scheduler/scheduler_cpu.cpp b/src/system/kernel/scheduler/scheduler_cpu.cpp index 57544ae83e..bd812677c2 100644 --- a/src/system/kernel/scheduler/scheduler_cpu.cpp +++ b/src/system/kernel/scheduler/scheduler_cpu.cpp @@ -272,6 +272,7 @@ CoreEntry::CoreEntry() { B_INITIALIZE_SPINLOCK(&fCPULock); B_INITIALIZE_SPINLOCK(&fQueueLock); + B_INITIALIZE_SEQLOCK(&fActiveTimeLock); } diff --git a/src/system/kernel/scheduler/scheduler_cpu.h b/src/system/kernel/scheduler/scheduler_cpu.h index 14c1a80836..b2f5727cff 100644 --- a/src/system/kernel/scheduler/scheduler_cpu.h +++ b/src/system/kernel/scheduler/scheduler_cpu.h @@ -100,6 +100,7 @@ struct CoreEntry : public MinMaxHeapLinkImpl, spinlock fQueueLock; bigtime_t fActiveTime; + seqlock fActiveTimeLock; int32 fLoad; bool fHighLoad; diff --git a/src/system/kernel/scheduler/scheduler_thread.h b/src/system/kernel/scheduler/scheduler_thread.h index ffdae08035..9c98b7e7d0 100644 --- a/src/system/kernel/scheduler/scheduler_thread.h +++ b/src/system/kernel/scheduler/scheduler_thread.h @@ -177,8 +177,13 @@ ThreadData::GoesAway() fLastInterruptTime = 0; fWentSleep = system_time(); - fWentSleepActive = atomic_get64(&fCore->fActiveTime); fWentSleepCount = atomic_get(&fCore->fStarvationCounter); + + uint32 count; + do { + count = acquire_read_seqlock(&fCore->fActiveTimeLock); + fWentSleepActive = fCore->fActiveTime; + } while (!release_read_seqlock(&fCore->fActiveTimeLock, count)); } @@ -262,7 +267,10 @@ ThreadData::UpdateActivity(bigtime_t active) { fMeasureActiveTime += active; gCPUEntries[smp_get_current_cpu()].fMeasureActiveTime += active; - atomic_add64(&fCore->fActiveTime, active); + + WriteSequentialLocker locker(fCore->fActiveTimeLock); + fCore->fActiveTime += active; + locker.Unlock(); }