Line | Branch | Decision | Exec | Source |
---|---|---|---|---|
1 | #include <rusefi/timer.h> | |||
2 | #include <rusefi/rusefi_time_math.h> | |||
3 | ||||
4 | 11649 | void Timer::reset() { | ||
5 | 11649 | m_lastReset = getTimeNowNt(); | ||
6 | 11649 | } | ||
7 | ||||
8 | 6062 | void Timer::init() { | ||
9 | // Use not-quite-minimum value to avoid overflow | |||
10 | 6062 | m_lastReset = InitialState; | ||
11 | 6062 | } | ||
12 | ||||
13 | 279327 | void Timer::reset(efitick_t const nowNt) { | ||
14 | 279327 | m_lastReset = nowNt; | ||
15 | 279327 | } | ||
16 | ||||
17 | 2203228 | bool Timer::hasElapsedSec(float const seconds) const { | ||
18 | 2203228 | return hasElapsedMs(seconds * 1000); | ||
19 | } | |||
20 | ||||
21 | 2203261 | bool Timer::hasElapsedMs(float const milliseconds) const { | ||
22 | 2203261 | return hasElapsedUs(milliseconds * 1000); | ||
23 | } | |||
24 | ||||
25 | 2203261 | bool Timer::hasElapsedUs(float const microseconds) const { | ||
26 | // Like past has already passed... | |||
27 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 2203261 times.
|
1/2✗ Decision 'true' not taken.
✓ Decision 'false' taken 2203261 times.
|
2203261 | if (microseconds <= 0) { |
28 | ✗ | return true;; | ||
29 | } | |||
30 | ||||
31 | 2203261 | efitick_t const delta{ getTimeNowNt() - m_lastReset }; | ||
32 | ||||
33 | // If larger than 32 bits, timer has certainly expired | |||
34 |
2/2✓ Branch 0 taken 1134154 times.
✓ Branch 1 taken 1069107 times.
|
2/2✓ Decision 'true' taken 1134154 times.
✓ Decision 'false' taken 1069107 times.
|
2203261 | if (delta >= UINT32_MAX) { |
35 | 1134154 | return true; | ||
36 | } | |||
37 | ||||
38 | 1069107 | constexpr float max_32_bit_fit_float{ 4294967295.f }; | ||
39 | ||||
40 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 1069107 times.
|
1/2✗ Decision 'true' not taken.
✓ Decision 'false' taken 1069107 times.
|
1069107 | if (microseconds >= max_32_bit_fit_float) { |
41 | ✗ | auto const ntDouble{ static_cast<double>(microseconds) * US_TO_NT_MULTIPLIER }; | ||
42 | ✗ | return delta > static_cast<efitick_t>(ntDouble); | ||
43 | } | |||
44 | ||||
45 | 1069107 | return static_cast<uint32_t>(delta) > static_cast<uint32_t>(USF2NT(microseconds)); | ||
46 | } | |||
47 | ||||
48 | 3438 | float Timer::getElapsedSeconds() const { | ||
49 | 3438 | return getElapsedSeconds(getTimeNowNt()); | ||
50 | } | |||
51 | ||||
52 | 223595 | float Timer::getElapsedSeconds(efitick_t nowNt) const { | ||
53 | 223595 | return 1.f / US_PER_SECOND_F * getElapsedUs(nowNt); | ||
54 | } | |||
55 | ||||
56 | 6 | float Timer::getElapsedUs() const { | ||
57 | 6 | return getElapsedUs(getTimeNowNt()); | ||
58 | } | |||
59 | ||||
60 | 260909 | uint32_t Timer::getElapsedNt(efitick_t const nowNt) const { | ||
61 | 260909 | int64_t const deltaNt{ nowNt - m_lastReset }; | ||
62 | ||||
63 | // Yes, things can happen slightly in the future if we get a lucky interrupt between | |||
64 | // the timestamp and this subtraction, that updates m_lastReset to what's now "the future", | |||
65 | // resulting in a negative delta. | |||
66 |
2/2✓ Branch 0 taken 985 times.
✓ Branch 1 taken 259924 times.
|
2/2✓ Decision 'true' taken 985 times.
✓ Decision 'false' taken 259924 times.
|
260909 | if (deltaNt < 0) { |
67 | 985 | return 0; | ||
68 | } | |||
69 | ||||
70 |
2/2✓ Branch 0 taken 249515 times.
✓ Branch 1 taken 10409 times.
|
259924 | return deltaNt >= static_cast<int64_t>(UINT32_MAX) ? UINT32_MAX : static_cast<uint32_t>(deltaNt); | |
71 | } | |||
72 | ||||
73 | 260810 | float Timer::getElapsedUs(efitick_t const nowNt) const { | ||
74 | // Wraparound is not considered | |||
75 | 260810 | auto const delta32{ getElapsedNt(nowNt) }; | ||
76 | ||||
77 | // One second at 168mhz is 168 mil of ticks | |||
78 | // float loses precision after 24bit ~ 16777216us; | |||
79 | // 16777216us / 1mil ~ 16.8s. So after 16s we lose precision | |||
80 | // On faster chips precision is lost proportionally | |||
81 | 260810 | constexpr uint32_t max_exact_float_int{ 16777216 }; | ||
82 | 260810 | constexpr uint32_t max_exact_int{ max_exact_float_int * US_TO_NT_MULTIPLIER }; | ||
83 | ||||
84 | // Waited too long, calculate in double to keep precision | |||
85 | // It is not like someone will be unhappy seeing elapsed time being up to 250us higher/lower after 16s | |||
86 | // It is to prevent error accumulation somewhere | |||
87 |
2/2✓ Branch 0 taken 10327 times.
✓ Branch 1 taken 250483 times.
|
2/2✓ Decision 'true' taken 10327 times.
✓ Decision 'false' taken 250483 times.
|
260810 | if (delta32 > max_exact_int) { |
88 | 10327 | auto const delta32f{ static_cast<double>(delta32) }; | ||
89 | 10327 | return static_cast<float>(NT2US(delta32f)); | ||
90 | } | |||
91 | ||||
92 | // Ok less than 16s so can be float for faster calc while keeping precision | |||
93 | 250483 | auto const delta32f{ static_cast<float>(delta32) }; | ||
94 | 250483 | return static_cast<float>(NT2US(delta32f)); | ||
95 | } | |||
96 | ||||
97 | 200225 | float Timer::getElapsedSecondsAndReset(efitick_t const nowNt) { | ||
98 | 200225 | float const result{ getElapsedSeconds(nowNt) }; | ||
99 | ||||
100 | 200225 | reset(nowNt); | ||
101 | ||||
102 | 200225 | return result; | ||
103 | } | |||
104 | ||||
105 | ✗ | [[nodiscard]] efitick_t Timer::get() const { | ||
106 | ✗ | return m_lastReset; | ||
107 | } | |||
108 |