Files
epics-base/src/libCom/osiTime.h

300 lines
6.8 KiB
C++

/*
* $Id$
*
* Author Jeffrey O. Hill
* johill@lanl.gov
* 505 665 1831
*
* Experimental Physics and Industrial Control System (EPICS)
*
* Copyright 1991, the Regents of the University of California,
* and the University of Chicago Board of Governors.
*
* This software was produced under U.S. Government contracts:
* (W-7405-ENG-36) at the Los Alamos National Laboratory,
* and (W-31-109-ENG-38) at Argonne National Laboratory.
*
* Initial development by:
* The Controls and Automation Group (AT-8)
* Ground Test Accelerator
* Accelerator Technology Division
* Los Alamos National Laboratory
*
* Co-developed with
* The Controls and Computing Group
* Accelerator Systems Division
* Advanced Photon Source
* Argonne National Laboratory
*
*
*/
#ifndef osiTimehInclude
#define osiTimehInclude
//
// ANSI C
//
#include <time.h>
#include "shareLib.h"
struct TS_STAMP; // EPICS
class aitTimeStamp; // GDD
struct timespec; // POSIX real time
//
// an extended ANSI C RTL "struct tm" which includes nano seconds.
//
struct tm_nano_sec {
tm ansi_tm; // ANSI C time details
unsigned long nsec; // nano seconds extension
};
//
// wrapping this in a struct allows conversion to and
// from ANSI time_t but does not allow unexpected
// conversions to occur
//
struct time_t_wrapper {
time_t ts;
};
//
// class osiTime
//
// high resolution osiTime stamp
//
class epicsShareClass osiTime {
public:
//
// fetch the current time
//
static osiTime getCurrent();
//
// some systems have a high resolution time source which
// gradually drifts away from the master time base. Calling
// this routine will cause class "time" to realign the high
// resolution result from getCurrent() with some master
// time base.
//
// if this routine has not been called at least once so far
// by the current process then it is called the first time
// that getCurrent() is called
//
static void synchronize();
//
// create an osiTime for the EPICS epoch
//
osiTime ();
osiTime (const osiTime &t);
//
// convert to and from EPICS TS_STAMP format
//
operator struct TS_STAMP () const;
osiTime (const struct TS_STAMP &ts);
osiTime operator = (const struct TS_STAMP &rhs);
//
// convert to and from ANSI C's "time_t"
//
// "time_t" is wrapped in another structure to avoid
// unsuspected type conversions
// fetch value as an integer
//
operator time_t_wrapper () const;
osiTime (const time_t_wrapper &tv);
osiTime operator = (const time_t_wrapper &rhs);
//
// convert to and from ANSI C's "struct tm" (with nano seconds)
//
operator struct tm_nano_sec () const;
osiTime (const struct tm_nano_sec &ts);
osiTime operator = (const struct tm_nano_sec &rhs);
//
// convert to and from POSIX RT's "struct timespec"
//
operator struct timespec () const;
osiTime (const struct timespec &ts);
osiTime operator = (const struct timespec &rhs);
//
// convert to and from GDD's aitTimeStamp format
//
operator aitTimeStamp () const;
osiTime (const aitTimeStamp &ts);
osiTime operator = (const aitTimeStamp &rhs);
//
// arithmetic operators
//
long double operator- (const osiTime &rhs) const; // returns seconds
osiTime operator+ (const long double &rhs) const; // add rhs seconds
osiTime operator- (const long double &rhs) const; // subtract rhs seconds
osiTime operator+= (const long double &rhs); // add rhs seconds
osiTime operator-= (const long double &rhs); // subtract rhs seconds
//
// comparison operators
//
bool operator == (const osiTime &rhs) const;
bool operator != (const osiTime &rhs) const;
bool operator <= (const osiTime &rhs) const;
bool operator < (const osiTime &rhs) const;
bool operator >= (const osiTime &rhs) const;
bool operator > (const osiTime &rhs) const;
//
// dump current state to standard out
//
void show (unsigned interestLevel) const;
//
// useful public constants
//
static const unsigned secPerMin;
static const unsigned mSecPerSec;
static const unsigned uSecPerSec;
static const unsigned nSecPerSec;
static const unsigned nSecPerUSec;
private:
unsigned long sec; /* seconds since O000 Jan 1, 1990 */
unsigned long nSec; /* nanoseconds within second */
static osiTime osdGetCurrent();
static unsigned long time_tToInternalSec (const time_t &tv);
//
// private because:
// a) application does not break when EPICS epoch is changed
// b) no assumptions about internal storage or internal precision
// in the application
// c) it would be easy to forget which argument is nanoseconds
// and which argument is seconds (no help from compiler)
//
osiTime (unsigned long sec, unsigned long nSec);
};
/////////////////////////////////////
//
// time inline member functions
//
/////////////////////////////////////
inline osiTime::osiTime () : sec(0u), nSec(0u) {}
inline osiTime::osiTime (const osiTime &t) : sec(t.sec), nSec(t.nSec) {}
inline osiTime osiTime::operator - (const long double &rhs) const
{
return osiTime::operator + (-rhs);
}
inline osiTime osiTime::operator += (const long double &rhs)
{
*this = osiTime::operator + (rhs);
return *this;
}
inline osiTime osiTime::operator -= (const long double &rhs)
{
*this = osiTime::operator + (-rhs);
return *this;
}
inline bool osiTime::operator == (const osiTime &rhs) const
{
if (this->sec == rhs.sec && this->nSec == rhs.nSec) {
return true;
}
else {
return false;
}
}
//
// operator !=
//
inline bool osiTime::operator != (const osiTime &rhs) const
{
return !osiTime::operator == (rhs);
}
//
// operator >= (const osiTime &lhs, const osiTime &rhs)
//
inline bool osiTime::operator >= (const osiTime &rhs) const
{
return !(*this < rhs);
}
//
// operator > (const osiTime &lhs, const osiTime &rhs)
//
inline bool osiTime::operator > (const osiTime &rhs) const
{
return !(*this <= rhs);
}
//
// osiTime operator = (const struct tm_nano_sec &rhs)
//
inline osiTime osiTime::operator = (const struct tm_nano_sec &rhs)
{
return *this = osiTime (rhs);
}
//
// operator = (const struct timespec &rhs)
//
inline osiTime osiTime::operator = (const struct timespec &rhs)
{
*this = osiTime (rhs);
return *this;
}
//
// operator = (const aitTimeStamp &rhs)
//
inline osiTime osiTime::operator = (const aitTimeStamp &rhs)
{
*this = osiTime (rhs);
return *this;
}
inline osiTime osiTime::operator = (const struct TS_STAMP &rhs)
{
*this = osiTime (rhs);
return *this;
}
//
// osiTime (const time_t_wrapper &tv)
//
inline osiTime::osiTime (const time_t_wrapper &ansiTimeTicks)
{
this->sec = osiTime::time_tToInternalSec (ansiTimeTicks.ts);
this->nSec = 0;
}
//
// osiTime operator = (const time_t_wrapper &rhs)
// operator >= (const osiTime &lhs, const osiTime &rhs)
//
inline osiTime osiTime::operator = (const time_t_wrapper &rhs)
{
*this = osiTime (rhs);
return *this;
}
#endif // osiTimehInclude