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.*/
22typedef uint64_t monotime;
23
24/* Retrieve counter of micro-seconds relative to an arbitrary point in time. */
25extern monotime (*getMonotonicUs)(void);
26
27typedef 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.) */
36const char *monotonicInit();
37
38/* Return a string indicating the type of monotonic clock being used. */
39const char *monotonicInfoString();
40
41/* Return the type of monotonic clock being used. */
42monotonic_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 */
49static inline void elapsedStart(monotime *start_time) {
50 *start_time = getMonotonicUs();
51}
52
53static inline uint64_t elapsedUs(monotime start_time) {
54 return getMonotonicUs() - start_time;
55}
56
57static inline uint64_t elapsedMs(monotime start_time) {
58 return elapsedUs(start_time) / 1000;
59}
60
61#endif
62