Merge remote-tracking branch 'lp-Com/use-monotonic' into 7.0
* lp-Com/use-monotonic: VxWorks: Measure CPU time-base frequency if necessary replace most internal getCurrent() -> getMonotonic() dbScan periodic scan use monotonic time monotonic adapt to regular time APIs
This commit is contained in:
@@ -97,7 +97,7 @@ epicsShareFunc void fdManager::process (double delay)
|
||||
// more than once here so that fd activity get serviced
|
||||
// in a reasonable length of time.
|
||||
//
|
||||
double minDelay = this->pTimerQueue->process(epicsTime::getCurrent());
|
||||
double minDelay = this->pTimerQueue->process(epicsTime::getMonotonic());
|
||||
|
||||
if ( minDelay >= delay ) {
|
||||
minDelay = delay;
|
||||
@@ -121,7 +121,7 @@ epicsShareFunc void fdManager::process (double delay)
|
||||
fd_set * pExceptSet = & this->fdSetsPtr[fdrException];
|
||||
int status = select (this->maxFD, pReadSet, pWriteSet, pExceptSet, &tv);
|
||||
|
||||
this->pTimerQueue->process(epicsTime::getCurrent());
|
||||
this->pTimerQueue->process(epicsTime::getMonotonic());
|
||||
|
||||
if ( status > 0 ) {
|
||||
|
||||
@@ -204,7 +204,7 @@ epicsShareFunc void fdManager::process (double delay)
|
||||
* of select()
|
||||
*/
|
||||
epicsThreadSleep(minDelay);
|
||||
this->pTimerQueue->process(epicsTime::getCurrent());
|
||||
this->pTimerQueue->process(epicsTime::getMonotonic());
|
||||
}
|
||||
this->processInProg = false;
|
||||
return;
|
||||
|
||||
@@ -215,6 +215,14 @@ int epicsShareAPI epicsTimeGetCurrent(epicsTimeStamp *pDest)
|
||||
return status;
|
||||
}
|
||||
|
||||
int epicsTimeGetMonotonic ( epicsTimeStamp * pDest )
|
||||
{
|
||||
epicsUInt64 now = epicsMonotonicGet();
|
||||
pDest->nsec = now%1000000000ul;
|
||||
pDest->secPastEpoch = now/1000000000ul;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int epicsTimeGetCurrentInt(epicsTimeStamp *pDest)
|
||||
{
|
||||
gtProvider *ptp = gtPvt.lastTimeProvider;
|
||||
|
||||
@@ -164,7 +164,7 @@ bool epicsThread::exitWait ( const double delay ) throw ()
|
||||
}
|
||||
return true;
|
||||
}
|
||||
epicsTime exitWaitBegin = epicsTime::getCurrent ();
|
||||
epicsTime exitWaitBegin = epicsTime::getMonotonic ();
|
||||
double exitWaitElapsed = 0.0;
|
||||
epicsGuard < epicsMutex > guard ( this->mutex );
|
||||
this->cancel = true;
|
||||
@@ -172,7 +172,7 @@ bool epicsThread::exitWait ( const double delay ) throw ()
|
||||
epicsGuardRelease < epicsMutex > unguard ( guard );
|
||||
this->event.signal ();
|
||||
this->exitEvent.wait ( delay - exitWaitElapsed );
|
||||
epicsTime current = epicsTime::getCurrent ();
|
||||
epicsTime current = epicsTime::getMonotonic ();
|
||||
exitWaitElapsed = current - exitWaitBegin;
|
||||
}
|
||||
if(this->terminated && !joined) {
|
||||
|
||||
@@ -215,6 +215,13 @@ epicsTime epicsTime::getCurrent ()
|
||||
return epicsTime ( current );
|
||||
}
|
||||
|
||||
epicsTime epicsTime::getMonotonic()
|
||||
{
|
||||
epicsTimeStamp current;
|
||||
epicsTimeGetMonotonic (¤t); // can't fail
|
||||
return epicsTime ( current );
|
||||
}
|
||||
|
||||
epicsTime epicsTime::getEvent (const epicsTimeEvent &event)
|
||||
{
|
||||
epicsTimeStamp current;
|
||||
|
||||
@@ -85,6 +85,7 @@ public:
|
||||
|
||||
static epicsTime getEvent ( const epicsTimeEvent & );
|
||||
static epicsTime getCurrent ();
|
||||
static epicsTime getMonotonic ();
|
||||
|
||||
/* convert to and from EPICS epicsTimeStamp format */
|
||||
operator epicsTimeStamp () const;
|
||||
@@ -191,6 +192,7 @@ extern "C" {
|
||||
epicsShareFunc int epicsShareAPI epicsTimeGetCurrent ( epicsTimeStamp * pDest );
|
||||
epicsShareFunc int epicsShareAPI epicsTimeGetEvent (
|
||||
epicsTimeStamp *pDest, int eventNumber);
|
||||
epicsShareFunc int epicsTimeGetMonotonic ( epicsTimeStamp * pDest );
|
||||
|
||||
/* These are callable from an Interrupt Service Routine */
|
||||
epicsShareFunc int epicsTimeGetCurrentInt(epicsTimeStamp *pDest);
|
||||
|
||||
@@ -9,10 +9,13 @@
|
||||
|
||||
#include <vxWorks.h>
|
||||
#include <stdio.h>
|
||||
#include <sysLib.h>
|
||||
#include <taskLib.h>
|
||||
|
||||
#define EPICS_EXPOSE_LIBCOM_MONOTONIC_PRIVATE
|
||||
#include "epicsTypes.h"
|
||||
#include "epicsTime.h"
|
||||
#include "cantProceed.h"
|
||||
|
||||
|
||||
#define NS_PER_SEC 1000000000
|
||||
@@ -23,6 +26,7 @@ union timebase {
|
||||
UINT64 u64; /* epicsMonotonicGet() */
|
||||
};
|
||||
|
||||
static void measureTickRate(void);
|
||||
|
||||
#if CPU_FAMILY == PPC
|
||||
#include <arch/ppc/vxPpcLib.h>
|
||||
@@ -46,12 +50,15 @@ void osdMonotonicInit(void)
|
||||
if (sysTimeBaseFreq) {
|
||||
ticksPerSec = sysTimeBaseFreq();
|
||||
|
||||
if (!ticksPerSec)
|
||||
printf("Warning: Failed to set up monotonic time source.\n");
|
||||
/* Warn here only if the BSP routine exists but returned 0 */
|
||||
if (ticksPerSec)
|
||||
return;
|
||||
|
||||
/* This should never happen */
|
||||
printf("Warning: sysTimeBaseFreq() present but returned zero.\n");
|
||||
}
|
||||
else
|
||||
ticksPerSec = 0; /* Warn on first use */
|
||||
|
||||
/* Fall back to measuring */
|
||||
measureTickRate();
|
||||
}
|
||||
|
||||
|
||||
@@ -73,8 +80,14 @@ void osdMonotonicInit(void)
|
||||
{
|
||||
ticksPerSec = vxCpuIdGetFreq();
|
||||
|
||||
if (!ticksPerSec)
|
||||
printf("Warning: Failed to set up monotonic time source.\n");
|
||||
if (ticksPerSec)
|
||||
return;
|
||||
|
||||
/* This should never happen */
|
||||
printf("Warning: vxCpuIdGetFreq() returned zero.\n");
|
||||
|
||||
/* Fall back to measuring */
|
||||
measureTickRate();
|
||||
}
|
||||
|
||||
|
||||
@@ -96,13 +109,7 @@ epicsUInt64 epicsMonotonicGet(void)
|
||||
union timebase tbNow;
|
||||
|
||||
if (!ticksPerSec) {
|
||||
static int warned = 0;
|
||||
|
||||
if (!warned) {
|
||||
printf("Warning: Monotonic time source is not available.\n");
|
||||
warned = 1;
|
||||
}
|
||||
return 0;
|
||||
cantProceed("Monotonic time source not available.\n");
|
||||
}
|
||||
|
||||
TIMEBASEGET(tbNow);
|
||||
@@ -111,3 +118,20 @@ epicsUInt64 epicsMonotonicGet(void)
|
||||
*/
|
||||
return ((long double) tbNow.u64) * NS_PER_SEC / ticksPerSec;
|
||||
}
|
||||
|
||||
static void measureTickRate(void)
|
||||
{
|
||||
union timebase start, end;
|
||||
int sysTicks = sysClkRateGet(); /* 1 second */
|
||||
|
||||
printf("osdMonotonicInit: Measuring CPU time-base frequency ...");
|
||||
fflush(stdout);
|
||||
|
||||
taskDelay(1);
|
||||
TIMEBASEGET(start);
|
||||
taskDelay(sysTicks);
|
||||
TIMEBASEGET(end);
|
||||
ticksPerSec = end.u64 - start.u64;
|
||||
|
||||
printf(" %llu ticks/sec.\n", (unsigned long long) ticksPerSec);
|
||||
}
|
||||
|
||||
@@ -173,7 +173,7 @@ extern "C" double epicsShareAPI
|
||||
epicsTimerQueuePassiveProcess ( epicsTimerQueuePassiveId pQueue )
|
||||
{
|
||||
try {
|
||||
return pQueue->process ( epicsTime::getCurrent() );
|
||||
return pQueue->process ( epicsTime::getMonotonic() );
|
||||
}
|
||||
catch ( ... ) {
|
||||
return 1.0;
|
||||
|
||||
@@ -118,7 +118,7 @@ inline double epicsTimer::getExpireDelay ()
|
||||
{
|
||||
epicsTimer::expireInfo info = this->getExpireInfo ();
|
||||
if ( info.active ) {
|
||||
double delay = info.expireTime - epicsTime::getCurrent ();
|
||||
double delay = info.expireTime - epicsTime::getMonotonic ();
|
||||
if ( delay < 0.0 ) {
|
||||
delay = 0.0;
|
||||
}
|
||||
|
||||
@@ -54,7 +54,7 @@ void timer::destroy ()
|
||||
|
||||
void timer::start ( epicsTimerNotify & notify, double delaySeconds )
|
||||
{
|
||||
this->start ( notify, epicsTime::getCurrent () + delaySeconds );
|
||||
this->start ( notify, epicsTime::getMonotonic () + delaySeconds );
|
||||
}
|
||||
|
||||
void timer::start ( epicsTimerNotify & notify, const epicsTime & expire )
|
||||
@@ -129,7 +129,7 @@ void timer::privateStart ( epicsTimerNotify & notify, const epicsTime & expire )
|
||||
|
||||
debugPrintf ( ("Start of \"%s\" with delay %f at %p preempting %u\n",
|
||||
typeid ( this->notify ).name (),
|
||||
expire - epicsTime::getCurrent (),
|
||||
expire - epicsTime::getMonotonic (),
|
||||
this, preemptCount ) );
|
||||
}
|
||||
|
||||
@@ -190,7 +190,7 @@ void timer::show ( unsigned int level ) const
|
||||
double delay;
|
||||
if ( this->curState == statePending || this->curState == stateActive ) {
|
||||
try {
|
||||
delay = this->exp - epicsTime::getCurrent();
|
||||
delay = this->exp - epicsTime::getMonotonic();
|
||||
}
|
||||
catch ( ... ) {
|
||||
delay = - DBL_MAX;
|
||||
|
||||
@@ -30,7 +30,7 @@ timerQueue::timerQueue ( epicsTimerQueueNotify & notifyIn ) :
|
||||
pExpireTmr ( 0 ),
|
||||
processThread ( 0 ),
|
||||
exceptMsgTimeStamp (
|
||||
epicsTime :: getCurrent () - exceptMsgMinPeriod ),
|
||||
epicsTime :: getMonotonic () - exceptMsgMinPeriod ),
|
||||
cancelPending ( false )
|
||||
{
|
||||
}
|
||||
@@ -49,7 +49,7 @@ void timerQueue ::
|
||||
char date[64];
|
||||
double delay;
|
||||
try {
|
||||
epicsTime cur = epicsTime :: getCurrent ();
|
||||
epicsTime cur = epicsTime :: getMonotonic ();
|
||||
delay = cur - this->exceptMsgTimeStamp;
|
||||
cur.strftime ( date, sizeof ( date ),
|
||||
"%a %b %d %Y %H:%M:%S.%f" );
|
||||
|
||||
@@ -73,7 +73,7 @@ void timerQueueActive :: _printLastChanceExceptionMessage (
|
||||
{
|
||||
char date[64];
|
||||
try {
|
||||
epicsTime cur = epicsTime :: getCurrent ();
|
||||
epicsTime cur = epicsTime :: getMonotonic ();
|
||||
cur.strftime ( date, sizeof ( date ), "%a %b %d %Y %H:%M:%S.%f");
|
||||
}
|
||||
catch ( ... ) {
|
||||
@@ -91,7 +91,7 @@ void timerQueueActive :: run ()
|
||||
epics::atomic::set(this->exitFlag, 0);
|
||||
while ( ! this->terminateFlag ) {
|
||||
try {
|
||||
double delay = this->queue.process ( epicsTime::getCurrent() );
|
||||
double delay = this->queue.process ( epicsTime::getMonotonic() );
|
||||
debugPrintf ( ( "timer thread sleeping for %g sec (max)\n", delay ) );
|
||||
this->rescheduleEvent.wait ( delay );
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user