diff --git a/src/common/bit_util.h b/src/common/bit_util.h index 70e728a5e..a4f9ed4aa 100644 --- a/src/common/bit_util.h +++ b/src/common/bit_util.h @@ -59,7 +59,6 @@ inline u64 CountLeadingZeroes64(u64 value) { } #endif - #ifdef _MSC_VER inline u32 CountTrailingZeroes32(u32 value) { unsigned long trailing_zero = 0; diff --git a/src/common/multi_level_queue.h b/src/common/multi_level_queue.h index 68b35ffaa..2b61b91e0 100644 --- a/src/common/multi_level_queue.h +++ b/src/common/multi_level_queue.h @@ -7,12 +7,21 @@ #include #include #include +#include #include "common/bit_util.h" #include "common/common_types.h" namespace Common { +/** + * A MultiLevelQueue is a type of priority queue which has the following characteristics: + * - iteratable through each of its elements. + * - back can be obtained. + * - O(1) add, lookup (both front and back) + * - discrete priorities and a max of 64 priorities (limited domain) + * This type of priority queue is normaly used for managing threads within an scheduler + */ template class MultiLevelQueue { public: @@ -37,9 +46,7 @@ public: friend bool operator==(const iterator_impl& lhs, const iterator_impl& rhs) { if (lhs.IsEnd() && rhs.IsEnd()) return true; - if (lhs.current_priority == rhs.current_priority) - return lhs.it == rhs.it; - return false; + return std::tie(lhs.current_priority, lhs.it) == std::tie(rhs.current_priority, rhs.it); } friend bool operator!=(const iterator_impl& lhs, const iterator_impl& rhs) { @@ -301,7 +308,6 @@ private: using const_list_iterator = typename std::list::const_iterator; static void ListShiftForward(std::list& list, const std::size_t shift = 1) { - // NOTE: May want to consider making this an assertion or something if (shift >= list.size()) { return; } diff --git a/src/core/hle/kernel/scheduler.cpp b/src/core/hle/kernel/scheduler.cpp index 58217b732..6d0f13ecf 100644 --- a/src/core/hle/kernel/scheduler.cpp +++ b/src/core/hle/kernel/scheduler.cpp @@ -45,10 +45,10 @@ Thread* Scheduler::PopNextReadyThread() { Thread* next = nullptr; Thread* thread = GetCurrentThread(); - if (thread && thread->GetStatus() == ThreadStatus::Running) { - if (ready_queue.empty()) + if (ready_queue.empty()) { return thread; + } // We have to do better than the current thread. // This call returns null when that's not possible. next = ready_queue.front(); @@ -56,8 +56,9 @@ Thread* Scheduler::PopNextReadyThread() { next = thread; } } else { - if (ready_queue.empty()) + if (ready_queue.empty()) { return nullptr; + } next = ready_queue.front(); } @@ -176,8 +177,9 @@ void Scheduler::UnscheduleThread(Thread* thread, u32 priority) { void Scheduler::SetThreadPriority(Thread* thread, u32 priority) { std::lock_guard lock(scheduler_mutex); - if (thread->GetPriority() == priority) + if (thread->GetPriority() == priority) { return; + } // If thread was ready, adjust queues if (thread->GetStatus() == ThreadStatus::Ready) @@ -188,9 +190,10 @@ Thread* Scheduler::GetNextSuggestedThread(u32 core, u32 maximum_priority) const std::lock_guard lock(scheduler_mutex); const u32 mask = 1U << core; - for (auto& thread : ready_queue) { - if ((thread->GetAffinityMask() & mask) != 0 && thread->GetPriority() < maximum_priority) + for (auto* thread : ready_queue) { + if ((thread->GetAffinityMask() & mask) != 0 && thread->GetPriority() < maximum_priority) { return thread; + } } return nullptr; } diff --git a/src/tests/common/bit_utils.cpp b/src/tests/common/bit_utils.cpp index 77c17c526..479b5995a 100644 --- a/src/tests/common/bit_utils.cpp +++ b/src/tests/common/bit_utils.cpp @@ -8,35 +8,16 @@ namespace Common { -inline u32 CTZ32(u32 value) { - u32 count = 0; - while (((value >> count) & 0xf) == 0 && count < 32) - count += 4; - while (((value >> count) & 1) == 0 && count < 32) - count++; - return count; -} - -inline u64 CTZ64(u64 value) { - u64 count = 0; - while (((value >> count) & 0xf) == 0 && count < 64) - count += 4; - while (((value >> count) & 1) == 0 && count < 64) - count++; - return count; -} - - -TEST_CASE("BitUtils", "[common]") { - REQUIRE(Common::CountTrailingZeroes32(0) == CTZ32(0)); - REQUIRE(Common::CountTrailingZeroes64(0) == CTZ64(0)); - REQUIRE(Common::CountTrailingZeroes32(9) == CTZ32(9)); - REQUIRE(Common::CountTrailingZeroes32(8) == CTZ32(8)); - REQUIRE(Common::CountTrailingZeroes32(0x801000) == CTZ32(0x801000)); - REQUIRE(Common::CountTrailingZeroes64(9) == CTZ64(9)); - REQUIRE(Common::CountTrailingZeroes64(8) == CTZ64(8)); - REQUIRE(Common::CountTrailingZeroes64(0x801000) == CTZ64(0x801000)); - REQUIRE(Common::CountTrailingZeroes64(0x801000000000UL) == CTZ64(0x801000000000UL)); +TEST_CASE("BitUtils::CountTrailingZeroes", "[common]") { + REQUIRE(Common::CountTrailingZeroes32(0) == 32); + REQUIRE(Common::CountTrailingZeroes64(0) == 64); + REQUIRE(Common::CountTrailingZeroes32(9) == 0); + REQUIRE(Common::CountTrailingZeroes32(8) == 3); + REQUIRE(Common::CountTrailingZeroes32(0x801000) == 12); + REQUIRE(Common::CountTrailingZeroes64(9) == 0); + REQUIRE(Common::CountTrailingZeroes64(8) == 3); + REQUIRE(Common::CountTrailingZeroes64(0x801000) == 12); + REQUIRE(Common::CountTrailingZeroes64(0x801000000000UL) == 36); } } // namespace Common diff --git a/src/tests/common/multi_level_queue.cpp b/src/tests/common/multi_level_queue.cpp index 9a8b84695..cca7ec7da 100644 --- a/src/tests/common/multi_level_queue.cpp +++ b/src/tests/common/multi_level_queue.cpp @@ -11,7 +11,7 @@ namespace Common { TEST_CASE("MultiLevelQueue", "[common]") { std::array values = {0.0, 5.0, 1.0, 9.0, 8.0, 2.0, 6.0, 7.0}; - Common::MultiLevelQueue mlq; + Common::MultiLevelQueue mlq; REQUIRE(mlq.empty()); mlq.add(values[2], 2); mlq.add(values[7], 7);