summaryrefslogtreecommitdiff
path: root/src/tests
diff options
context:
space:
mode:
authorGravatar Lioncash2019-02-14 12:42:58 -0500
committerGravatar Lioncash2019-02-15 21:50:25 -0500
commitbd983414f643b734a1f8bebe3183723733344f72 (patch)
treebda0421458439e25cba9d772a6a79b56e473d72e /src/tests
parentMerge pull request #2113 from ReinUsesLisp/vulkan-base (diff)
downloadyuzu-bd983414f643b734a1f8bebe3183723733344f72.tar.gz
yuzu-bd983414f643b734a1f8bebe3183723733344f72.tar.xz
yuzu-bd983414f643b734a1f8bebe3183723733344f72.zip
core_timing: Convert core timing into a class
Gets rid of the largest set of mutable global state within the core. This also paves a way for eliminating usages of GetInstance() on the System class as a follow-up. Note that no behavioral changes have been made, and this simply extracts the functionality into a class. This also has the benefit of making dependencies on the core timing functionality explicit within the relevant interfaces.
Diffstat (limited to 'src/tests')
-rw-r--r--src/tests/core/core_timing.cpp215
1 files changed, 112 insertions, 103 deletions
diff --git a/src/tests/core/core_timing.cpp b/src/tests/core/core_timing.cpp
index 77607a755..340d6a272 100644
--- a/src/tests/core/core_timing.cpp
+++ b/src/tests/core/core_timing.cpp
@@ -28,100 +28,103 @@ void CallbackTemplate(u64 userdata, s64 cycles_late) {
28 REQUIRE(lateness == cycles_late); 28 REQUIRE(lateness == cycles_late);
29} 29}
30 30
31class ScopeInit final { 31struct ScopeInit final {
32public:
33 ScopeInit() { 32 ScopeInit() {
34 Core::Timing::Init(); 33 core_timing.Initialize();
35 } 34 }
36 ~ScopeInit() { 35 ~ScopeInit() {
37 Core::Timing::Shutdown(); 36 core_timing.Shutdown();
38 } 37 }
38
39 Core::Timing::CoreTiming core_timing;
39}; 40};
40 41
41static void AdvanceAndCheck(u32 idx, int downcount, int expected_lateness = 0, 42static void AdvanceAndCheck(Core::Timing::CoreTiming& core_timing, u32 idx, int downcount,
42 int cpu_downcount = 0) { 43 int expected_lateness = 0, int cpu_downcount = 0) {
43 callbacks_ran_flags = 0; 44 callbacks_ran_flags = 0;
44 expected_callback = CB_IDS[idx]; 45 expected_callback = CB_IDS[idx];
45 lateness = expected_lateness; 46 lateness = expected_lateness;
46 47
47 // Pretend we executed X cycles of instructions. 48 // Pretend we executed X cycles of instructions.
48 Core::Timing::AddTicks(Core::Timing::GetDowncount() - cpu_downcount); 49 core_timing.AddTicks(core_timing.GetDowncount() - cpu_downcount);
49 Core::Timing::Advance(); 50 core_timing.Advance();
50 51
51 REQUIRE(decltype(callbacks_ran_flags)().set(idx) == callbacks_ran_flags); 52 REQUIRE(decltype(callbacks_ran_flags)().set(idx) == callbacks_ran_flags);
52 REQUIRE(downcount == Core::Timing::GetDowncount()); 53 REQUIRE(downcount == core_timing.GetDowncount());
53} 54}
54 55
55TEST_CASE("CoreTiming[BasicOrder]", "[core]") { 56TEST_CASE("CoreTiming[BasicOrder]", "[core]") {
56 ScopeInit guard; 57 ScopeInit guard;
58 auto& core_timing = guard.core_timing;
57 59
58 Core::Timing::EventType* cb_a = Core::Timing::RegisterEvent("callbackA", CallbackTemplate<0>); 60 Core::Timing::EventType* cb_a = core_timing.RegisterEvent("callbackA", CallbackTemplate<0>);
59 Core::Timing::EventType* cb_b = Core::Timing::RegisterEvent("callbackB", CallbackTemplate<1>); 61 Core::Timing::EventType* cb_b = core_timing.RegisterEvent("callbackB", CallbackTemplate<1>);
60 Core::Timing::EventType* cb_c = Core::Timing::RegisterEvent("callbackC", CallbackTemplate<2>); 62 Core::Timing::EventType* cb_c = core_timing.RegisterEvent("callbackC", CallbackTemplate<2>);
61 Core::Timing::EventType* cb_d = Core::Timing::RegisterEvent("callbackD", CallbackTemplate<3>); 63 Core::Timing::EventType* cb_d = core_timing.RegisterEvent("callbackD", CallbackTemplate<3>);
62 Core::Timing::EventType* cb_e = Core::Timing::RegisterEvent("callbackE", CallbackTemplate<4>); 64 Core::Timing::EventType* cb_e = core_timing.RegisterEvent("callbackE", CallbackTemplate<4>);
63 65
64 // Enter slice 0 66 // Enter slice 0
65 Core::Timing::Advance(); 67 core_timing.Advance();
66 68
67 // D -> B -> C -> A -> E 69 // D -> B -> C -> A -> E
68 Core::Timing::ScheduleEvent(1000, cb_a, CB_IDS[0]); 70 core_timing.ScheduleEvent(1000, cb_a, CB_IDS[0]);
69 REQUIRE(1000 == Core::Timing::GetDowncount()); 71 REQUIRE(1000 == core_timing.GetDowncount());
70 Core::Timing::ScheduleEvent(500, cb_b, CB_IDS[1]); 72 core_timing.ScheduleEvent(500, cb_b, CB_IDS[1]);
71 REQUIRE(500 == Core::Timing::GetDowncount()); 73 REQUIRE(500 == core_timing.GetDowncount());
72 Core::Timing::ScheduleEvent(800, cb_c, CB_IDS[2]); 74 core_timing.ScheduleEvent(800, cb_c, CB_IDS[2]);
73 REQUIRE(500 == Core::Timing::GetDowncount()); 75 REQUIRE(500 == core_timing.GetDowncount());
74 Core::Timing::ScheduleEvent(100, cb_d, CB_IDS[3]); 76 core_timing.ScheduleEvent(100, cb_d, CB_IDS[3]);
75 REQUIRE(100 == Core::Timing::GetDowncount()); 77 REQUIRE(100 == core_timing.GetDowncount());
76 Core::Timing::ScheduleEvent(1200, cb_e, CB_IDS[4]); 78 core_timing.ScheduleEvent(1200, cb_e, CB_IDS[4]);
77 REQUIRE(100 == Core::Timing::GetDowncount()); 79 REQUIRE(100 == core_timing.GetDowncount());
78 80
79 AdvanceAndCheck(3, 400); 81 AdvanceAndCheck(core_timing, 3, 400);
80 AdvanceAndCheck(1, 300); 82 AdvanceAndCheck(core_timing, 1, 300);
81 AdvanceAndCheck(2, 200); 83 AdvanceAndCheck(core_timing, 2, 200);
82 AdvanceAndCheck(0, 200); 84 AdvanceAndCheck(core_timing, 0, 200);
83 AdvanceAndCheck(4, MAX_SLICE_LENGTH); 85 AdvanceAndCheck(core_timing, 4, MAX_SLICE_LENGTH);
84} 86}
85 87
86TEST_CASE("CoreTiming[Threadsave]", "[core]") { 88TEST_CASE("CoreTiming[Threadsave]", "[core]") {
87 ScopeInit guard; 89 ScopeInit guard;
90 auto& core_timing = guard.core_timing;
88 91
89 Core::Timing::EventType* cb_a = Core::Timing::RegisterEvent("callbackA", CallbackTemplate<0>); 92 Core::Timing::EventType* cb_a = core_timing.RegisterEvent("callbackA", CallbackTemplate<0>);
90 Core::Timing::EventType* cb_b = Core::Timing::RegisterEvent("callbackB", CallbackTemplate<1>); 93 Core::Timing::EventType* cb_b = core_timing.RegisterEvent("callbackB", CallbackTemplate<1>);
91 Core::Timing::EventType* cb_c = Core::Timing::RegisterEvent("callbackC", CallbackTemplate<2>); 94 Core::Timing::EventType* cb_c = core_timing.RegisterEvent("callbackC", CallbackTemplate<2>);
92 Core::Timing::EventType* cb_d = Core::Timing::RegisterEvent("callbackD", CallbackTemplate<3>); 95 Core::Timing::EventType* cb_d = core_timing.RegisterEvent("callbackD", CallbackTemplate<3>);
93 Core::Timing::EventType* cb_e = Core::Timing::RegisterEvent("callbackE", CallbackTemplate<4>); 96 Core::Timing::EventType* cb_e = core_timing.RegisterEvent("callbackE", CallbackTemplate<4>);
94 97
95 // Enter slice 0 98 // Enter slice 0
96 Core::Timing::Advance(); 99 core_timing.Advance();
97 100
98 // D -> B -> C -> A -> E 101 // D -> B -> C -> A -> E
99 Core::Timing::ScheduleEventThreadsafe(1000, cb_a, CB_IDS[0]); 102 core_timing.ScheduleEventThreadsafe(1000, cb_a, CB_IDS[0]);
100 // Manually force since ScheduleEventThreadsafe doesn't call it 103 // Manually force since ScheduleEventThreadsafe doesn't call it
101 Core::Timing::ForceExceptionCheck(1000); 104 core_timing.ForceExceptionCheck(1000);
102 REQUIRE(1000 == Core::Timing::GetDowncount()); 105 REQUIRE(1000 == core_timing.GetDowncount());
103 Core::Timing::ScheduleEventThreadsafe(500, cb_b, CB_IDS[1]); 106 core_timing.ScheduleEventThreadsafe(500, cb_b, CB_IDS[1]);
104 // Manually force since ScheduleEventThreadsafe doesn't call it 107 // Manually force since ScheduleEventThreadsafe doesn't call it
105 Core::Timing::ForceExceptionCheck(500); 108 core_timing.ForceExceptionCheck(500);
106 REQUIRE(500 == Core::Timing::GetDowncount()); 109 REQUIRE(500 == core_timing.GetDowncount());
107 Core::Timing::ScheduleEventThreadsafe(800, cb_c, CB_IDS[2]); 110 core_timing.ScheduleEventThreadsafe(800, cb_c, CB_IDS[2]);
108 // Manually force since ScheduleEventThreadsafe doesn't call it 111 // Manually force since ScheduleEventThreadsafe doesn't call it
109 Core::Timing::ForceExceptionCheck(800); 112 core_timing.ForceExceptionCheck(800);
110 REQUIRE(500 == Core::Timing::GetDowncount()); 113 REQUIRE(500 == core_timing.GetDowncount());
111 Core::Timing::ScheduleEventThreadsafe(100, cb_d, CB_IDS[3]); 114 core_timing.ScheduleEventThreadsafe(100, cb_d, CB_IDS[3]);
112 // Manually force since ScheduleEventThreadsafe doesn't call it 115 // Manually force since ScheduleEventThreadsafe doesn't call it
113 Core::Timing::ForceExceptionCheck(100); 116 core_timing.ForceExceptionCheck(100);
114 REQUIRE(100 == Core::Timing::GetDowncount()); 117 REQUIRE(100 == core_timing.GetDowncount());
115 Core::Timing::ScheduleEventThreadsafe(1200, cb_e, CB_IDS[4]); 118 core_timing.ScheduleEventThreadsafe(1200, cb_e, CB_IDS[4]);
116 // Manually force since ScheduleEventThreadsafe doesn't call it 119 // Manually force since ScheduleEventThreadsafe doesn't call it
117 Core::Timing::ForceExceptionCheck(1200); 120 core_timing.ForceExceptionCheck(1200);
118 REQUIRE(100 == Core::Timing::GetDowncount()); 121 REQUIRE(100 == core_timing.GetDowncount());
119 122
120 AdvanceAndCheck(3, 400); 123 AdvanceAndCheck(core_timing, 3, 400);
121 AdvanceAndCheck(1, 300); 124 AdvanceAndCheck(core_timing, 1, 300);
122 AdvanceAndCheck(2, 200); 125 AdvanceAndCheck(core_timing, 2, 200);
123 AdvanceAndCheck(0, 200); 126 AdvanceAndCheck(core_timing, 0, 200);
124 AdvanceAndCheck(4, MAX_SLICE_LENGTH); 127 AdvanceAndCheck(core_timing, 4, MAX_SLICE_LENGTH);
125} 128}
126 129
127namespace SharedSlotTest { 130namespace SharedSlotTest {
@@ -142,59 +145,62 @@ TEST_CASE("CoreTiming[SharedSlot]", "[core]") {
142 using namespace SharedSlotTest; 145 using namespace SharedSlotTest;
143 146
144 ScopeInit guard; 147 ScopeInit guard;
148 auto& core_timing = guard.core_timing;
145 149
146 Core::Timing::EventType* cb_a = Core::Timing::RegisterEvent("callbackA", FifoCallback<0>); 150 Core::Timing::EventType* cb_a = core_timing.RegisterEvent("callbackA", FifoCallback<0>);
147 Core::Timing::EventType* cb_b = Core::Timing::RegisterEvent("callbackB", FifoCallback<1>); 151 Core::Timing::EventType* cb_b = core_timing.RegisterEvent("callbackB", FifoCallback<1>);
148 Core::Timing::EventType* cb_c = Core::Timing::RegisterEvent("callbackC", FifoCallback<2>); 152 Core::Timing::EventType* cb_c = core_timing.RegisterEvent("callbackC", FifoCallback<2>);
149 Core::Timing::EventType* cb_d = Core::Timing::RegisterEvent("callbackD", FifoCallback<3>); 153 Core::Timing::EventType* cb_d = core_timing.RegisterEvent("callbackD", FifoCallback<3>);
150 Core::Timing::EventType* cb_e = Core::Timing::RegisterEvent("callbackE", FifoCallback<4>); 154 Core::Timing::EventType* cb_e = core_timing.RegisterEvent("callbackE", FifoCallback<4>);
151 155
152 Core::Timing::ScheduleEvent(1000, cb_a, CB_IDS[0]); 156 core_timing.ScheduleEvent(1000, cb_a, CB_IDS[0]);
153 Core::Timing::ScheduleEvent(1000, cb_b, CB_IDS[1]); 157 core_timing.ScheduleEvent(1000, cb_b, CB_IDS[1]);
154 Core::Timing::ScheduleEvent(1000, cb_c, CB_IDS[2]); 158 core_timing.ScheduleEvent(1000, cb_c, CB_IDS[2]);
155 Core::Timing::ScheduleEvent(1000, cb_d, CB_IDS[3]); 159 core_timing.ScheduleEvent(1000, cb_d, CB_IDS[3]);
156 Core::Timing::ScheduleEvent(1000, cb_e, CB_IDS[4]); 160 core_timing.ScheduleEvent(1000, cb_e, CB_IDS[4]);
157 161
158 // Enter slice 0 162 // Enter slice 0
159 Core::Timing::Advance(); 163 core_timing.Advance();
160 REQUIRE(1000 == Core::Timing::GetDowncount()); 164 REQUIRE(1000 == core_timing.GetDowncount());
161 165
162 callbacks_ran_flags = 0; 166 callbacks_ran_flags = 0;
163 counter = 0; 167 counter = 0;
164 lateness = 0; 168 lateness = 0;
165 Core::Timing::AddTicks(Core::Timing::GetDowncount()); 169 core_timing.AddTicks(core_timing.GetDowncount());
166 Core::Timing::Advance(); 170 core_timing.Advance();
167 REQUIRE(MAX_SLICE_LENGTH == Core::Timing::GetDowncount()); 171 REQUIRE(MAX_SLICE_LENGTH == core_timing.GetDowncount());
168 REQUIRE(0x1FULL == callbacks_ran_flags.to_ullong()); 172 REQUIRE(0x1FULL == callbacks_ran_flags.to_ullong());
169} 173}
170 174
171TEST_CASE("Core::Timing[PredictableLateness]", "[core]") { 175TEST_CASE("Core::Timing[PredictableLateness]", "[core]") {
172 ScopeInit guard; 176 ScopeInit guard;
177 auto& core_timing = guard.core_timing;
173 178
174 Core::Timing::EventType* cb_a = Core::Timing::RegisterEvent("callbackA", CallbackTemplate<0>); 179 Core::Timing::EventType* cb_a = core_timing.RegisterEvent("callbackA", CallbackTemplate<0>);
175 Core::Timing::EventType* cb_b = Core::Timing::RegisterEvent("callbackB", CallbackTemplate<1>); 180 Core::Timing::EventType* cb_b = core_timing.RegisterEvent("callbackB", CallbackTemplate<1>);
176 181
177 // Enter slice 0 182 // Enter slice 0
178 Core::Timing::Advance(); 183 core_timing.Advance();
179 184
180 Core::Timing::ScheduleEvent(100, cb_a, CB_IDS[0]); 185 core_timing.ScheduleEvent(100, cb_a, CB_IDS[0]);
181 Core::Timing::ScheduleEvent(200, cb_b, CB_IDS[1]); 186 core_timing.ScheduleEvent(200, cb_b, CB_IDS[1]);
182 187
183 AdvanceAndCheck(0, 90, 10, -10); // (100 - 10) 188 AdvanceAndCheck(core_timing, 0, 90, 10, -10); // (100 - 10)
184 AdvanceAndCheck(1, MAX_SLICE_LENGTH, 50, -50); 189 AdvanceAndCheck(core_timing, 1, MAX_SLICE_LENGTH, 50, -50);
185} 190}
186 191
187namespace ChainSchedulingTest { 192namespace ChainSchedulingTest {
188static int reschedules = 0; 193static int reschedules = 0;
189 194
190static void RescheduleCallback(u64 userdata, s64 cycles_late) { 195static void RescheduleCallback(Core::Timing::CoreTiming& core_timing, u64 userdata,
196 s64 cycles_late) {
191 --reschedules; 197 --reschedules;
192 REQUIRE(reschedules >= 0); 198 REQUIRE(reschedules >= 0);
193 REQUIRE(lateness == cycles_late); 199 REQUIRE(lateness == cycles_late);
194 200
195 if (reschedules > 0) { 201 if (reschedules > 0) {
196 Core::Timing::ScheduleEvent(1000, reinterpret_cast<Core::Timing::EventType*>(userdata), 202 core_timing.ScheduleEvent(1000, reinterpret_cast<Core::Timing::EventType*>(userdata),
197 userdata); 203 userdata);
198 } 204 }
199} 205}
200} // namespace ChainSchedulingTest 206} // namespace ChainSchedulingTest
@@ -203,36 +209,39 @@ TEST_CASE("CoreTiming[ChainScheduling]", "[core]") {
203 using namespace ChainSchedulingTest; 209 using namespace ChainSchedulingTest;
204 210
205 ScopeInit guard; 211 ScopeInit guard;
212 auto& core_timing = guard.core_timing;
206 213
207 Core::Timing::EventType* cb_a = Core::Timing::RegisterEvent("callbackA", CallbackTemplate<0>); 214 Core::Timing::EventType* cb_a = core_timing.RegisterEvent("callbackA", CallbackTemplate<0>);
208 Core::Timing::EventType* cb_b = Core::Timing::RegisterEvent("callbackB", CallbackTemplate<1>); 215 Core::Timing::EventType* cb_b = core_timing.RegisterEvent("callbackB", CallbackTemplate<1>);
209 Core::Timing::EventType* cb_c = Core::Timing::RegisterEvent("callbackC", CallbackTemplate<2>); 216 Core::Timing::EventType* cb_c = core_timing.RegisterEvent("callbackC", CallbackTemplate<2>);
210 Core::Timing::EventType* cb_rs = 217 Core::Timing::EventType* cb_rs = core_timing.RegisterEvent(
211 Core::Timing::RegisterEvent("callbackReschedule", RescheduleCallback); 218 "callbackReschedule", [&core_timing](u64 userdata, s64 cycles_late) {
219 RescheduleCallback(core_timing, userdata, cycles_late);
220 });
212 221
213 // Enter slice 0 222 // Enter slice 0
214 Core::Timing::Advance(); 223 core_timing.Advance();
215 224
216 Core::Timing::ScheduleEvent(800, cb_a, CB_IDS[0]); 225 core_timing.ScheduleEvent(800, cb_a, CB_IDS[0]);
217 Core::Timing::ScheduleEvent(1000, cb_b, CB_IDS[1]); 226 core_timing.ScheduleEvent(1000, cb_b, CB_IDS[1]);
218 Core::Timing::ScheduleEvent(2200, cb_c, CB_IDS[2]); 227 core_timing.ScheduleEvent(2200, cb_c, CB_IDS[2]);
219 Core::Timing::ScheduleEvent(1000, cb_rs, reinterpret_cast<u64>(cb_rs)); 228 core_timing.ScheduleEvent(1000, cb_rs, reinterpret_cast<u64>(cb_rs));
220 REQUIRE(800 == Core::Timing::GetDowncount()); 229 REQUIRE(800 == core_timing.GetDowncount());
221 230
222 reschedules = 3; 231 reschedules = 3;
223 AdvanceAndCheck(0, 200); // cb_a 232 AdvanceAndCheck(core_timing, 0, 200); // cb_a
224 AdvanceAndCheck(1, 1000); // cb_b, cb_rs 233 AdvanceAndCheck(core_timing, 1, 1000); // cb_b, cb_rs
225 REQUIRE(2 == reschedules); 234 REQUIRE(2 == reschedules);
226 235
227 Core::Timing::AddTicks(Core::Timing::GetDowncount()); 236 core_timing.AddTicks(core_timing.GetDowncount());
228 Core::Timing::Advance(); // cb_rs 237 core_timing.Advance(); // cb_rs
229 REQUIRE(1 == reschedules); 238 REQUIRE(1 == reschedules);
230 REQUIRE(200 == Core::Timing::GetDowncount()); 239 REQUIRE(200 == core_timing.GetDowncount());
231 240
232 AdvanceAndCheck(2, 800); // cb_c 241 AdvanceAndCheck(core_timing, 2, 800); // cb_c
233 242
234 Core::Timing::AddTicks(Core::Timing::GetDowncount()); 243 core_timing.AddTicks(core_timing.GetDowncount());
235 Core::Timing::Advance(); // cb_rs 244 core_timing.Advance(); // cb_rs
236 REQUIRE(0 == reschedules); 245 REQUIRE(0 == reschedules);
237 REQUIRE(MAX_SLICE_LENGTH == Core::Timing::GetDowncount()); 246 REQUIRE(MAX_SLICE_LENGTH == core_timing.GetDowncount());
238} 247}