// Copyright (C) 2021 The Android Open Source Project // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. #include #include int64_t TimespecToNanos(const timespec& t) { return t.tv_sec * 1e9 + t.tv_nsec; } double TimespecToDoubleNanos(const timespec& t) { return static_cast(TimespecToNanos(t)); } std::vector TimespecToNanos(const std::vector& tv) { std::vector nsv; nsv.reserve(tv.size()); for (const auto& it : tv) nsv.push_back(TimespecToNanos(it)); return nsv; } std::vector TimespecToDoubleNanos(const std::vector& tv) { std::vector nsv; nsv.reserve(tv.size()); for (const auto& it : tv) nsv.push_back(TimespecToDoubleNanos(it)); return nsv; } timespec NanosToTimespec(const int64_t t_ns) { timespec result; result.tv_sec = t_ns / 1e9; result.tv_nsec = t_ns % static_cast(1e9); return result; } timespec MicrosToTimespec(const int64_t t_us) { timespec result; result.tv_sec = t_us / 1e6; result.tv_nsec = (t_us % static_cast(1e6)) * static_cast(1e3); return result; } bool operator==(const timespec& t1, const timespec& t2) { return t1.tv_sec == t2.tv_sec && t1.tv_nsec == t2.tv_nsec; } bool operator!=(const timespec& t1, const timespec& t2) { return !(t1 == t2); } bool operator<(const timespec& t1, const timespec& t2) { return ((t1.tv_sec < t2.tv_sec) || (t1.tv_sec == t2.tv_sec && t1.tv_nsec < t2.tv_nsec)); } bool operator<=(const timespec& t1, const timespec& t2) { return t1 == t2 || t1 < t2; } bool operator>(const timespec& t1, const timespec& t2) { return !(t1 <= t2); } bool operator>=(const timespec& t1, const timespec& t2) { return t1 == t2 || t1 > t2; } // Return the value of t1 - t2, if t1 >= t2 or fail. timespec operator-(const timespec& t1, const timespec& t2) { timespec result = {0, 0}; if (t1 < t2) { LOGF("Subtraction cannot return negative timespec values"); } else { result.tv_sec = t1.tv_sec - t2.tv_sec; if (t1.tv_nsec < t2.tv_nsec) { result.tv_sec--; result.tv_nsec = 1e9 - t2.tv_nsec + t1.tv_nsec; } else { result.tv_nsec = t1.tv_nsec - t2.tv_nsec; } } return result; } timespec operator+(const timespec& t1, const timespec& t2) { timespec result = {0, 0}; result.tv_sec = t1.tv_sec + t2.tv_sec; if (t1.tv_nsec + t2.tv_nsec >= 1e9) { result.tv_sec++; result.tv_nsec = t1.tv_nsec + t2.tv_nsec - 1e9; } else { result.tv_nsec = t1.tv_nsec + t2.tv_nsec; } return result; } timespec operator/(const timespec& t1, uint64_t t2_ns) { if (t2_ns == 0) LOGF("Division by 0 for timespec"); auto t1_ns = TimespecToNanos(t1); return NanosToTimespec(t1_ns / t2_ns); } timespec operator/(const timespec& t1, const timespec& t2) { return t1 / TimespecToNanos(t2); } std::string TimespecToString(const timespec& ts) { std::stringstream ss; ss << ts.tv_sec << '.' << std::setfill('0') << std::setw(9) << ts.tv_nsec; return ss.str(); }