| Line | Branch | Decision | Exec | Source |
|---|---|---|---|---|
| 1 | #include <rusefi/timer.h> | |||
| 2 | #include <rusefi/rusefi_time_math.h> | |||
| 3 | ||||
| 4 | 12286 | void Timer::reset() { | ||
| 5 | 12286 | m_lastReset = getTimeNowNt(); | ||
| 6 | 12286 | } | ||
| 7 | ||||
| 8 | 6080 | void Timer::init() { | ||
| 9 | // Use not-quite-minimum value to avoid overflow | |||
| 10 | 6080 | m_lastReset = InitialState; | ||
| 11 | 6080 | } | ||
| 12 | ||||
| 13 | 289743 | void Timer::reset(efitick_t const nowNt) { | ||
| 14 | 289743 | m_lastReset = nowNt; | ||
| 15 | 289743 | } | ||
| 16 | ||||
| 17 | 2318905 | bool Timer::hasElapsedSec(float const seconds) const { | ||
| 18 | 2318905 | return hasElapsedMs(seconds * 1000); | ||
| 19 | } | |||
| 20 | ||||
| 21 | 2318938 | bool Timer::hasElapsedMs(float const milliseconds) const { | ||
| 22 | 2318938 | return hasElapsedUs(milliseconds * 1000); | ||
| 23 | } | |||
| 24 | ||||
| 25 | 2318938 | bool Timer::hasElapsedUs(float const microseconds) const { | ||
| 26 | // Like past has already passed... | |||
| 27 |
2/2✓ Branch 0 taken 60 times.
✓ Branch 1 taken 2318878 times.
|
2/2✓ Decision 'true' taken 60 times.
✓ Decision 'false' taken 2318878 times.
|
2318938 | if (microseconds <= 0) { |
| 28 | 60 | return true;; | ||
| 29 | } | |||
| 30 | ||||
| 31 | 2318878 | efitick_t const delta{ getTimeNowNt() - m_lastReset }; | ||
| 32 | ||||
| 33 | // If larger than 32 bits, timer has certainly expired | |||
| 34 |
2/2✓ Branch 0 taken 1146312 times.
✓ Branch 1 taken 1172566 times.
|
2/2✓ Decision 'true' taken 1146312 times.
✓ Decision 'false' taken 1172566 times.
|
2318878 | if (delta >= UINT32_MAX) { |
| 35 | 1146312 | return true; | ||
| 36 | } | |||
| 37 | ||||
| 38 | 1172566 | constexpr float max_32_bit_fit_float{ 4294967295.f }; | ||
| 39 | ||||
| 40 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 1172566 times.
|
1/2✗ Decision 'true' not taken.
✓ Decision 'false' taken 1172566 times.
|
1172566 | 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 | 1172566 | return static_cast<uint32_t>(delta) > static_cast<uint32_t>(USF2NT(microseconds)); | ||
| 46 | } | |||
| 47 | ||||
| 48 | 3715 | float Timer::getElapsedSeconds() const { | ||
| 49 | 3715 | return getElapsedSeconds(getTimeNowNt()); | ||
| 50 | } | |||
| 51 | ||||
| 52 | 229854 | float Timer::getElapsedSeconds(efitick_t nowNt) const { | ||
| 53 | 229854 | 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 | 270987 | uint32_t Timer::getElapsedNt(efitick_t const nowNt) const { | ||
| 61 | 270987 | 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 990 times.
✓ Branch 1 taken 269997 times.
|
2/2✓ Decision 'true' taken 990 times.
✓ Decision 'false' taken 269997 times.
|
270987 | if (deltaNt < 0) { |
| 67 | 990 | return 0; | ||
| 68 | } | |||
| 69 | ||||
| 70 |
2/2✓ Branch 0 taken 259596 times.
✓ Branch 1 taken 10401 times.
|
269997 | return deltaNt >= static_cast<int64_t>(UINT32_MAX) ? UINT32_MAX : static_cast<uint32_t>(deltaNt); | |
| 71 | } | |||
| 72 | ||||
| 73 | 270888 | float Timer::getElapsedUs(efitick_t const nowNt) const { | ||
| 74 | // Wraparound is not considered | |||
| 75 | 270888 | 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 | 270888 | constexpr uint32_t max_exact_float_int{ 16777216 }; | ||
| 82 | 270888 | 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 10319 times.
✓ Branch 1 taken 260569 times.
|
2/2✓ Decision 'true' taken 10319 times.
✓ Decision 'false' taken 260569 times.
|
270888 | if (delta32 > max_exact_int) { |
| 88 | 10319 | auto const delta32f{ static_cast<double>(delta32) }; | ||
| 89 | 10319 | return static_cast<float>(NT2US(delta32f)); | ||
| 90 | } | |||
| 91 | ||||
| 92 | // Ok less than 16s so can be float for faster calc while keeping precision | |||
| 93 | 260569 | auto const delta32f{ static_cast<float>(delta32) }; | ||
| 94 | 260569 | return static_cast<float>(NT2US(delta32f)); | ||
| 95 | } | |||
| 96 | ||||
| 97 | 205221 | float Timer::getElapsedSecondsAndReset(efitick_t const nowNt) { | ||
| 98 | 205221 | float const result{ getElapsedSeconds(nowNt) }; | ||
| 99 | ||||
| 100 | 205221 | reset(nowNt); | ||
| 101 | ||||
| 102 | 205221 | return result; | ||
| 103 | } | |||
| 104 | ||||
| 105 | ✗ | [[nodiscard]] efitick_t Timer::get() const { | ||
| 106 | ✗ | return m_lastReset; | ||
| 107 | } | |||
| 108 |