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