1*6fa2df46SAndroid Build Coastguard Worker // Copyright (C) 2021 The Android Open Source Project
2*6fa2df46SAndroid Build Coastguard Worker //
3*6fa2df46SAndroid Build Coastguard Worker // Licensed under the Apache License, Version 2.0 (the "License");
4*6fa2df46SAndroid Build Coastguard Worker // you may not use this file except in compliance with the License.
5*6fa2df46SAndroid Build Coastguard Worker // You may obtain a copy of the License at
6*6fa2df46SAndroid Build Coastguard Worker //
7*6fa2df46SAndroid Build Coastguard Worker // http://www.apache.org/licenses/LICENSE-2.0
8*6fa2df46SAndroid Build Coastguard Worker //
9*6fa2df46SAndroid Build Coastguard Worker // Unless required by applicable law or agreed to in writing, software
10*6fa2df46SAndroid Build Coastguard Worker // distributed under the License is distributed on an "AS IS" BASIS,
11*6fa2df46SAndroid Build Coastguard Worker // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12*6fa2df46SAndroid Build Coastguard Worker // See the License for the specific language governing permissions and
13*6fa2df46SAndroid Build Coastguard Worker // limitations under the License.
14*6fa2df46SAndroid Build Coastguard Worker
15*6fa2df46SAndroid Build Coastguard Worker #include <ditto/logger.h>
16*6fa2df46SAndroid Build Coastguard Worker #include <ditto/sampler.h>
17*6fa2df46SAndroid Build Coastguard Worker
TimespecToNanos(const timespec & t)18*6fa2df46SAndroid Build Coastguard Worker int64_t TimespecToNanos(const timespec& t) {
19*6fa2df46SAndroid Build Coastguard Worker return t.tv_sec * 1e9 + t.tv_nsec;
20*6fa2df46SAndroid Build Coastguard Worker }
21*6fa2df46SAndroid Build Coastguard Worker
TimespecToDoubleNanos(const timespec & t)22*6fa2df46SAndroid Build Coastguard Worker double TimespecToDoubleNanos(const timespec& t) {
23*6fa2df46SAndroid Build Coastguard Worker return static_cast<double>(TimespecToNanos(t));
24*6fa2df46SAndroid Build Coastguard Worker }
25*6fa2df46SAndroid Build Coastguard Worker
TimespecToNanos(const std::vector<timespec> & tv)26*6fa2df46SAndroid Build Coastguard Worker std::vector<int64_t> TimespecToNanos(const std::vector<timespec>& tv) {
27*6fa2df46SAndroid Build Coastguard Worker std::vector<int64_t> nsv;
28*6fa2df46SAndroid Build Coastguard Worker nsv.reserve(tv.size());
29*6fa2df46SAndroid Build Coastguard Worker for (const auto& it : tv) nsv.push_back(TimespecToNanos(it));
30*6fa2df46SAndroid Build Coastguard Worker return nsv;
31*6fa2df46SAndroid Build Coastguard Worker }
32*6fa2df46SAndroid Build Coastguard Worker
TimespecToDoubleNanos(const std::vector<timespec> & tv)33*6fa2df46SAndroid Build Coastguard Worker std::vector<double> TimespecToDoubleNanos(const std::vector<timespec>& tv) {
34*6fa2df46SAndroid Build Coastguard Worker std::vector<double> nsv;
35*6fa2df46SAndroid Build Coastguard Worker nsv.reserve(tv.size());
36*6fa2df46SAndroid Build Coastguard Worker for (const auto& it : tv) nsv.push_back(TimespecToDoubleNanos(it));
37*6fa2df46SAndroid Build Coastguard Worker return nsv;
38*6fa2df46SAndroid Build Coastguard Worker }
39*6fa2df46SAndroid Build Coastguard Worker
NanosToTimespec(const int64_t t_ns)40*6fa2df46SAndroid Build Coastguard Worker timespec NanosToTimespec(const int64_t t_ns) {
41*6fa2df46SAndroid Build Coastguard Worker timespec result;
42*6fa2df46SAndroid Build Coastguard Worker result.tv_sec = t_ns / 1e9;
43*6fa2df46SAndroid Build Coastguard Worker result.tv_nsec = t_ns % static_cast<int64_t>(1e9);
44*6fa2df46SAndroid Build Coastguard Worker return result;
45*6fa2df46SAndroid Build Coastguard Worker }
46*6fa2df46SAndroid Build Coastguard Worker
MicrosToTimespec(const int64_t t_us)47*6fa2df46SAndroid Build Coastguard Worker timespec MicrosToTimespec(const int64_t t_us) {
48*6fa2df46SAndroid Build Coastguard Worker timespec result;
49*6fa2df46SAndroid Build Coastguard Worker result.tv_sec = t_us / 1e6;
50*6fa2df46SAndroid Build Coastguard Worker result.tv_nsec = (t_us % static_cast<int64_t>(1e6)) * static_cast<int64_t>(1e3);
51*6fa2df46SAndroid Build Coastguard Worker return result;
52*6fa2df46SAndroid Build Coastguard Worker }
53*6fa2df46SAndroid Build Coastguard Worker
operator ==(const timespec & t1,const timespec & t2)54*6fa2df46SAndroid Build Coastguard Worker bool operator==(const timespec& t1, const timespec& t2) {
55*6fa2df46SAndroid Build Coastguard Worker return t1.tv_sec == t2.tv_sec && t1.tv_nsec == t2.tv_nsec;
56*6fa2df46SAndroid Build Coastguard Worker }
57*6fa2df46SAndroid Build Coastguard Worker
operator !=(const timespec & t1,const timespec & t2)58*6fa2df46SAndroid Build Coastguard Worker bool operator!=(const timespec& t1, const timespec& t2) {
59*6fa2df46SAndroid Build Coastguard Worker return !(t1 == t2);
60*6fa2df46SAndroid Build Coastguard Worker }
61*6fa2df46SAndroid Build Coastguard Worker
operator <(const timespec & t1,const timespec & t2)62*6fa2df46SAndroid Build Coastguard Worker bool operator<(const timespec& t1, const timespec& t2) {
63*6fa2df46SAndroid Build Coastguard Worker return ((t1.tv_sec < t2.tv_sec) || (t1.tv_sec == t2.tv_sec && t1.tv_nsec < t2.tv_nsec));
64*6fa2df46SAndroid Build Coastguard Worker }
65*6fa2df46SAndroid Build Coastguard Worker
operator <=(const timespec & t1,const timespec & t2)66*6fa2df46SAndroid Build Coastguard Worker bool operator<=(const timespec& t1, const timespec& t2) {
67*6fa2df46SAndroid Build Coastguard Worker return t1 == t2 || t1 < t2;
68*6fa2df46SAndroid Build Coastguard Worker }
69*6fa2df46SAndroid Build Coastguard Worker
operator >(const timespec & t1,const timespec & t2)70*6fa2df46SAndroid Build Coastguard Worker bool operator>(const timespec& t1, const timespec& t2) {
71*6fa2df46SAndroid Build Coastguard Worker return !(t1 <= t2);
72*6fa2df46SAndroid Build Coastguard Worker }
73*6fa2df46SAndroid Build Coastguard Worker
operator >=(const timespec & t1,const timespec & t2)74*6fa2df46SAndroid Build Coastguard Worker bool operator>=(const timespec& t1, const timespec& t2) {
75*6fa2df46SAndroid Build Coastguard Worker return t1 == t2 || t1 > t2;
76*6fa2df46SAndroid Build Coastguard Worker }
77*6fa2df46SAndroid Build Coastguard Worker
78*6fa2df46SAndroid Build Coastguard Worker // Return the value of t1 - t2, if t1 >= t2 or fail.
operator -(const timespec & t1,const timespec & t2)79*6fa2df46SAndroid Build Coastguard Worker timespec operator-(const timespec& t1, const timespec& t2) {
80*6fa2df46SAndroid Build Coastguard Worker timespec result = {0, 0};
81*6fa2df46SAndroid Build Coastguard Worker if (t1 < t2) {
82*6fa2df46SAndroid Build Coastguard Worker LOGF("Subtraction cannot return negative timespec values");
83*6fa2df46SAndroid Build Coastguard Worker } else {
84*6fa2df46SAndroid Build Coastguard Worker result.tv_sec = t1.tv_sec - t2.tv_sec;
85*6fa2df46SAndroid Build Coastguard Worker if (t1.tv_nsec < t2.tv_nsec) {
86*6fa2df46SAndroid Build Coastguard Worker result.tv_sec--;
87*6fa2df46SAndroid Build Coastguard Worker result.tv_nsec = 1e9 - t2.tv_nsec + t1.tv_nsec;
88*6fa2df46SAndroid Build Coastguard Worker } else {
89*6fa2df46SAndroid Build Coastguard Worker result.tv_nsec = t1.tv_nsec - t2.tv_nsec;
90*6fa2df46SAndroid Build Coastguard Worker }
91*6fa2df46SAndroid Build Coastguard Worker }
92*6fa2df46SAndroid Build Coastguard Worker return result;
93*6fa2df46SAndroid Build Coastguard Worker }
94*6fa2df46SAndroid Build Coastguard Worker
operator +(const timespec & t1,const timespec & t2)95*6fa2df46SAndroid Build Coastguard Worker timespec operator+(const timespec& t1, const timespec& t2) {
96*6fa2df46SAndroid Build Coastguard Worker timespec result = {0, 0};
97*6fa2df46SAndroid Build Coastguard Worker result.tv_sec = t1.tv_sec + t2.tv_sec;
98*6fa2df46SAndroid Build Coastguard Worker if (t1.tv_nsec + t2.tv_nsec >= 1e9) {
99*6fa2df46SAndroid Build Coastguard Worker result.tv_sec++;
100*6fa2df46SAndroid Build Coastguard Worker result.tv_nsec = t1.tv_nsec + t2.tv_nsec - 1e9;
101*6fa2df46SAndroid Build Coastguard Worker } else {
102*6fa2df46SAndroid Build Coastguard Worker result.tv_nsec = t1.tv_nsec + t2.tv_nsec;
103*6fa2df46SAndroid Build Coastguard Worker }
104*6fa2df46SAndroid Build Coastguard Worker return result;
105*6fa2df46SAndroid Build Coastguard Worker }
106*6fa2df46SAndroid Build Coastguard Worker
operator /(const timespec & t1,uint64_t t2_ns)107*6fa2df46SAndroid Build Coastguard Worker timespec operator/(const timespec& t1, uint64_t t2_ns) {
108*6fa2df46SAndroid Build Coastguard Worker if (t2_ns == 0) LOGF("Division by 0 for timespec");
109*6fa2df46SAndroid Build Coastguard Worker
110*6fa2df46SAndroid Build Coastguard Worker auto t1_ns = TimespecToNanos(t1);
111*6fa2df46SAndroid Build Coastguard Worker
112*6fa2df46SAndroid Build Coastguard Worker return NanosToTimespec(t1_ns / t2_ns);
113*6fa2df46SAndroid Build Coastguard Worker }
114*6fa2df46SAndroid Build Coastguard Worker
operator /(const timespec & t1,const timespec & t2)115*6fa2df46SAndroid Build Coastguard Worker timespec operator/(const timespec& t1, const timespec& t2) {
116*6fa2df46SAndroid Build Coastguard Worker return t1 / TimespecToNanos(t2);
117*6fa2df46SAndroid Build Coastguard Worker }
118*6fa2df46SAndroid Build Coastguard Worker
TimespecToString(const timespec & ts)119*6fa2df46SAndroid Build Coastguard Worker std::string TimespecToString(const timespec& ts) {
120*6fa2df46SAndroid Build Coastguard Worker std::stringstream ss;
121*6fa2df46SAndroid Build Coastguard Worker ss << ts.tv_sec << '.' << std::setfill('0') << std::setw(9) << ts.tv_nsec;
122*6fa2df46SAndroid Build Coastguard Worker return ss.str();
123*6fa2df46SAndroid Build Coastguard Worker }
124