17ec681f3Smrg/* 27ec681f3Smrg * Copyright (C) 2005-2017 The Android Open Source Project 37ec681f3Smrg * 47ec681f3Smrg * Licensed under the Apache License, Version 2.0 (the "License"); 57ec681f3Smrg * you may not use this file except in compliance with the License. 67ec681f3Smrg * You may obtain a copy of the License at 77ec681f3Smrg * 87ec681f3Smrg * http://www.apache.org/licenses/LICENSE-2.0 97ec681f3Smrg * 107ec681f3Smrg * Unless required by applicable law or agreed to in writing, software 117ec681f3Smrg * distributed under the License is distributed on an "AS IS" BASIS, 127ec681f3Smrg * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 137ec681f3Smrg * See the License for the specific language governing permissions and 147ec681f3Smrg * limitations under the License. 157ec681f3Smrg */ 167ec681f3Smrg 177ec681f3Smrg#pragma once 187ec681f3Smrg 197ec681f3Smrg#include <stdint.h> 207ec681f3Smrg#include <time.h> 217ec681f3Smrg 227ec681f3Smrg/* struct log_time is a wire-format variant of struct timespec */ 237ec681f3Smrg#define NS_PER_SEC 1000000000ULL 247ec681f3Smrg#define US_PER_SEC 1000000ULL 257ec681f3Smrg#define MS_PER_SEC 1000ULL 267ec681f3Smrg 277ec681f3Smrg#define LOG_TIME_SEC(t) ((t)->tv_sec) 287ec681f3Smrg/* next power of two after NS_PER_SEC */ 297ec681f3Smrg#define LOG_TIME_NSEC(t) ((t)->tv_nsec & (UINT32_MAX >> 2)) 307ec681f3Smrg 317ec681f3Smrg#ifdef __cplusplus 327ec681f3Smrg 337ec681f3Smrgextern "C" { 347ec681f3Smrg 357ec681f3Smrgstruct log_time { 367ec681f3Smrg public: 377ec681f3Smrg uint32_t tv_sec = 0; /* good to Feb 5 2106 */ 387ec681f3Smrg uint32_t tv_nsec = 0; 397ec681f3Smrg 407ec681f3Smrg static constexpr timespec EPOCH = {0, 0}; 417ec681f3Smrg 427ec681f3Smrg log_time() {} 437ec681f3Smrg explicit log_time(const timespec& T) 447ec681f3Smrg : tv_sec(static_cast<uint32_t>(T.tv_sec)), tv_nsec(static_cast<uint32_t>(T.tv_nsec)) {} 457ec681f3Smrg explicit log_time(uint32_t sec, uint32_t nsec = 0) 467ec681f3Smrg : tv_sec(sec), tv_nsec(nsec) { 477ec681f3Smrg } 487ec681f3Smrg#ifdef __linux__ 497ec681f3Smrg explicit log_time(clockid_t id) { 507ec681f3Smrg timespec T; 517ec681f3Smrg clock_gettime(id, &T); 527ec681f3Smrg tv_sec = static_cast<uint32_t>(T.tv_sec); 537ec681f3Smrg tv_nsec = static_cast<uint32_t>(T.tv_nsec); 547ec681f3Smrg } 557ec681f3Smrg#endif 567ec681f3Smrg /* timespec */ 577ec681f3Smrg bool operator==(const timespec& T) const { 587ec681f3Smrg return (tv_sec == static_cast<uint32_t>(T.tv_sec)) && 597ec681f3Smrg (tv_nsec == static_cast<uint32_t>(T.tv_nsec)); 607ec681f3Smrg } 617ec681f3Smrg bool operator!=(const timespec& T) const { 627ec681f3Smrg return !(*this == T); 637ec681f3Smrg } 647ec681f3Smrg bool operator<(const timespec& T) const { 657ec681f3Smrg return (tv_sec < static_cast<uint32_t>(T.tv_sec)) || 667ec681f3Smrg ((tv_sec == static_cast<uint32_t>(T.tv_sec)) && 677ec681f3Smrg (tv_nsec < static_cast<uint32_t>(T.tv_nsec))); 687ec681f3Smrg } 697ec681f3Smrg bool operator>=(const timespec& T) const { 707ec681f3Smrg return !(*this < T); 717ec681f3Smrg } 727ec681f3Smrg bool operator>(const timespec& T) const { 737ec681f3Smrg return (tv_sec > static_cast<uint32_t>(T.tv_sec)) || 747ec681f3Smrg ((tv_sec == static_cast<uint32_t>(T.tv_sec)) && 757ec681f3Smrg (tv_nsec > static_cast<uint32_t>(T.tv_nsec))); 767ec681f3Smrg } 777ec681f3Smrg bool operator<=(const timespec& T) const { 787ec681f3Smrg return !(*this > T); 797ec681f3Smrg } 807ec681f3Smrg 817ec681f3Smrg /* log_time */ 827ec681f3Smrg bool operator==(const log_time& T) const { 837ec681f3Smrg return (tv_sec == T.tv_sec) && (tv_nsec == T.tv_nsec); 847ec681f3Smrg } 857ec681f3Smrg bool operator!=(const log_time& T) const { 867ec681f3Smrg return !(*this == T); 877ec681f3Smrg } 887ec681f3Smrg bool operator<(const log_time& T) const { 897ec681f3Smrg return (tv_sec < T.tv_sec) || 907ec681f3Smrg ((tv_sec == T.tv_sec) && (tv_nsec < T.tv_nsec)); 917ec681f3Smrg } 927ec681f3Smrg bool operator>=(const log_time& T) const { 937ec681f3Smrg return !(*this < T); 947ec681f3Smrg } 957ec681f3Smrg bool operator>(const log_time& T) const { 967ec681f3Smrg return (tv_sec > T.tv_sec) || 977ec681f3Smrg ((tv_sec == T.tv_sec) && (tv_nsec > T.tv_nsec)); 987ec681f3Smrg } 997ec681f3Smrg bool operator<=(const log_time& T) const { 1007ec681f3Smrg return !(*this > T); 1017ec681f3Smrg } 1027ec681f3Smrg 1037ec681f3Smrg log_time operator-=(const log_time& T) { 1047ec681f3Smrg // No concept of negative time, clamp to EPOCH 1057ec681f3Smrg if (*this <= T) { 1067ec681f3Smrg return *this = log_time(EPOCH); 1077ec681f3Smrg } 1087ec681f3Smrg 1097ec681f3Smrg if (this->tv_nsec < T.tv_nsec) { 1107ec681f3Smrg --this->tv_sec; 1117ec681f3Smrg this->tv_nsec = NS_PER_SEC + this->tv_nsec - T.tv_nsec; 1127ec681f3Smrg } else { 1137ec681f3Smrg this->tv_nsec -= T.tv_nsec; 1147ec681f3Smrg } 1157ec681f3Smrg this->tv_sec -= T.tv_sec; 1167ec681f3Smrg 1177ec681f3Smrg return *this; 1187ec681f3Smrg } 1197ec681f3Smrg log_time operator-(const log_time& T) const { 1207ec681f3Smrg log_time local(*this); 1217ec681f3Smrg return local -= T; 1227ec681f3Smrg } 1237ec681f3Smrg log_time operator+=(const log_time& T) { 1247ec681f3Smrg this->tv_nsec += T.tv_nsec; 1257ec681f3Smrg if (this->tv_nsec >= NS_PER_SEC) { 1267ec681f3Smrg this->tv_nsec -= NS_PER_SEC; 1277ec681f3Smrg ++this->tv_sec; 1287ec681f3Smrg } 1297ec681f3Smrg this->tv_sec += T.tv_sec; 1307ec681f3Smrg 1317ec681f3Smrg return *this; 1327ec681f3Smrg } 1337ec681f3Smrg log_time operator+(const log_time& T) const { 1347ec681f3Smrg log_time local(*this); 1357ec681f3Smrg return local += T; 1367ec681f3Smrg } 1377ec681f3Smrg 1387ec681f3Smrg uint64_t nsec() const { 1397ec681f3Smrg return static_cast<uint64_t>(tv_sec) * NS_PER_SEC + tv_nsec; 1407ec681f3Smrg } 1417ec681f3Smrg uint64_t usec() const { 1427ec681f3Smrg return static_cast<uint64_t>(tv_sec) * US_PER_SEC + 1437ec681f3Smrg tv_nsec / (NS_PER_SEC / US_PER_SEC); 1447ec681f3Smrg } 1457ec681f3Smrg uint64_t msec() const { 1467ec681f3Smrg return static_cast<uint64_t>(tv_sec) * MS_PER_SEC + 1477ec681f3Smrg tv_nsec / (NS_PER_SEC / MS_PER_SEC); 1487ec681f3Smrg } 1497ec681f3Smrg 1507ec681f3Smrg /* Add %#q for the fraction of a second to the standard library functions */ 1517ec681f3Smrg char* strptime(const char* s, const char* format); 1527ec681f3Smrg} __attribute__((__packed__)); 1537ec681f3Smrg} 1547ec681f3Smrg 1557ec681f3Smrg#else /* __cplusplus */ 1567ec681f3Smrg 1577ec681f3Smrgtypedef struct log_time { 1587ec681f3Smrg uint32_t tv_sec; 1597ec681f3Smrg uint32_t tv_nsec; 1607ec681f3Smrg} __attribute__((__packed__)) log_time; 1617ec681f3Smrg 1627ec681f3Smrg#endif /* __cplusplus */ 163