GCC Code Coverage Report


Directory: ./
File: firmware/libfirmware/util/include/rusefi/rusefi_time_wraparound.h
Date: 2025-10-03 00:57:22
Coverage Exec Excl Total
Lines: 100.0% 7 0 7
Functions: 100.0% 1 0 1
Branches: -% 0 0 0
Decisions: -% 0 - 0

Line Branch Decision Exec Source
1 #pragma once
2
3 #include <rusefi/rusefi_time_types.h>
4
5 // custom start value could be useful for testing
6 #ifndef WRAP_AROUND_INITIAL_UPPER
7 #define WRAP_AROUND_INITIAL_UPPER 0
8 #endif
9
10 /**
11 * Provide a 62-bit counter from a 32-bit counter source that wraps around.
12 *
13 * If you'd like it use it with a 16-bit counter, shift the source by 16 before passing it here.
14 * This class is thread/interrupt-safe.
15 */
16 struct WrapAround62 {
17 10028 uint64_t update(uint32_t source) {
18 // Shift cannot be 31, as we wouldn't be able to tell if time is moving forward or
19 // backward relative to m_upper. We do need to handle both directions as our
20 // "thread" can be racing with other "threads" in sampling stamp and updating
21 // m_upper.
22 10028 constexpr unsigned shift = 30;
23
24 10028 uint32_t upper = m_upper;
25 10028 uint32_t relative_unsigned = source - (upper << shift);
26 10028 upper += int32_t(relative_unsigned) >> shift;
27 10028 m_upper = upper;
28
29 // Yes we could just do upper<<shift, but then the result would span both halves of
30 // the 64-bit result. Doing it this way means we only operate on one half at a
31 // time. Source will supply those bits anyways, so we don't need them from
32 // upper...
33 10028 return (efitick_t(upper >> (32 - shift)) << 32) | source;
34 }
35
36 private:
37 volatile uint32_t m_upper = WRAP_AROUND_INITIAL_UPPER;
38 };
39