Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Ranges Algorithms Modernization - Spaceship #13092

Draft
wants to merge 2 commits into
base: master
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 7 additions & 17 deletions Source/Core/Core/CoreTiming.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down Expand Up @@ -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.
Expand Down Expand Up @@ -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
{
Expand All @@ -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{});
}
}

Expand Down Expand Up @@ -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{});
}
}

Expand All @@ -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);
Expand Down Expand Up @@ -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,
Expand Down Expand Up @@ -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);
Expand Down
11 changes: 10 additions & 1 deletion Source/Core/Core/CoreTiming.h
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,11 @@
// inside callback:
// ScheduleEvent(periodInCycles - cyclesLate, callback, "whatever")

#include <compare>
#include <mutex>
#include <string>
#include <unordered_map>
#include <utility>
#include <vector>

#include "Common/CommonTypes.h"
Expand Down Expand Up @@ -58,6 +60,13 @@ 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 std::strong_ordering 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 = default;
};

enum class FromThread
Expand Down Expand Up @@ -163,7 +172,7 @@ class CoreTimingManager
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.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -330,8 +330,3 @@ void GraphicsModConfig::DeserializeFromProfile(const picojson::object& obj)
}
}
}

bool GraphicsModConfig::operator<(const GraphicsModConfig& other) const
{
return m_weight < other.m_weight;
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@

#pragma once

#include <compare>
#include <optional>
#include <string>
#include <vector>
Expand Down Expand Up @@ -44,5 +45,9 @@ struct GraphicsModConfig
void SerializeToProfile(picojson::object* value) const;
void DeserializeFromProfile(const picojson::object& value);

bool operator<(const GraphicsModConfig& other) const;
constexpr std::strong_ordering operator<=>(const GraphicsModConfig& other) const
{
return m_weight <=> other.m_weight;
}
constexpr bool operator==(const GraphicsModConfig& other) const = default;
};
Original file line number Diff line number Diff line change
Expand Up @@ -111,7 +111,7 @@ void GraphicsModGroupConfig::Load()
try_add_mod(graphics_mod_directory, GraphicsModConfig::Source::System);
}

std::sort(m_graphics_mods.begin(), m_graphics_mods.end());
std::ranges::sort(m_graphics_mods);
for (auto& mod : m_graphics_mods)
{
m_path_to_graphics_mod[mod.GetAbsolutePath()] = &mod;
Expand Down