summaryrefslogtreecommitdiff
path: root/src/core/core_timing.cpp
diff options
context:
space:
mode:
authorGravatar Narr the Reg2024-01-01 13:56:31 -0600
committerGravatar GitHub2024-01-01 13:56:31 -0600
commitaa9ff2ffc2d9c3c1b7d6f4f6a7170acda7e17e9c (patch)
tree3f7ca8e93b7bc523b8dd357ec43d302fd794b37c /src/core/core_timing.cpp
parentMerge pull request #12466 from liamwhite/sh2 (diff)
parentcore_timing: block advance thread while clearing and signal after (diff)
downloadyuzu-aa9ff2ffc2d9c3c1b7d6f4f6a7170acda7e17e9c.tar.gz
yuzu-aa9ff2ffc2d9c3c1b7d6f4f6a7170acda7e17e9c.tar.xz
yuzu-aa9ff2ffc2d9c3c1b7d6f4f6a7170acda7e17e9c.zip
Merge pull request #12454 from liamwhite/ct-stuff
core_timing: minor refactors
Diffstat (limited to 'src/core/core_timing.cpp')
-rw-r--r--src/core/core_timing.cpp48
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
29struct CoreTiming::Event { 29struct 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
78void CoreTiming::ClearPendingEvents() { 74void 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
83void CoreTiming::Pause(bool is_paused) { 80void CoreTiming::Pause(bool is_paused) {
@@ -119,14 +116,12 @@ bool CoreTiming::HasPendingEvents() const {
119} 116}
120 117
121void CoreTiming::ScheduleEvent(std::chrono::nanoseconds ns_into_future, 118void 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,
136void CoreTiming::ScheduleLoopingEvent(std::chrono::nanoseconds start_time, 131void 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
152void CoreTiming::UnscheduleEvent(const std::shared_ptr<EventType>& event_type, 147void 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