static int ClockTimeGetCurrent(epicsTimeStamp *pDest) { struct timespec clockNow; /* If a Hi-Res clock is available and works, use it */ #ifdef CLOCK_REALTIME_HR clock_gettime(CLOCK_REALTIME_HR, &clockNow) && #endif clock_gettime(CLOCK_REALTIME, &clockNow); if (!ClockTimePvt.synchronized && clockNow.tv_sec < POSIX_TIME_AT_EPICS_EPOCH) { clockNow.tv_sec = POSIX_TIME_AT_EPICS_EPOCH + 86400; clockNow.tv_nsec = 0; clock_settime(CLOCK_REALTIME, &clockNow); errlogPrintf("WARNING: OS Clock time was read before being set.\n" "Using 1990-01-02 00:00:00.000000 UTC\n"); } epicsTimeFromTimespec(pDest, &clockNow); return 0; }
static void NTPTime_InitOnce(void *pprio) { struct timespec timespecNow; NTPTimePvt.synchronize = 1; NTPTimePvt.synchronized = 0; NTPTimePvt.loopEvent = epicsEventMustCreate(epicsEventEmpty); NTPTimePvt.syncsFailed = 0; NTPTimePvt.lock = epicsMutexCreate(); /* Initialize OS-dependent code */ osdNTPInit(); /* Try to sync with NTP server */ if (!osdNTPGet(×pecNow)) { NTPTimePvt.syncTick = osdTickGet(); if (timespecNow.tv_sec > POSIX_TIME_AT_EPICS_EPOCH && epicsTimeOK == epicsTimeFromTimespec(&NTPTimePvt.syncTime, ×pecNow)) { NTPTimePvt.clockTick = NTPTimePvt.syncTick; NTPTimePvt.clockTime = NTPTimePvt.syncTime; NTPTimePvt.synchronized = 1; } } /* Start the sync thread */ epicsThreadCreate("NTPTimeSync", epicsThreadPriorityHigh, epicsThreadGetStackSize(epicsThreadStackSmall), NTPTimeSync, NULL); epicsAtExit(NTPTime_Shutdown, NULL); /* Register the iocsh commands */ iocshRegister(&ReportFuncDef, ReportCallFunc); iocshRegister(&ShutdownFuncDef, ShutdownCallFunc); /* Finally register as a time provider */ generalTimeRegisterCurrentProvider("NTP", *(int *)pprio, NTPTimeGetCurrent); }
static void NTPTimeSync(void *dummy) { taskwdInsert(0, NULL, NULL); for (epicsEventWaitWithTimeout(NTPTimePvt.loopEvent, NTPTimeSyncInterval); NTPTimePvt.synchronize; epicsEventWaitWithTimeout(NTPTimePvt.loopEvent, NTPTimeSyncInterval)) { int status; struct timespec timespecNow; epicsTimeStamp timeNow; epicsUInt32 tickNow; double diff; double ntpDelta; status = osdNTPGet(×pecNow); tickNow = osdTickGet(); if (status) { if (++NTPTimePvt.syncsFailed > NTPTimeSyncRetries && NTPTimePvt.synchronized) { errlogPrintf("NTPTimeSync: NTP requests failing - %s\n", strerror(errno)); NTPTimePvt.synchronized = 0; } continue; } if (timespecNow.tv_sec <= POSIX_TIME_AT_EPICS_EPOCH || epicsTimeFromTimespec(&timeNow, ×pecNow) == epicsTimeERROR) { errlogPrintf("NTPTimeSync: Bad time received from NTP server\n"); NTPTimePvt.synchronized = 0; continue; } ntpDelta = epicsTimeDiffInSeconds(&timeNow, &NTPTimePvt.syncTime); if (ntpDelta <= 0.0 && NTPTimePvt.synchronized) { errlogPrintf("NTPTimeSync: NTP time not increasing, delta = %g\n", ntpDelta); NTPTimePvt.synchronized = 0; continue; } NTPTimePvt.syncsFailed = 0; if (!NTPTimePvt.synchronized) { errlogPrintf("NTPTimeSync: Sync recovered.\n"); } epicsMutexMustLock(NTPTimePvt.lock); diff = epicsTimeDiffInSeconds(&timeNow, &NTPTimePvt.clockTime); if (diff >= 0.0) { NTPTimePvt.ticksToSkip = 0; } else { /* dont go back in time */ NTPTimePvt.ticksToSkip = -diff * osdTickRateGet(); } NTPTimePvt.clockTick = tickNow; NTPTimePvt.clockTime = timeNow; NTPTimePvt.synchronized = 1; epicsMutexUnlock(NTPTimePvt.lock); NTPTimePvt.tickRate = (tickNow - NTPTimePvt.syncTick) / ntpDelta; NTPTimePvt.syncTick = tickNow; NTPTimePvt.syncTime = timeNow; } NTPTimePvt.synchronized = 0; taskwdRemove(0); }