From a6f6ed8822b0680794dc24c96c8ebae8f50a5657 Mon Sep 17 00:00:00 2001 From: "Walter F.J. Mueller" Date: Sun, 26 Feb 2017 14:41:22 +0100 Subject: [PATCH] add librtools/Rtime: class for absolute and delta times --- tools/src/librtools/Makefile | 18 +- tools/src/librtools/Rtime.cpp | 125 ++++++++++++++ tools/src/librtools/Rtime.hpp | 92 +++++++++++ tools/src/librtools/Rtime.ipp | 299 ++++++++++++++++++++++++++++++++++ 4 files changed, 528 insertions(+), 6 deletions(-) create mode 100644 tools/src/librtools/Rtime.cpp create mode 100644 tools/src/librtools/Rtime.hpp create mode 100644 tools/src/librtools/Rtime.ipp diff --git a/tools/src/librtools/Makefile b/tools/src/librtools/Makefile index a114c50e..b4518723 100644 --- a/tools/src/librtools/Makefile +++ b/tools/src/librtools/Makefile @@ -1,4 +1,4 @@ -# $Id: Makefile 733 2016-02-20 12:24:13Z mueller $ +# $Id: Makefile 851 2017-02-18 09:20:40Z mueller $ # # Revision History: # Date Rev Version Comment @@ -24,11 +24,17 @@ LDLIBS = -L${BOOSTLIB} -lboost_thread -lboost_system # # Object files to be included # -OBJ_all = RerrMsg.o RosFill.o RosPrintBvi.o RosPrintfBase.o RosPrintfS.o \ - RiosState.o Rbits.o \ - RlogFile.o RlogFileCatalog.o RlogMsg.o \ - Rstats.o Rtools.o \ - Rexception.o RparseUrl.o +OBJ_all = Rbits.o +OBJ_all += RerrMsg.o +OBJ_all += Rexception.o +OBJ_all += RiosState.o +OBJ_all += RlogFile.o RlogFileCatalog.o RlogMsg.o +OBJ_all += RosFill.o +OBJ_all += RosPrintBvi.o RosPrintfBase.o RosPrintfS.o +OBJ_all += RparseUrl.o +OBJ_all += Rstats.o +OBJ_all += Rtime.o +OBJ_all += Rtools.o # DEP_all = $(OBJ_all:.o=.dep) # diff --git a/tools/src/librtools/Rtime.cpp b/tools/src/librtools/Rtime.cpp new file mode 100644 index 00000000..0f319bd9 --- /dev/null +++ b/tools/src/librtools/Rtime.cpp @@ -0,0 +1,125 @@ +// $Id: Rtime.cpp 854 2017-02-25 14:46:03Z mueller $ +// +// Copyright 2017- by Walter F.J. Mueller +// +// This program is free software; you may redistribute and/or modify it under +// the terms of the GNU General Public License as published by the Free +// Software Foundation, either version 2, or at your option any later version. +// +// This program is distributed in the hope that it will be useful, but +// WITHOUT ANY WARRANTY, without even the implied warranty of MERCHANTABILITY +// or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +// for complete details. +// +// Revision History: +// Date Rev Version Comment +// 2017-02-20 854 1.0 Initial version +// --------------------------------------------------------------------------- + +/*! + \file + \version $Id: Rtime.cpp 854 2017-02-25 14:46:03Z mueller $ + \brief Implemenation of Rtime . +*/ +// Note on double conversion precision: +// double has 52 bits mantissa --> 52*log10(2) = 15.6 dig or ~4.e15 res +// --> up to ~4.e6sec or ~ 46days we have 1nsec resolution +// for realclock time stamps: t = ~1.5e9 --> 1/2600000 res --> better 1usec + +#include + +#include + +#include "RosFill.hpp" +#include "RosPrintf.hpp" +#include "Rexception.hpp" + +#include "Rtime.hpp" + +using namespace std; + +/*! + \class Retro::Rtime + \brief FIXME_docs +*/ + +// all method definitions in namespace Retro +namespace Retro { + +//------------------------------------------+----------------------------------- +//! FIXME_docs + +void Rtime::GetClock(clockid_t clkid) +{ + if (::clock_gettime(clkid, &fTime) != 0) { + throw Rexception("Rtime::GetClock()", "clock_gettime() failed: ", errno); + } + return; +} + +//------------------------------------------+----------------------------------- +//! FIXME_docs + +void Rtime::SetNSec(long nsec) +{ + if (nsec < 0 || nsec > 999999999) + throw Rexception("Rtime::SetNSec()", "bad args: <0 or >999999999 "); + fTime.tv_nsec = nsec; +} + +//------------------------------------------+----------------------------------- +//! FIXME_docs + +std::string Rtime::ToString() const +{ + ostringstream sos; + Print(sos); + return sos.str(); +} + +//------------------------------------------+----------------------------------- +//! FIXME_docs + +double Rtime::Age(clockid_t clkid) const +{ + if (IsZero()) return 0.; + Rtime now(clkid); + return double(now - *this); +} + +//------------------------------------------+----------------------------------- +//! FIXME_docs + +void Rtime::Print(std::ostream& os) const +{ + if (fTime.tv_sec < 365*24*3600) { // looks like dt (<1year) + os << RosPrintf(ToDouble(),"f",18,9); + } else { + struct tm tymd; + ::localtime_r(&fTime.tv_sec, &tymd); + os << RosPrintf(tymd.tm_year+1900,"d",4) << "-" + << RosPrintf(tymd.tm_mon+1,"d0",2) << "-" + << RosPrintf(tymd.tm_mday,"d0",2) << " " + << RosPrintf(tymd.tm_hour,"d0",2) << ":" + << RosPrintf(tymd.tm_min,"d0",2) << ":" + << RosPrintf(tymd.tm_sec,"d0",2) << "." + << RosPrintf(fTime.tv_nsec,"d0",9); + } + return; +} + +//------------------------------------------+----------------------------------- +//! FIXME_docs + +void Rtime::Dump(std::ostream& os, int ind, const char* text) const +{ + RosFill bl(ind); + os << bl << (text?text:"--") << "Rtime @ " << this << endl; + os << bl << " fTime: " << RosPrintf(fTime.tv_sec,"d",10) + << "," << RosPrintf(fTime.tv_nsec,"d",9) + << " : " << ToString() << endl; + return; +} + + +} // end namespace Retro diff --git a/tools/src/librtools/Rtime.hpp b/tools/src/librtools/Rtime.hpp new file mode 100644 index 00000000..ee49854c --- /dev/null +++ b/tools/src/librtools/Rtime.hpp @@ -0,0 +1,92 @@ +// $Id: Rtime.hpp 853 2017-02-19 18:54:30Z mueller $ +// +// Copyright 2017- by Walter F.J. Mueller +// +// This program is free software; you may redistribute and/or modify it under +// the terms of the GNU General Public License as published by the Free +// Software Foundation, either version 2, or at your option any later version. +// +// This program is distributed in the hope that it will be useful, but +// WITHOUT ANY WARRANTY, without even the implied warranty of MERCHANTABILITY +// or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +// for complete details. +// +// Revision History: +// Date Rev Version Comment +// 2017-02-19 853 1.0 Initial version +// --------------------------------------------------------------------------- + +/*! + \file + \version $Id: Rtime.hpp 853 2017-02-19 18:54:30Z mueller $ + \brief Declaration of class Rtime . +*/ + +#ifndef included_Retro_Rtime +#define included_Retro_Rtime 1 + +#include + +#include +#include + +namespace Retro { + + class Rtime { + public: + Rtime(); + explicit Rtime(clockid_t clkid); + explicit Rtime(double dt); + ~Rtime(); + + void GetClock(clockid_t clkid); + void SetSec(time_t sec); + void SetNSec(long nsec); + void Set(const struct timespec& ts); + void Set(double dt); + void Clear(); + + bool IsZero() const; + bool IsPositive() const; + bool IsNegative() const; + + time_t Sec() const; + long NSec() const; + const struct timespec& Timespec() const; + int ToMSec() const; + double ToDouble() const; + std::string ToString() const; + double Age(clockid_t clkid) const; + + void Print(std::ostream& os) const; + void Dump(std::ostream& os, int ind=0, const char* text=0) const; + + explicit operator double() const; + + Rtime& operator+=(const Rtime& rhs); + Rtime& operator-=(const Rtime& rhs); + + bool operator==(const Rtime& rhs); + bool operator!=(const Rtime& rhs); + bool operator<(const Rtime& rhs); + bool operator<=(const Rtime& rhs); + bool operator>(const Rtime& rhs); + bool operator>=(const Rtime& rhs); + + protected: + void Fixup(); + + private: + struct timespec fTime; //!< time + }; + + Rtime operator+(const Rtime& x, const Rtime& y); + Rtime operator-(const Rtime& x, const Rtime& y); + + std::ostream& operator<<(std::ostream& os, const Rtime& obj); + +} // end namespace Retro + +#include "Rtime.ipp" + +#endif diff --git a/tools/src/librtools/Rtime.ipp b/tools/src/librtools/Rtime.ipp new file mode 100644 index 00000000..b77ab841 --- /dev/null +++ b/tools/src/librtools/Rtime.ipp @@ -0,0 +1,299 @@ +// $Id: Rtime.ipp 854 2017-02-25 14:46:03Z mueller $ +// +// Copyright 2017- by Walter F.J. Mueller +// +// This program is free software; you may redistribute and/or modify it under +// the terms of the GNU General Public License as published by the Free +// Software Foundation, either version 2, or at your option any later version. +// +// This program is distributed in the hope that it will be useful, but +// WITHOUT ANY WARRANTY, without even the implied warranty of MERCHANTABILITY +// or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +// for complete details. +// +// Revision History: +// Date Rev Version Comment +// 2017-02-20 854 1.0 Initial version +// --------------------------------------------------------------------------- + +/*! + \file + \version $Id: Rtime.ipp 854 2017-02-25 14:46:03Z mueller $ + \brief Implemenation (inline) of Rtime. +*/ + +#include + +// all method definitions in namespace Retro +namespace Retro { + +//------------------------------------------+----------------------------------- +//! Default constructor + +inline Rtime::Rtime() +{ + fTime.tv_sec = 0; + fTime.tv_nsec = 0; +} + +//------------------------------------------+----------------------------------- +//! FIXME_docs + +inline Rtime::Rtime(clockid_t clkid) +{ + GetClock(clkid); +} + +//------------------------------------------+----------------------------------- +//! FIXME_docs + +inline Rtime::Rtime(double dt) +{ + Set(dt); +} + +//------------------------------------------+----------------------------------- +//! Destructor + +inline Rtime::~Rtime() +{} + +//------------------------------------------+----------------------------------- +//! FIXME_docs + +inline void Rtime::SetSec(time_t sec) +{ + fTime.tv_sec = sec; +} + +//------------------------------------------+----------------------------------- +//! FIXME_docs + +inline void Rtime::Set(const struct timespec& ts) +{ + fTime = ts; +} + +//------------------------------------------+----------------------------------- +//! FIXME_docs + +inline void Rtime::Set(double dt) +{ + double nsec = floor(1.e9*dt); + double sec = floor(dt); + fTime.tv_sec = sec; + fTime.tv_nsec = nsec - 1.e9*sec; + return; +} + +//------------------------------------------+----------------------------------- +//! FIXME_docs + +inline void Rtime::Clear() +{ + fTime.tv_sec = 0; + fTime.tv_nsec = 0; +} + +//------------------------------------------+----------------------------------- +//! FIXME_docs + +inline bool Rtime::IsZero() const +{ + return fTime.tv_sec==0 && fTime.tv_nsec==0; +} + +//------------------------------------------+----------------------------------- +//! FIXME_docs + +inline bool Rtime::IsPositive() const +{ + return fTime.tv_sec > 0 || (fTime.tv_sec == 0 && fTime.tv_nsec > 0); +} + +//------------------------------------------+----------------------------------- +//! FIXME_docs + +inline bool Rtime::IsNegative() const +{ + return fTime.tv_sec < 0; +} + +//------------------------------------------+----------------------------------- +//! FIXME_docs + +inline time_t Rtime::Sec() const +{ + return fTime.tv_sec; +} + +//------------------------------------------+----------------------------------- +//! FIXME_docs + +inline long Rtime::NSec() const +{ + return fTime.tv_nsec; +} + +//------------------------------------------+----------------------------------- +//! FIXME_docs + +inline const struct timespec& Rtime::Timespec() const +{ + return fTime; +} + +//------------------------------------------+----------------------------------- +//! FIXME_docs + +inline int Rtime::ToMSec() const +{ + // round up here !! + return 1000*fTime.tv_sec + (fTime.tv_nsec+999999)/1000000; +} + +//------------------------------------------+----------------------------------- +//! FIXME_docs + +inline double Rtime::ToDouble() const +{ + return double(fTime.tv_sec) + 1.e-9*double(fTime.tv_nsec); +} + +//------------------------------------------+----------------------------------- +//! FIXME_docs + +inline Rtime::operator double() const +{ + return ToDouble(); +} + +//------------------------------------------+----------------------------------- +//! FIXME_docs + +inline Rtime& Rtime::operator+=(const Rtime& rhs) +{ + fTime.tv_sec += rhs.fTime.tv_sec; + fTime.tv_nsec += rhs.fTime.tv_nsec; + Fixup(); + return *this; +} + +//------------------------------------------+----------------------------------- +//! FIXME_docs + +inline Rtime& Rtime::operator-=(const Rtime& rhs) +{ + fTime.tv_sec -= rhs.fTime.tv_sec; + fTime.tv_nsec -= rhs.fTime.tv_nsec; + Fixup(); + return *this; +} + +//------------------------------------------+----------------------------------- +//! FIXME_docs + +inline bool Rtime::operator==(const Rtime& rhs) +{ + return fTime.tv_sec == rhs.fTime.tv_sec && + fTime.tv_nsec == rhs.fTime.tv_nsec; +} + +//------------------------------------------+----------------------------------- +//! FIXME_docs + +inline bool Rtime::operator!=(const Rtime& rhs) +{ + return ! operator==(rhs); +} + +//------------------------------------------+----------------------------------- +//! FIXME_docs + +inline bool Rtime::operator<(const Rtime& rhs) +{ + return fTime.tv_sec < rhs.fTime.tv_sec || + (fTime.tv_sec == rhs.fTime.tv_sec && + fTime.tv_nsec < rhs.fTime.tv_nsec); +} + +//------------------------------------------+----------------------------------- +//! FIXME_docs + +inline bool Rtime::operator<=(const Rtime& rhs) +{ + return fTime.tv_sec < rhs.fTime.tv_sec || + (fTime.tv_sec == rhs.fTime.tv_sec && + fTime.tv_nsec <= rhs.fTime.tv_nsec); +} + +//------------------------------------------+----------------------------------- +//! FIXME_docs + +inline bool Rtime::operator>(const Rtime& rhs) +{ + return !operator<=(rhs); +} + +//------------------------------------------+----------------------------------- +//! FIXME_docs + +inline bool Rtime::operator>=(const Rtime& rhs) +{ + return !operator<(rhs); +} + +//------------------------------------------+----------------------------------- +//! FIXME_docs + +inline void Rtime::Fixup() +{ + if (fTime.tv_nsec >= 1000000000) { + fTime.tv_nsec -= 1000000000; + fTime.tv_sec += 1; + } else if (fTime.tv_nsec < 0) { + fTime.tv_nsec += 1000000000; + fTime.tv_sec -= 1; + } + return; +} + +//------------------------------------------+----------------------------------- +/*! + \relates Rtime + \brief operator+: Rtime + Rtime. +*/ + +inline Rtime operator+(const Rtime& x, const Rtime& y) +{ + Rtime res(x); + res += y; + return res; +} + +//------------------------------------------+----------------------------------- +/*! + \relates Rtime + \brief operator-: Rtime - Rtime. +*/ + +inline Rtime operator-(const Rtime& x, const Rtime& y) +{ + Rtime res(x); + res -= y; + return res; +} + +//------------------------------------------+----------------------------------- +/*! + \relates Rtime + \brief ostream insertion operator. +*/ + +inline std::ostream& operator<<(std::ostream& os, const Rtime& obj) +{ + obj.Print(os); + return os; +} + +} // end namespace Retro