From e18ee8d681bf05e8c1480dd1ad7133778ead773d Mon Sep 17 00:00:00 2001 From: bunnei Date: Mon, 16 Nov 2020 21:02:45 -0800 Subject: hle: kernel: Port KAffinityMask from Mesosphere. --- src/core/hle/kernel/thread.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'src/core/hle/kernel/thread.h') diff --git a/src/core/hle/kernel/thread.h b/src/core/hle/kernel/thread.h index a75071e9b..5192ecff1 100644 --- a/src/core/hle/kernel/thread.h +++ b/src/core/hle/kernel/thread.h @@ -12,6 +12,7 @@ #include "common/common_types.h" #include "common/spin_lock.h" #include "core/arm/arm_interface.h" +#include "core/hle/kernel/k_affinity_mask.h" #include "core/hle/kernel/object.h" #include "core/hle/kernel/synchronization_object.h" #include "core/hle/result.h" @@ -469,7 +470,7 @@ public: return ideal_core; } - u64 GetAffinityMask() const { + constexpr const KAffinityMask& GetAffinityMask() const { return affinity_mask; } @@ -649,10 +650,9 @@ private: Scheduler* scheduler = nullptr; u32 ideal_core{0xFFFFFFFF}; - u64 affinity_mask{0x1}; + KAffinityMask affinity_mask{}; s32 ideal_core_override = -1; - u64 affinity_mask_override = 0x1; u32 affinity_override_count = 0; u32 scheduling_state = 0; -- cgit v1.2.3 From 9e29e36a784496f7290c03b6a42e400a164a5b1e Mon Sep 17 00:00:00 2001 From: bunnei Date: Wed, 2 Dec 2020 18:08:35 -0800 Subject: hle: kernel: Rewrite scheduler implementation based on Mesopshere. --- src/core/hle/kernel/thread.h | 107 ++++++++++++++++++++++++++++++++----------- 1 file changed, 80 insertions(+), 27 deletions(-) (limited to 'src/core/hle/kernel/thread.h') diff --git a/src/core/hle/kernel/thread.h b/src/core/hle/kernel/thread.h index 5192ecff1..f1aa358a4 100644 --- a/src/core/hle/kernel/thread.h +++ b/src/core/hle/kernel/thread.h @@ -28,10 +28,10 @@ class System; namespace Kernel { -class GlobalScheduler; +class GlobalSchedulerContext; class KernelCore; class Process; -class Scheduler; +class KScheduler; enum ThreadPriority : u32 { THREADPRIO_HIGHEST = 0, ///< Highest thread priority @@ -346,8 +346,11 @@ public: void SetStatus(ThreadStatus new_status); - u64 GetLastRunningTicks() const { - return last_running_ticks; + constexpr s64 GetLastScheduledTick() const { + return this->last_scheduled_tick; + } + constexpr void SetLastScheduledTick(s64 tick) { + this->last_scheduled_tick = tick; } u64 GetTotalCPUTimeTicks() const { @@ -362,10 +365,18 @@ public: return processor_id; } + s32 GetActiveCore() const { + return GetProcessorID(); + } + void SetProcessorID(s32 new_core) { processor_id = new_core; } + void SetActiveCore(s32 new_core) { + processor_id = new_core; + } + Process* GetOwnerProcess() { return owner_process; } @@ -479,21 +490,11 @@ public: /// Sleeps this thread for the given amount of nanoseconds. ResultCode Sleep(s64 nanoseconds); - /// Yields this thread without rebalancing loads. - std::pair YieldSimple(); - - /// Yields this thread and does a load rebalancing. - std::pair YieldAndBalanceLoad(); - - /// Yields this thread and if the core is left idle, loads are rebalanced - std::pair YieldAndWaitForLoadBalancing(); - - void IncrementYieldCount() { - yield_count++; + constexpr s64 GetYieldScheduleCount() const { + return this->schedule_count; } - - u64 GetYieldCount() const { - return yield_count; + constexpr void SetYieldScheduleCount(s64 count) { + this->schedule_count = count; } ThreadSchedStatus GetSchedulingStatus() const { @@ -569,9 +570,62 @@ public: return has_exited; } + struct QueueEntry { + private: + Thread* prev; + Thread* next; + + public: + constexpr QueueEntry() : prev(nullptr), next(nullptr) { /* ... */ + } + + constexpr void Initialize() { + this->prev = nullptr; + this->next = nullptr; + } + + constexpr Thread* GetPrev() const { + return this->prev; + } + constexpr Thread* GetNext() const { + return this->next; + } + constexpr void SetPrev(Thread* t) { + this->prev = t; + } + constexpr void SetNext(Thread* t) { + this->next = t; + } + }; + + constexpr QueueEntry& GetPriorityQueueEntry(s32 core) { + return this->per_core_priority_queue_entry[core]; + } + constexpr const QueueEntry& GetPriorityQueueEntry(s32 core) const { + return this->per_core_priority_queue_entry[core]; + } + + s32 GetDisableDispatchCount() const { + return disable_count; + } + + void DisableDispatch() { + ASSERT(GetDisableDispatchCount() >= 0); + disable_count++; + } + + void EnableDispatch() { + ASSERT(GetDisableDispatchCount() > 0); + disable_count--; + } + + ThreadStatus status = ThreadStatus::Dormant; + u32 scheduling_state = 0; + private: - friend class GlobalScheduler; - friend class Scheduler; + friend class GlobalSchedulerContext; + friend class KScheduler; + friend class Process; void SetSchedulingStatus(ThreadSchedStatus new_status); void AddSchedulingFlag(ThreadSchedFlags flag); @@ -586,10 +640,9 @@ private: u64 thread_id = 0; - ThreadStatus status = ThreadStatus::Dormant; - VAddr entry_point = 0; VAddr stack_top = 0; + std::atomic_int disable_count = 0; ThreadType type; @@ -603,9 +656,8 @@ private: u32 current_priority = 0; u64 total_cpu_time_ticks = 0; ///< Total CPU running ticks. - u64 last_running_ticks = 0; ///< CPU tick when thread was last running - u64 yield_count = 0; ///< Number of redundant yields carried by this thread. - ///< a redundant yield is one where no scheduling is changed + s64 schedule_count{}; + s64 last_scheduled_tick{}; s32 processor_id = 0; @@ -647,7 +699,9 @@ private: Handle hle_time_event; SynchronizationObject* hle_object; - Scheduler* scheduler = nullptr; + KScheduler* scheduler = nullptr; + + QueueEntry per_core_priority_queue_entry[Core::Hardware::NUM_CPU_CORES]{}; u32 ideal_core{0xFFFFFFFF}; KAffinityMask affinity_mask{}; @@ -655,7 +709,6 @@ private: s32 ideal_core_override = -1; u32 affinity_override_count = 0; - u32 scheduling_state = 0; u32 pausing_state = 0; bool is_running = false; bool is_waiting_on_sync = false; -- cgit v1.2.3 From 9b492430bb349b98ac4768ddde044a63976fe146 Mon Sep 17 00:00:00 2001 From: bunnei Date: Sat, 5 Dec 2020 00:17:18 -0800 Subject: hle: kernel: Thread: Various style fixes based on code review feedback. --- src/core/hle/kernel/thread.h | 47 +++++++++++++++++++++++--------------------- 1 file changed, 25 insertions(+), 22 deletions(-) (limited to 'src/core/hle/kernel/thread.h') diff --git a/src/core/hle/kernel/thread.h b/src/core/hle/kernel/thread.h index f1aa358a4..11ef29888 100644 --- a/src/core/hle/kernel/thread.h +++ b/src/core/hle/kernel/thread.h @@ -4,6 +4,7 @@ #pragma once +#include #include #include #include @@ -346,10 +347,11 @@ public: void SetStatus(ThreadStatus new_status); - constexpr s64 GetLastScheduledTick() const { + s64 GetLastScheduledTick() const { return this->last_scheduled_tick; } - constexpr void SetLastScheduledTick(s64 tick) { + + void SetLastScheduledTick(s64 tick) { this->last_scheduled_tick = tick; } @@ -481,7 +483,7 @@ public: return ideal_core; } - constexpr const KAffinityMask& GetAffinityMask() const { + const KAffinityMask& GetAffinityMask() const { return affinity_mask; } @@ -490,10 +492,11 @@ public: /// Sleeps this thread for the given amount of nanoseconds. ResultCode Sleep(s64 nanoseconds); - constexpr s64 GetYieldScheduleCount() const { + s64 GetYieldScheduleCount() const { return this->schedule_count; } - constexpr void SetYieldScheduleCount(s64 count) { + + void SetYieldScheduleCount(s64 count) { this->schedule_count = count; } @@ -570,14 +573,9 @@ public: return has_exited; } - struct QueueEntry { - private: - Thread* prev; - Thread* next; - + class QueueEntry { public: - constexpr QueueEntry() : prev(nullptr), next(nullptr) { /* ... */ - } + constexpr QueueEntry() = default; constexpr void Initialize() { this->prev = nullptr; @@ -590,18 +588,23 @@ public: constexpr Thread* GetNext() const { return this->next; } - constexpr void SetPrev(Thread* t) { - this->prev = t; + constexpr void SetPrev(Thread* thread) { + this->prev = thread; } - constexpr void SetNext(Thread* t) { - this->next = t; + constexpr void SetNext(Thread* thread) { + this->next = thread; } + + private: + Thread* prev{}; + Thread* next{}; }; - constexpr QueueEntry& GetPriorityQueueEntry(s32 core) { + QueueEntry& GetPriorityQueueEntry(s32 core) { return this->per_core_priority_queue_entry[core]; } - constexpr const QueueEntry& GetPriorityQueueEntry(s32 core) const { + + const QueueEntry& GetPriorityQueueEntry(s32 core) const { return this->per_core_priority_queue_entry[core]; } @@ -619,9 +622,6 @@ public: disable_count--; } - ThreadStatus status = ThreadStatus::Dormant; - u32 scheduling_state = 0; - private: friend class GlobalSchedulerContext; friend class KScheduler; @@ -638,6 +638,9 @@ private: ThreadContext64 context_64{}; std::shared_ptr host_context{}; + ThreadStatus status = ThreadStatus::Dormant; + u32 scheduling_state = 0; + u64 thread_id = 0; VAddr entry_point = 0; @@ -701,7 +704,7 @@ private: KScheduler* scheduler = nullptr; - QueueEntry per_core_priority_queue_entry[Core::Hardware::NUM_CPU_CORES]{}; + std::array per_core_priority_queue_entry{}; u32 ideal_core{0xFFFFFFFF}; KAffinityMask affinity_mask{}; -- cgit v1.2.3