From 318bfe9d4f4308321dfa923d3da36230fc98d62e Mon Sep 17 00:00:00 2001 From: Nathan Binkert Date: Sat, 15 Jan 2011 07:48:25 -0800 Subject: time: improve time datastructure Use posix clock functions (and librt) if it is available. Inline a bunch of functions and implement more operators. * * * time: more cleanup --- src/base/time.hh | 261 ++++++++++++++++++++++++++++++++++++++++++------------- 1 file changed, 200 insertions(+), 61 deletions(-) (limited to 'src/base/time.hh') diff --git a/src/base/time.hh b/src/base/time.hh index 565ea0aac..2c54f2675 100644 --- a/src/base/time.hh +++ b/src/base/time.hh @@ -29,84 +29,223 @@ * Nathan Binkert */ -#ifndef __SIM_TIME_HH__ -#define __SIM_TIME_HH__ +#ifndef __BASE_TIME_HH__ +#define __BASE_TIME_HH__ #include +#include + +#include +#include +#include #include #include -struct _timeval; - class Time { protected: - mutable _timeval *time; + timespec _time; + + /** + * Internal time set function + */ + void _set(bool monotonic); public: - explicit Time(bool set_now = false); - Time(const timeval &val); - Time(const Time &val); - ~Time(); + static const long NSEC_PER_SEC = 1000 * 1000 * 1000; + static const long NSEC_PER_MSEC = 1000 * 1000; + static const long NSEC_PER_USEC = 1000; - void set(); - const timeval &get() const; - void set(const timeval &val); + public: + explicit Time() { clear(); } + explicit Time(double sec) { operator=(sec); } + Time(const Time &val) : _time(val._time) { } + Time(uint64_t sec, uint64_t nsec) { set(sec, nsec); } + Time(const timeval &tv) { operator=(tv); } + Time(const timespec &ts) { operator=(ts); } - double operator()() const; - std::string date(std::string format = "") const; + /** + * Accessors for getting and setting the current clock + */ + time_t sec() const { return _time.tv_sec; } + long msec() const { return _time.tv_nsec / NSEC_PER_MSEC; } + long usec() const { return _time.tv_nsec / NSEC_PER_USEC; } + long nsec() const { return _time.tv_nsec; } - public: - static const Time start; + void sec(time_t sec) { _time.tv_sec = sec; } + void msec(long msec) { _time.tv_nsec = msec * NSEC_PER_MSEC; } + void usec(long usec) { _time.tv_nsec = usec * NSEC_PER_USEC; } + void nsec(long nsec) { _time.tv_nsec = nsec; } + + /** + * Clear the time + */ + void clear() { memset(&_time, 0, sizeof(_time)); } + + /** + * Use this to set time for the purposes of time measurement (use + * a monotonic clock if it is available + */ + void setTimer() { _set(true); } + + /** + * Use this to set the time to the actual current time + */ + void setWallclock() { _set(false); } + + /** + * Set the current time + */ + void set(time_t _sec, long _nsec) { sec(_sec); nsec(_nsec); } + + const Time & + operator=(const Time &other) + { + sec(other.sec()); + nsec(other.nsec()); + return *this; + } + + const Time & + operator=(double new_time) + { + double seconds = floor(new_time); + sec((time_t)seconds); + nsec((long)((seconds - new_time) * 1e9)); + return *this; + } + + const Time & + operator=(const timeval &tv) + { + sec(tv.tv_sec); + nsec(tv.tv_usec * 1000); + return *this; + } + + const Time & + operator=(const timespec &ts) + { + sec(ts.tv_sec); + nsec(ts.tv_nsec); + return *this; + } + + /** + * Get the time in floating point seconds + */ + operator double() const + { + return (double)sec() + ((double)nsec()) * 1e-9; + } + + /** + * operators for time conversion + */ + operator timespec() const { return _time; } + operator timeval() const + { + timeval tv; + tv.tv_sec = sec(); + tv.tv_usec = usec(); + return tv; + } + + const Time & + operator+=(const Time &other) + { + + _time.tv_sec += other.sec(); + _time.tv_nsec += other.nsec(); + if (_time.tv_nsec > NSEC_PER_SEC) { + _time.tv_sec++; + _time.tv_nsec -= NSEC_PER_SEC; + } + + return *this; + } + + const Time & + operator-=(const Time &other) + { + _time.tv_sec -= other.sec(); + _time.tv_nsec -= other.nsec(); + if (_time.tv_nsec < 0) { + _time.tv_sec--; + _time.tv_nsec += NSEC_PER_SEC; + } + + return *this; + } + + std::string date(const std::string &format = "") const; + std::string time() const; }; -Time operator-(const Time &l, const Time &r); +void sleep(const Time &time); -std::ostream &operator<<(std::ostream &out, const Time &time); +inline bool +operator==(const Time &l, const Time &r) +{ + return l.sec() == r.sec() && l.nsec() == r.nsec(); +} +inline bool +operator!=(const Time &l, const Time &r) +{ + return l.sec() != r.sec() || l.nsec() != r.nsec(); +} -/* - * Copyright (c) 1982, 1986, 1993 - * The Regents of the University of California. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * @(#)time.h 8.2 (Berkeley) 7/10/94 - */ +inline bool +operator<(const Time &l, const Time &r) +{ + return (l.sec() < r.sec()) || + (l.sec() == r.sec() && l.nsec() < r.nsec()); +} + +inline bool +operator<=(const Time &l, const Time &r) +{ + return (l.sec() < r.sec()) || + (l.sec() == r.sec() && l.nsec() <= r.nsec()); +} + +inline bool +operator>(const Time &l, const Time &r) +{ + return (l.sec() > r.sec()) || + (l.sec() == r.sec() && l.nsec() > r.nsec()); +} + +inline bool +operator>=(const Time &l, const Time &r) +{ + return (l.sec() > r.sec()) || + (l.sec() == r.sec() && l.nsec() >= r.nsec()); +} + +inline Time +operator+(const Time &l, const Time &r) +{ + Time time(l); + time += r; + return time; +} + +inline Time +operator-(const Time &l, const Time &r) +{ + Time time(l); + time -= r; + return time; +} + +inline std::ostream & +operator<<(std::ostream &out, const Time &time) +{ + out << time.date(); + return out; +} -#if defined(__sun) -#define timersub(tvp, uvp, vvp) \ - do { \ - (vvp)->tv_sec = (tvp)->tv_sec - (uvp)->tv_sec; \ - (vvp)->tv_usec = (tvp)->tv_usec - (uvp)->tv_usec; \ - if ((vvp)->tv_usec < 0) { \ - (vvp)->tv_sec--; \ - (vvp)->tv_usec += 1000000; \ - } \ - } while (0) -#endif - -#endif // __SIM_TIME_HH__ +#endif // __BASE_TIME_HH__ -- cgit v1.2.3