[haiku-commits] BRANCH pdziepak-github.scheduler [7b55bf5] src/system/kernel/scheduler

  • From: pdziepak-github.scheduler <community@xxxxxxxxxxxx>
  • To: haiku-commits@xxxxxxxxxxxxx
  • Date: Mon, 6 Jan 2014 06:00:32 +0100 (CET)

added 2 changesets to branch 'refs/remotes/pdziepak-github/scheduler'
old head: 667617ad043a4587d8d366d5192d9ad291cfa37a
new head: 7b55bf560cdf757d66223228bb13796a4e788c71
overview: https://github.com/pdziepak/Haiku/compare/667617a...7b55bf5

----------------------------------------------------------------------------

06ac482: scheduler: Work around GCC2 limitations in function inlining
  
  GCC2 won't inline a function if it is used before its definition.

7b55bf5: scheduler: Improve thread creation performance

                                    [ Pawel Dziepak <pdziepak@xxxxxxxxxxx> ]

----------------------------------------------------------------------------

7 files changed, 386 insertions(+), 342 deletions(-)
headers/private/kernel/smp.h                     |   9 +-
src/system/kernel/scheduler/scheduler.cpp        |  92 +----------
src/system/kernel/scheduler/scheduler_cpu.cpp    |  98 +++--------
src/system/kernel/scheduler/scheduler_cpu.h      | 117 +++++++------
src/system/kernel/scheduler/scheduler_locking.h  | 158 ++++++++++++++++++
src/system/kernel/scheduler/scheduler_thread.cpp | 165 ++++++++++---------
src/system/kernel/scheduler/scheduler_thread.h   |  89 +++++-----

############################################################################

Commit:      06ac482d9692c07e95af8516800001622e62e32a
Author:      Pawel Dziepak <pdziepak@xxxxxxxxxxx>
Date:        Sun Jan  5 04:55:13 2014 UTC

scheduler: Work around GCC2 limitations in function inlining

GCC2 won't inline a function if it is used before its definition.

----------------------------------------------------------------------------

diff --git a/headers/private/kernel/smp.h b/headers/private/kernel/smp.h
index 88a89e4..3378f23 100644
--- a/headers/private/kernel/smp.h
+++ b/headers/private/kernel/smp.h
@@ -41,7 +41,7 @@ typedef void (*smp_call_func)(addr_t data1, int32 currentCPU, 
addr_t data2, addr
 
 class CPUSet {
 public:
-                                               CPUSet() { ClearAll(); }
+       inline                          CPUSet();
 
        inline  void            ClearAll();
        inline  void            SetAll();
@@ -92,6 +92,13 @@ int smp_intercpu_int_handler(int32 cpu);
 #endif
 
 
+inline
+CPUSet::CPUSet()
+{
+       memset(fBitmap, 0, sizeof(fBitmap));
+}
+
+
 inline void
 CPUSet::ClearAll()
 {
diff --git a/src/system/kernel/scheduler/scheduler.cpp 
b/src/system/kernel/scheduler/scheduler.cpp
index de6a49f..2916b5b 100644
--- a/src/system/kernel/scheduler/scheduler.cpp
+++ b/src/system/kernel/scheduler/scheduler.cpp
@@ -31,6 +31,7 @@
 
 #include "scheduler_common.h"
 #include "scheduler_cpu.h"
+#include "scheduler_locking.h"
 #include "scheduler_modes.h"
 #include "scheduler_profiler.h"
 #include "scheduler_thread.h"
@@ -40,93 +41,6 @@
 namespace Scheduler {
 
 
-class SchedulerModeLocking {
-public:
-       bool Lock(int* /* lockable */)
-       {
-               CPUEntry::GetCPU(smp_get_current_cpu())->EnterScheduler();
-               return true;
-       }
-
-       void Unlock(int* /* lockable */)
-       {
-               CPUEntry::GetCPU(smp_get_current_cpu())->ExitScheduler();
-       }
-};
-
-class SchedulerModeLocker :
-       public AutoLocker<int, SchedulerModeLocking> {
-public:
-       SchedulerModeLocker(bool alreadyLocked = false, bool lockIfNotLocked = 
true)
-               :
-               AutoLocker<int, SchedulerModeLocking>(NULL, alreadyLocked,
-                       lockIfNotLocked)
-       {
-       }
-};
-
-class InterruptsSchedulerModeLocking {
-public:
-       bool Lock(int* lockable)
-       {
-               *lockable = disable_interrupts();
-               CPUEntry::GetCPU(smp_get_current_cpu())->EnterScheduler();
-               return true;
-       }
-
-       void Unlock(int* lockable)
-       {
-               CPUEntry::GetCPU(smp_get_current_cpu())->ExitScheduler();
-               restore_interrupts(*lockable);
-       }
-};
-
-class InterruptsSchedulerModeLocker :
-       public AutoLocker<int, InterruptsSchedulerModeLocking> {
-public:
-       InterruptsSchedulerModeLocker(bool alreadyLocked = false,
-               bool lockIfNotLocked = true)
-               :
-               AutoLocker<int, InterruptsSchedulerModeLocking>(&fState, 
alreadyLocked,
-                       lockIfNotLocked)
-       {
-       }
-
-private:
-       int             fState;
-};
-
-class InterruptsBigSchedulerLocking {
-public:
-       bool Lock(int* lockable)
-       {
-               *lockable = disable_interrupts();
-               for (int32 i = 0; i < smp_get_num_cpus(); i++)
-                       CPUEntry::GetCPU(i)->LockScheduler();
-               return true;
-       }
-
-       void Unlock(int* lockable)
-       {
-               for (int32 i = 0; i < smp_get_num_cpus(); i++)
-                       CPUEntry::GetCPU(i)->UnlockScheduler();
-               restore_interrupts(*lockable);
-       }
-};
-
-class InterruptsBigSchedulerLocker :
-       public AutoLocker<int, InterruptsBigSchedulerLocking> {
-public:
-       InterruptsBigSchedulerLocker()
-               :
-               AutoLocker<int, InterruptsBigSchedulerLocking>(&fState, false, 
true)
-       {
-       }
-
-private:
-       int             fState;
-};
-
 class ThreadEnqueuer : public ThreadProcessing {
 public:
        void            operator()(ThreadData* thread);
@@ -624,6 +538,8 @@ scheduler_on_thread_create(Thread* thread, bool idleThread)
 void
 scheduler_on_thread_init(Thread* thread)
 {
+       ASSERT(thread->scheduler_data != NULL);
+
        if (thread_is_idle_thread(thread)) {
                static int32 sIdleThreadsID;
                int32 cpuID = atomic_add(&sIdleThreadsID, 1);
diff --git a/src/system/kernel/scheduler/scheduler_cpu.cpp 
b/src/system/kernel/scheduler/scheduler_cpu.cpp
index a88c041..7ec4ab5 100644
--- a/src/system/kernel/scheduler/scheduler_cpu.cpp
+++ b/src/system/kernel/scheduler/scheduler_cpu.cpp
@@ -392,14 +392,6 @@ CoreEntry::Remove(ThreadData* thread)
 }
 
 
-inline ThreadData*
-CoreEntry::PeekThread() const
-{
-       SCHEDULER_ENTER_FUNCTION();
-       return fRunQueue.PeekMaximum();
-}
-
-
 void
 CoreEntry::UpdateLoad(int32 delta)
 {
@@ -454,26 +446,6 @@ CoreEntry::UpdateLoad(int32 delta)
 }
 
 
-inline void
-CoreEntry::CPUGoesIdle(CPUEntry* /* cpu */)
-{
-       ASSERT(fCPUIdleCount < fCPUCount);
-
-       if (++fCPUIdleCount == fCPUCount)
-               fPackage->CoreGoesIdle(this);
-}
-
-
-inline void
-CoreEntry::CPUWakesUp(CPUEntry* /* cpu */)
-{
-       ASSERT(fCPUIdleCount > 0);
-
-       if (fCPUIdleCount-- == fCPUCount)
-               fPackage->CoreWakesUp(this);
-}
-
-
 void
 CoreEntry::AddCPU(CPUEntry* cpu)
 {
@@ -599,48 +571,6 @@ PackageEntry::Init(int32 id)
 }
 
 
-inline void
-PackageEntry::CoreGoesIdle(CoreEntry* core)
-{
-       SCHEDULER_ENTER_FUNCTION();
-
-       WriteSpinLocker _(fCoreLock);
-
-       ASSERT(fIdleCoreCount >= 0);
-       ASSERT(fIdleCoreCount < fCoreCount);
-
-       fIdleCoreCount++;
-       fIdleCores.Add(core);
-
-       if (fIdleCoreCount == fCoreCount) {
-               // package goes idle
-               WriteSpinLocker _(gIdlePackageLock);
-               gIdlePackageList.Add(this);
-       }
-}
-
-
-inline void
-PackageEntry::CoreWakesUp(CoreEntry* core)
-{
-       SCHEDULER_ENTER_FUNCTION();
-
-       WriteSpinLocker _(fCoreLock);
-
-       ASSERT(fIdleCoreCount > 0);
-       ASSERT(fIdleCoreCount <= fCoreCount);
-
-       fIdleCoreCount--;
-       fIdleCores.Remove(core);
-
-       if (fIdleCoreCount + 1 == fCoreCount) {
-               // package wakes up
-               WriteSpinLocker _(gIdlePackageLock);
-               gIdlePackageList.Remove(this);
-       }
-}
-
-
 void
 PackageEntry::AddIdleCore(CoreEntry* core)
 {
diff --git a/src/system/kernel/scheduler/scheduler_cpu.h 
b/src/system/kernel/scheduler/scheduler_cpu.h
index c76ccf1..b62ee5f 100644
--- a/src/system/kernel/scheduler/scheduler_cpu.h
+++ b/src/system/kernel/scheduler/scheduler_cpu.h
@@ -85,7 +85,7 @@ public:
        static inline           CPUEntry*               GetCPU(int32 cpu);
 
 private:
-       inline                          void                    
_RequestPerformanceLevel(
+                                               void                    
_RequestPerformanceLevel(
                                                                                
        ThreadData* threadData);
 
                                                int32                   
fCPUNumber;
@@ -112,21 +112,6 @@ public:
                                                void                    Dump();
 };
 
-class CPURunQueueLocking {
-public:
-       inline bool Lock(CPUEntry* cpu)
-       {
-               cpu->LockRunQueue();
-               return true;
-       }
-
-       inline void Unlock(CPUEntry* cpu)
-       {
-               cpu->UnlockRunQueue();
-       }
-};
-
-typedef AutoLocker<CPUEntry, CPURunQueueLocking> CPURunQueueLocker;
 
 class CoreEntry : public MinMaxHeapLinkImpl<CoreEntry, int32>,
        public DoublyLinkedListLinkImpl<CoreEntry> {
@@ -205,37 +190,6 @@ private:
                                                friend class DebugDumper;
 } CACHE_LINE_ALIGN;
 
-class CoreRunQueueLocking {
-public:
-       inline bool Lock(CoreEntry* core)
-       {
-               core->LockRunQueue();
-               return true;
-       }
-
-       inline void Unlock(CoreEntry* core)
-       {
-               core->UnlockRunQueue();
-       }
-};
-
-typedef AutoLocker<CoreEntry, CoreRunQueueLocking> CoreRunQueueLocker;
-
-class CoreCPUHeapLocking {
-public:
-       inline bool Lock(CoreEntry* core)
-       {
-               core->LockCPUHeap();
-               return true;
-       }
-
-       inline void Unlock(CoreEntry* core)
-       {
-               core->UnlockCPUHeap();
-       }
-};
-
-typedef AutoLocker<CoreEntry, CoreCPUHeapLocking> CoreCPUHeapLocker;
 
 class CoreLoadHeap : public MinMaxHeap<CoreEntry, int32> {
 public:
@@ -402,6 +356,14 @@ CoreEntry::IncreaseActiveTime(bigtime_t activeTime)
 }
 
 
+inline ThreadData*
+CoreEntry::PeekThread() const
+{
+       SCHEDULER_ENTER_FUNCTION();
+       return fRunQueue.PeekMaximum();
+}
+
+
 inline bigtime_t
 CoreEntry::GetActiveTime() const
 {
@@ -435,6 +397,73 @@ CoreEntry::StarvationCounter() const
 }
 
 
+/* PackageEntry::CoreGoesIdle and PackageEntry::CoreWakesUp have to be defined
+   before CoreEntry::CPUGoesIdle and CoreEntry::CPUWakesUp. If they weren't
+   GCC2 wouldn't inline them as, apparently, it doesn't do enough optimization
+   passes.
+*/
+inline void
+PackageEntry::CoreGoesIdle(CoreEntry* core)
+{
+       SCHEDULER_ENTER_FUNCTION();
+
+       WriteSpinLocker _(fCoreLock);
+
+       ASSERT(fIdleCoreCount >= 0);
+       ASSERT(fIdleCoreCount < fCoreCount);
+
+       fIdleCoreCount++;
+       fIdleCores.Add(core);
+
+       if (fIdleCoreCount == fCoreCount) {
+               // package goes idle
+               WriteSpinLocker _(gIdlePackageLock);
+               gIdlePackageList.Add(this);
+       }
+}
+
+
+inline void
+PackageEntry::CoreWakesUp(CoreEntry* core)
+{
+       SCHEDULER_ENTER_FUNCTION();
+
+       WriteSpinLocker _(fCoreLock);
+
+       ASSERT(fIdleCoreCount > 0);
+       ASSERT(fIdleCoreCount <= fCoreCount);
+
+       fIdleCoreCount--;
+       fIdleCores.Remove(core);
+
+       if (fIdleCoreCount + 1 == fCoreCount) {
+               // package wakes up
+               WriteSpinLocker _(gIdlePackageLock);
+               gIdlePackageList.Remove(this);
+       }
+}
+
+
+inline void
+CoreEntry::CPUGoesIdle(CPUEntry* /* cpu */)
+{
+       ASSERT(fCPUIdleCount < fCPUCount);
+
+       if (++fCPUIdleCount == fCPUCount)
+               fPackage->CoreGoesIdle(this);
+}
+
+
+inline void
+CoreEntry::CPUWakesUp(CPUEntry* /* cpu */)
+{
+       ASSERT(fCPUIdleCount > 0);
+
+       if (fCPUIdleCount-- == fCPUCount)
+               fPackage->CoreWakesUp(this);
+}
+
+
 /* static */ inline CoreEntry*
 CoreEntry::GetCore(int32 cpu)
 {
diff --git a/src/system/kernel/scheduler/scheduler_locking.h 
b/src/system/kernel/scheduler/scheduler_locking.h
new file mode 100644
index 0000000..044015c
--- /dev/null
+++ b/src/system/kernel/scheduler/scheduler_locking.h
@@ -0,0 +1,158 @@
+/*
+ * Copyright 2014, Paweł Dziepak, pdziepak@xxxxxxxxxxx.
+ * Distributed under the terms of the MIT License.
+ */
+#ifndef KERNEL_SCHEDULER_LOCKING_H
+#define KERNEL_SCHEDULER_LOCKING_H
+
+
+#include <util/AutoLock.h>
+
+#include "scheduler_cpu.h"
+
+
+namespace Scheduler {
+
+
+class CPURunQueueLocking {
+public:
+       inline bool Lock(CPUEntry* cpu)
+       {
+               cpu->LockRunQueue();
+               return true;
+       }
+
+       inline void Unlock(CPUEntry* cpu)
+       {
+               cpu->UnlockRunQueue();
+       }
+};
+
+typedef AutoLocker<CPUEntry, CPURunQueueLocking> CPURunQueueLocker;
+
+
+class CoreRunQueueLocking {
+public:
+       inline bool Lock(CoreEntry* core)
+       {
+               core->LockRunQueue();
+               return true;
+       }
+
+       inline void Unlock(CoreEntry* core)
+       {
+               core->UnlockRunQueue();
+       }
+};
+
+typedef AutoLocker<CoreEntry, CoreRunQueueLocking> CoreRunQueueLocker;
+
+class CoreCPUHeapLocking {
+public:
+       inline bool Lock(CoreEntry* core)
+       {
+               core->LockCPUHeap();
+               return true;
+       }
+
+       inline void Unlock(CoreEntry* core)
+       {
+               core->UnlockCPUHeap();
+       }
+};
+
+typedef AutoLocker<CoreEntry, CoreCPUHeapLocking> CoreCPUHeapLocker;
+
+class SchedulerModeLocking {
+public:
+       bool Lock(int* /* lockable */)
+       {
+               CPUEntry::GetCPU(smp_get_current_cpu())->EnterScheduler();
+               return true;
+       }
+
+       void Unlock(int* /* lockable */)
+       {
+               CPUEntry::GetCPU(smp_get_current_cpu())->ExitScheduler();
+       }
+};
+
+class SchedulerModeLocker :
+       public AutoLocker<int, SchedulerModeLocking> {
+public:
+       SchedulerModeLocker(bool alreadyLocked = false, bool lockIfNotLocked = 
true)
+               :
+               AutoLocker<int, SchedulerModeLocking>(NULL, alreadyLocked,
+                       lockIfNotLocked)
+       {
+       }
+};
+
+class InterruptsSchedulerModeLocking {
+public:
+       bool Lock(int* lockable)
+       {
+               *lockable = disable_interrupts();
+               CPUEntry::GetCPU(smp_get_current_cpu())->EnterScheduler();
+               return true;
+       }
+
+       void Unlock(int* lockable)
+       {
+               CPUEntry::GetCPU(smp_get_current_cpu())->ExitScheduler();
+               restore_interrupts(*lockable);
+       }
+};
+
+class InterruptsSchedulerModeLocker :
+       public AutoLocker<int, InterruptsSchedulerModeLocking> {
+public:
+       InterruptsSchedulerModeLocker(bool alreadyLocked = false,
+               bool lockIfNotLocked = true)
+               :
+               AutoLocker<int, InterruptsSchedulerModeLocking>(&fState, 
alreadyLocked,
+                       lockIfNotLocked)
+       {
+       }
+
+private:
+       int             fState;
+};
+
+class InterruptsBigSchedulerLocking {
+public:
+       bool Lock(int* lockable)
+       {
+               *lockable = disable_interrupts();
+               for (int32 i = 0; i < smp_get_num_cpus(); i++)
+                       CPUEntry::GetCPU(i)->LockScheduler();
+               return true;
+       }
+
+       void Unlock(int* lockable)
+       {
+               for (int32 i = 0; i < smp_get_num_cpus(); i++)
+                       CPUEntry::GetCPU(i)->UnlockScheduler();
+               restore_interrupts(*lockable);
+       }
+};
+
+class InterruptsBigSchedulerLocker :
+       public AutoLocker<int, InterruptsBigSchedulerLocking> {
+public:
+       InterruptsBigSchedulerLocker()
+               :
+               AutoLocker<int, InterruptsBigSchedulerLocking>(&fState, false, 
true)
+       {
+       }
+
+private:
+       int             fState;
+};
+
+
+}      // namespace Scheduler
+
+
+#endif // KERNEL_SCHEDULER_LOCKING_H
+
diff --git a/src/system/kernel/scheduler/scheduler_thread.cpp 
b/src/system/kernel/scheduler/scheduler_thread.cpp
index ec84ee4..aef21a5 100644
--- a/src/system/kernel/scheduler/scheduler_thread.cpp
+++ b/src/system/kernel/scheduler/scheduler_thread.cpp
@@ -12,6 +12,58 @@ using namespace Scheduler;
 static bigtime_t sQuantumLengths[THREAD_MAX_SET_PRIORITY + 1];
 
 
+inline CoreEntry*
+ThreadData::_ChooseCore() const
+{
+       SCHEDULER_ENTER_FUNCTION();
+
+       ASSERT(!gSingleCore);
+       return gCurrentMode->choose_core(this);
+}
+
+
+inline CPUEntry*
+ThreadData::_ChooseCPU(CoreEntry* core, bool& rescheduleNeeded) const
+{
+       SCHEDULER_ENTER_FUNCTION();
+
+       int32 threadPriority = GetEffectivePriority();
+
+       if (fThread->previous_cpu != NULL) {
+               CPUEntry* previousCPU = 
&gCPUEntries[fThread->previous_cpu->cpu_num];
+               if (previousCPU->Core() == core && 
!fThread->previous_cpu->disabled) {
+                       CoreCPUHeapLocker _(core);
+                       if (CPUPriorityHeap::GetKey(previousCPU) < 
threadPriority) {
+                               previousCPU->UpdatePriority(threadPriority);
+                               rescheduleNeeded = true;
+                               return previousCPU;
+                       }
+               }
+       }
+
+       CoreCPUHeapLocker _(core);
+       CPUEntry* cpu = core->CPUHeap()->PeekRoot();
+       ASSERT(cpu != NULL);
+
+       if (CPUPriorityHeap::GetKey(cpu) < threadPriority) {
+               cpu->UpdatePriority(threadPriority);
+               rescheduleNeeded = true;
+       } else
+               rescheduleNeeded = false;
+
+       return cpu;
+}
+
+
+inline bigtime_t
+ThreadData::_GetBaseQuantum() const
+{
+       SCHEDULER_ENTER_FUNCTION();
+
+       return sQuantumLengths[GetEffectivePriority()];
+}
+
+
 ThreadData::ThreadData(Thread* thread)
        :
        fThread(thread)
@@ -190,6 +242,21 @@ ThreadData::ComputeQuantumLengths()
 }
 
 
+inline int32
+ThreadData::_GetPenalty() const
+{
+       SCHEDULER_ENTER_FUNCTION();
+
+       int32 penalty = fPriorityPenalty;
+
+       const int kMinimalPriority = _GetMinimalPriority();
+       if (kMinimalPriority > 0)
+               penalty += fAdditionalPenalty % kMinimalPriority;
+
+       return penalty;
+}
+
+
 void
 ThreadData::_ComputeEffectivePriority() const
 {
@@ -209,58 +276,6 @@ ThreadData::_ComputeEffectivePriority() const
 }
 
 
-inline CoreEntry*
-ThreadData::_ChooseCore() const
-{
-       SCHEDULER_ENTER_FUNCTION();
-
-       ASSERT(!gSingleCore);
-       return gCurrentMode->choose_core(this);
-}
-
-
-inline CPUEntry*
-ThreadData::_ChooseCPU(CoreEntry* core, bool& rescheduleNeeded) const
-{
-       SCHEDULER_ENTER_FUNCTION();
-
-       int32 threadPriority = GetEffectivePriority();
-
-       if (fThread->previous_cpu != NULL) {
-               CPUEntry* previousCPU = 
&gCPUEntries[fThread->previous_cpu->cpu_num];
-               if (previousCPU->Core() == core && 
!fThread->previous_cpu->disabled) {
-                       CoreCPUHeapLocker _(core);
-                       if (CPUPriorityHeap::GetKey(previousCPU) < 
threadPriority) {
-                               previousCPU->UpdatePriority(threadPriority);
-                               rescheduleNeeded = true;
-                               return previousCPU;
-                       }
-               }
-       }
-
-       CoreCPUHeapLocker _(core);
-       CPUEntry* cpu = core->CPUHeap()->PeekRoot();
-       ASSERT(cpu != NULL);
-
-       if (CPUPriorityHeap::GetKey(cpu) < threadPriority) {
-               cpu->UpdatePriority(threadPriority);
-               rescheduleNeeded = true;
-       } else
-               rescheduleNeeded = false;
-
-       return cpu;
-}
-
-
-inline bigtime_t
-ThreadData::_GetBaseQuantum() const
-{
-       SCHEDULER_ENTER_FUNCTION();
-
-       return sQuantumLengths[GetEffectivePriority()];
-}
-
-
 /* static */ bigtime_t
 ThreadData::_ScaleQuantum(bigtime_t maxQuantum, bigtime_t minQuantum,
        int32 maxPriority, int32 minPriority, int32 priority)
diff --git a/src/system/kernel/scheduler/scheduler_thread.h 
b/src/system/kernel/scheduler/scheduler_thread.h
index debcf2d..de932dd 100644
--- a/src/system/kernel/scheduler/scheduler_thread.h
+++ b/src/system/kernel/scheduler/scheduler_thread.h
@@ -11,6 +11,7 @@
 
 #include "scheduler_common.h"
 #include "scheduler_cpu.h"
+#include "scheduler_locking.h"
 #include "scheduler_profiler.h"
 
 
@@ -19,6 +20,17 @@ namespace Scheduler {
 
 struct ThreadData : public DoublyLinkedListLinkImpl<ThreadData>,
        RunQueueLinkImpl<ThreadData> {
+private:
+       inline  void            _InitBase();
+
+       inline  int32           _GetMinimalPriority() const;
+
+       inline  CoreEntry*      _ChooseCore() const;
+       inline  CPUEntry*       _ChooseCPU(CoreEntry* core,
+                                                       bool& rescheduleNeeded) 
const;
+
+       inline  bigtime_t       _GetBaseQuantum() const;
+
 public:
                                                ThreadData(Thread* thread);
 
@@ -72,17 +84,12 @@ public:
        inline  void            UnassignCore() { fCore = NULL; }
 
        static  void            ComputeQuantumLengths();
+
 private:
        inline  int32           _GetPenalty() const;
-       inline  int32           _GetMinimalPriority() const;
 
                        void            _ComputeEffectivePriority() const;
 
-       inline  CoreEntry*      _ChooseCore() const;
-       inline  CPUEntry*       _ChooseCPU(CoreEntry* core,
-                                                       bool& rescheduleNeeded) 
const;
-
-       inline  bigtime_t       _GetBaseQuantum() const;
        static  bigtime_t       _ScaleQuantum(bigtime_t maxQuantum,
                                                        bigtime_t minQuantum, 
int32 maxPriority,
                                                        int32 minPriority, 
int32 priority);
@@ -121,6 +128,21 @@ public:
 };
 
 
+inline int32
+ThreadData::_GetMinimalPriority() const
+{
+       SCHEDULER_ENTER_FUNCTION();
+
+       const int32 kDivisor = 5;
+
+       const int32 kMaximalPriority = 25;
+       const int32 kMinimalPriority = B_LOWEST_ACTIVE_PRIORITY;
+
+       int32 priority = fThread->priority / kDivisor;
+       return std::max(std::min(priority, kMaximalPriority), kMinimalPriority);
+}
+
+
 inline bool
 ThreadData::HasCacheExpired() const
 {
@@ -259,6 +281,7 @@ ThreadData::Enqueue()
        SCHEDULER_ENTER_FUNCTION();
 
        fThread->state = B_THREAD_READY;
+
        ComputeLoad();
        fWentSleepCount = 0;
 
@@ -350,36 +373,6 @@ ThreadData::StartQuantum()
 }
 
 
-inline int32
-ThreadData::_GetPenalty() const
-{
-       SCHEDULER_ENTER_FUNCTION();
-
-       int32 penalty = fPriorityPenalty;
-
-       const int kMinimalPriority = _GetMinimalPriority();
-       if (kMinimalPriority > 0)
-               penalty += fAdditionalPenalty % kMinimalPriority;
-
-       return penalty;
-}
-
-
-inline int32
-ThreadData::_GetMinimalPriority() const
-{
-       SCHEDULER_ENTER_FUNCTION();
-
-       const int32 kDivisor = 5;
-
-       const int32 kMaximalPriority = 25;
-       const int32 kMinimalPriority = B_LOWEST_ACTIVE_PRIORITY;
-
-       int32 priority = fThread->priority / kDivisor;
-       return std::max(std::min(priority, kMaximalPriority), kMinimalPriority);
-}
-
-
 }      // namespace Scheduler
 
 

############################################################################

Commit:      7b55bf560cdf757d66223228bb13796a4e788c71
Author:      Pawel Dziepak <pdziepak@xxxxxxxxxxx>
Date:        Mon Jan  6 00:18:37 2014 UTC

scheduler: Improve thread creation performance

----------------------------------------------------------------------------

diff --git a/src/system/kernel/scheduler/scheduler.cpp 
b/src/system/kernel/scheduler/scheduler.cpp
index 2916b5b..646c756 100644
--- a/src/system/kernel/scheduler/scheduler.cpp
+++ b/src/system/kernel/scheduler/scheduler.cpp
@@ -383,7 +383,7 @@ reschedule(int32 nextState)
 
        int32 thisCPU = smp_get_current_cpu();
 
-       CPUEntry* cpu = &gCPUEntries[thisCPU];
+       CPUEntry* cpu = CPUEntry::GetCPU(thisCPU);
        CoreEntry* core = CoreEntry::GetCore(thisCPU);
 
        TRACE("reschedule(): cpu %ld, current thread = %ld\n", thisCPU,
diff --git a/src/system/kernel/scheduler/scheduler_cpu.cpp 
b/src/system/kernel/scheduler/scheduler_cpu.cpp
index 7ec4ab5..771f1d7 100644
--- a/src/system/kernel/scheduler/scheduler_cpu.cpp
+++ b/src/system/kernel/scheduler/scheduler_cpu.cpp
@@ -124,6 +124,14 @@ CPUEntry::Remove(ThreadData* thread)
 
 
 inline ThreadData*
+CoreEntry::PeekThread() const
+{
+       SCHEDULER_ENTER_FUNCTION();
+       return fRunQueue.PeekMaximum();
+}
+
+
+inline ThreadData*
 CPUEntry::PeekThread() const
 {
        SCHEDULER_ENTER_FUNCTION();
@@ -152,6 +160,9 @@ CPUEntry::UpdatePriority(int32 priority)
                return;
        fCore->CPUHeap()->ModifyKey(this, priority);
 
+       if (gSingleCore)
+               return;
+
        if (oldPriority == B_IDLE_PRIORITY)
                fCore->CPUWakesUp(this);
        else if (priority == B_IDLE_PRIORITY)
@@ -164,6 +175,7 @@ CPUEntry::ComputeLoad()
 {
        SCHEDULER_ENTER_FUNCTION();
 
+       ASSERT(gTrackLoad);
        ASSERT(fCPUNumber == smp_get_current_cpu());
 
        int oldLoad = compute_load(fMeasureTime, fMeasureActiveTime, fLoad);
@@ -244,10 +256,12 @@ CPUEntry::TrackActivity(ThreadData* oldThreadData, 
ThreadData* nextThreadData)
                oldThreadData->UpdateActivity(active);
        }
 
-       oldThreadData->ComputeLoad();
-       nextThreadData->ComputeLoad();
-       if (gTrackLoad && !cpuEntry->disabled)
-               ComputeLoad();
+       if (gTrackLoad) {
+               oldThreadData->ComputeLoad();
+               nextThreadData->ComputeLoad();
+               if (!cpuEntry->disabled)
+                       ComputeLoad();
+       }
 
        Thread* nextThread = nextThreadData->GetThread();
        if (!thread_is_idle_thread(nextThread)) {
@@ -256,19 +270,17 @@ CPUEntry::TrackActivity(ThreadData* oldThreadData, 
ThreadData* nextThreadData)
 
                nextThreadData->SetLastInterruptTime(cpuEntry->interrupt_time);
 
+               if (gCPUFrequencyManagement)
                _RequestPerformanceLevel(nextThreadData);
        }
 }
 
 
-inline void
+void
 CPUEntry::_RequestPerformanceLevel(ThreadData* threadData)
 {
        SCHEDULER_ENTER_FUNCTION();
 
-       if (!gCPUFrequencyManagement)
-               return;
-
        if (gCPU[fCPUNumber].disabled) {
                decrease_cpu_performance(kCPUPerformanceScaleMax);
                return;
diff --git a/src/system/kernel/scheduler/scheduler_cpu.h 
b/src/system/kernel/scheduler/scheduler_cpu.h
index b62ee5f..1def98d 100644
--- a/src/system/kernel/scheduler/scheduler_cpu.h
+++ b/src/system/kernel/scheduler/scheduler_cpu.h
@@ -112,7 +112,6 @@ public:
                                                void                    Dump();
 };
 
-
 class CoreEntry : public MinMaxHeapLinkImpl<CoreEntry, int32>,
        public DoublyLinkedListLinkImpl<CoreEntry> {
 public:
@@ -190,7 +189,6 @@ private:
                                                friend class DebugDumper;
 } CACHE_LINE_ALIGN;
 
-
 class CoreLoadHeap : public MinMaxHeap<CoreEntry, int32> {
 public:
                                                                                
CoreLoadHeap() { }
@@ -356,14 +354,6 @@ CoreEntry::IncreaseActiveTime(bigtime_t activeTime)
 }
 
 
-inline ThreadData*
-CoreEntry::PeekThread() const
-{
-       SCHEDULER_ENTER_FUNCTION();
-       return fRunQueue.PeekMaximum();
-}
-
-
 inline bigtime_t
 CoreEntry::GetActiveTime() const
 {
diff --git a/src/system/kernel/scheduler/scheduler_thread.cpp 
b/src/system/kernel/scheduler/scheduler_thread.cpp
index aef21a5..6f9c818 100644
--- a/src/system/kernel/scheduler/scheduler_thread.cpp
+++ b/src/system/kernel/scheduler/scheduler_thread.cpp
@@ -12,6 +12,28 @@ using namespace Scheduler;
 static bigtime_t sQuantumLengths[THREAD_MAX_SET_PRIORITY + 1];
 
 
+void
+ThreadData::_InitBase()
+{
+       fPriorityPenalty = 0;
+       fAdditionalPenalty = 0;
+       fEffectivePriority = fThread->priority;
+
+       fTimeLeft = 0;
+       fStolenTime = 0;
+
+       fMeasureActiveTime = 0;
+       fMeasureTime = 0;
+       fLoad = 0;
+
+       fWentSleep = 0;
+       fWentSleepActive = 0;
+       fWentSleepCount = -1;
+
+       fEnqueued = false;
+}
+
+
 inline CoreEntry*
 ThreadData::_ChooseCore() const
 {
@@ -30,7 +52,8 @@ ThreadData::_ChooseCPU(CoreEntry* core, bool& 
rescheduleNeeded) const
        int32 threadPriority = GetEffectivePriority();
 
        if (fThread->previous_cpu != NULL) {
-               CPUEntry* previousCPU = 
&gCPUEntries[fThread->previous_cpu->cpu_num];
+               CPUEntry* previousCPU
+                       = CPUEntry::GetCPU(fThread->previous_cpu->cpu_num);
                if (previousCPU->Core() == core && 
!fThread->previous_cpu->disabled) {
                        CoreCPUHeapLocker _(core);
                        if (CPUPriorityHeap::GetKey(previousCPU) < 
threadPriority) {
@@ -74,48 +97,18 @@ ThreadData::ThreadData(Thread* thread)
 void
 ThreadData::Init()
 {
-       fAdditionalPenalty = 0;
-       fEffectivePriority = -1;
-
-       fTimeLeft = 0;
-       fStolenTime = 0;
-
-       fMeasureActiveTime = 0;
-       fMeasureTime = 0;
-       fLoad = 0;
+       _InitBase();
 
-       fWentSleep = 0;
-       fWentSleepActive = 0;
-       fWentSleepCount = -1;
-
-       fEnqueued = false;
-
-       Thread* currentThread = thread_get_current_thread();
-       ASSERT(currentThread != NULL);
-       if (!thread_is_idle_thread(currentThread)) {
-               ThreadData* currentThreadData = currentThread->scheduler_data;
-               int32 penalty = currentThreadData->fPriorityPenalty;
-
-               int32 minimalPriority = _GetMinimalPriority();
-               if (fThread->priority - penalty >= minimalPriority)
-                       fPriorityPenalty = penalty;
-               else
-                       fPriorityPenalty = fThread->priority - minimalPriority;
-
-               fCore = currentThreadData->fCore;
-       } else {
-               fPriorityPenalty = 0;
-               fAdditionalPenalty = 0;
-
-               fCore = NULL;
-       }
+       ThreadData* currentThreadData = 
thread_get_current_thread()->scheduler_data;
+       fCore = currentThreadData->fCore;
 }
 
 
 void
 ThreadData::Init(CoreEntry* core)
 {
-       Init();
+       _InitBase();
+
        fCore = core;
 }
 
@@ -172,8 +165,7 @@ ThreadData::ComputeLoad()
 {
        SCHEDULER_ENTER_FUNCTION();
 
-       if (!gTrackLoad)
-               return;
+       ASSERT(gTrackLoad);
 
        if (fLastInterruptTime > 0) {
                bigtime_t interruptTime = 
gCPU[smp_get_current_cpu()].interrupt_time;
diff --git a/src/system/kernel/scheduler/scheduler_thread.h 
b/src/system/kernel/scheduler/scheduler_thread.h
index de932dd..8d9cbdd 100644
--- a/src/system/kernel/scheduler/scheduler_thread.h
+++ b/src/system/kernel/scheduler/scheduler_thread.h
@@ -165,9 +165,6 @@ inline int32
 ThreadData::GetEffectivePriority() const
 {
        SCHEDULER_ENTER_FUNCTION();
-
-       if (fEffectivePriority == -1)
-               _ComputeEffectivePriority();
        return fEffectivePriority;
 }
 
@@ -184,7 +181,6 @@ ThreadData::IncreasePenalty()
 
        TRACE("increasing thread %ld penalty\n", fThread->id);
 
-       fEffectivePriority = -1;
        int32 oldPenalty = fPriorityPenalty++;
 
        ASSERT(fThread->priority - oldPenalty >= B_LOWEST_ACTIVE_PRIORITY);
@@ -194,6 +190,8 @@ ThreadData::IncreasePenalty()
                fPriorityPenalty = oldPenalty;
                fAdditionalPenalty++;
        }
+
+       _ComputeEffectivePriority();
 }
 
 
@@ -202,13 +200,15 @@ ThreadData::CancelPenalty()
 {
        SCHEDULER_ENTER_FUNCTION();
 
-       if (fPriorityPenalty != 0) {
-               TRACE("cancelling thread %ld penalty\n", fThread->id);
-               fEffectivePriority = -1;
-       }
+       int32 oldPenalty = fPriorityPenalty;
 
        fAdditionalPenalty = 0;
        fPriorityPenalty = 0;
+
+       if (oldPenalty != 0) {
+               TRACE("cancelling thread %ld penalty\n", fThread->id);
+               _ComputeEffectivePriority();
+       }
 }
 
 
@@ -217,7 +217,7 @@ ThreadData::ShouldCancelPenalty() const
 {
        SCHEDULER_ENTER_FUNCTION();
 
-       if (fCore == NULL || fWentSleep == 0)
+       if (fCore == NULL)
                return false;
 
        return fCore->StarvationCounter() != fWentSleepCount
@@ -251,7 +251,8 @@ ThreadData::PutBack()
 {
        SCHEDULER_ENTER_FUNCTION();
 
-       ComputeLoad();
+       if (gTrackLoad)
+               ComputeLoad();
        fWentSleepCount = -1;
 
        int32 priority = GetEffectivePriority();
@@ -282,7 +283,8 @@ ThreadData::Enqueue()
 
        fThread->state = B_THREAD_READY;
 
-       ComputeLoad();
+       if (gTrackLoad)
+               ComputeLoad();
        fWentSleepCount = 0;
 
        int32 priority = GetEffectivePriority();


Other related posts:

  • » [haiku-commits] BRANCH pdziepak-github.scheduler [7b55bf5] src/system/kernel/scheduler - pdziepak-github . scheduler