time.hh revision 8229:78bf55f23338
1/* 2 * Copyright (c) 2003-2005 The Regents of The University of Michigan 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions are 7 * met: redistributions of source code must retain the above copyright 8 * notice, this list of conditions and the following disclaimer; 9 * redistributions in binary form must reproduce the above copyright 10 * notice, this list of conditions and the following disclaimer in the 11 * documentation and/or other materials provided with the distribution; 12 * neither the name of the copyright holders nor the names of its 13 * contributors may be used to endorse or promote products derived from 14 * this software without specific prior written permission. 15 * 16 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 17 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 18 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 19 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 20 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 21 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 22 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 23 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 24 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 26 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 * 28 * Authors: Steve Reinhardt 29 * Nathan Binkert 30 */ 31 32#ifndef __BASE_TIME_HH__ 33#define __BASE_TIME_HH__ 34 35#include <sys/time.h> 36#include <inttypes.h> 37 38#include <cmath> 39#include <cstring> 40#include <ctime> 41#include <iosfwd> 42#include <iostream> 43#include <string> 44 45#include "base/types.hh" 46 47class Checkpoint; 48 49class Time 50{ 51 protected: 52 timespec _time; 53 54 /** 55 * Internal time set function 56 */ 57 void _set(bool monotonic); 58 59 public: 60 static const long NSEC_PER_SEC = 1000 * 1000 * 1000; 61 static const long NSEC_PER_MSEC = 1000 * 1000; 62 static const long NSEC_PER_USEC = 1000; 63 64 public: 65 explicit Time() { clear(); } 66 explicit Time(double sec) { operator=(sec); } 67 Time(const Time &val) : _time(val._time) { } 68 Time(uint64_t sec, uint64_t nsec) { set(sec, nsec); } 69 Time(const timeval &tv) { operator=(tv); } 70 Time(const timespec &ts) { operator=(ts); } 71 72 /** 73 * Accessors for getting and setting the current clock 74 */ 75 time_t sec() const { return _time.tv_sec; } 76 long msec() const { return _time.tv_nsec / NSEC_PER_MSEC; } 77 long usec() const { return _time.tv_nsec / NSEC_PER_USEC; } 78 long nsec() const { return _time.tv_nsec; } 79 80 void sec(time_t sec) { _time.tv_sec = sec; } 81 void msec(long msec) { _time.tv_nsec = msec * NSEC_PER_MSEC; } 82 void usec(long usec) { _time.tv_nsec = usec * NSEC_PER_USEC; } 83 void nsec(long nsec) { _time.tv_nsec = nsec; } 84 85 /** 86 * Clear the time 87 */ 88 void clear() { memset(&_time, 0, sizeof(_time)); } 89 90 /** 91 * Use this to set time for the purposes of time measurement (use 92 * a monotonic clock if it is available 93 */ 94 void setTimer() { _set(true); } 95 96 /** 97 * Use this to set the time to the actual current time 98 */ 99 void setWallclock() { _set(false); } 100 101 /** 102 * Set the current time 103 */ 104 void set(time_t _sec, long _nsec) { sec(_sec); nsec(_nsec); } 105 106 /** 107 * Set the current time from a value measured in Ticks 108 * @param ticks Number of ticks to convert into a time. 109 */ 110 void setTick(Tick ticks); 111 112 /** 113 * Get the current time from a value measured in Ticks 114 * @return Time value measured in Ticks. 115 */ 116 Tick getTick() const; 117 118 const Time & 119 operator=(const Time &other) 120 { 121 sec(other.sec()); 122 nsec(other.nsec()); 123 return *this; 124 } 125 126 const Time & 127 operator=(double new_time) 128 { 129 double seconds = floor(new_time); 130 sec((time_t)seconds); 131 nsec((long)((seconds - new_time) * 1e9)); 132 return *this; 133 } 134 135 const Time & 136 operator=(const timeval &tv) 137 { 138 sec(tv.tv_sec); 139 nsec(tv.tv_usec * 1000); 140 return *this; 141 } 142 143 const Time & 144 operator=(const timespec &ts) 145 { 146 sec(ts.tv_sec); 147 nsec(ts.tv_nsec); 148 return *this; 149 } 150 151 /** 152 * Get the time in floating point seconds 153 */ 154 operator double() const 155 { 156 return (double)sec() + ((double)nsec()) * 1e-9; 157 } 158 159 /** 160 * operators for time conversion 161 */ 162 operator timespec() const { return _time; } 163 operator timeval() const 164 { 165 timeval tv; 166 tv.tv_sec = sec(); 167 tv.tv_usec = usec(); 168 return tv; 169 } 170 171 const Time & 172 operator+=(const Time &other) 173 { 174 175 _time.tv_sec += other.sec(); 176 _time.tv_nsec += other.nsec(); 177 if (_time.tv_nsec > NSEC_PER_SEC) { 178 _time.tv_sec++; 179 _time.tv_nsec -= NSEC_PER_SEC; 180 } 181 182 return *this; 183 } 184 185 const Time & 186 operator-=(const Time &other) 187 { 188 _time.tv_sec -= other.sec(); 189 _time.tv_nsec -= other.nsec(); 190 if (_time.tv_nsec < 0) { 191 _time.tv_sec--; 192 _time.tv_nsec += NSEC_PER_SEC; 193 } 194 195 return *this; 196 } 197 198 std::string date(const std::string &format = "") const; 199 std::string time() const; 200 201 void serialize(const std::string &base, std::ostream &os); 202 void unserialize(const std::string &base, Checkpoint *cp, 203 const std::string §ion); 204}; 205 206void sleep(const Time &time); 207 208inline bool 209operator==(const Time &l, const Time &r) 210{ 211 return l.sec() == r.sec() && l.nsec() == r.nsec(); 212} 213 214inline bool 215operator!=(const Time &l, const Time &r) 216{ 217 return l.sec() != r.sec() || l.nsec() != r.nsec(); 218} 219 220inline bool 221operator<(const Time &l, const Time &r) 222{ 223 return (l.sec() < r.sec()) || 224 (l.sec() == r.sec() && l.nsec() < r.nsec()); 225} 226 227inline bool 228operator<=(const Time &l, const Time &r) 229{ 230 return (l.sec() < r.sec()) || 231 (l.sec() == r.sec() && l.nsec() <= r.nsec()); 232} 233 234inline bool 235operator>(const Time &l, const Time &r) 236{ 237 return (l.sec() > r.sec()) || 238 (l.sec() == r.sec() && l.nsec() > r.nsec()); 239} 240 241inline bool 242operator>=(const Time &l, const Time &r) 243{ 244 return (l.sec() > r.sec()) || 245 (l.sec() == r.sec() && l.nsec() >= r.nsec()); 246} 247 248inline Time 249operator+(const Time &l, const Time &r) 250{ 251 Time time(l); 252 time += r; 253 return time; 254} 255 256inline Time 257operator-(const Time &l, const Time &r) 258{ 259 Time time(l); 260 time -= r; 261 return time; 262} 263 264inline std::ostream & 265operator<<(std::ostream &out, const Time &time) 266{ 267 out << time.date(); 268 return out; 269} 270 271#endif // __BASE_TIME_HH__ 272