mirror of
https://git.suyu.dev/suyu/suyu.git
synced 2024-12-23 00:40:58 +01:00
Fixes and corrections on formatting.
This commit is contained in:
parent
f35e09fe0d
commit
db42bcb306
5 changed files with 30 additions and 41 deletions
|
@ -59,7 +59,6 @@ inline u64 CountLeadingZeroes64(u64 value) {
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
#ifdef _MSC_VER
|
#ifdef _MSC_VER
|
||||||
inline u32 CountTrailingZeroes32(u32 value) {
|
inline u32 CountTrailingZeroes32(u32 value) {
|
||||||
unsigned long trailing_zero = 0;
|
unsigned long trailing_zero = 0;
|
||||||
|
|
|
@ -7,12 +7,21 @@
|
||||||
#include <array>
|
#include <array>
|
||||||
#include <iterator>
|
#include <iterator>
|
||||||
#include <list>
|
#include <list>
|
||||||
|
#include <utility>
|
||||||
|
|
||||||
#include "common/bit_util.h"
|
#include "common/bit_util.h"
|
||||||
#include "common/common_types.h"
|
#include "common/common_types.h"
|
||||||
|
|
||||||
namespace Common {
|
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 <typename T, std::size_t Depth>
|
template <typename T, std::size_t Depth>
|
||||||
class MultiLevelQueue {
|
class MultiLevelQueue {
|
||||||
public:
|
public:
|
||||||
|
@ -37,9 +46,7 @@ public:
|
||||||
friend bool operator==(const iterator_impl& lhs, const iterator_impl& rhs) {
|
friend bool operator==(const iterator_impl& lhs, const iterator_impl& rhs) {
|
||||||
if (lhs.IsEnd() && rhs.IsEnd())
|
if (lhs.IsEnd() && rhs.IsEnd())
|
||||||
return true;
|
return true;
|
||||||
if (lhs.current_priority == rhs.current_priority)
|
return std::tie(lhs.current_priority, lhs.it) == std::tie(rhs.current_priority, rhs.it);
|
||||||
return lhs.it == rhs.it;
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
friend bool operator!=(const iterator_impl& lhs, const iterator_impl& rhs) {
|
friend bool operator!=(const iterator_impl& lhs, const iterator_impl& rhs) {
|
||||||
|
@ -301,7 +308,6 @@ private:
|
||||||
using const_list_iterator = typename std::list<T>::const_iterator;
|
using const_list_iterator = typename std::list<T>::const_iterator;
|
||||||
|
|
||||||
static void ListShiftForward(std::list<T>& list, const std::size_t shift = 1) {
|
static void ListShiftForward(std::list<T>& list, const std::size_t shift = 1) {
|
||||||
// NOTE: May want to consider making this an assertion or something
|
|
||||||
if (shift >= list.size()) {
|
if (shift >= list.size()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
|
@ -45,10 +45,10 @@ Thread* Scheduler::PopNextReadyThread() {
|
||||||
Thread* next = nullptr;
|
Thread* next = nullptr;
|
||||||
Thread* thread = GetCurrentThread();
|
Thread* thread = GetCurrentThread();
|
||||||
|
|
||||||
|
|
||||||
if (thread && thread->GetStatus() == ThreadStatus::Running) {
|
if (thread && thread->GetStatus() == ThreadStatus::Running) {
|
||||||
if (ready_queue.empty())
|
if (ready_queue.empty()) {
|
||||||
return thread;
|
return thread;
|
||||||
|
}
|
||||||
// We have to do better than the current thread.
|
// We have to do better than the current thread.
|
||||||
// This call returns null when that's not possible.
|
// This call returns null when that's not possible.
|
||||||
next = ready_queue.front();
|
next = ready_queue.front();
|
||||||
|
@ -56,8 +56,9 @@ Thread* Scheduler::PopNextReadyThread() {
|
||||||
next = thread;
|
next = thread;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (ready_queue.empty())
|
if (ready_queue.empty()) {
|
||||||
return nullptr;
|
return nullptr;
|
||||||
|
}
|
||||||
next = ready_queue.front();
|
next = ready_queue.front();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -176,8 +177,9 @@ void Scheduler::UnscheduleThread(Thread* thread, u32 priority) {
|
||||||
|
|
||||||
void Scheduler::SetThreadPriority(Thread* thread, u32 priority) {
|
void Scheduler::SetThreadPriority(Thread* thread, u32 priority) {
|
||||||
std::lock_guard<std::mutex> lock(scheduler_mutex);
|
std::lock_guard<std::mutex> lock(scheduler_mutex);
|
||||||
if (thread->GetPriority() == priority)
|
if (thread->GetPriority() == priority) {
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
// If thread was ready, adjust queues
|
// If thread was ready, adjust queues
|
||||||
if (thread->GetStatus() == ThreadStatus::Ready)
|
if (thread->GetStatus() == ThreadStatus::Ready)
|
||||||
|
@ -188,9 +190,10 @@ Thread* Scheduler::GetNextSuggestedThread(u32 core, u32 maximum_priority) const
|
||||||
std::lock_guard<std::mutex> lock(scheduler_mutex);
|
std::lock_guard<std::mutex> lock(scheduler_mutex);
|
||||||
|
|
||||||
const u32 mask = 1U << core;
|
const u32 mask = 1U << core;
|
||||||
for (auto& thread : ready_queue) {
|
for (auto* thread : ready_queue) {
|
||||||
if ((thread->GetAffinityMask() & mask) != 0 && thread->GetPriority() < maximum_priority)
|
if ((thread->GetAffinityMask() & mask) != 0 && thread->GetPriority() < maximum_priority) {
|
||||||
return thread;
|
return thread;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,35 +8,16 @@
|
||||||
|
|
||||||
namespace Common {
|
namespace Common {
|
||||||
|
|
||||||
inline u32 CTZ32(u32 value) {
|
TEST_CASE("BitUtils::CountTrailingZeroes", "[common]") {
|
||||||
u32 count = 0;
|
REQUIRE(Common::CountTrailingZeroes32(0) == 32);
|
||||||
while (((value >> count) & 0xf) == 0 && count < 32)
|
REQUIRE(Common::CountTrailingZeroes64(0) == 64);
|
||||||
count += 4;
|
REQUIRE(Common::CountTrailingZeroes32(9) == 0);
|
||||||
while (((value >> count) & 1) == 0 && count < 32)
|
REQUIRE(Common::CountTrailingZeroes32(8) == 3);
|
||||||
count++;
|
REQUIRE(Common::CountTrailingZeroes32(0x801000) == 12);
|
||||||
return count;
|
REQUIRE(Common::CountTrailingZeroes64(9) == 0);
|
||||||
}
|
REQUIRE(Common::CountTrailingZeroes64(8) == 3);
|
||||||
|
REQUIRE(Common::CountTrailingZeroes64(0x801000) == 12);
|
||||||
inline u64 CTZ64(u64 value) {
|
REQUIRE(Common::CountTrailingZeroes64(0x801000000000UL) == 36);
|
||||||
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));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace Common
|
} // namespace Common
|
||||||
|
|
|
@ -11,7 +11,7 @@ namespace Common {
|
||||||
|
|
||||||
TEST_CASE("MultiLevelQueue", "[common]") {
|
TEST_CASE("MultiLevelQueue", "[common]") {
|
||||||
std::array<f32, 8> values = {0.0, 5.0, 1.0, 9.0, 8.0, 2.0, 6.0, 7.0};
|
std::array<f32, 8> values = {0.0, 5.0, 1.0, 9.0, 8.0, 2.0, 6.0, 7.0};
|
||||||
Common::MultiLevelQueue<f32,64> mlq;
|
Common::MultiLevelQueue<f32, 64> mlq;
|
||||||
REQUIRE(mlq.empty());
|
REQUIRE(mlq.empty());
|
||||||
mlq.add(values[2], 2);
|
mlq.add(values[2], 2);
|
||||||
mlq.add(values[7], 7);
|
mlq.add(values[7], 7);
|
||||||
|
|
Loading…
Reference in a new issue