diff --git a/headers/private/kernel/cpu.h b/headers/private/kernel/cpu.h index 17b056afdb..dad23c6c56 100644 --- a/headers/private/kernel/cpu.h +++ b/headers/private/kernel/cpu.h @@ -56,6 +56,7 @@ typedef struct cpu_ent { timer quantum_timer; // keeping track of CPU activity + seqlock active_time_lock; bigtime_t active_time; bigtime_t irq_time; bigtime_t interrupt_time; diff --git a/src/system/kernel/cpu.cpp b/src/system/kernel/cpu.cpp index a0ffcaf7f4..c984f353d1 100644 --- a/src/system/kernel/cpu.cpp +++ b/src/system/kernel/cpu.cpp @@ -159,7 +159,15 @@ cpu_get_active_time(int32 cpu) if (cpu < 0 || cpu > smp_get_num_cpus()) return 0; - return atomic_get64(&gCPU[cpu].active_time); + bigtime_t activeTime; + uint32 count; + + do { + count = acquire_read_seqlock(&gCPU[cpu].active_time_lock); + activeTime = gCPU[cpu].active_time; + } while (!release_read_seqlock(&gCPU[cpu].active_time_lock, count)); + + return activeTime; } diff --git a/src/system/kernel/scheduler/scheduler_cpu.cpp b/src/system/kernel/scheduler/scheduler_cpu.cpp index 3c8203ac12..57544ae83e 100644 --- a/src/system/kernel/scheduler/scheduler_cpu.cpp +++ b/src/system/kernel/scheduler/scheduler_cpu.cpp @@ -180,7 +180,10 @@ CPUEntry::TrackActivity(ThreadData* oldThreadData, ThreadData* nextThreadData) = (oldThread->kernel_time - cpuEntry->last_kernel_time) + (oldThread->user_time - cpuEntry->last_user_time); - atomic_add64(&cpuEntry->active_time, active); + WriteSequentialLocker locker(cpuEntry->active_time_lock); + cpuEntry->active_time += active; + locker.Unlock(); + oldThreadData->UpdateActivity(active); } diff --git a/src/system/kernel/smp.cpp b/src/system/kernel/smp.cpp index 780912abc8..3631234771 100644 --- a/src/system/kernel/smp.cpp +++ b/src/system/kernel/smp.cpp @@ -701,6 +701,7 @@ acquire_read_seqlock(seqlock* lock) { bool release_read_seqlock(seqlock* lock, uint32 count) { + arch_cpu_memory_read_barrier(); uint32 current = atomic_get((int32*)&lock->count); if (count % 2 == 1 || current != count) {