summaryrefslogtreecommitdiff
path: root/Source
diff options
context:
space:
mode:
authormitaclaw <140017135+mitaclaw@users.noreply.github.com>2024-10-05 16:09:15 -0700
committermitaclaw <140017135+mitaclaw@users.noreply.github.com>2024-10-11 12:08:22 -0700
commit2edf6c641998e3e2d144d8e28cbfc5985c690841 (patch)
treef2afcafaf7c453a86efc2f96cf64d8cd7d9068de /Source
parentd374284d929b6852db6a43e6a79d71679fb21a61 (diff)
CoreTiming: Simplify algorithms using ranges and three-way comparison
Diffstat (limited to 'Source')
-rw-r--r--Source/Core/Core/CoreTiming.cpp24
-rw-r--r--Source/Core/Core/CoreTiming.h14
2 files changed, 20 insertions, 18 deletions
diff --git a/Source/Core/Core/CoreTiming.cpp b/Source/Core/Core/CoreTiming.cpp
index f34bc5f9de..549c455a3f 100644
--- a/Source/Core/Core/CoreTiming.cpp
+++ b/Source/Core/Core/CoreTiming.cpp
@@ -32,16 +32,6 @@
namespace CoreTiming
{
-// Sort by time, unless the times are the same, in which case sort by the order added to the queue
-static bool operator>(const Event& left, const Event& right)
-{
- return std::tie(left.time, left.fifo_order) > std::tie(right.time, right.fifo_order);
-}
-static bool operator<(const Event& left, const Event& right)
-{
- return std::tie(left.time, left.fifo_order) < std::tie(right.time, right.fifo_order);
-}
-
static constexpr int MAX_SLICE_LENGTH = 20000;
static void EmptyTimedCallback(Core::System& system, u64 userdata, s64 cyclesLate)
@@ -205,7 +195,7 @@ void CoreTimingManager::DoState(PointerWrap& p)
// When loading from a save state, we must assume the Event order is random and meaningless.
// The exact layout of the heap in memory is implementation defined, therefore it is platform
// and library version specific.
- std::make_heap(m_event_queue.begin(), m_event_queue.end(), std::greater<Event>());
+ std::ranges::make_heap(m_event_queue, std::ranges::greater{});
// The stave state has changed the time, so our previous Throttle targets are invalid.
// Especially when global_time goes down; So we create a fake throttle update.
@@ -263,7 +253,7 @@ void CoreTimingManager::ScheduleEvent(s64 cycles_into_future, EventType* event_t
ForceExceptionCheck(cycles_into_future);
m_event_queue.emplace_back(Event{timeout, m_event_fifo_id++, userdata, event_type});
- std::push_heap(m_event_queue.begin(), m_event_queue.end(), std::greater<Event>());
+ std::ranges::push_heap(m_event_queue, std::ranges::greater{});
}
else
{
@@ -288,7 +278,7 @@ void CoreTimingManager::RemoveEvent(EventType* event_type)
// Removing random items breaks the invariant so we have to re-establish it.
if (erased != 0)
{
- std::make_heap(m_event_queue.begin(), m_event_queue.end(), std::greater<Event>());
+ std::ranges::make_heap(m_event_queue, std::ranges::greater{});
}
}
@@ -317,7 +307,7 @@ void CoreTimingManager::MoveEvents()
{
ev.fifo_order = m_event_fifo_id++;
m_event_queue.emplace_back(std::move(ev));
- std::push_heap(m_event_queue.begin(), m_event_queue.end(), std::greater<Event>());
+ std::ranges::push_heap(m_event_queue, std::ranges::greater{});
}
}
@@ -341,7 +331,7 @@ void CoreTimingManager::Advance()
while (!m_event_queue.empty() && m_event_queue.front().time <= m_globals.global_timer)
{
Event evt = std::move(m_event_queue.front());
- std::pop_heap(m_event_queue.begin(), m_event_queue.end(), std::greater<Event>());
+ std::ranges::pop_heap(m_event_queue, std::ranges::greater{});
m_event_queue.pop_back();
Throttle(evt.time);
@@ -440,7 +430,7 @@ bool CoreTimingManager::UseSyncOnSkipIdle() const
void CoreTimingManager::LogPendingEvents() const
{
auto clone = m_event_queue;
- std::sort(clone.begin(), clone.end());
+ std::ranges::sort(clone);
for (const Event& ev : clone)
{
INFO_LOG_FMT(POWERPC, "PENDING: Now: {} Pending: {} Type: {}", m_globals.global_timer, ev.time,
@@ -483,7 +473,7 @@ std::string CoreTimingManager::GetScheduledEventsSummary() const
text.reserve(1000);
auto clone = m_event_queue;
- std::sort(clone.begin(), clone.end());
+ std::ranges::sort(clone);
for (const Event& ev : clone)
{
text += fmt::format("{} : {} {:016x}\n", *ev.type->name, ev.time, ev.userdata);
diff --git a/Source/Core/Core/CoreTiming.h b/Source/Core/Core/CoreTiming.h
index 6c60b74479..b76e898e70 100644
--- a/Source/Core/Core/CoreTiming.h
+++ b/Source/Core/Core/CoreTiming.h
@@ -16,8 +16,10 @@
// inside callback:
// ScheduleEvent(periodInCycles - cyclesLate, callback, "whatever")
+#include <compare>
#include <mutex>
#include <string>
+#include <tuple>
#include <unordered_map>
#include <vector>
@@ -58,6 +60,16 @@ struct Event
u64 fifo_order;
u64 userdata;
EventType* type;
+
+ // Sort by time, unless the times are the same, in which case sort by the order added to the queue
+ constexpr auto operator<=>(const Event& other) const
+ {
+ return std::tie(time, fifo_order) <=> std::tie(other.time, other.fifo_order);
+ }
+ constexpr bool operator==(const Event& other) const
+ {
+ return std::tie(time, fifo_order) == std::tie(other.time, other.fifo_order);
+ }
};
enum class FromThread
@@ -163,7 +175,7 @@ private:
std::unordered_map<std::string, EventType> m_event_types;
// STATE_TO_SAVE
- // The queue is a min-heap using std::make_heap/push_heap/pop_heap.
+ // The queue is a min-heap using std::ranges::make_heap/push_heap/pop_heap.
// We don't use std::priority_queue because we need to be able to serialize, unserialize and
// erase arbitrary events (RemoveEvent()) regardless of the queue order. These aren't accomodated
// by the standard adaptor class.