libCom: NTP Time Provider adjusts to OS tick rate changes

Allow the NTP Time provider (used on VxWorks and RTEMS only)
to adapt to changes in the OS clock tick rate after the provider
has been initialized.

Changing the tick rate after iocInit() is not advisable,
other software might still misbehave if initialized before
an OS tick rate change.
This commit is contained in:
2014-02-13 10:09:12 -06:00
committed by Andrew Johnson
parent 0b374ef8a6
commit a3354f5db9
2 changed files with 18 additions and 11 deletions
+8
View File
@@ -15,6 +15,14 @@ EPICS Base 3.15.0.x releases are not intended for use in production systems.</p>
<h2 align="center">Changes between 3.15.0.1 and 3.15.0.2</h2>
<!-- Insert new items immediately below here ... -->
<h3>NTP Time Provider adjusts to OS tick rate changes</h3>
<p>Dirk Zimoch provided code that allows the NTP Time provider (used on VxWorks
and RTEMS only) to adapt to changes in the OS clock tick rate after the provider
has been initialized. Note that changing the tick rate after iocInit() is not
advisable, and that other software might still misbehave if initialized before
an OS tick rate change.</p>
<h3>Added newEpicsMutex macro</h3>
<p>Internal C++ uses of <tt>new epicsMutex()</tt> have been replaced with a new
+10 -11
View File
@@ -47,8 +47,6 @@ static struct {
epicsUInt32 syncTick;
epicsTimeStamp clockTime;
epicsUInt32 clockTick;
epicsUInt32 nsecsPerTick;
epicsUInt32 ticksPerSecond;
epicsUInt32 ticksToSkip;
double tickRate;
} NTPTimePvt;
@@ -90,8 +88,6 @@ static void NTPTime_InitOnce(void *pprio)
NTPTimePvt.loopEvent = epicsEventMustCreate(epicsEventEmpty);
NTPTimePvt.syncsFailed = 0;
NTPTimePvt.lock = epicsMutexCreate();
NTPTimePvt.ticksPerSecond = osdTickRateGet();
NTPTimePvt.nsecsPerTick = NSEC_PER_SEC / NTPTimePvt.ticksPerSecond;
/* Initialize OS-dependent code */
osdNTPInit();
@@ -100,7 +96,7 @@ static void NTPTime_InitOnce(void *pprio)
if (!osdNTPGet(&timespecNow)) {
NTPTimePvt.syncTick = osdTickGet();
if (timespecNow.tv_sec > POSIX_TIME_AT_EPICS_EPOCH && epicsTimeOK ==
epicsTimeFromTimespec(&NTPTimePvt.syncTime, &timespecNow)) {
epicsTimeFromTimespec(&NTPTimePvt.syncTime, &timespecNow)) {
NTPTimePvt.clockTick = NTPTimePvt.syncTick;
NTPTimePvt.clockTime = NTPTimePvt.syncTime;
NTPTimePvt.synchronized = 1;
@@ -191,7 +187,7 @@ static void NTPTimeSync(void *dummy)
if (diff >= 0.0) {
NTPTimePvt.ticksToSkip = 0;
} else { /* dont go back in time */
NTPTimePvt.ticksToSkip = -diff * NTPTimePvt.ticksPerSecond;
NTPTimePvt.ticksToSkip = -diff * osdTickRateGet();
}
NTPTimePvt.clockTick = tickNow;
NTPTimePvt.clockTime = timeNow;
@@ -230,10 +226,12 @@ static int NTPTimeGetCurrent(epicsTimeStamp *pDest)
}
if (ticksSince) {
epicsUInt32 secsSince = ticksSince / NTPTimePvt.ticksPerSecond;
ticksSince -= secsSince * NTPTimePvt.ticksPerSecond;
epicsUInt32 ticksPerSecond = osdTickRateGet();
epicsUInt32 nsecsPerTick = NSEC_PER_SEC / ticksPerSecond;
epicsUInt32 secsSince = ticksSince / ticksPerSecond;
NTPTimePvt.clockTime.nsec += ticksSince * NTPTimePvt.nsecsPerTick;
ticksSince -= secsSince * ticksPerSecond;
NTPTimePvt.clockTime.nsec += ticksSince * nsecsPerTick;
if (NTPTimePvt.clockTime.nsec >= NSEC_PER_SEC) {
secsSince++;
NTPTimePvt.clockTime.nsec -= NSEC_PER_SEC;
@@ -265,14 +263,15 @@ int NTPTime_Report(int level)
}
if (level) {
char lastSync[32];
epicsTimeToStrftime(lastSync, sizeof(lastSync),
"%Y-%m-%d %H:%M:%S.%06f", &NTPTimePvt.syncTime);
printf("Syncronization interval = %.1f seconds\n",
NTPTimeSyncInterval);
printf("Last synchronized at %s\n",
lastSync);
printf("OS tick rate = %u Hz (nominal)\n",
NTPTimePvt.ticksPerSecond);
printf("Current OS tick rate = %u Hz\n",
osdTickRateGet());
printf("Measured tick rate = %.3f Hz\n",
NTPTimePvt.tickRate);
osdNTPReport();