1/* 2 * Copyright (c) 2000-2001,2003-2004,2011,2014 Apple Inc. All Rights Reserved. 3 * 4 * @APPLE_LICENSE_HEADER_START@ 5 * 6 * This file contains Original Code and/or Modifications of Original Code 7 * as defined in and that are subject to the Apple Public Source License 8 * Version 2.0 (the 'License'). You may not use this file except in 9 * compliance with the License. Please obtain a copy of the License at 10 * http://www.opensource.apple.com/apsl/ and read it before using this 11 * file. 12 * 13 * The Original Code and all software distributed under the License are 14 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER 15 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, 16 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, 17 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. 18 * Please see the License for the specific language governing rights and 19 * limitations under the License. 20 * 21 * @APPLE_LICENSE_HEADER_END@ 22 */ 23 24 25// 26// timeflow - abstract view of the flow of time 27// 28// We happily publish both absolute and relative times as floating-point values. 29// Absolute times are off the UNIX Epoch (1/1/1970, midnight). This leaves us about 30// microsecond resolution in Modern Times. 31// 32#ifndef _H_TIMEFLOW 33#define _H_TIMEFLOW 34 35#include <sys/time.h> 36#include <limits.h> 37#include <math.h> // for MAXFLOAT 38 39 40namespace Security { 41namespace Time { 42 43 44// 45// A Time::Interval is a time difference (distance). 46// 47class Interval { 48 friend class Absolute; 49public: 50 Interval() { } 51 Interval(int seconds) { mValue = seconds; } 52 Interval(double seconds) { mValue = seconds; } 53 explicit Interval(time_t seconds) { mValue = seconds; } 54 55 Interval &operator += (Interval rel) { mValue += rel.mValue; return *this; } 56 Interval &operator -= (Interval rel) { mValue -= rel.mValue; return *this; } 57 Interval &operator *= (double f) { mValue *= f; return *this; } 58 Interval &operator /= (double f) { mValue /= f; return *this; } 59 60 bool operator < (Interval other) const { return mValue < other.mValue; } 61 bool operator <= (Interval other) const { return mValue <= other.mValue; } 62 bool operator > (Interval other) const { return mValue > other.mValue; } 63 bool operator >= (Interval other) const { return mValue >= other.mValue; } 64 bool operator == (Interval other) const { return mValue == other.mValue; } 65 bool operator != (Interval other) const { return mValue != other.mValue; } 66 67 // express as (fractions of) seconds, milliseconds, or microseconds 68 double seconds() const { return mValue; } 69 double mSeconds() const { return mValue * 1E3; } 70 double uSeconds() const { return mValue * 1E6; } 71 72 // struct timeval is sometimes used for time intervals, but not often - so be explicit 73 struct timeval timevalInterval() const; 74 75private: 76 double mValue; 77}; 78 79 80// 81// A Time::Absolute is a moment in time. 82// 83class Absolute { 84 friend class Interval; 85 friend Interval operator - (Absolute, Absolute); 86 friend Absolute now(); 87 friend Absolute bigBang(); 88 friend Absolute heatDeath(); 89public: 90 Absolute() { } // uninitialized 91 Absolute(time_t t) { mValue = t; } // from time_t 92 Absolute(const struct timeval &tv); // from timeval 93 Absolute(const struct timespec &ts); // from timespec 94 95 // *crement operators 96 Absolute &operator += (Interval rel) { mValue += rel.mValue; return *this; } 97 Absolute &operator -= (Interval rel) { mValue -= rel.mValue; return *this; } 98 99 // comparisons 100 bool operator < (Absolute other) const { return mValue < other.mValue; } 101 bool operator <= (Absolute other) const { return mValue <= other.mValue; } 102 bool operator > (Absolute other) const { return mValue > other.mValue; } 103 bool operator >= (Absolute other) const { return mValue >= other.mValue; } 104 bool operator == (Absolute other) const { return mValue == other.mValue; } 105 bool operator != (Absolute other) const { return mValue != other.mValue; } 106 107 // express as conventional (absolute!) time measures 108 operator struct timeval() const; 109 operator struct timespec() const; 110 operator time_t () const { return time_t(mValue); } 111 112 // internal form for debugging ONLY 113 double internalForm() const { return mValue; } 114 115private: 116 double mValue; 117 118 Absolute(double value) : mValue(value) { } 119}; 120 121 122// 123// Time::now produces the current time 124// 125Absolute now(); // get "now" 126 127 128// 129// Time::resolution(when) gives a conservative estimate of the available resolution 130// at a given time. 131// 132Interval resolution(Absolute at); // estimate available resolution at given time 133 134 135// 136// Some useful "constants" 137// 138inline Absolute bigBang() { return -MAXFLOAT; } 139inline Absolute heatDeath() { return +MAXFLOAT; } 140 141 142 143// 144// More inline arithmetic 145// 146inline Interval operator + (Interval r, Interval r2) { r += r2; return r; } 147inline Interval operator - (Interval r, Interval r2) { r -= r2; return r; } 148inline Interval operator * (Interval r, double f) { r *= f; return r; } 149inline Interval operator / (Interval r, double f) { r /= f; return r; } 150 151inline Absolute operator + (Absolute a, Interval r) { return a += r; } 152inline Absolute operator + (Interval r, Absolute a) { return a += r; } 153inline Absolute operator - (Absolute a, Interval r) { return a -= r; } 154 155inline Interval operator - (Absolute t1, Absolute t0) 156{ return t1.mValue - t0.mValue; } 157 158 159} // end namespace Time 160} // end namespace Security 161 162#endif //_H_TIMEFLOW 163