summaryrefslogtreecommitdiff
path: root/src/core/core_timing.cpp
diff options
context:
space:
mode:
authorGravatar bunnei2019-06-30 12:54:00 -0400
committerGravatar GitHub2019-06-30 12:54:00 -0400
commitd992909636269cde90cf6cb3749ccffcff9a6c56 (patch)
tree9dd14057dab85c1ba171df75f2112697cdc85cb6 /src/core/core_timing.cpp
parentMerge pull request #2653 from FearlessTobi/revert-2474-patch-1 (diff)
parentCore_Timing: Make core_timing threadsafe by default. (diff)
downloadyuzu-d992909636269cde90cf6cb3749ccffcff9a6c56.tar.gz
yuzu-d992909636269cde90cf6cb3749ccffcff9a6c56.tar.xz
yuzu-d992909636269cde90cf6cb3749ccffcff9a6c56.zip
Merge pull request #2583 from FernandoS27/core-timing-safe
Core_Timing: Make core_timing threadsafe by default.
Diffstat (limited to 'src/core/core_timing.cpp')
-rw-r--r--src/core/core_timing.cpp34
1 files changed, 7 insertions, 27 deletions
diff --git a/src/core/core_timing.cpp b/src/core/core_timing.cpp
index 41adb2302..a58f7b131 100644
--- a/src/core/core_timing.cpp
+++ b/src/core/core_timing.cpp
@@ -56,12 +56,12 @@ void CoreTiming::Initialize() {
56} 56}
57 57
58void CoreTiming::Shutdown() { 58void CoreTiming::Shutdown() {
59 MoveEvents();
60 ClearPendingEvents(); 59 ClearPendingEvents();
61 UnregisterAllEvents(); 60 UnregisterAllEvents();
62} 61}
63 62
64EventType* CoreTiming::RegisterEvent(const std::string& name, TimedCallback callback) { 63EventType* CoreTiming::RegisterEvent(const std::string& name, TimedCallback callback) {
64 std::lock_guard guard{inner_mutex};
65 // check for existing type with same name. 65 // check for existing type with same name.
66 // we want event type names to remain unique so that we can use them for serialization. 66 // we want event type names to remain unique so that we can use them for serialization.
67 ASSERT_MSG(event_types.find(name) == event_types.end(), 67 ASSERT_MSG(event_types.find(name) == event_types.end(),
@@ -82,6 +82,7 @@ void CoreTiming::UnregisterAllEvents() {
82 82
83void CoreTiming::ScheduleEvent(s64 cycles_into_future, const EventType* event_type, u64 userdata) { 83void CoreTiming::ScheduleEvent(s64 cycles_into_future, const EventType* event_type, u64 userdata) {
84 ASSERT(event_type != nullptr); 84 ASSERT(event_type != nullptr);
85 std::lock_guard guard{inner_mutex};
85 const s64 timeout = GetTicks() + cycles_into_future; 86 const s64 timeout = GetTicks() + cycles_into_future;
86 87
87 // If this event needs to be scheduled before the next advance(), force one early 88 // If this event needs to be scheduled before the next advance(), force one early
@@ -93,12 +94,8 @@ void CoreTiming::ScheduleEvent(s64 cycles_into_future, const EventType* event_ty
93 std::push_heap(event_queue.begin(), event_queue.end(), std::greater<>()); 94 std::push_heap(event_queue.begin(), event_queue.end(), std::greater<>());
94} 95}
95 96
96void CoreTiming::ScheduleEventThreadsafe(s64 cycles_into_future, const EventType* event_type,
97 u64 userdata) {
98 ts_queue.Push(Event{global_timer + cycles_into_future, 0, userdata, event_type});
99}
100
101void CoreTiming::UnscheduleEvent(const EventType* event_type, u64 userdata) { 97void CoreTiming::UnscheduleEvent(const EventType* event_type, u64 userdata) {
98 std::lock_guard guard{inner_mutex};
102 const auto itr = std::remove_if(event_queue.begin(), event_queue.end(), [&](const Event& e) { 99 const auto itr = std::remove_if(event_queue.begin(), event_queue.end(), [&](const Event& e) {
103 return e.type == event_type && e.userdata == userdata; 100 return e.type == event_type && e.userdata == userdata;
104 }); 101 });
@@ -110,10 +107,6 @@ void CoreTiming::UnscheduleEvent(const EventType* event_type, u64 userdata) {
110 } 107 }
111} 108}
112 109
113void CoreTiming::UnscheduleEventThreadsafe(const EventType* event_type, u64 userdata) {
114 unschedule_queue.Push(std::make_pair(event_type, userdata));
115}
116
117u64 CoreTiming::GetTicks() const { 110u64 CoreTiming::GetTicks() const {
118 u64 ticks = static_cast<u64>(global_timer); 111 u64 ticks = static_cast<u64>(global_timer);
119 if (!is_global_timer_sane) { 112 if (!is_global_timer_sane) {
@@ -135,6 +128,7 @@ void CoreTiming::ClearPendingEvents() {
135} 128}
136 129
137void CoreTiming::RemoveEvent(const EventType* event_type) { 130void CoreTiming::RemoveEvent(const EventType* event_type) {
131 std::lock_guard guard{inner_mutex};
138 const auto itr = std::remove_if(event_queue.begin(), event_queue.end(), 132 const auto itr = std::remove_if(event_queue.begin(), event_queue.end(),
139 [&](const Event& e) { return e.type == event_type; }); 133 [&](const Event& e) { return e.type == event_type; });
140 134
@@ -145,11 +139,6 @@ void CoreTiming::RemoveEvent(const EventType* event_type) {
145 } 139 }
146} 140}
147 141
148void CoreTiming::RemoveNormalAndThreadsafeEvent(const EventType* event_type) {
149 MoveEvents();
150 RemoveEvent(event_type);
151}
152
153void CoreTiming::ForceExceptionCheck(s64 cycles) { 142void CoreTiming::ForceExceptionCheck(s64 cycles) {
154 cycles = std::max<s64>(0, cycles); 143 cycles = std::max<s64>(0, cycles);
155 if (downcount <= cycles) { 144 if (downcount <= cycles) {
@@ -162,19 +151,8 @@ void CoreTiming::ForceExceptionCheck(s64 cycles) {
162 downcount = static_cast<int>(cycles); 151 downcount = static_cast<int>(cycles);
163} 152}
164 153
165void CoreTiming::MoveEvents() {
166 for (Event ev; ts_queue.Pop(ev);) {
167 ev.fifo_order = event_fifo_id++;
168 event_queue.emplace_back(std::move(ev));
169 std::push_heap(event_queue.begin(), event_queue.end(), std::greater<>());
170 }
171}
172
173void CoreTiming::Advance() { 154void CoreTiming::Advance() {
174 MoveEvents(); 155 std::unique_lock<std::mutex> guard(inner_mutex);
175 for (std::pair<const EventType*, u64> ev; unschedule_queue.Pop(ev);) {
176 UnscheduleEvent(ev.first, ev.second);
177 }
178 156
179 const int cycles_executed = slice_length - downcount; 157 const int cycles_executed = slice_length - downcount;
180 global_timer += cycles_executed; 158 global_timer += cycles_executed;
@@ -186,7 +164,9 @@ void CoreTiming::Advance() {
186 Event evt = std::move(event_queue.front()); 164 Event evt = std::move(event_queue.front());
187 std::pop_heap(event_queue.begin(), event_queue.end(), std::greater<>()); 165 std::pop_heap(event_queue.begin(), event_queue.end(), std::greater<>());
188 event_queue.pop_back(); 166 event_queue.pop_back();
167 inner_mutex.unlock();
189 evt.type->callback(evt.userdata, global_timer - evt.time); 168 evt.type->callback(evt.userdata, global_timer - evt.time);
169 inner_mutex.lock();
190 } 170 }
191 171
192 is_global_timer_sane = false; 172 is_global_timer_sane = false;