summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorGravatar Fernando Sahmkow2020-02-09 16:53:22 -0400
committerGravatar Fernando Sahmkow2020-06-18 16:29:17 -0400
commit234b5ff6a999d7d69cdcdf214e0c3984cdab11cf (patch)
tree4f0ef41d7738b53d1b81ac2f7072bec1ba5fe8f1 /src
parentTests: Add base tests to host timing (diff)
downloadyuzu-234b5ff6a999d7d69cdcdf214e0c3984cdab11cf.tar.gz
yuzu-234b5ff6a999d7d69cdcdf214e0c3984cdab11cf.tar.xz
yuzu-234b5ff6a999d7d69cdcdf214e0c3984cdab11cf.zip
Common: Implement WallClock Interface and implement a native clock for x64
Diffstat (limited to 'src')
-rw-r--r--src/common/CMakeLists.txt4
-rw-r--r--src/common/wall_clock.cpp90
-rw-r--r--src/common/wall_clock.h40
-rw-r--r--src/common/x64/cpu_detect.cpp33
-rw-r--r--src/common/x64/cpu_detect.h12
-rw-r--r--src/common/x64/native_clock.cpp128
-rw-r--r--src/common/x64/native_clock.h41
-rw-r--r--src/core/host_timing.cpp21
-rw-r--r--src/core/host_timing.h4
-rw-r--r--src/tests/core/host_timing.cpp45
10 files changed, 378 insertions, 40 deletions
diff --git a/src/common/CMakeLists.txt b/src/common/CMakeLists.txt
index 554d6e253..aacea0ab7 100644
--- a/src/common/CMakeLists.txt
+++ b/src/common/CMakeLists.txt
@@ -167,6 +167,8 @@ add_library(common STATIC
167 vector_math.h 167 vector_math.h
168 virtual_buffer.cpp 168 virtual_buffer.cpp
169 virtual_buffer.h 169 virtual_buffer.h
170 wall_clock.cpp
171 wall_clock.h
170 web_result.h 172 web_result.h
171 zstd_compression.cpp 173 zstd_compression.cpp
172 zstd_compression.h 174 zstd_compression.h
@@ -177,6 +179,8 @@ if(ARCHITECTURE_x86_64)
177 PRIVATE 179 PRIVATE
178 x64/cpu_detect.cpp 180 x64/cpu_detect.cpp
179 x64/cpu_detect.h 181 x64/cpu_detect.h
182 x64/native_clock.cpp
183 x64/native_clock.h
180 x64/xbyak_abi.h 184 x64/xbyak_abi.h
181 x64/xbyak_util.h 185 x64/xbyak_util.h
182 ) 186 )
diff --git a/src/common/wall_clock.cpp b/src/common/wall_clock.cpp
new file mode 100644
index 000000000..eabbba9da
--- /dev/null
+++ b/src/common/wall_clock.cpp
@@ -0,0 +1,90 @@
1// Copyright 2020 yuzu Emulator Project
2// Licensed under GPLv2 or any later version
3// Refer to the license.txt file included.
4
5#include "common/uint128.h"
6#include "common/wall_clock.h"
7
8#ifdef ARCHITECTURE_x86_64
9#include "common/x64/cpu_detect.h"
10#include "common/x64/native_clock.h"
11#endif
12
13namespace Common {
14
15using base_timer = std::chrono::steady_clock;
16using base_time_point = std::chrono::time_point<base_timer>;
17
18class StandardWallClock : public WallClock {
19public:
20 StandardWallClock(u64 emulated_cpu_frequency, u64 emulated_clock_frequency)
21 : WallClock(emulated_cpu_frequency, emulated_clock_frequency, false) {
22 start_time = base_timer::now();
23 }
24
25 std::chrono::nanoseconds GetTimeNS() override {
26 base_time_point current = base_timer::now();
27 auto elapsed = current - start_time;
28 return std::chrono::duration_cast<std::chrono::nanoseconds>(elapsed);
29 }
30
31 std::chrono::microseconds GetTimeUS() override {
32 base_time_point current = base_timer::now();
33 auto elapsed = current - start_time;
34 return std::chrono::duration_cast<std::chrono::microseconds>(elapsed);
35 }
36
37 std::chrono::milliseconds GetTimeMS() override {
38 base_time_point current = base_timer::now();
39 auto elapsed = current - start_time;
40 return std::chrono::duration_cast<std::chrono::milliseconds>(elapsed);
41 }
42
43 u64 GetClockCycles() override {
44 std::chrono::nanoseconds time_now = GetTimeNS();
45 const u128 temporal = Common::Multiply64Into128(time_now.count(), emulated_clock_frequency);
46 return Common::Divide128On32(temporal, 1000000000).first;
47 }
48
49 u64 GetCPUCycles() override {
50 std::chrono::nanoseconds time_now = GetTimeNS();
51 const u128 temporal = Common::Multiply64Into128(time_now.count(), emulated_cpu_frequency);
52 return Common::Divide128On32(temporal, 1000000000).first;
53 }
54
55private:
56 base_time_point start_time;
57};
58
59#ifdef ARCHITECTURE_x86_64
60
61WallClock* CreateBestMatchingClock(u32 emulated_cpu_frequency, u32 emulated_clock_frequency) {
62 const auto& caps = GetCPUCaps();
63 u64 rtsc_frequency = 0;
64 if (caps.invariant_tsc) {
65 if (caps.base_frequency != 0) {
66 rtsc_frequency = static_cast<u64>(caps.base_frequency) * 1000000U;
67 }
68 if (rtsc_frequency == 0) {
69 rtsc_frequency = EstimateRDTSCFrequency();
70 }
71 }
72 if (rtsc_frequency == 0) {
73 return static_cast<WallClock*>(
74 new StandardWallClock(emulated_cpu_frequency, emulated_clock_frequency));
75 } else {
76 return static_cast<WallClock*>(
77 new X64::NativeClock(emulated_cpu_frequency, emulated_clock_frequency, rtsc_frequency));
78 }
79}
80
81#else
82
83WallClock* CreateBestMatchingClock(u32 emulated_cpu_frequency, u32 emulated_clock_frequency) {
84 return static_cast<WallClock*>(
85 new StandardWallClock(emulated_cpu_frequency, emulated_clock_frequency));
86}
87
88#endif
89
90} // namespace Common
diff --git a/src/common/wall_clock.h b/src/common/wall_clock.h
new file mode 100644
index 000000000..6f763d74b
--- /dev/null
+++ b/src/common/wall_clock.h
@@ -0,0 +1,40 @@
1// Copyright 2020 yuzu Emulator Project
2// Licensed under GPLv2 or any later version
3// Refer to the license.txt file included.
4
5#pragma once
6
7#include <chrono>
8
9#include "common/common_types.h"
10
11namespace Common {
12
13class WallClock {
14public:
15 virtual std::chrono::nanoseconds GetTimeNS() = 0;
16 virtual std::chrono::microseconds GetTimeUS() = 0;
17 virtual std::chrono::milliseconds GetTimeMS() = 0;
18 virtual u64 GetClockCycles() = 0;
19 virtual u64 GetCPUCycles() = 0;
20
21 /// Tells if the wall clock, uses the host CPU's hardware clock
22 bool IsNative() const {
23 return is_native;
24 }
25
26protected:
27 WallClock(u64 emulated_cpu_frequency, u64 emulated_clock_frequency, bool is_native)
28 : emulated_cpu_frequency{emulated_cpu_frequency},
29 emulated_clock_frequency{emulated_clock_frequency}, is_native{is_native} {}
30
31 u64 emulated_cpu_frequency;
32 u64 emulated_clock_frequency;
33
34private:
35 bool is_native;
36};
37
38WallClock* CreateBestMatchingClock(u32 emulated_cpu_frequency, u32 emulated_clock_frequency);
39
40} // namespace Common
diff --git a/src/common/x64/cpu_detect.cpp b/src/common/x64/cpu_detect.cpp
index c9349a6b4..d767c544c 100644
--- a/src/common/x64/cpu_detect.cpp
+++ b/src/common/x64/cpu_detect.cpp
@@ -62,6 +62,17 @@ static CPUCaps Detect() {
62 std::memcpy(&caps.brand_string[0], &cpu_id[1], sizeof(int)); 62 std::memcpy(&caps.brand_string[0], &cpu_id[1], sizeof(int));
63 std::memcpy(&caps.brand_string[4], &cpu_id[3], sizeof(int)); 63 std::memcpy(&caps.brand_string[4], &cpu_id[3], sizeof(int));
64 std::memcpy(&caps.brand_string[8], &cpu_id[2], sizeof(int)); 64 std::memcpy(&caps.brand_string[8], &cpu_id[2], sizeof(int));
65 if (cpu_id[1] == 0x756e6547 && cpu_id[2] == 0x6c65746e && cpu_id[3] == 0x49656e69)
66 caps.manufacturer = Manufacturer::Intel;
67 else if (cpu_id[1] == 0x68747541 && cpu_id[2] == 0x444d4163 && cpu_id[3] == 0x69746e65)
68 caps.manufacturer = Manufacturer::AMD;
69 else if (cpu_id[1] == 0x6f677948 && cpu_id[2] == 0x656e6975 && cpu_id[3] == 0x6e65476e)
70 caps.manufacturer = Manufacturer::Hygon;
71 else
72 caps.manufacturer = Manufacturer::Unknown;
73
74 u32 family = {};
75 u32 model = {};
65 76
66 __cpuid(cpu_id, 0x80000000); 77 __cpuid(cpu_id, 0x80000000);
67 78
@@ -73,6 +84,14 @@ static CPUCaps Detect() {
73 // Detect family and other miscellaneous features 84 // Detect family and other miscellaneous features
74 if (max_std_fn >= 1) { 85 if (max_std_fn >= 1) {
75 __cpuid(cpu_id, 0x00000001); 86 __cpuid(cpu_id, 0x00000001);
87 family = (cpu_id[0] >> 8) & 0xf;
88 model = (cpu_id[0] >> 4) & 0xf;
89 if (family == 0xf) {
90 family += (cpu_id[0] >> 20) & 0xff;
91 }
92 if (family >= 6) {
93 model += ((cpu_id[0] >> 16) & 0xf) << 4;
94 }
76 95
77 if ((cpu_id[3] >> 25) & 1) 96 if ((cpu_id[3] >> 25) & 1)
78 caps.sse = true; 97 caps.sse = true;
@@ -130,6 +149,20 @@ static CPUCaps Detect() {
130 caps.fma4 = true; 149 caps.fma4 = true;
131 } 150 }
132 151
152 if (max_ex_fn >= 0x80000007) {
153 __cpuid(cpu_id, 0x80000007);
154 if (cpu_id[3] & (1 << 8)) {
155 caps.invariant_tsc = true;
156 }
157 }
158
159 if (max_std_fn >= 0x16) {
160 __cpuid(cpu_id, 0x16);
161 caps.base_frequency = cpu_id[0];
162 caps.max_frequency = cpu_id[1];
163 caps.bus_frequency = cpu_id[2];
164 }
165
133 return caps; 166 return caps;
134} 167}
135 168
diff --git a/src/common/x64/cpu_detect.h b/src/common/x64/cpu_detect.h
index 20f2ba234..f0676fa5e 100644
--- a/src/common/x64/cpu_detect.h
+++ b/src/common/x64/cpu_detect.h
@@ -6,8 +6,16 @@
6 6
7namespace Common { 7namespace Common {
8 8
9enum class Manufacturer : u32 {
10 Intel = 0,
11 AMD = 1,
12 Hygon = 2,
13 Unknown = 3,
14};
15
9/// x86/x64 CPU capabilities that may be detected by this module 16/// x86/x64 CPU capabilities that may be detected by this module
10struct CPUCaps { 17struct CPUCaps {
18 Manufacturer manufacturer;
11 char cpu_string[0x21]; 19 char cpu_string[0x21];
12 char brand_string[0x41]; 20 char brand_string[0x41];
13 bool sse; 21 bool sse;
@@ -24,6 +32,10 @@ struct CPUCaps {
24 bool fma; 32 bool fma;
25 bool fma4; 33 bool fma4;
26 bool aes; 34 bool aes;
35 bool invariant_tsc;
36 u32 base_frequency;
37 u32 max_frequency;
38 u32 bus_frequency;
27}; 39};
28 40
29/** 41/**
diff --git a/src/common/x64/native_clock.cpp b/src/common/x64/native_clock.cpp
new file mode 100644
index 000000000..c799111fd
--- /dev/null
+++ b/src/common/x64/native_clock.cpp
@@ -0,0 +1,128 @@
1// Copyright 2020 yuzu Emulator Project
2// Licensed under GPLv2 or any later version
3// Refer to the license.txt file included.
4
5#include <chrono>
6#include <thread>
7
8#ifdef _MSC_VER
9#include <intrin.h>
10#else
11#include <x86intrin.h>
12#endif
13
14#include "common/x64/native_clock.h"
15
16namespace Common {
17
18#ifdef _MSC_VER
19
20namespace {
21
22struct uint128 {
23 u64 low;
24 u64 high;
25};
26
27u64 umuldiv64(u64 a, u64 b, u64 d) {
28 uint128 r{};
29 r.low = _umul128(a, b, &r.high);
30 u64 remainder;
31 return _udiv128(r.high, r.low, d, &remainder);
32}
33
34} // namespace
35
36#else
37
38namespace {
39
40u64 umuldiv64(u64 a, u64 b, u64 d) {
41 const u64 diva = a / d;
42 const u64 moda = a % d;
43 const u64 divb = b / d;
44 const u64 modb = b % d;
45 return diva * b + moda * divb + moda * modb / d;
46}
47
48} // namespace
49
50#endif
51
52u64 EstimateRDTSCFrequency() {
53 const auto milli_10 = std::chrono::milliseconds{10};
54 // get current time
55 _mm_mfence();
56 const u64 tscStart = __rdtsc();
57 const auto startTime = std::chrono::high_resolution_clock::now();
58 // wait roughly 3 seconds
59 while (true) {
60 auto milli = std::chrono::duration_cast<std::chrono::milliseconds>(
61 std::chrono::high_resolution_clock::now() - startTime);
62 if (milli.count() >= 3000)
63 break;
64 std::this_thread::sleep_for(milli_10);
65 }
66 const auto endTime = std::chrono::high_resolution_clock::now();
67 _mm_mfence();
68 const u64 tscEnd = __rdtsc();
69 // calculate difference
70 const u64 timer_diff =
71 std::chrono::duration_cast<std::chrono::nanoseconds>(endTime - startTime).count();
72 const u64 tsc_diff = tscEnd - tscStart;
73 const u64 tsc_freq = umuldiv64(tsc_diff, 1000000000ULL, timer_diff);
74 return tsc_freq;
75}
76
77namespace X64 {
78NativeClock::NativeClock(u64 emulated_cpu_frequency, u64 emulated_clock_frequency,
79 u64 rtsc_frequency)
80 : WallClock(emulated_cpu_frequency, emulated_clock_frequency, true), rtsc_frequency{
81 rtsc_frequency} {
82 _mm_mfence();
83 last_measure = __rdtsc();
84 accumulated_ticks = 0U;
85}
86
87u64 NativeClock::GetRTSC() {
88 rtsc_serialize.lock();
89 _mm_mfence();
90 const u64 current_measure = __rdtsc();
91 u64 diff = current_measure - last_measure;
92 diff = diff & ~static_cast<u64>(static_cast<s64>(diff) >> 63); // max(diff, 0)
93 if (current_measure > last_measure) {
94 last_measure = current_measure;
95 }
96 accumulated_ticks += diff;
97 rtsc_serialize.unlock();
98 return accumulated_ticks;
99}
100
101std::chrono::nanoseconds NativeClock::GetTimeNS() {
102 const u64 rtsc_value = GetRTSC();
103 return std::chrono::nanoseconds{umuldiv64(rtsc_value, 1000000000, rtsc_frequency)};
104}
105
106std::chrono::microseconds NativeClock::GetTimeUS() {
107 const u64 rtsc_value = GetRTSC();
108 return std::chrono::microseconds{umuldiv64(rtsc_value, 1000000, rtsc_frequency)};
109}
110
111std::chrono::milliseconds NativeClock::GetTimeMS() {
112 const u64 rtsc_value = GetRTSC();
113 return std::chrono::milliseconds{umuldiv64(rtsc_value, 1000, rtsc_frequency)};
114}
115
116u64 NativeClock::GetClockCycles() {
117 const u64 rtsc_value = GetRTSC();
118 return umuldiv64(rtsc_value, emulated_clock_frequency, rtsc_frequency);
119}
120
121u64 NativeClock::GetCPUCycles() {
122 const u64 rtsc_value = GetRTSC();
123 return umuldiv64(rtsc_value, emulated_cpu_frequency, rtsc_frequency);
124}
125
126} // namespace X64
127
128} // namespace Common
diff --git a/src/common/x64/native_clock.h b/src/common/x64/native_clock.h
new file mode 100644
index 000000000..b58cf9f5a
--- /dev/null
+++ b/src/common/x64/native_clock.h
@@ -0,0 +1,41 @@
1// Copyright 2020 yuzu Emulator Project
2// Licensed under GPLv2 or any later version
3// Refer to the license.txt file included.
4
5#pragma once
6
7#include <optional>
8
9#include "common/spin_lock.h"
10#include "common/wall_clock.h"
11
12namespace Common {
13
14namespace X64 {
15class NativeClock : public WallClock {
16public:
17 NativeClock(u64 emulated_cpu_frequency, u64 emulated_clock_frequency, u64 rtsc_frequency);
18
19 std::chrono::nanoseconds GetTimeNS() override;
20
21 std::chrono::microseconds GetTimeUS() override;
22
23 std::chrono::milliseconds GetTimeMS() override;
24
25 u64 GetClockCycles() override;
26
27 u64 GetCPUCycles() override;
28
29private:
30 u64 GetRTSC();
31
32 SpinLock rtsc_serialize{};
33 u64 last_measure{};
34 u64 accumulated_ticks{};
35 u64 rtsc_frequency;
36};
37} // namespace X64
38
39u64 EstimateRDTSCFrequency();
40
41} // namespace Common
diff --git a/src/core/host_timing.cpp b/src/core/host_timing.cpp
index d9514b2c5..ef9977b76 100644
--- a/src/core/host_timing.cpp
+++ b/src/core/host_timing.cpp
@@ -35,7 +35,11 @@ struct CoreTiming::Event {
35 } 35 }
36}; 36};
37 37
38CoreTiming::CoreTiming() = default; 38CoreTiming::CoreTiming() {
39 Common::WallClock* wall = Common::CreateBestMatchingClock(Core::Timing::BASE_CLOCK_RATE, Core::Timing::CNTFREQ);
40 clock = std::unique_ptr<Common::WallClock>(wall);
41}
42
39CoreTiming::~CoreTiming() = default; 43CoreTiming::~CoreTiming() = default;
40 44
41void CoreTiming::ThreadEntry(CoreTiming& instance) { 45void CoreTiming::ThreadEntry(CoreTiming& instance) {
@@ -46,7 +50,6 @@ void CoreTiming::Initialize() {
46 event_fifo_id = 0; 50 event_fifo_id = 0;
47 const auto empty_timed_callback = [](u64, s64) {}; 51 const auto empty_timed_callback = [](u64, s64) {};
48 ev_lost = CreateEvent("_lost_event", empty_timed_callback); 52 ev_lost = CreateEvent("_lost_event", empty_timed_callback);
49 start_time = std::chrono::steady_clock::now();
50 timer_thread = std::make_unique<std::thread>(ThreadEntry, std::ref(*this)); 53 timer_thread = std::make_unique<std::thread>(ThreadEntry, std::ref(*this));
51} 54}
52 55
@@ -108,13 +111,11 @@ void CoreTiming::UnscheduleEvent(const std::shared_ptr<EventType>& event_type, u
108} 111}
109 112
110u64 CoreTiming::GetCPUTicks() const { 113u64 CoreTiming::GetCPUTicks() const {
111 std::chrono::nanoseconds time_now = GetGlobalTimeNs(); 114 return clock->GetCPUCycles();
112 return Core::Timing::nsToCycles(time_now);
113} 115}
114 116
115u64 CoreTiming::GetClockTicks() const { 117u64 CoreTiming::GetClockTicks() const {
116 std::chrono::nanoseconds time_now = GetGlobalTimeNs(); 118 return clock->GetClockCycles();
117 return Core::Timing::nsToClockCycles(time_now);
118} 119}
119 120
120void CoreTiming::ClearPendingEvents() { 121void CoreTiming::ClearPendingEvents() {
@@ -174,15 +175,11 @@ void CoreTiming::Advance() {
174} 175}
175 176
176std::chrono::nanoseconds CoreTiming::GetGlobalTimeNs() const { 177std::chrono::nanoseconds CoreTiming::GetGlobalTimeNs() const {
177 sys_time_point current = std::chrono::steady_clock::now(); 178 return clock->GetTimeNS();
178 auto elapsed = current - start_time;
179 return std::chrono::duration_cast<std::chrono::nanoseconds>(elapsed);
180} 179}
181 180
182std::chrono::microseconds CoreTiming::GetGlobalTimeUs() const { 181std::chrono::microseconds CoreTiming::GetGlobalTimeUs() const {
183 sys_time_point current = std::chrono::steady_clock::now(); 182 return clock->GetTimeUS();
184 auto elapsed = current - start_time;
185 return std::chrono::duration_cast<std::chrono::microseconds>(elapsed);
186} 183}
187 184
188} // namespace Core::Timing 185} // namespace Core::Timing
diff --git a/src/core/host_timing.h b/src/core/host_timing.h
index 1d053a7fa..f04a150ee 100644
--- a/src/core/host_timing.h
+++ b/src/core/host_timing.h
@@ -17,12 +17,12 @@
17#include "common/spin_lock.h" 17#include "common/spin_lock.h"
18#include "common/thread.h" 18#include "common/thread.h"
19#include "common/threadsafe_queue.h" 19#include "common/threadsafe_queue.h"
20#include "common/wall_clock.h"
20 21
21namespace Core::HostTiming { 22namespace Core::HostTiming {
22 23
23/// A callback that may be scheduled for a particular core timing event. 24/// A callback that may be scheduled for a particular core timing event.
24using TimedCallback = std::function<void(u64 userdata, s64 cycles_late)>; 25using TimedCallback = std::function<void(u64 userdata, s64 cycles_late)>;
25using sys_time_point = std::chrono::time_point<std::chrono::steady_clock>;
26 26
27/// Contains the characteristics of a particular event. 27/// Contains the characteristics of a particular event.
28struct EventType { 28struct EventType {
@@ -112,7 +112,7 @@ private:
112 static void ThreadEntry(CoreTiming& instance); 112 static void ThreadEntry(CoreTiming& instance);
113 void Advance(); 113 void Advance();
114 114
115 sys_time_point start_time; 115 std::unique_ptr<Common::WallClock> clock;
116 116
117 u64 global_timer = 0; 117 u64 global_timer = 0;
118 118
diff --git a/src/tests/core/host_timing.cpp b/src/tests/core/host_timing.cpp
index ca9c8e50a..3d0532d02 100644
--- a/src/tests/core/host_timing.cpp
+++ b/src/tests/core/host_timing.cpp
@@ -17,7 +17,7 @@
17// Numbers are chosen randomly to make sure the correct one is given. 17// Numbers are chosen randomly to make sure the correct one is given.
18static constexpr std::array<u64, 5> CB_IDS{{42, 144, 93, 1026, UINT64_C(0xFFFF7FFFF7FFFF)}}; 18static constexpr std::array<u64, 5> CB_IDS{{42, 144, 93, 1026, UINT64_C(0xFFFF7FFFF7FFFF)}};
19static constexpr int MAX_SLICE_LENGTH = 10000; // Copied from CoreTiming internals 19static constexpr int MAX_SLICE_LENGTH = 10000; // Copied from CoreTiming internals
20static constexpr std::array<u64, 5> calls_order{{2,0,1,4,3}}; 20static constexpr std::array<u64, 5> calls_order{{2, 0, 1, 4, 3}};
21static std::array<s64, 5> delays{}; 21static std::array<s64, 5> delays{};
22 22
23static std::bitset<CB_IDS.size()> callbacks_ran_flags; 23static std::bitset<CB_IDS.size()> callbacks_ran_flags;
@@ -52,16 +52,11 @@ TEST_CASE("HostTiming[BasicOrder]", "[core]") {
52 auto& core_timing = guard.core_timing; 52 auto& core_timing = guard.core_timing;
53 std::vector<std::shared_ptr<Core::HostTiming::EventType>> events; 53 std::vector<std::shared_ptr<Core::HostTiming::EventType>> events;
54 events.resize(5); 54 events.resize(5);
55 events[0] = 55 events[0] = Core::HostTiming::CreateEvent("callbackA", HostCallbackTemplate<0>);
56 Core::HostTiming::CreateEvent("callbackA", HostCallbackTemplate<0>); 56 events[1] = Core::HostTiming::CreateEvent("callbackB", HostCallbackTemplate<1>);
57 events[1] = 57 events[2] = Core::HostTiming::CreateEvent("callbackC", HostCallbackTemplate<2>);
58 Core::HostTiming::CreateEvent("callbackB", HostCallbackTemplate<1>); 58 events[3] = Core::HostTiming::CreateEvent("callbackD", HostCallbackTemplate<3>);
59 events[2] = 59 events[4] = Core::HostTiming::CreateEvent("callbackE", HostCallbackTemplate<4>);
60 Core::HostTiming::CreateEvent("callbackC", HostCallbackTemplate<2>);
61 events[3] =
62 Core::HostTiming::CreateEvent("callbackD", HostCallbackTemplate<3>);
63 events[4] =
64 Core::HostTiming::CreateEvent("callbackE", HostCallbackTemplate<4>);
65 60
66 expected_callback = 0; 61 expected_callback = 0;
67 62
@@ -70,14 +65,15 @@ TEST_CASE("HostTiming[BasicOrder]", "[core]") {
70 u64 one_micro = 1000U; 65 u64 one_micro = 1000U;
71 for (std::size_t i = 0; i < events.size(); i++) { 66 for (std::size_t i = 0; i < events.size(); i++) {
72 u64 order = calls_order[i]; 67 u64 order = calls_order[i];
73 core_timing.ScheduleEvent(i*one_micro + 100U, events[order], CB_IDS[order]); 68 core_timing.ScheduleEvent(i * one_micro + 100U, events[order], CB_IDS[order]);
74 } 69 }
75 /// test pause 70 /// test pause
76 REQUIRE(callbacks_ran_flags.none()); 71 REQUIRE(callbacks_ran_flags.none());
77 72
78 core_timing.Pause(false); // No need to sync 73 core_timing.Pause(false); // No need to sync
79 74
80 while (core_timing.HasPendingEvents()); 75 while (core_timing.HasPendingEvents())
76 ;
81 77
82 REQUIRE(callbacks_ran_flags.all()); 78 REQUIRE(callbacks_ran_flags.all());
83 79
@@ -106,16 +102,11 @@ TEST_CASE("HostTiming[BasicOrderNoPausing]", "[core]") {
106 auto& core_timing = guard.core_timing; 102 auto& core_timing = guard.core_timing;
107 std::vector<std::shared_ptr<Core::HostTiming::EventType>> events; 103 std::vector<std::shared_ptr<Core::HostTiming::EventType>> events;
108 events.resize(5); 104 events.resize(5);
109 events[0] = 105 events[0] = Core::HostTiming::CreateEvent("callbackA", HostCallbackTemplate<0>);
110 Core::HostTiming::CreateEvent("callbackA", HostCallbackTemplate<0>); 106 events[1] = Core::HostTiming::CreateEvent("callbackB", HostCallbackTemplate<1>);
111 events[1] = 107 events[2] = Core::HostTiming::CreateEvent("callbackC", HostCallbackTemplate<2>);
112 Core::HostTiming::CreateEvent("callbackB", HostCallbackTemplate<1>); 108 events[3] = Core::HostTiming::CreateEvent("callbackD", HostCallbackTemplate<3>);
113 events[2] = 109 events[4] = Core::HostTiming::CreateEvent("callbackE", HostCallbackTemplate<4>);
114 Core::HostTiming::CreateEvent("callbackC", HostCallbackTemplate<2>);
115 events[3] =
116 Core::HostTiming::CreateEvent("callbackD", HostCallbackTemplate<3>);
117 events[4] =
118 Core::HostTiming::CreateEvent("callbackE", HostCallbackTemplate<4>);
119 110
120 core_timing.SyncPause(true); 111 core_timing.SyncPause(true);
121 core_timing.SyncPause(false); 112 core_timing.SyncPause(false);
@@ -126,13 +117,14 @@ TEST_CASE("HostTiming[BasicOrderNoPausing]", "[core]") {
126 u64 one_micro = 1000U; 117 u64 one_micro = 1000U;
127 for (std::size_t i = 0; i < events.size(); i++) { 118 for (std::size_t i = 0; i < events.size(); i++) {
128 u64 order = calls_order[i]; 119 u64 order = calls_order[i];
129 core_timing.ScheduleEvent(i*one_micro + 100U, events[order], CB_IDS[order]); 120 core_timing.ScheduleEvent(i * one_micro + 100U, events[order], CB_IDS[order]);
130 } 121 }
131 u64 end = core_timing.GetGlobalTimeNs().count(); 122 u64 end = core_timing.GetGlobalTimeNs().count();
132 const double scheduling_time = static_cast<double>(end - start); 123 const double scheduling_time = static_cast<double>(end - start);
133 const double timer_time = static_cast<double>(TestTimerSpeed(core_timing)); 124 const double timer_time = static_cast<double>(TestTimerSpeed(core_timing));
134 125
135 while (core_timing.HasPendingEvents()); 126 while (core_timing.HasPendingEvents())
127 ;
136 128
137 REQUIRE(callbacks_ran_flags.all()); 129 REQUIRE(callbacks_ran_flags.all());
138 130
@@ -146,5 +138,6 @@ TEST_CASE("HostTiming[BasicOrderNoPausing]", "[core]") {
146 const double micro = scheduling_time / 1000.0f; 138 const double micro = scheduling_time / 1000.0f;
147 const double mili = micro / 1000.0f; 139 const double mili = micro / 1000.0f;
148 printf("HostTimer No Pausing Scheduling Time: %.3f %.6f\n", micro, mili); 140 printf("HostTimer No Pausing Scheduling Time: %.3f %.6f\n", micro, mili);
149 printf("HostTimer No Pausing Timer Time: %.3f %.6f\n", timer_time / 1000.f, timer_time / 1000000.f); 141 printf("HostTimer No Pausing Timer Time: %.3f %.6f\n", timer_time / 1000.f,
142 timer_time / 1000000.f);
150} 143}