Comment 3 for bug 1392516

Revision history for this message
mdavidsaver (mdavidsaver) wrote :

Andrew asks:

> Can explain in writing which subsystems you think should be changed to use the monotonic clock? I suspect that may turn out to be a rather large can of worms (the like of which I have delved into before). I realize that's not relevant to this branch, but I would like to start thinking about it.

As previously stated the first candidate is the timer queue. Some worms can be expected here in trying to define behaviors for absolute and relative timers in one queue.

The FLL in dbScan should probably use monotonic time.

RSRV and logClient use epicsTimeGetCurrent() to test for timeouts. Strictly speaking this should be switched to monotonic time, but except for large jumps (resync after extended network partition) this wouldn't see any real work use.

I'd also like to revisit generalTime in a significant way. Performance wise I'd like to get rid of the global timeListLock and eventListLock locks. I'd also like to remove the current backwards time prevention check from the OSI layer, both because this is the primary reason for the locks, and because I think the design is inherently infeasible, and unnecessary for most targets.

The generalTime API tries to encompass two features which are conceptually separate.

1) epicsTimeGetEvent() Get the last (cached) time that some numbered event occurred.
2) epicsTimeGetCurrent() Provide real (wall clock) time an the moment the call is made.

There are also the associated support functions to add providers, and generalTimeGetExceptPriority() which is a slight generalization of epicsTimeGetCurrent().

And the variants epicsTimeGetEvent() and epicsTimeGetCurrentInt(), which only support a single provider, and promise to be safely callable in interrupt context.

1) epicsTimeGetEvent()

With epicsTimeGetEvent() I think it would be reasonable to remove support for multiple providers. Most IOCs have no event provider, some have one, but I'm not aware of any with more. Code-wise this could be identical to the ISR-safe variant, and could perhaps be deprecated in favor of the ISR safe variant.

It might also be interesting to combine this with the named events of dbScan and perhaps have Base maintain the event cache (in an ISR safe manner).

2) epicsTimeGetCurrent()

I think that epicsTimeGetCurrent() should become mostly OSD. The default except for RTEMS/vxWorks should be to use the OS current time calls with no backwards/jump protection. This would delegate maintenance of current time to the OS, which already has to do this.

Since RTEMS (and presumably vxWorks) lacks a common API for managing the OS tick timer, I would think to promote the present osiClockTime.c source as the default, perhaps with some ntpd-like logic to measure frequency and soften jumps by a linear scaling instead of just calling clock_settime().

Alternately, if RTEMS is the only holdout, maybe we fix RTEMS. While there is no uniform API, for PPC at least, there isn't much variation.

To handle the case where more than one real time source is available I would change the provider registration API to 1) only allow registration before iocInit(), 2) allow a newly registered provider to learn about the existing provider to allow the possibility of chaining.

Another idea I have is to hijack the existing current time provider API so that instead of being called from every epicsTimeGetCurrent(), to run a thread to periodically call the provider and publish the result via the NTPD shared memory protocol (as is done by mrfioc2).

This would be directly usable on all *nix targets, and probably even on windows http://www.satsignal.eu/ntp/setup.html

This may be too specialized for Base, but it is possible.