diff --git a/src/libCom/osi/osiTime.cpp b/src/libCom/osi/osiTime.cpp index 4a6b20af3..aed66b124 100644 --- a/src/libCom/osi/osiTime.cpp +++ b/src/libCom/osi/osiTime.cpp @@ -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 (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 (nSecAdj) / nSecPerSec; + *this += secAdj; } // @@ -257,8 +212,8 @@ osiTime::osiTime (const time_t_wrapper &ansiTimeTicks) sec = sec - static_cast(sec/uLongMax)*uLongMax; } - this->sec = static_cast (sec); - this->nSec = static_cast ( (sec-this->sec) * nSecPerSec ); + this->secPastEpoch = static_cast (sec); + this->nSec = static_cast ( (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 (lti.ntpEpochOffset); // underflow expected - ts.l_ui = this->sec - offset; + ts.l_ui = this->secPastEpoch - offset; } else { unsigned long offset = static_cast (-lti.ntpEpochOffset); // overflow expected - ts.l_ui = this->sec + offset; + ts.l_ui = this->secPastEpoch + offset; } ts.l_uf = static_cast ( ( 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 (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 (-lti.ntpEpochOffset); // underflow expected - this->sec = ts.l_ui + this->sec - offset; + this->secPastEpoch = ts.l_ui + this->secPastEpoch - offset; } this->nSec = static_cast ( ( 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 (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 (-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->secsec; + if (this->secPastEpochsecPastEpoch; 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->secsec < ULONG_MAX/2) { + if (this->secPastEpochsecPastEpoch < 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->secsec < ULONG_MAX/2) { + if (this->secPastEpochsecPastEpoch < 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); } } diff --git a/src/libCom/osi/osiTime.h b/src/libCom/osi/osiTime.h index c772a025c..1d2daef2f 100644 --- a/src/libCom/osi/osiTime.h +++ b/src/libCom/osi/osiTime.h @@ -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 #include #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 (¤t); +# 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 (¤t, 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