diff options
Diffstat (limited to 'src/core/core_timing.cpp')
| -rw-r--r-- | src/core/core_timing.cpp | 48 |
1 files changed, 24 insertions, 24 deletions
diff --git a/src/core/core_timing.cpp b/src/core/core_timing.cpp index d6b5abc68..fc536413b 100644 --- a/src/core/core_timing.cpp +++ b/src/core/core_timing.cpp | |||
| @@ -29,7 +29,6 @@ std::shared_ptr<EventType> CreateEvent(std::string name, TimedCallback&& callbac | |||
| 29 | struct CoreTiming::Event { | 29 | struct CoreTiming::Event { |
| 30 | s64 time; | 30 | s64 time; |
| 31 | u64 fifo_order; | 31 | u64 fifo_order; |
| 32 | std::uintptr_t user_data; | ||
| 33 | std::weak_ptr<EventType> type; | 32 | std::weak_ptr<EventType> type; |
| 34 | s64 reschedule_time; | 33 | s64 reschedule_time; |
| 35 | heap_t::handle_type handle{}; | 34 | heap_t::handle_type handle{}; |
| @@ -67,17 +66,15 @@ void CoreTiming::Initialize(std::function<void()>&& on_thread_init_) { | |||
| 67 | event_fifo_id = 0; | 66 | event_fifo_id = 0; |
| 68 | shutting_down = false; | 67 | shutting_down = false; |
| 69 | cpu_ticks = 0; | 68 | cpu_ticks = 0; |
| 70 | const auto empty_timed_callback = [](std::uintptr_t, u64, std::chrono::nanoseconds) | ||
| 71 | -> std::optional<std::chrono::nanoseconds> { return std::nullopt; }; | ||
| 72 | ev_lost = CreateEvent("_lost_event", empty_timed_callback); | ||
| 73 | if (is_multicore) { | 69 | if (is_multicore) { |
| 74 | timer_thread = std::make_unique<std::jthread>(ThreadEntry, std::ref(*this)); | 70 | timer_thread = std::make_unique<std::jthread>(ThreadEntry, std::ref(*this)); |
| 75 | } | 71 | } |
| 76 | } | 72 | } |
| 77 | 73 | ||
| 78 | void CoreTiming::ClearPendingEvents() { | 74 | void CoreTiming::ClearPendingEvents() { |
| 79 | std::scoped_lock lock{basic_lock}; | 75 | std::scoped_lock lock{advance_lock, basic_lock}; |
| 80 | event_queue.clear(); | 76 | event_queue.clear(); |
| 77 | event.Set(); | ||
| 81 | } | 78 | } |
| 82 | 79 | ||
| 83 | void CoreTiming::Pause(bool is_paused) { | 80 | void CoreTiming::Pause(bool is_paused) { |
| @@ -119,14 +116,12 @@ bool CoreTiming::HasPendingEvents() const { | |||
| 119 | } | 116 | } |
| 120 | 117 | ||
| 121 | void CoreTiming::ScheduleEvent(std::chrono::nanoseconds ns_into_future, | 118 | void CoreTiming::ScheduleEvent(std::chrono::nanoseconds ns_into_future, |
| 122 | const std::shared_ptr<EventType>& event_type, | 119 | const std::shared_ptr<EventType>& event_type, bool absolute_time) { |
| 123 | std::uintptr_t user_data, bool absolute_time) { | ||
| 124 | { | 120 | { |
| 125 | std::scoped_lock scope{basic_lock}; | 121 | std::scoped_lock scope{basic_lock}; |
| 126 | const auto next_time{absolute_time ? ns_into_future : GetGlobalTimeNs() + ns_into_future}; | 122 | const auto next_time{absolute_time ? ns_into_future : GetGlobalTimeNs() + ns_into_future}; |
| 127 | 123 | ||
| 128 | auto h{event_queue.emplace( | 124 | auto h{event_queue.emplace(Event{next_time.count(), event_fifo_id++, event_type, 0})}; |
| 129 | Event{next_time.count(), event_fifo_id++, user_data, event_type, 0})}; | ||
| 130 | (*h).handle = h; | 125 | (*h).handle = h; |
| 131 | } | 126 | } |
| 132 | 127 | ||
| @@ -136,13 +131,13 @@ void CoreTiming::ScheduleEvent(std::chrono::nanoseconds ns_into_future, | |||
| 136 | void CoreTiming::ScheduleLoopingEvent(std::chrono::nanoseconds start_time, | 131 | void CoreTiming::ScheduleLoopingEvent(std::chrono::nanoseconds start_time, |
| 137 | std::chrono::nanoseconds resched_time, | 132 | std::chrono::nanoseconds resched_time, |
| 138 | const std::shared_ptr<EventType>& event_type, | 133 | const std::shared_ptr<EventType>& event_type, |
| 139 | std::uintptr_t user_data, bool absolute_time) { | 134 | bool absolute_time) { |
| 140 | { | 135 | { |
| 141 | std::scoped_lock scope{basic_lock}; | 136 | std::scoped_lock scope{basic_lock}; |
| 142 | const auto next_time{absolute_time ? start_time : GetGlobalTimeNs() + start_time}; | 137 | const auto next_time{absolute_time ? start_time : GetGlobalTimeNs() + start_time}; |
| 143 | 138 | ||
| 144 | auto h{event_queue.emplace(Event{next_time.count(), event_fifo_id++, user_data, event_type, | 139 | auto h{event_queue.emplace( |
| 145 | resched_time.count()})}; | 140 | Event{next_time.count(), event_fifo_id++, event_type, resched_time.count()})}; |
| 146 | (*h).handle = h; | 141 | (*h).handle = h; |
| 147 | } | 142 | } |
| 148 | 143 | ||
| @@ -150,14 +145,14 @@ void CoreTiming::ScheduleLoopingEvent(std::chrono::nanoseconds start_time, | |||
| 150 | } | 145 | } |
| 151 | 146 | ||
| 152 | void CoreTiming::UnscheduleEvent(const std::shared_ptr<EventType>& event_type, | 147 | void CoreTiming::UnscheduleEvent(const std::shared_ptr<EventType>& event_type, |
| 153 | std::uintptr_t user_data, bool wait) { | 148 | UnscheduleEventType type) { |
| 154 | { | 149 | { |
| 155 | std::scoped_lock lk{basic_lock}; | 150 | std::scoped_lock lk{basic_lock}; |
| 156 | 151 | ||
| 157 | std::vector<heap_t::handle_type> to_remove; | 152 | std::vector<heap_t::handle_type> to_remove; |
| 158 | for (auto itr = event_queue.begin(); itr != event_queue.end(); itr++) { | 153 | for (auto itr = event_queue.begin(); itr != event_queue.end(); itr++) { |
| 159 | const Event& e = *itr; | 154 | const Event& e = *itr; |
| 160 | if (e.type.lock().get() == event_type.get() && e.user_data == user_data) { | 155 | if (e.type.lock().get() == event_type.get()) { |
| 161 | to_remove.push_back(itr->handle); | 156 | to_remove.push_back(itr->handle); |
| 162 | } | 157 | } |
| 163 | } | 158 | } |
| @@ -165,10 +160,12 @@ void CoreTiming::UnscheduleEvent(const std::shared_ptr<EventType>& event_type, | |||
| 165 | for (auto h : to_remove) { | 160 | for (auto h : to_remove) { |
| 166 | event_queue.erase(h); | 161 | event_queue.erase(h); |
| 167 | } | 162 | } |
| 163 | |||
| 164 | event_type->sequence_number++; | ||
| 168 | } | 165 | } |
| 169 | 166 | ||
| 170 | // Force any in-progress events to finish | 167 | // Force any in-progress events to finish |
| 171 | if (wait) { | 168 | if (type == UnscheduleEventType::Wait) { |
| 172 | std::scoped_lock lk{advance_lock}; | 169 | std::scoped_lock lk{advance_lock}; |
| 173 | } | 170 | } |
| 174 | } | 171 | } |
| @@ -208,28 +205,31 @@ std::optional<s64> CoreTiming::Advance() { | |||
| 208 | const Event& evt = event_queue.top(); | 205 | const Event& evt = event_queue.top(); |
| 209 | 206 | ||
| 210 | if (const auto event_type{evt.type.lock()}) { | 207 | if (const auto event_type{evt.type.lock()}) { |
| 211 | if (evt.reschedule_time == 0) { | 208 | const auto evt_time = evt.time; |
| 212 | const auto evt_user_data = evt.user_data; | 209 | const auto evt_sequence_num = event_type->sequence_number; |
| 213 | const auto evt_time = evt.time; | ||
| 214 | 210 | ||
| 211 | if (evt.reschedule_time == 0) { | ||
| 215 | event_queue.pop(); | 212 | event_queue.pop(); |
| 216 | 213 | ||
| 217 | basic_lock.unlock(); | 214 | basic_lock.unlock(); |
| 218 | 215 | ||
| 219 | event_type->callback( | 216 | event_type->callback( |
| 220 | evt_user_data, evt_time, | 217 | evt_time, std::chrono::nanoseconds{GetGlobalTimeNs().count() - evt_time}); |
| 221 | std::chrono::nanoseconds{GetGlobalTimeNs().count() - evt_time}); | ||
| 222 | 218 | ||
| 223 | basic_lock.lock(); | 219 | basic_lock.lock(); |
| 224 | } else { | 220 | } else { |
| 225 | basic_lock.unlock(); | 221 | basic_lock.unlock(); |
| 226 | 222 | ||
| 227 | const auto new_schedule_time{event_type->callback( | 223 | const auto new_schedule_time{event_type->callback( |
| 228 | evt.user_data, evt.time, | 224 | evt_time, std::chrono::nanoseconds{GetGlobalTimeNs().count() - evt_time})}; |
| 229 | std::chrono::nanoseconds{GetGlobalTimeNs().count() - evt.time})}; | ||
| 230 | 225 | ||
| 231 | basic_lock.lock(); | 226 | basic_lock.lock(); |
| 232 | 227 | ||
| 228 | if (evt_sequence_num != event_type->sequence_number) { | ||
| 229 | // Heap handle is invalidated after external modification. | ||
| 230 | continue; | ||
| 231 | } | ||
| 232 | |||
| 233 | const auto next_schedule_time{new_schedule_time.has_value() | 233 | const auto next_schedule_time{new_schedule_time.has_value() |
| 234 | ? new_schedule_time.value().count() | 234 | ? new_schedule_time.value().count() |
| 235 | : evt.reschedule_time}; | 235 | : evt.reschedule_time}; |
| @@ -241,8 +241,8 @@ std::optional<s64> CoreTiming::Advance() { | |||
| 241 | next_time = pause_end_time + next_schedule_time; | 241 | next_time = pause_end_time + next_schedule_time; |
| 242 | } | 242 | } |
| 243 | 243 | ||
| 244 | event_queue.update(evt.handle, Event{next_time, event_fifo_id++, evt.user_data, | 244 | event_queue.update(evt.handle, Event{next_time, event_fifo_id++, evt.type, |
| 245 | evt.type, next_schedule_time, evt.handle}); | 245 | next_schedule_time, evt.handle}); |
| 246 | } | 246 | } |
| 247 | } | 247 | } |
| 248 | 248 | ||