|
|
@ -23,7 +23,7 @@ std::shared_ptr<EventType> CreateEvent(std::string name, TimedCallback&& callbac |
|
|
struct CoreTiming::Event { |
|
|
struct CoreTiming::Event { |
|
|
u64 time; |
|
|
u64 time; |
|
|
u64 fifo_order; |
|
|
u64 fifo_order; |
|
|
u64 userdata; |
|
|
|
|
|
|
|
|
std::uintptr_t user_data; |
|
|
std::weak_ptr<EventType> type; |
|
|
std::weak_ptr<EventType> type; |
|
|
|
|
|
|
|
|
// Sort by time, unless the times are the same, in which case sort by
|
|
|
// Sort by time, unless the times are the same, in which case sort by
|
|
|
@ -58,7 +58,7 @@ void CoreTiming::Initialize(std::function<void()>&& on_thread_init_) { |
|
|
event_fifo_id = 0; |
|
|
event_fifo_id = 0; |
|
|
shutting_down = false; |
|
|
shutting_down = false; |
|
|
ticks = 0; |
|
|
ticks = 0; |
|
|
const auto empty_timed_callback = [](u64, std::chrono::nanoseconds) {}; |
|
|
|
|
|
|
|
|
const auto empty_timed_callback = [](std::uintptr_t, std::chrono::nanoseconds) {}; |
|
|
ev_lost = CreateEvent("_lost_event", empty_timed_callback); |
|
|
ev_lost = CreateEvent("_lost_event", empty_timed_callback); |
|
|
if (is_multicore) { |
|
|
if (is_multicore) { |
|
|
timer_thread = std::make_unique<std::thread>(ThreadEntry, std::ref(*this)); |
|
|
timer_thread = std::make_unique<std::thread>(ThreadEntry, std::ref(*this)); |
|
|
@ -107,22 +107,24 @@ bool CoreTiming::HasPendingEvents() const { |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
void CoreTiming::ScheduleEvent(std::chrono::nanoseconds ns_into_future, |
|
|
void CoreTiming::ScheduleEvent(std::chrono::nanoseconds ns_into_future, |
|
|
const std::shared_ptr<EventType>& event_type, u64 userdata) { |
|
|
|
|
|
|
|
|
const std::shared_ptr<EventType>& event_type, |
|
|
|
|
|
std::uintptr_t user_data) { |
|
|
{ |
|
|
{ |
|
|
std::scoped_lock scope{basic_lock}; |
|
|
std::scoped_lock scope{basic_lock}; |
|
|
const u64 timeout = static_cast<u64>((GetGlobalTimeNs() + ns_into_future).count()); |
|
|
const u64 timeout = static_cast<u64>((GetGlobalTimeNs() + ns_into_future).count()); |
|
|
|
|
|
|
|
|
event_queue.emplace_back(Event{timeout, event_fifo_id++, userdata, event_type}); |
|
|
|
|
|
|
|
|
event_queue.emplace_back(Event{timeout, event_fifo_id++, user_data, event_type}); |
|
|
|
|
|
|
|
|
std::push_heap(event_queue.begin(), event_queue.end(), std::greater<>()); |
|
|
std::push_heap(event_queue.begin(), event_queue.end(), std::greater<>()); |
|
|
} |
|
|
} |
|
|
event.Set(); |
|
|
event.Set(); |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
void CoreTiming::UnscheduleEvent(const std::shared_ptr<EventType>& event_type, u64 userdata) { |
|
|
|
|
|
|
|
|
void CoreTiming::UnscheduleEvent(const std::shared_ptr<EventType>& event_type, |
|
|
|
|
|
std::uintptr_t user_data) { |
|
|
std::scoped_lock scope{basic_lock}; |
|
|
std::scoped_lock scope{basic_lock}; |
|
|
const auto itr = std::remove_if(event_queue.begin(), event_queue.end(), [&](const Event& e) { |
|
|
const auto itr = std::remove_if(event_queue.begin(), event_queue.end(), [&](const Event& e) { |
|
|
return e.type.lock().get() == event_type.get() && e.userdata == userdata; |
|
|
|
|
|
|
|
|
return e.type.lock().get() == event_type.get() && e.user_data == user_data; |
|
|
}); |
|
|
}); |
|
|
|
|
|
|
|
|
// Removing random items breaks the invariant so we have to re-establish it.
|
|
|
// Removing random items breaks the invariant so we have to re-establish it.
|
|
|
@ -197,7 +199,7 @@ std::optional<s64> CoreTiming::Advance() { |
|
|
|
|
|
|
|
|
if (const auto event_type{evt.type.lock()}) { |
|
|
if (const auto event_type{evt.type.lock()}) { |
|
|
event_type->callback( |
|
|
event_type->callback( |
|
|
evt.userdata, std::chrono::nanoseconds{static_cast<s64>(global_timer - evt.time)}); |
|
|
|
|
|
|
|
|
evt.user_data, std::chrono::nanoseconds{static_cast<s64>(global_timer - evt.time)}); |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
basic_lock.lock(); |
|
|
basic_lock.lock(); |
|
|
|