changeset ed75cee5c793 in /z/repo/m5 details: http://repo.m5sim.org/m5?cmd=changeset;node=ed75cee5c793 description: 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 diffstat: SConstruct | 11 +- src/base/time.cc | 123 +++++++++------------- src/base/time.hh | 261 ++++++++++++++++++++++++++++++++++++----------- src/sim/stat_control.cc | 8 +- 4 files changed, 264 insertions(+), 139 deletions(-) diffs (truncated from 507 to 300 lines): diff -r 9e556fb25900 -r ed75cee5c793 SConstruct --- a/SConstruct Mon Jan 17 18:46:16 2011 -0600 +++ b/SConstruct Sat Jan 15 07:48:25 2011 -0800 @@ -703,6 +703,13 @@ print ' Please install zlib and try again.' Exit(1) +# Check for librt. +have_posix_clock = conf.CheckLib(None, 'clock_nanosleep', 'time.h') or \ + conf.CheckLib('rt', 'clock_nanosleep', 'time.h') + +if not have_posix_clock: + print "Can't find library for POSIX clocks." + # Check for <fenv.h> (C99 FP environment control) have_fenv = conf.CheckHeader('fenv.h', '<>') if not have_fenv: @@ -819,6 +826,7 @@ 'Compile for SSE2 (-msse2) to get IEEE FP on x86 hosts', False), BoolVariable('USE_MYSQL', 'Use MySQL for stats output', have_mysql), + BoolVariable('USE_POSIX_CLOCK', 'Use POSIX Clocks', have_posix_clock), BoolVariable('USE_FENV', 'Use <fenv.h> IEEE mode control', have_fenv), BoolVariable('USE_CHECKER', 'Use checker for detailed CPU models', False), BoolVariable('CP_ANNOTATE', 'Enable critical path annotation capability', False), @@ -828,7 +836,8 @@ # These variables get exported to #defines in config/*.hh (see src/SConscript). export_vars += ['FULL_SYSTEM', 'USE_FENV', 'USE_MYSQL', 'NO_FAST_ALLOC', 'FAST_ALLOC_DEBUG', 'FAST_ALLOC_STATS', - 'SS_COMPATIBLE_FP', 'USE_CHECKER', 'TARGET_ISA', 'CP_ANNOTATE'] + 'SS_COMPATIBLE_FP', 'USE_CHECKER', 'TARGET_ISA', 'CP_ANNOTATE', + 'USE_POSIX_CLOCK' ] ################################################### # diff -r 9e556fb25900 -r ed75cee5c793 src/base/time.cc --- a/src/base/time.cc Mon Jan 17 18:46:16 2011 -0600 +++ b/src/base/time.cc Sat Jan 15 07:48:25 2011 -0800 @@ -28,85 +28,35 @@ * Authors: Nathan Binkert */ -#include <cctype> -#include <cstring> -#include <ctime> #include <iostream> -#include <string> +#include <sstream> #include "base/time.hh" +#include "config/use_posix_clock.hh" using namespace std; -struct _timeval +void +Time::_set(bool monotonic) { +#if USE_POSIX_CLOCK + ::clock_gettime(monotonic ? CLOCK_MONOTONIC : CLOCK_REALTIME, &_time); +#else timeval tv; -}; - -double -convert(const timeval &tv) -{ - return (double)tv.tv_sec + (double)tv.tv_usec / 1000000.0; -} - -Time::Time(bool set_now) -{ - time = new _timeval; - if (set_now) - set(); -} - -Time::Time(const timeval &val) -{ - time = new _timeval; - set(val); -} - -Time::Time(const Time &val) -{ - time = new _timeval; - set(val.get()); -} - -Time::~Time() -{ - delete time; -} - -const timeval & -Time::get() const -{ - return time->tv; -} - -void -Time::set() -{ - ::gettimeofday(&time->tv, NULL); -} - -void -Time::set(const timeval &tv) -{ - memcpy(&time->tv, &tv, sizeof(timeval)); -} - -double -Time::operator()() const -{ - return convert(get()); + ::gettimeofday(&tv, NULL); + operator=(tv); +#endif } string -Time::date(string format) const +Time::date(const string &format) const { - const timeval &tv = get(); - time_t sec = tv.tv_sec; + time_t sec = this->sec(); char buf[256]; if (format.empty()) { #ifdef __SUNPRO_CC - ctime_r(&sec, buf, 256); + ctime_r(&sec, buf, sizeof(buf)); #else ctime_r(&sec, buf); #endif @@ -119,19 +69,44 @@ return buf; } -ostream & -operator<<(ostream &out, const Time &start) +string +Time::time() const { - out << start.date(); - return out; + double time = double(*this); + double secs = fmod(time, 60.0); + double all_mins = floor(time / 60.0); + double mins = fmod(all_mins, 60.0); + double hours = floor(all_mins / 60.0); + + stringstream str; + + if (hours > 0.0) { + if (hours < 10.0) + str << '0'; + str << hours << ':'; + } + + if (mins > 0.0) { + if (mins < 10.0) + str << '0'; + str << mins << ':'; + } + + if (secs < 10.0 && !str.str().empty()) + str << '0'; + str << secs; + + return str.str(); } -Time -operator-(const Time &l, const Time &r) +void +sleep(const Time &time) { - timeval tv; - timersub(&l.get(), &r.get(), &tv); - return tv; + timespec ts = time; + +#if USE_POSIX_CLOCK + clock_nanosleep(CLOCK_MONOTONIC, 0, &ts, NULL); +#else + nanosleep(&ts, NULL); +#endif } - -const Time Time::start(true); diff -r 9e556fb25900 -r ed75cee5c793 src/base/time.hh --- a/src/base/time.hh Mon Jan 17 18:46:16 2011 -0600 +++ b/src/base/time.hh Sat Jan 15 07:48:25 2011 -0800 @@ -29,84 +29,223 @@ * Nathan Binkert */ -#ifndef __SIM_TIME_HH__ -#define __SIM_TIME_HH__ +#ifndef __BASE_TIME_HH__ +#define __BASE_TIME_HH__ #include <sys/time.h> +#include <inttypes.h> + +#include <cmath> +#include <cstring> +#include <ctime> #include <iosfwd> #include <string> -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(); - - void set(); - const timeval &get() const; - void set(const timeval &val); - - double operator()() const; - std::string date(std::string format = "") const; + static const long NSEC_PER_SEC = 1000 * 1000 * 1000; + static const long NSEC_PER_MSEC = 1000 * 1000; + static const long NSEC_PER_USEC = 1000; public: - static const Time start; + 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); } + + /** + * 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; } + + 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); _______________________________________________ m5-dev mailing list m5-dev@m5sim.org http://m5sim.org/mailman/listinfo/m5-dev