revised to use tsStamp.h

This commit is contained in:
Jeff Hill
1999-12-21 23:17:02 +00:00
parent eda455f6f6
commit 3992ca8e38
2 changed files with 298 additions and 407 deletions

View File

@@ -35,6 +35,7 @@
#include "epicsAssert.h"
#include "envDefs.h"
#include "osiTime.h"
#include "tsStamp.h"
//
// useful public constants
@@ -62,13 +63,6 @@ const unsigned osiTime::secPerMin = 60u;
struct tm *gmtime_r (const time_t *, struct tm *);
struct tm *localtime_r (const time_t *, struct tm *);
#endif
#if 0
struct TS_STAMP {
epicsUInt32 secPastEpoch; /* seconds since 0000 Jan 1, 1990 */
epicsUInt32 nsec; /* nanoseconds within second */
};
#endif
static const unsigned ntpEpochYear = 1900;
static const unsigned ntpEpocMonth = 0; // January
@@ -97,32 +91,10 @@ static const unsigned epicsEpocDayOfTheMonth = 1; // the 1st day of the month
//
inline osiTime::osiTime (const unsigned long secIn, const unsigned long nSecIn)
{
this->sec = nSecIn/nSecPerSec + secIn;
this->secPastEpoch = nSecIn/nSecPerSec + secIn;
this->nSec = nSecIn%nSecPerSec;
}
//
// getCurrent ()
//
// force a logical progression of time
//
// (this does not appear to add any significant
// overhead when the code is optimized)
//
osiTime osiTime::getCurrent ()
{
static osiTime last;
osiTime ts = osiTime::osdGetCurrent();
if (last<ts) {
last = ts;
return ts;
}
else {
return last;
}
}
//
// loadTimeInit
//
@@ -210,25 +182,8 @@ loadTimeInit::loadTimeInit ()
//
inline void osiTime::addNanoSec (long nSecAdj)
{
//
// for now assume that they dont allow negative nanoseconds
// on UNIX platforms (this could be a mistake)
//
if ( nSecAdj < 0 ) {
throw negNanoSecInTimeStampFromUNIX ();
}
unsigned long offset = static_cast<unsigned long> (nSecAdj);
if ( offset >= nSecPerSec ) {
throw nanoSecFieldIsTooLarge ();
}
//
// no need to worry about overflow here because
// offset + this->nSec will be less than ULONG_MAX/2
//
*this = osiTime (this->sec, this->nSec + offset);
long double secAdj = static_cast <long double> (nSecAdj) / nSecPerSec;
*this += secAdj;
}
//
@@ -257,8 +212,8 @@ osiTime::osiTime (const time_t_wrapper &ansiTimeTicks)
sec = sec - static_cast<unsigned long>(sec/uLongMax)*uLongMax;
}
this->sec = static_cast <unsigned long> (sec);
this->nSec = static_cast <unsigned long> ( (sec-this->sec) * nSecPerSec );
this->secPastEpoch = static_cast <unsigned long> (sec);
this->nSec = static_cast <unsigned long> ( (sec-this->secPastEpoch) * nSecPerSec );
}
//
@@ -269,7 +224,7 @@ osiTime::operator time_t_wrapper () const
long double tmp;
time_t_wrapper wrap;
tmp = (this->sec + lti.epicsEpochOffset) / lti.time_tSecPerTick;
tmp = (this->secPastEpoch + lti.epicsEpochOffset) / lti.time_tSecPerTick;
tmp += (this->nSec / lti.time_tSecPerTick) / nSecPerSec;
//
@@ -321,7 +276,7 @@ osiTime::osiTime (const tm_nano_sec &tm)
if (tm.nSec>=nSecPerSec) {
throw nanoSecFieldIsTooLarge ();
}
*this = osiTime (this->sec, this->nSec + tm.nSec);
*this = osiTime (this->secPastEpoch, this->nSec + tm.nSec);
}
//
@@ -403,27 +358,7 @@ osiTime::osiTime (const aitTimeStamp &ts)
if ( ts.tv_nsec>=nSecPerSec ) {
throw nanoSecFieldIsTooLarge ();
}
*this = osiTime ( this->sec, this->nSec + ts.tv_nsec );
}
//
// operator TS_STAMP ()
//
osiTime::operator struct TS_STAMP () const
{
struct TS_STAMP ts;
ts.secPastEpoch = this->sec;
ts.nsec = this->nSec;
return ts;
}
//
// osiTime (const TS_STAMP &ts)
//
osiTime::osiTime (const struct TS_STAMP &ts)
{
this->sec = ts.secPastEpoch;
this->nSec = ts.nsec;
*this = osiTime ( this->secPastEpoch, this->nSec + ts.tv_nsec );
}
//
@@ -437,12 +372,12 @@ osiTime::operator ntpTimeStamp () const
if (lti.ntpEpochOffset>=0) {
unsigned long offset = static_cast<unsigned long> (lti.ntpEpochOffset);
// underflow expected
ts.l_ui = this->sec - offset;
ts.l_ui = this->secPastEpoch - offset;
}
else {
unsigned long offset = static_cast<unsigned long> (-lti.ntpEpochOffset);
// overflow expected
ts.l_ui = this->sec + offset;
ts.l_ui = this->secPastEpoch + offset;
}
ts.l_uf = static_cast<unsigned long> ( ( this->nSec * ULONG_MAX_PLUS_ONE ) / nSecPerSec );
@@ -461,12 +396,12 @@ osiTime::osiTime (const ntpTimeStamp &ts)
if (lti.ntpEpochOffset>=0) {
unsigned long offset = static_cast<unsigned long> (lti.ntpEpochOffset);
// overflow expected
this->sec = ts.l_ui + this->sec + offset;
this->secPastEpoch = ts.l_ui + this->secPastEpoch + offset;
}
else {
unsigned long offset = static_cast<unsigned long> (-lti.ntpEpochOffset);
// underflow expected
this->sec = ts.l_ui + this->sec - offset;
this->secPastEpoch = ts.l_ui + this->secPastEpoch - offset;
}
this->nSec = static_cast<unsigned long> ( ( ts.l_uf / ULONG_MAX_PLUS_ONE ) * nSecPerSec );
@@ -504,7 +439,7 @@ osiTime osiTime::operator + (const long double &rhs) const
fnsec = rhs - secOffset;
nSecOffset = static_cast <unsigned long> (fnsec * nSecPerSec);
newSec = this->sec + secOffset; // overflow expected
newSec = this->secPastEpoch + secOffset; // overflow expected
newNSec = this->nSec + nSecOffset;
if (newNSec >= nSecPerSec) {
newSec++; // overflow expected
@@ -516,7 +451,7 @@ osiTime osiTime::operator + (const long double &rhs) const
fnsec = rhs + secOffset;
nSecOffset = static_cast <unsigned long> (-fnsec * nSecPerSec);
newSec = this->sec - secOffset; // underflow expected
newSec = this->secPastEpoch - secOffset; // underflow expected
if (this->nSec>=nSecOffset) {
newNSec = this->nSec - nSecOffset;
}
@@ -567,8 +502,8 @@ long double osiTime::operator - (const osiTime &rhs) const
// and invert the sign of the nano seconds result if there
// is a range violation
//
if (this->sec<rhs.sec) {
secRes = rhs.sec - this->sec;
if (this->secPastEpoch<rhs.secPastEpoch) {
secRes = rhs.secPastEpoch - this->secPastEpoch;
if (secRes > ULONG_MAX/2) {
//
// In this situation where the difference is more than
@@ -583,7 +518,7 @@ long double osiTime::operator - (const osiTime &rhs) const
}
}
else {
secRes = this->sec - rhs.sec;
secRes = this->secPastEpoch - rhs.secPastEpoch;
if (secRes > ULONG_MAX/2) {
//
// In this situation where the difference is more than
@@ -606,8 +541,8 @@ bool osiTime::operator <= (const osiTime &rhs) const
{
bool rc;
if (this->sec<rhs.sec) {
if (rhs.sec-this->sec < ULONG_MAX/2) {
if (this->secPastEpoch<rhs.secPastEpoch) {
if (rhs.secPastEpoch-this->secPastEpoch < ULONG_MAX/2) {
//
// In this situation where the difference is less than
// 69 years compute the expected result
@@ -623,8 +558,8 @@ bool osiTime::operator <= (const osiTime &rhs) const
rc = false;
}
}
else if (this->sec>rhs.sec) {
if (this->sec-rhs.sec < ULONG_MAX/2) {
else if (this->secPastEpoch>rhs.secPastEpoch) {
if (this->secPastEpoch-rhs.secPastEpoch < ULONG_MAX/2) {
//
// In this situation where the difference is less than
// 69 years compute the expected result
@@ -658,8 +593,8 @@ bool osiTime::operator < (const osiTime &rhs) const
{
bool rc;
if (this->sec<rhs.sec) {
if (rhs.sec-this->sec < ULONG_MAX/2) {
if (this->secPastEpoch<rhs.secPastEpoch) {
if (rhs.secPastEpoch-this->secPastEpoch < ULONG_MAX/2) {
//
// In this situation where the difference is less than
// 69 years compute the expected result
@@ -675,8 +610,8 @@ bool osiTime::operator < (const osiTime &rhs) const
rc = false;
}
}
else if (this->sec>rhs.sec) {
if (this->sec-rhs.sec < ULONG_MAX/2) {
else if (this->secPastEpoch>rhs.secPastEpoch) {
if (this->secPastEpoch-rhs.secPastEpoch < ULONG_MAX/2) {
//
// In this situation where the difference is less than
// 69 years compute the expected result
@@ -704,138 +639,115 @@ bool osiTime::operator < (const osiTime &rhs) const
}
extern "C" {
/*
* ANSI C interface
*
* its too bad that these cant be implemented with inline functions
* at least when running the GNU compiler
*/
epicsShareFunc void osiTimeGetCurrent (osiTime *pDest)
{
*pDest = osiTime::getCurrent();
}
epicsShareFunc void osiTimeSynchronize ()
{
osiTime::synchronize ();
}
epicsShareFunc int osiTimeToTS_STAMP (TS_STAMP *pDest, const osiTime *pSrc)
{
try {
*pDest = *pSrc;
}
catch (...) {
return -1;
}
return 0;
}
epicsShareFunc int osiTimeFromTS_STAMP (osiTime *pDest, const TS_STAMP *pSrc)
{
try {
*pDest = *pSrc;
}
catch (...) {
return -1;
}
return 0;
}
epicsShareFunc int osiTimeToTime_t (time_t *pDest, const osiTime *pSrc)
//
// ANSI C interface
//
// its too bad that these cant be implemented with inline functions
// at least when running the GNU compiler
//
epicsShareFunc int epicsShareAPI tsStampToTime_t (time_t *pDest, const TS_STAMP *pSrc)
{
try {
time_t_wrapper dst;
dst = *pSrc;
dst = osiTime (*pSrc);
*pDest = dst.ts;
}
catch (...) {
return -1;
return tsStampERROR;
}
return 0;
return tsStampOK;
}
epicsShareFunc int osiTimeFromTime_t (osiTime *pDest, time_t src)
epicsShareFunc int epicsShareAPI tsStampFromTime_t (TS_STAMP *pDest, time_t src)
{
try {
time_t_wrapper dst;
dst.ts = src;
*pDest = dst;
*pDest = osiTime (dst);
}
catch (...) {
return -1;
return tsStampERROR;
}
return 0;
return tsStampOK;
}
epicsShareFunc int osiTimeToTM (tm_nano_sec *pDest, const osiTime *pSrc)
epicsShareFunc int epicsShareAPI tsStampToTM (struct tm *pDest, unsigned long *pNSecDest, const TS_STAMP *pSrc)
{
try {
*pDest = *pSrc;
tm_nano_sec tmns = osiTime (*pSrc);
*pDest = tmns.ansi_tm;
*pNSecDest = tmns.nSec;
}
catch (...) {
return -1;
return tsStampERROR;
}
return 0;
return tsStampOK;
}
epicsShareFunc int osiTimeFromTM (osiTime *pDest, const tm_nano_sec *pSrc)
epicsShareFunc int epicsShareAPI tsStampFromTM (TS_STAMP *pDest, const struct tm *pSrc, unsigned long nSecSrc)
{
try {
*pDest = *pSrc;
tm_nano_sec tmns;
tmns.ansi_tm = *pSrc;
tmns.nSec = nSecSrc;
*pDest = osiTime (tmns);
}
catch (...) {
return -1;
return tsStampERROR;
}
return 0;
return tsStampOK;
}
epicsShareFunc int osiTimeToTimespec (struct timespec *pDest, const osiTime *pSrc)
epicsShareFunc int epicsShareAPI tsStampToTimespec (struct timespec *pDest, const TS_STAMP *pSrc)
{
try {
*pDest = *pSrc;
*pDest = osiTime (*pSrc);
}
catch (...) {
return -1;
return tsStampERROR;
}
return 0;
return tsStampOK;
}
epicsShareFunc int osiTimeFromTimespec (osiTime *pDest, const struct timespec *pSrc)
epicsShareFunc int epicsShareAPI tsStampFromTimespec (TS_STAMP *pDest, const struct timespec *pSrc)
{
try {
*pDest = *pSrc;
*pDest = osiTime (*pSrc);
}
catch (...) {
return -1;
return tsStampERROR;
}
return 0;
return tsStampOK;
}
epicsShareFunc long double osiTimeDiffInSeconds (const osiTime *pLeft, const osiTime *pRight)
epicsShareFunc long double epicsShareAPI tsStampDiffInSeconds (const TS_STAMP *pLeft, const TS_STAMP *pRight)
{
return *pLeft - *pRight;
return osiTime (*pLeft) - osiTime (*pRight);
}
epicsShareFunc void osiTimeAddSeconds (osiTime *pDest, long double seconds)
epicsShareFunc void epicsShareAPI tsStampAddSeconds (TS_STAMP *pDest, long double seconds)
{
*pDest += seconds;
*pDest = osiTime (*pDest) + seconds;
}
epicsShareFunc int osiTimeEqual (const osiTime *pLeft, const osiTime *pRight)
epicsShareFunc int epicsShareAPI tsStampEqual (const TS_STAMP *pLeft, const TS_STAMP *pRight)
{
return *pLeft == *pRight;
return osiTime (*pLeft) == osiTime (*pRight);
}
epicsShareFunc int osiTimeNotEqual (const osiTime *pLeft, const osiTime *pRight)
epicsShareFunc int epicsShareAPI tsStampNotEqual (const TS_STAMP *pLeft, const TS_STAMP *pRight)
{
return *pLeft != *pRight;
return osiTime (*pLeft) != osiTime (*pRight);
}
epicsShareFunc int osiTimeLessThan (const osiTime *pLeft, const osiTime *pRight)
epicsShareFunc int epicsShareAPI tsStampLessThan (const TS_STAMP *pLeft, const TS_STAMP *pRight)
{
return *pLeft < *pRight;
return osiTime (*pLeft) < osiTime (*pRight);
}
epicsShareFunc int osiTimeLessThanEqual (const osiTime *pLeft, const osiTime *pRight)
epicsShareFunc int epicsShareAPI tsStampLessThanEqual (const TS_STAMP *pLeft, const TS_STAMP *pRight)
{
return *pLeft <= *pRight;
return osiTime (*pLeft) <= osiTime (*pRight);
}
epicsShareFunc int osiTimeGreaterThan (const osiTime *pLeft, const osiTime *pRight)
epicsShareFunc int epicsShareAPI tsStampGreaterThan (const TS_STAMP *pLeft, const TS_STAMP *pRight)
{
return *pLeft > *pRight;
return osiTime (*pLeft) > osiTime (*pRight);
}
epicsShareFunc int osiTimeGreaterThanEqual (const osiTime *pLeft, const osiTime *pRight)
epicsShareFunc int epicsShareAPI tsStampGreaterThanEqual (const TS_STAMP *pLeft, const TS_STAMP *pRight)
{
return *pLeft >= *pRight;
return osiTime (*pLeft) >= osiTime (*pRight);
}
epicsShareFunc void osiTimeShow (const osiTime *pTS, unsigned interestLevel)
epicsShareFunc void epicsShareAPI tsStampShow (const TS_STAMP *pTS, unsigned interestLevel)
{
pTS->show (interestLevel);
osiTime(*pTS).show (interestLevel);
}
}

View File

@@ -1,210 +1,207 @@
/*
* $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
*
*
*/
//
// $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
*/
//
// ANSI
//
#include <String>
#include <time.h>
#include "shareLib.h"
#include "epicsTypes.h"
#include "tsStamp.h"
#include "epicsAssert.h"
struct TS_STAMP; /* EPICS */
struct timespec; /* POSIX real time */
struct timeval; /* BSD */
#ifdef __cplusplus
class aitTimeStamp; /* GDD */
#endif
struct timespec; // POSIX real time
struct timeval; // BSD
class aitTimeStamp; // GDD
/*
* an extended ANSI C RTL "struct tm" which includes nano seconds.
*/
typedef struct tm_nano_sec {
//
// an extended ANSI C RTL "struct tm" which includes
// additional nano seconds within a second.
//
struct tm_nano_sec {
struct tm ansi_tm; /* ANSI C time details */
unsigned long nSec; /* nano seconds extension */
} tm_nano_sec;
};
/*
* wrapping this in a struct allows conversion to and
* from ANSI time_t but does not allow unexpected
* conversions to occur
*/
typedef struct time_t_wrapper {
//
// 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;
} time_t_wrapper;
};
/*
* NTP uses two fixed point formats. The first (l_fp) is the "long"
* format and is 64 bits long with the decimal between bits 31 and 32.
* This is used for time stamps in the NTP packet header (in network
* byte order) and for internal computations of offsets (in local host
* byte order). We use the same structure for both signed and unsigned
* values, which is a big hack but saves rewriting all the operators
* twice. Just to confuse this, we also sometimes just carry the
* fractional part in calculations, in both signed and unsigned forms.
* Anyway, an l_fp looks like:
*
* 0 1 2 3
* 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
* | Integral Part |
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
* | Fractional Part |
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
*
*/
typedef struct {
//
// This comment is from the NTP header files:
//
// NTP uses two fixed point formats. The first (l_fp) is the "long"
// format and is 64 bits long with the decimal between bits 31 and 32.
// This is used for time stamps in the NTP packet header (in network
// byte order) and for internal computations of offsets (in local host
// byte order). We use the same structure for both signed and unsigned
// values, which is a big hack but saves rewriting all the operators
// twice. Just to confuse this, we also sometimes just carry the
// fractional part in calculations, in both signed and unsigned forms.
// Anyway, an l_fp looks like:
//
// 0 1 2 3
// 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
// | Integral Part |
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
// | Fractional Part |
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
//
//
struct ntpTimeStamp {
epicsUInt32 l_ui; /* sec past NTP epoch */
epicsUInt32 l_uf; /* fractional seconds */
}ntpTimeStamp;
};
/*
* The number of nanoseconds past 0000 Jan 1, 1990, GMT (or UTC, if you prefer).
*/
typedef struct TS_STAMP {
epicsUInt32 secPastEpoch; /* seconds since 0000 Jan 1, 1990 */
epicsUInt32 nsec; /* nanoseconds within second */
} TS_STAMP;
class osiTime;
/*
* type osiTime
*
* high resolution osiTime stamp class (struct) which can be used
* from both C++ and also from ANSI C
*/
typedef struct epicsShareClass osiTime
//
// type osiTimeEvent
//
class epicsShareClass osiTimeEvent
{
#ifdef __cplusplus
friend class osiTime;
public:
osiTimeEvent (const int &eventName);
private:
unsigned eventNumber;
};
/*
* exceptions
*/
//
// type osiTime
//
// high resolution osiTime stamp class (struct) which can be used
// from both C++ and also from ANSI C
//
class epicsShareClass osiTime
{
public:
//
// exceptions
//
class unableToFetchCurrentTime {};
class negNanoSecInTimeStampFromUNIX {};
class nanoSecFieldIsTooLarge {};
class formatProblemWithStructTM {};
class internalFailure {};
/*
* fetch the current time
*/
static osiTime getCurrent();
//
// fetch the current time
//
static osiTime getEvent (const osiTimeEvent &event);
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
*/
//
// 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 EPICS TS_STAMP format
//
operator TS_STAMP () const;
osiTime (const TS_STAMP &ts);
osiTime operator = (const 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
*/
//
// 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)
*/
//
// convert to and from ANSI C's "struct tm" (with nano seconds)
//
operator tm_nano_sec () const;
osiTime (const tm_nano_sec &ts);
osiTime operator = (const tm_nano_sec &rhs);
/*
* convert to and from POSIX RT's "struct timespec"
*/
//
// 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 BSD's "struct timeval"
*/
//
// convert to and from BSD's "struct timeval"
//
operator struct timeval () const;
osiTime (const struct timeval &ts);
osiTime operator = (const struct timeval &rhs);
/*
* convert to and from NTP timestamp format
*/
//
// convert to and from NTP timestamp format
//
operator ntpTimeStamp () const;
osiTime (const ntpTimeStamp &ts);
osiTime operator = (const ntpTimeStamp &rhs);
/*
* convert to and from GDD's aitTimeStamp format
*/
//
// convert to and from GDD's aitTimeStamp format
//
operator aitTimeStamp () const;
osiTime (const aitTimeStamp &ts);
osiTime operator = (const aitTimeStamp &rhs);
/*
* arithmetic operators
*/
//
// 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
*/
//
// comparison operators
//
bool operator == (const osiTime &rhs) const;
bool operator != (const osiTime &rhs) const;
bool operator <= (const osiTime &rhs) const;
@@ -212,117 +209,87 @@ typedef struct epicsShareClass osiTime
bool operator >= (const osiTime &rhs) const;
bool operator > (const osiTime &rhs) const;
/*
* dump current state to standard out
*/
//
// dump current state to standard out
//
void show (unsigned interestLevel) const;
/*
* useful public constants
*/
//
// useful public constants
//
static const unsigned secPerMin;
static const unsigned mSecPerSec;
static const unsigned uSecPerSec;
static const unsigned nSecPerSec;
static const unsigned nSecPerUSec;
// depricated
static void synchronize ();
private:
static osiTime osdGetCurrent();
/*
* 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 (const unsigned long sec, const unsigned long nSec);
//
// 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 (const unsigned long secPastEpoch, const unsigned long nSec);
void addNanoSec (long nanoSecAdjust);
#endif /* ifdef __cplusplus */
unsigned long secPastEpoch; // seconds since O000 Jan 1, 1990
unsigned long nSec; // nanoseconds within second
};
/*
* private - do not touch these from within C programs
*/
unsigned long sec; /* seconds since O000 Jan 1, 1990 */
unsigned long nSec; /* nanoseconds within second */
} osiTime;
//
// type osiTime inline member functions
//
/*
* ANSI C interface to osiTime
*
* all conversion functions return -1 on failure and 0 on success
*/
#ifdef __cplusplus
extern "C" {
#endif
//
// getCurrent ()
//
inline osiTime osiTime::getCurrent ()
{
TS_STAMP current;
int status;
/*
* fetch and synchronize the current time
*/
epicsShareFunc void osiTimeGetCurrent (osiTime *pDest);
epicsShareFunc void osiTimeSynchronize ();
status = tsStampGetCurrent (&current);
# ifdef osiTimeCanThrowException
if (status) {
throw unableToFetchCurrentTime ();
}
# else
assert (!status);
# endif
/*
* convert to and from EPICS TS_STAMP format
*/
epicsShareFunc int osiTimeToTS_STAMP (TS_STAMP *pDest, const osiTime *pSrc);
epicsShareFunc int osiTimeFromTS_STAMP (osiTime *pDest, const TS_STAMP *pSrc);
/*
* convert to and from ANSI C's "time_t"
*/
epicsShareFunc int osiTimeToTime_t (time_t *pDest, const osiTime *pSrc);
epicsShareFunc int osiTimeFromTime_t (osiTime *pDest, time_t src);
/*
* convert to and from ANSI C's "struct tm" (with nano seconds)
*/
epicsShareFunc int osiTimeToTM (tm_nano_sec *pDest, const osiTime *pSrc);
epicsShareFunc int osiTimeFromTM (osiTime *pDest, const tm_nano_sec *pSrc);
/*
* convert to and from POSIX RT's "struct timespec"
*/
epicsShareFunc int osiTimeToTimespec (struct timespec *pDest, const osiTime *pSrc);
epicsShareFunc int osiTimeFromTimespec (osiTime *pDest, const struct timespec *pSrc);
/*
* arithmetic operations
*/
epicsShareFunc long double osiTimeDiffInSeconds (const osiTime *pLeft, const osiTime *pRight); /* returns *pLeft - *pRight in seconds */
epicsShareFunc void osiTimeAddSeconds (osiTime *pDest, long double secondsToAdd); /* adds seconds to *pLeft */
/*
* comparison operations
*/
epicsShareFunc int osiTimeEqual (const osiTime *pLeft, const osiTime *pRight); /* returns boolean result */
epicsShareFunc int osiTimeNotEqual (const osiTime *pLeft, const osiTime *pRight); /* returns boolean result */
epicsShareFunc int osiTimeLessThan (const osiTime *pLeft, const osiTime *pRight); /* returns boolean result (true if *pLeft < *pRight) */
epicsShareFunc int osiTimeLessThanEqual (const osiTime *pLeft, const osiTime *pRight); /* returns boolean result (true if *pLeft <= *pRight) */
epicsShareFunc int osiTimeGreaterThan (const osiTime *pLeft, const osiTime *pRight); /* returns boolean result (true if *pLeft > *pRight) */
epicsShareFunc int osiTimeGreaterThanEqual (const osiTime *pLeft, const osiTime *pRight); /* returns boolean result (true if *pLeft >= *pRight) */
/*
* dump current state to standard out
*/
epicsShareFunc void osiTimeShow (const osiTime *, unsigned interestLevel);
#ifdef __cplusplus
return osiTime (current);
}
#endif
#ifdef __cplusplus
inline osiTime osiTime::getEvent (const osiTimeEvent &event)
{
TS_STAMP current;
int status;
/*
* type osiTime inline member functions
*/
status = tsStampGetEvent (&current, event.eventNumber);
# ifdef osiTimeCanThrowException
if (status) {
throw unableToFetchCurrentTime ();
}
# else
assert (!status);
# endif
inline osiTime::osiTime () : sec(0u), nSec(0u) {}
return osiTime (current);
}
inline osiTime::osiTime (const osiTime &t) : sec(t.sec), nSec(t.nSec) {}
// depricated
inline void osiTime::synchronize () {}
inline osiTime::osiTime () : secPastEpoch(0u), nSec(0u) {}
inline osiTime::osiTime (const osiTime &t) : secPastEpoch (t.secPastEpoch), nSec (t.nSec) {}
inline osiTime osiTime::operator - (const long double &rhs) const
{
@@ -343,7 +310,7 @@ inline osiTime osiTime::operator -= (const long double &rhs)
inline bool osiTime::operator == (const osiTime &rhs) const
{
if (this->sec == rhs.sec && this->nSec == rhs.nSec) {
if (this->secPastEpoch == rhs.secPastEpoch && this->nSec == rhs.nSec) {
return true;
}
else {
@@ -383,12 +350,26 @@ inline osiTime osiTime::operator = (const aitTimeStamp &rhs)
return *this;
}
inline osiTime osiTime::operator = (const struct TS_STAMP &rhs)
inline osiTime::osiTime (const TS_STAMP &ts)
{
this->secPastEpoch = ts.secPastEpoch;
this->nSec = ts.nSec;
}
inline osiTime osiTime::operator = (const TS_STAMP &rhs)
{
*this = osiTime (rhs);
return *this;
}
inline osiTime::operator TS_STAMP () const
{
TS_STAMP ts;
ts.secPastEpoch = this->secPastEpoch;
ts.nSec = this->nSec;
return ts;
}
#ifdef NTP_SUPPORT
inline osiTime osiTime::operator = (const ntpTimeStamp &rhs)
{
@@ -403,7 +384,5 @@ inline osiTime osiTime::operator = (const time_t_wrapper &rhs)
return *this;
}
#endif /* __cplusplus */
#endif /* osiTimehInclude */
#endif // osiTimehInclude