1 | #ifndef __MONOTONIC_H |
2 | #define __MONOTONIC_H |
3 | /* The monotonic clock is an always increasing clock source. It is unrelated to |
4 | * the actual time of day and should only be used for relative timings. The |
5 | * monotonic clock is also not guaranteed to be chronologically precise; there |
6 | * may be slight skew/shift from a precise clock. |
7 | * |
8 | * Depending on system architecture, the monotonic time may be able to be |
9 | * retrieved much faster than a normal clock source by using an instruction |
10 | * counter on the CPU. On x86 architectures (for example), the RDTSC |
11 | * instruction is a very fast clock source for this purpose. |
12 | */ |
13 | |
14 | #include "fmacros.h" |
15 | #include <stdint.h> |
16 | #include <unistd.h> |
17 | |
18 | /* A counter in micro-seconds. The 'monotime' type is provided for variables |
19 | * holding a monotonic time. This will help distinguish & document that the |
20 | * variable is associated with the monotonic clock and should not be confused |
21 | * with other types of time.*/ |
22 | typedef uint64_t monotime; |
23 | |
24 | /* Retrieve counter of micro-seconds relative to an arbitrary point in time. */ |
25 | extern monotime (*getMonotonicUs)(void); |
26 | |
27 | typedef enum monotonic_clock_type { |
28 | MONOTONIC_CLOCK_POSIX, |
29 | MONOTONIC_CLOCK_HW, |
30 | } monotonic_clock_type; |
31 | |
32 | /* Call once at startup to initialize the monotonic clock. Though this only |
33 | * needs to be called once, it may be called additional times without impact. |
34 | * Returns a printable string indicating the type of clock initialized. |
35 | * (The returned string is static and doesn't need to be freed.) */ |
36 | const char *monotonicInit(); |
37 | |
38 | /* Return a string indicating the type of monotonic clock being used. */ |
39 | const char *monotonicInfoString(); |
40 | |
41 | /* Return the type of monotonic clock being used. */ |
42 | monotonic_clock_type monotonicGetType(); |
43 | |
44 | /* Functions to measure elapsed time. Example: |
45 | * monotime myTimer; |
46 | * elapsedStart(&myTimer); |
47 | * while (elapsedMs(myTimer) < 10) {} // loops for 10ms |
48 | */ |
49 | static inline void elapsedStart(monotime *start_time) { |
50 | *start_time = getMonotonicUs(); |
51 | } |
52 | |
53 | static inline uint64_t elapsedUs(monotime start_time) { |
54 | return getMonotonicUs() - start_time; |
55 | } |
56 | |
57 | static inline uint64_t elapsedMs(monotime start_time) { |
58 | return elapsedUs(start_time) / 1000; |
59 | } |
60 | |
61 | #endif |
62 | |