1e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko#ifndef ANDROID_DVR_CLOCK_NS_H_
2e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko#define ANDROID_DVR_CLOCK_NS_H_
3e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
4e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko#include <stdint.h>
5e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko#include <time.h>
6e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
7e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkonamespace android {
8e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkonamespace dvr {
9e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
10e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkoconstexpr int64_t kNanosPerSecond = 1000000000ll;
11e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
12e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko// Returns the standard Dream OS monotonic system time that corresponds with all
13e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko// timestamps found in Dream OS APIs.
14e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkostatic inline timespec GetSystemClock() {
15e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  timespec t;
16e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  clock_gettime(CLOCK_MONOTONIC, &t);
17e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  return t;
18e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko}
19e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
20e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkostatic inline timespec GetSystemClockRaw() {
21e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  timespec t;
22e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  clock_gettime(CLOCK_MONOTONIC_RAW, &t);
23e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  return t;
24e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko}
25e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
26e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkostatic inline int64_t GetSystemClockNs() {
27e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  timespec t = GetSystemClock();
28e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  int64_t ns = kNanosPerSecond * (int64_t)t.tv_sec + (int64_t)t.tv_nsec;
29e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  return ns;
30e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko}
31e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
32e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkostatic inline int64_t GetSystemClockRawNs() {
33e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  timespec t = GetSystemClockRaw();
34e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  int64_t ns = kNanosPerSecond * (int64_t)t.tv_sec + (int64_t)t.tv_nsec;
35e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  return ns;
36e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko}
37e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
38e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkostatic inline double NsToSec(int64_t nanoseconds) {
39e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  return nanoseconds / static_cast<double>(kNanosPerSecond);
40e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko}
41e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
42e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkostatic inline double GetSystemClockSec() { return NsToSec(GetSystemClockNs()); }
43e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
44e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkostatic inline double GetSystemClockMs() { return GetSystemClockSec() * 1000.0; }
45e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
46e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko// Converts a nanosecond timestamp to a timespec. Based on the kernel function
47e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko// of the same name.
48e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkostatic inline timespec NsToTimespec(int64_t ns) {
49e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  timespec t;
50e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  int32_t remainder;
51e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
52e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  t.tv_sec = ns / kNanosPerSecond;
53e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  remainder = ns % kNanosPerSecond;
54e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  if (remainder < 0) {
55e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko    t.tv_nsec--;
56e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko    remainder += kNanosPerSecond;
57e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  }
58e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  t.tv_nsec = remainder;
59e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
60e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  return t;
61e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko}
62e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
63e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko// Timestamp comparison functions that handle wrapping values correctly.
64e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkostatic inline bool TimestampLT(int64_t a, int64_t b) {
65e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  return static_cast<int64_t>(static_cast<uint64_t>(a) -
66e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko                              static_cast<uint64_t>(b)) < 0;
67e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko}
68e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkostatic inline bool TimestampLE(int64_t a, int64_t b) {
69e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  return static_cast<int64_t>(static_cast<uint64_t>(a) -
70e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko                              static_cast<uint64_t>(b)) <= 0;
71e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko}
72e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkostatic inline bool TimestampGT(int64_t a, int64_t b) {
73e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  return static_cast<int64_t>(static_cast<uint64_t>(a) -
74e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko                              static_cast<uint64_t>(b)) > 0;
75e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko}
76e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkostatic inline bool TimestampGE(int64_t a, int64_t b) {
77e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  return static_cast<int64_t>(static_cast<uint64_t>(a) -
78e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko                              static_cast<uint64_t>(b)) >= 0;
79e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko}
80e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
81e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko}  // namespace dvr
82e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko}  // namespace android
83e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
84e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko#endif  // ANDROID_DVR_CLOCK_NS_H_
85