EPICS Controls Argonne National Laboratory

Experimental Physics and
Industrial Control System

2002  2003  2004  2005  2006  2007  2008  2009  2010  2011  2012  2013  2014  <20152016  2017  2018  2019  2020  2021  2022  2023  2024  Index 2002  2003  2004  2005  2006  2007  2008  2009  2010  2011  2012  2013  2014  <20152016  2017  2018  2019  2020  2021  2022  2023  2024 
<== Date ==> <== Thread ==>

Subject: Re: Problem with generalTime clock synchronization
From: Andrew Johnson <[email protected]>
To: <[email protected]>
Date: Tue, 15 Dec 2015 18:39:35 -0600
On 12/15/2015 05:19 PM, Michael Davidsaver wrote:
> 
> FYI, mrfioc2 also uses this to initialize the EVG's time from its NTP
> source (since this can't be queried directly w/o OS dependent calls).

I've been working on a major new release of the apsEvent system, so
similar to your experience.

> I'd like to see what exactly your doing, but I don't think this will be
> an issue.

See attached patch, untested at this point though.

> I would point out that allowing jumps backwards will allow timers to
> expire early as the timer queue uses general time. 

The epicsEventWaitWithTimeout() and epicsThreadSleep() APIs are both
safe since they're implemented using tick counts on the two RTOS's, but
you're talking about Jeff's epicsTimer implementations, which I now see
do absolute time comparisons to determine when a timer should go off.

I'm not sure how big a problem this is in practice.

We could apply a configurable maximum limit to the time change that we
send to the clock_settime() routine, and make the ClockTimeSyncInterval
a configurable parameter instead of a macro. Alternatively maintain an
offset to the OS clock that we slowly adjust.

The osiNTPTime provider currently never returns a backwards jump, but I
suspect that could be taken out. In fact the code could be rewritten to
measure the actual OS tick rate and correct it against the NTP server.

> Changing this situation is the motivation behind:
> 
> https://bugs.launchpad.net/epics-base/+bug/1392516
> 
> https://code.launchpad.net/~epics-core/epics-base/monotonictime/+merge/269124

Obviously related, but not quite the same issue IMHO.

Anyway I'm out of time right now, I'm sure there'll be more discussion
tomorrow.

- Andrew

-- 
Light thinks it travels faster than anything but it is wrong.
No matter how fast light travels, it finds the darkness has
always got there first, and is waiting for it.
    -- Terry Pratchett, Reaper Man
=== modified file 'src/libCom/osi/epicsGeneralTime.c'
--- src/libCom/osi/epicsGeneralTime.c	2013-12-11 23:50:29 +0000
+++ src/libCom/osi/epicsGeneralTime.c	2015-12-15 23:06:59 +0000
@@ -98,18 +98,43 @@
 
         status = ptp->get.Time(pDest);
         if (status == epicsTimeOK) {
+            /* time from this API may not be monotonic */
+            if (ignore == 0)
+                gtPvt.lastTimeProvider = ptp;
+            if (pPrio)
+                *pPrio = ptp->priority;
+            break;
+        }
+    }
+    if (status == epicsTimeERROR &&
+        ignore == 0)
+        gtPvt.lastTimeProvider = NULL;
+    epicsMutexUnlock(gtPvt.timeListLock);
+
+    return status;
+}
+
+int epicsShareAPI epicsTimeGetCurrent(epicsTimeStamp *pDest)
+{
+    gtProvider *ptp;
+    int status = epicsTimeERROR;
+
+    generalTime_Init();
+
+    epicsMutexMustLock(gtPvt.timeListLock);
+    for (ptp = (gtProvider *)ellFirst(&gtPvt.timeProviders);
+         ptp; ptp = (gtProvider *)ellNext(&ptp->node)) {
+
+        status = ptp->get.Time(pDest);
+        if (status == epicsTimeOK) {
             /* check time is monotonic */
             if (epicsTimeGreaterThanEqual(pDest, &gtPvt.lastProvidedTime)) {
                 gtPvt.lastProvidedTime = *pDest;
-                if (ignore == 0)
-                    gtPvt.lastTimeProvider = ptp;
-                if (pPrio)
-                    *pPrio = ptp->priority;
+                gtPvt.lastTimeProvider = ptp;
             } else {
                 int key;
+
                 *pDest = gtPvt.lastProvidedTime;
-                if (pPrio)
-                    *pPrio = gtPvt.lastTimeProvider->priority;
                 key = epicsInterruptLock();
                 gtPvt.ErrorCounts++;
                 epicsInterruptUnlock(key);
@@ -117,19 +142,13 @@
             break;
         }
     }
-    if (status == epicsTimeERROR &&
-        ignore == 0)
+    if (status == epicsTimeERROR)
         gtPvt.lastTimeProvider = NULL;
     epicsMutexUnlock(gtPvt.timeListLock);
 
     return status;
 }
 
-int epicsShareAPI epicsTimeGetCurrent(epicsTimeStamp *pDest)
-{
-    return generalTimeGetExceptPriority(pDest, NULL, 0);
-}
-
 int epicsTimeGetCurrentInt(epicsTimeStamp *pDest)
 {
     gtProvider *ptp = gtPvt.lastTimeProvider;


Replies:
Re: Problem with generalTime clock synchronization J. Lewis Muir
Re: Problem with generalTime clock synchronization Michael Davidsaver
References:
Problem with generalTime clock synchronization Andrew Johnson
Re: Problem with generalTime clock synchronization Michael Davidsaver

Navigate by Date:
Prev: Re: Problem with generalTime clock synchronization Michael Davidsaver
Next: Re: Problem with generalTime clock synchronization J. Lewis Muir
Index: 2002  2003  2004  2005  2006  2007  2008  2009  2010  2011  2012  2013  2014  <20152016  2017  2018  2019  2020  2021  2022  2023  2024 
Navigate by Thread:
Prev: Re: Problem with generalTime clock synchronization Michael Davidsaver
Next: Re: Problem with generalTime clock synchronization J. Lewis Muir
Index: 2002  2003  2004  2005  2006  2007  2008  2009  2010  2011  2012  2013  2014  <20152016  2017  2018  2019  2020  2021  2022  2023  2024 
ANJ, 16 Dec 2015 Valid HTML 4.01! · Home · News · About · Base · Modules · Extensions · Distributions · Download ·
· Search · EPICS V4 · IRMIS · Talk · Bugs · Documents · Links · Licensing ·