<div dir="ltr"><br><div class="gmail_extra"><br><div class="gmail_quote">On Mon, Jul 18, 2016 at 11:02 AM, Ben Coman <span dir="ltr">&lt;<a href="mailto:btc@openinworld.com" target="_blank">btc@openinworld.com</a>&gt;</span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">Hi All,<br>
<br>
Did anything further come of this discussion...<br>
<div><div class="h5"><br>
On Wed, Feb 17, 2016 at 1:13 AM, Eliot Miranda &lt;<a href="mailto:eliot.miranda@gmail.com">eliot.miranda@gmail.com</a>&gt; wrote:<br>
&gt; Hi Tim,<br>
&gt;<br>
&gt; On Tue, Feb 16, 2016 at 2:19 AM, Tim Felgentreff &lt;<a href="mailto:timfelgentreff@gmail.com">timfelgentreff@gmail.com</a>&gt;<br>
&gt; wrote:<br>
&gt;&gt;<br>
&gt;&gt; Hi Eliot,<br>
&gt;&gt;<br>
&gt;&gt; am I understanding correctly that (one of) your ideas is to have just one<br>
&gt;&gt; clock that &quot;drifts&quot; towards wall clock time? How fast would it drift? I<br>
&gt;&gt; agree this would be neat for a local image, but what if someone from Japan<br>
&gt;&gt; sends me their image (happened to me just last week) and wants me to check<br>
&gt;&gt; something in it? Will the in-image clock run slow for a few hours until my<br>
&gt;&gt; timezone has caught up with Japan?<br>
&gt;<br>
&gt;<br>
&gt; First, the timezone issue is completely separate, and is only an image<br>
&gt; issue.  The VM&#39;s time basis is UTC microseconds since 1901 (see Time<br>
&gt; class&gt;&gt;utcMicrosecondClock).  This should answer the same value at the same<br>
&gt; time, within the bounds of clock drift, any where on the globe.  So if you<br>
&gt; are sent an image from Japan nothing changes to times in that image when yu<br>
&gt; start it locally, except for the inaccuracies between wall time (some atomic<br>
&gt; clock somewhere) and your machine and the machine on which the image was<br>
&gt; saved in Japan.<br>
&gt;<br>
&gt; As a convenience the VM also offers microseconds since 1901 in local time<br>
&gt; (see Time class&gt;&gt;localMicrosecondClock).  This is suitable for deriving UI<br>
&gt; times to display to the user, or times to write to a log, etc.  But it is<br>
&gt; /not/ to be used to schedule delays, etc, etc.<br>
&gt;<br>
&gt; Second, yes, the idea is to have the VM drift time towards wall time.  First<br>
&gt; some back ground.<br>
&gt;<br>
&gt; By wall time I mean the UTC time as provided by some atomic clock, i.e. an<br>
&gt; extremely accurate absolute time as is accessed by a network time protocol<br>
&gt; daemon (ntpd) to keep one&#39;s machine&#39;s clock accurate.<br>
&gt; Current hardware provide inaccurate clocks.  See e.g.<br>
&gt; <a href="http://www.pcworld.com/article/2891892/why-computers-still-struggle-to-tell-the-time.html" rel="noreferrer" target="_blank">http://www.pcworld.com/article/2891892/why-computers-still-struggle-to-tell-the-time.html</a>.<br>
&gt; One can expect such hardware to drift relative to wall time by less than a<br>
&gt; minute a day, but still drift by ammounts noticeable to humans over the<br>
&gt; course of hours.<br>
&gt; OS&#39;s such as Mac OS and linux provide several clocks, two of which are of<br>
&gt; interest.  One is the computer&#39;s notion of wall time, typically provided by<br>
&gt; gettimeofday.  I&#39;m going to call this &quot;local time&quot;.  This clock can run fast<br>
&gt; or slow and can jump backwards.  It does this because the underlying clock<br>
&gt; drifts relative to wall time (and I guess may drift faster or slower<br>
&gt; depending on temperature) and periodically is corrected by ntpd.<br>
&gt; The second notion of time is monotonic time which is a local clock (the<br>
&gt; hardware&#39;s underlying clock) which is guaranteed to advance monotonically<br>
&gt; but is not guaranteed to agree with local time, let alone wall time.  On<br>
&gt; Unix this is provided by clock_gettime and on Mac OS X by mach_absolute_time<br>
&gt; (see Ryan&#39;s message below).   I&#39;m going to call this &quot;monotonic time&quot;.<br>
&gt;<br>
&gt; The issue is that because local time jumps around it can&#39;t be used to<br>
&gt; measure durations reliably.  If you&#39;re profiling something using local time<br>
&gt; and half-way through something the ntpd adjusts local time then one&#39;s<br>
&gt; measurements will be off.  One solution to this is to use monotonic time.<br>
&gt; The problem is that this complicates the programmer model.  It is now up to<br>
&gt; the programmer to understand the difference between local and monotonic<br>
&gt; times and use the &quot;right clock&quot; in the &quot;right circumstances&quot;.  This seems to<br>
&gt; me to be against the Smalltalk approach, which is to provide a safe virtual<br>
&gt; machine which protects the programmer from the vagaries and dangers of real<br>
&gt; machines.<br>
<br>
</div></div>The flip side of this is it restricts the tools available to a<br>
programmer at the Image level, and adds complexity to the VM that<br>
Image programmers can&#39;t see if ThingsGoWrong(TM).  If the Image had<br>
direct access to the several clocks provided by clock_gettime(), it<br>
would be possible for an Image level programmer to explore and<br>
*understand* the difference in them.  I know I could write a routine<br>
in C to explore this, but I&#39;d prefer to do it in Smalltalk.<br>
<br>
Indeed for Delay scheduler, it might be good to choose between<br>
CLOCK_MONOTONIC and CLOCK_MONOTONIC_RAW without modifying the VM, and<br>
observe what happens when I set the system time back a couple of days.<br>
Or maybe explore  CLOCK_PROCESS_CPUTIME_ID for benchmarking.<br>
<span class=""><br>
&gt; Further I think that providing a more ideal clock is<br>
&gt; straight-forward.  Here&#39;s what I propose.<br>
<br>
<br>
</span>But why do our own slewing to match local &quot;real&quot; time, when it seems<br>
NTP already slews CLOCK_MONOTONIC to wall-time using adjtime [1].<br></blockquote><div><br></div><div>What do we do on platforms that don&#39;t have adjtime?  The skewing algorithm is simple and adding it to the VM means we&#39;re not dependent on adjtime.  Isn&#39;t that a good thing?</div><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
<br>
There seem to be a couple of choices to making clock_gettime() cross platform...<br>
a. <a href="https://gist.github.com/alfwatt/3588c5aa1f7a1ef7a3bb" rel="noreferrer" target="_blank">https://gist.github.com/alfwatt/3588c5aa1f7a1ef7a3bb</a><br>
b. <a href="https://github.com/ThomasHabets/monotonic_clock" rel="noreferrer" target="_blank">https://github.com/ThomasHabets/monotonic_clock</a><br>
<br>
[1] <a href="http://man7.org/linux/man-pages/man2/clock_gettime.2.html" rel="noreferrer" target="_blank">http://man7.org/linux/man-pages/man2/clock_gettime.2.html</a></blockquote><div><br></div><div>Sure.  It&#39;s implementable.  Why not add the simple algorithm to our VM and then we&#39;re done?</div><div><br></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div><div class="h5">
&gt; The Cog VMs use a heartbeat to control the rate at which the VM checks for<br>
&gt; external input, delay expiry, etc.  This is typically a 500Hz/2ms heartbeat,<br>
&gt; but for the purposes of this discussion let&#39;s imagine its a 1Khz/1ms<br>
&gt; heartbeat.  One thing that happens every heartbeat is that the VM updates<br>
&gt; its notion of local time.  Currently the VM&#39;s notion of local time can jump<br>
&gt; forwards or backwards because of ntpd activity.<br>
&gt;<br>
&gt; Current computer clocks are accurate to a few seconds a day, but let&#39;s<br>
&gt; assume a pessimal accuracy of 1 second an hour.  That&#39;s an accuracy of<br>
&gt; 1/3600, 0r 0.0277777%.  If the heartbeat accesses both local time (via<br>
&gt; gettimeofday) and monotonic time (via clock_gettime) on every heartbeat it<br>
&gt; can compute a delta which it computes from the difference between local and<br>
&gt; monotonic times.  On each heartbeat it sums the delta to compute an offset<br>
&gt; and applies this offset to monotonic time.  The VM then answers offset<br>
&gt; monotonic time as the value of &quot;wall time&quot;.  If we restrict the the delta on<br>
&gt; each heartbeat we can keep the VMs clock monotonic and have it drift towards<br>
&gt; local time, which itself is periodically corrected to wall time by ntpd.<br>
&gt; If, for example, the delta is restricted to +/-5usecs when moving in one<br>
&gt; direction and +/-10usecs when changing direction, the VM&#39;s notion of<br>
&gt; monotonic time advances within 1% of actual monotonic time and approaches<br>
&gt; local time &quot;soon&quot;, since, because monotonic time is reasonably accurate a<br>
&gt; rate of change of 1% soon overcomes a drift of at most 0.0277777%.<br>
&gt;<br>
&gt; Let&#39;s express this as a Smalltalk class.  Units are microseconds (usecs).<br>
&gt;<br>
&gt; Object subclass: VMClock instanceVariableNames: &#39;offset now&#39;<br>
&gt;<br>
&gt; initialize<br>
&gt; now := OperatingSystem gettimeofday.<br>
&gt; offset := now - OperatingSystem clock_gettime<br>
&gt;<br>
&gt; run<br>
&gt; &quot;Compute now every 1ms such that now approaches localTime.&quot;<br>
&gt; [(Delay forMilliseconds: 1) wait.<br>
&gt; self computeNowGivenMonotonic: OperatingSystem clock_gettime andLocal:<br>
&gt; OperatingSystem gettimeofday.<br>
&gt; true] whileTrue<br>
&gt;<br>
&gt; computeNowGivenMonotonic: monotonicTime andLocal: localTime<br>
&gt; &quot;Compute now such that now approaches localTime.&quot;<br>
&gt; | difference putativeNow delta |<br>
&gt; &quot;Note now = (monotonicTime + offset) and we want (monotonicTime + offset) =<br>
&gt; localTime.<br>
&gt; delta is the ammount to change offset by in this tick.&quot;<br>
&gt; localTime = monotonicTime<br>
&gt; ifTrue:<br>
&gt; [&quot;the two clocks agree; if an offset is in effect, reduce it by no more than<br>
&gt; 5 usecs&quot;<br>
&gt; delta := offset &gt;= 0<br>
&gt; ifTrue: [(offset min: 5) negated]<br>
&gt; ifFalse: [(offset max: -5) negated]]<br>
&gt; ifFalse:<br>
&gt; [putativeNow := monotonicTime + offset.<br>
&gt; difference := localTime - putativeNow.<br>
&gt; delta := 0.<br>
&gt; difference &lt; 0 ifTrue: &quot;localTime is behind; make the offset more negative<br>
&gt; by no more than 5 usecs&quot;<br>
&gt; [delta := difference max: (offset &gt;= 0 ifTrue: [-10] ifFalse: [-5])].<br>
&gt; difference &gt; 0 ifTrue: &quot;localTime is ahead; make the offset more positive by<br>
&gt; no more than 5 usecs&quot;<br>
&gt; [delta := difference min: (offset &gt;= 0 ifTrue: [5] ifFalse: [10])]].<br>
&gt; offset := offset + delta.<br>
&gt; now := monotonicTime + offset.<br>
&gt; ^now<br>
&gt;<br>
&gt; I&#39;ve written and attached a little test program that randomly offsets<br>
&gt; localTime every &quot;3.6 seconds&quot; in a simulation.  Here&#39;s the simulation; the<br>
&gt; drift is exaggerated:<br>
&gt;<br>
&gt; run<br>
&gt; &quot;VMClockTester new run&quot;<br>
&gt; &quot;VMClockTester new run last: 20&quot;<br>
&gt; &quot;VMClockTester new run copyFrom: 36 * 3 - 5 to: 36 * 3 + 50&quot;<br>
&gt; | times |<br>
&gt; times := (Array new: 1000) writeStream.<br>
&gt; 1 to: 1000000 do: &quot;1 million ticks = 1000 seconds&quot;<br>
&gt; [:i|<br>
&gt; monotonicClock := monotonicClock + 1000.<br>
&gt; localClock := localClock + 1000 + (i \\ 3600 = 0<br>
&gt; ifTrue: [| drift |<br>
&gt; [(drift := (drifter next - 0.5 * (20 * 3600)) rounded) = 0] whileTrue.<br>
&gt; drift]<br>
&gt; ifFalse: [0]).<br>
&gt; self computeNowGivenMonotonic: monotonicClock andLocal: localClock.<br>
&gt; i \\ 100 = 0 ifTrue:<br>
&gt; [times nextPut: {now. offset. monotonicClock. localClock. monotonicClock -<br>
&gt; localClock. now - localClock}]].<br>
&gt; ^times contents<br>
&gt;<br>
&gt; Here&#39;s what happens on the third perturbation.  Before the perturbation<br>
&gt; localTime is behind monotonicTime by 13ms, and the offset has stabilised to<br>
&gt; -13ms.  At the perturbation localTime jumps to 44ms behind monotonic time,<br>
&gt; and over successive iterations the offset increases (negatively) and the<br>
&gt; error is reduced from 30ms to 13ms.<br>
</div></div>[snip]<br>
<span class="">&gt;<br>
&gt; Here&#39;s the last 20 entries.  localTime is now 197ms ahead of monotonic time,<br>
&gt; and the offset reduces from 221ms to 202ms, and the difference between now<br>
&gt; and localTime reduces from 24ms to 5ms.<br>
</span>[snip]<br>
<div><div class="h5">&gt;<br>
&gt; Note that a clock that is accurate to within 1% is more than accurate enough<br>
&gt; for good time measurements.  the VM&#39;s GC introduces pauses of around 1ms<br>
&gt; even on fast hardware, and the occasional code zone reclamation introduces<br>
&gt; similar pauses.  So times can be affected by the odd millisecond anyway.<br>
&gt;<br>
&gt; I&#39;m sure the above is some standard piece of control theory but apart from<br>
&gt; one open university program I&#39;ll never forget which began with attempts to<br>
&gt; make a moving model tank target a moving object and ended with a sparrow on<br>
&gt; a wind-blown branch keeping its head perfectly stationary, I&#39;ve never<br>
&gt; studied it.  Anyone who knows what the above algorithm&#39;s known as please let<br>
&gt; me know.<br>
&gt;<br>
&gt;&gt; Also, this sounds like a lot of logic to have in the VM and a source of<br>
&gt;&gt; possible confusion for the user - they would have to know to use the right<br>
&gt;&gt; invocations for measuring timespans, and not rely on a naive &quot;let&#39;s get the<br>
&gt;&gt; time now and subtract it from the time later to get the difference&quot;, because<br>
&gt;&gt; they might end up with a timespan over &quot;slow&quot; or &quot;fast&quot; seconds.<br>
&gt;<br>
&gt;<br>
&gt; No, that&#39;s exactly the point.  With the above algorithm in use, (I believe)<br>
&gt; time is never more than 1% inaccurate, but converges on wall time, and hence<br>
&gt; the programmer can use one clock for both measurement and determining wall<br>
&gt; time.  The only assumptions are that computer clocks are accurate to more<br>
&gt; than 1% and that the ntpd daemon adjusts the local notion of wall time based<br>
&gt; on a reputable clock.<br>
&gt;<br>
&gt;<br>
&gt; Review appreciated.<br>
&gt;<br>
&gt;&gt; cheers,<br>
&gt;&gt; Tim<br>
&gt;&gt;<br>
&gt;&gt; On 16 February 2016 at 00:49, Eliot Miranda &lt;<a href="mailto:eliot.miranda@gmail.com">eliot.miranda@gmail.com</a>&gt;<br>
&gt;&gt; wrote:<br>
&gt;&gt;&gt;<br>
&gt;&gt;&gt; Hi Levente, Hi Bert, Hi All,<br>
&gt;&gt;&gt;<br>
&gt;&gt;&gt; On Mon, Feb 15, 2016 at 3:39 PM, Levente Uzonyi &lt;<a href="mailto:leves@caesar.elte.hu">leves@caesar.elte.hu</a>&gt;<br>
&gt;&gt;&gt; wrote:<br>
&gt;&gt;&gt;&gt;<br>
&gt;&gt;&gt;&gt; On Mon, 15 Feb 2016, Bert Freudenberg wrote:<br>
&gt;&gt;&gt;&gt;<br>
&gt;&gt;&gt;&gt;&gt;<br>
&gt;&gt;&gt;&gt;&gt;&gt; On 15.02.2016, at 10:17, marcel.taeumel &lt;<a href="mailto:Marcel.Taeumel@hpi.de">Marcel.Taeumel@hpi.de</a>&gt; wrote:<br>
&gt;&gt;&gt;&gt;&gt;&gt;<br>
&gt;&gt;&gt;&gt;&gt;&gt; Hi Bert,<br>
&gt;&gt;&gt;&gt;&gt;&gt;<br>
&gt;&gt;&gt;&gt;&gt;&gt; this was just a regression. There has always been this check in the<br>
&gt;&gt;&gt;&gt;&gt;&gt; past for<br>
&gt;&gt;&gt;&gt;&gt;&gt; Morphic projects and still today for MVC projects.<br>
&gt;&gt;&gt;&gt;&gt;<br>
&gt;&gt;&gt;&gt;&gt;<br>
&gt;&gt;&gt;&gt;&gt; Ah, so we lost the check at some point?<br>
&gt;&gt;&gt;&gt;&gt;<br>
&gt;&gt;&gt;&gt;&gt;&gt; If you would have used VM or OS startup time, this would still be<br>
&gt;&gt;&gt;&gt;&gt;&gt; problematic after an overflow. (Hence the comment about snapshotting).<br>
&gt;&gt;&gt;&gt;&gt;&gt; So,<br>
&gt;&gt;&gt;&gt;&gt;&gt; this fix does not directly address the discussion about synching<br>
&gt;&gt;&gt;&gt;&gt;&gt; #millisecondClockValue to wall clock.<br>
&gt;&gt;&gt;&gt;&gt;<br>
&gt;&gt;&gt;&gt;&gt;<br>
&gt;&gt;&gt;&gt;&gt; I still think it should answer milliseconds since startup. Why would we<br>
&gt;&gt;&gt;&gt;&gt; change that?<br>
&gt;&gt;&gt;&gt;<br>
&gt;&gt;&gt;&gt;<br>
&gt;&gt;&gt;&gt; Eliot changed it recently. Probably to avoid the rollover issues. The<br>
&gt;&gt;&gt;&gt; correct fix would be to use to UTC clock instead of the local one in Time<br>
&gt;&gt;&gt;&gt; class &gt;&gt; #millisecondClockValue.<br>
&gt;&gt;&gt;<br>
&gt;&gt;&gt;<br>
&gt;&gt;&gt; I changed it for simplicity.  Alas it turns out to be a much more complex<br>
&gt;&gt;&gt; issue.  Here&#39;s a discussion I&#39;m having with Ryan Macnak, which covers what<br>
&gt;&gt;&gt; his team did with the Dart VM.  Please read, it&#39;s interesting.<br>
&gt;&gt;&gt;<br>
&gt;&gt;&gt;<br>
&gt;&gt;&gt;  On Sun, Feb 14, 2016 at 12:08 AM, Ryan Macnak &lt;<a href="mailto:rmacnak@gmail.com">rmacnak@gmail.com</a>&gt; wrote:<br>
&gt;&gt;&gt;&gt;<br>
&gt;&gt;&gt;&gt; On Sat, Feb 13, 2016 at 5:32 PM, Eliot Miranda &lt;<a href="mailto:eliot.miranda@gmail.com">eliot.miranda@gmail.com</a>&gt;<br>
&gt;&gt;&gt;&gt; wrote:<br>
&gt;&gt;&gt;&gt;&gt;<br>
&gt;&gt;&gt;&gt;&gt; Hi Ryan,<br>
&gt;&gt;&gt;&gt;&gt;<br>
&gt;&gt;&gt;&gt;&gt;<br>
&gt;&gt;&gt;&gt;&gt; On Sat, Feb 13, 2016 at 11:21 AM, Ryan Macnak &lt;<a href="mailto:rmacnak@gmail.com">rmacnak@gmail.com</a>&gt;<br>
&gt;&gt;&gt;&gt;&gt; wrote:<br>
&gt;&gt;&gt;&gt;&gt;&gt;<br>
&gt;&gt;&gt;&gt;&gt;&gt; On Thu, Feb 11, 2016 at 10:46 PM, Eliot Miranda<br>
&gt;&gt;&gt;&gt;&gt;&gt; &lt;<a href="mailto:eliot.miranda@gmail.com">eliot.miranda@gmail.com</a>&gt; wrote:<br>
&gt;&gt;&gt;&gt;&gt;<br>
&gt;&gt;&gt;&gt;&gt;     Further back Ryan wrote:<br>
&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;<br>
&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt; 5) Travis found an assertion failure. Unfortunately the assertions<br>
&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt; fail to include paths with the line numbers.<br>
&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;<br>
&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;<br>
&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt; (newUtcMicrosecondClock &gt;= utcMicrosecondClock 124)<br>
&gt;&gt;&gt;&gt;&gt;&gt;&gt;<br>
&gt;&gt;&gt;&gt;&gt;&gt;&gt;<br>
&gt;&gt;&gt;&gt;&gt;&gt;&gt; It&#39;s easy to track down.  Just grep for the string.  You&#39;ll find it<br>
&gt;&gt;&gt;&gt;&gt;&gt;&gt; in sqUnixHeartbeat.c.  I&#39;ve seen this from time to time, and have yet to<br>
&gt;&gt;&gt;&gt;&gt;&gt;&gt; understand it. What OS are you seeing this on?<br>
&gt;&gt;&gt;&gt;&gt;&gt;<br>
&gt;&gt;&gt;&gt;&gt;&gt;<br>
&gt;&gt;&gt;&gt;&gt;&gt; Linux. Looking at the comment above this assert, I see Cog is using<br>
&gt;&gt;&gt;&gt;&gt;&gt; the wrong clock. One should not rely on the realtime clock (gettimeofday) to<br>
&gt;&gt;&gt;&gt;&gt;&gt; move steadily forward. It can jump around due to NTP syncs, the machine<br>
&gt;&gt;&gt;&gt;&gt;&gt; sleeping or the user changing the time settings. Programs running at startup<br>
&gt;&gt;&gt;&gt;&gt;&gt; on the Raspberry Pi in particular can see very large jumps because it has no<br>
&gt;&gt;&gt;&gt;&gt;&gt; hardware clock (battery too expensive) so the first NTP sync will be a very<br>
&gt;&gt;&gt;&gt;&gt;&gt; large correction. We fixed this in the Dart VM a few months ago. Timers need<br>
&gt;&gt;&gt;&gt;&gt;&gt; to be scheduled using the monotonic clock (Linux clock_gettime, Mac<br>
&gt;&gt;&gt;&gt;&gt;&gt; mach_absolute_time).<br>
&gt;&gt;&gt;&gt;&gt;<br>
&gt;&gt;&gt;&gt;&gt;<br>
&gt;&gt;&gt;&gt;&gt; Yes, this isn&#39;t satisfactory either.  One needs the VM to answer<br>
&gt;&gt;&gt;&gt;&gt; something that is close to wall time, not drift over time.  I think there<br>
&gt;&gt;&gt;&gt;&gt; needs to be some clever averaging algorithm that has the property of always<br>
&gt;&gt;&gt;&gt;&gt; advancing the clock but trying to converge on wall time.<br>
&gt;&gt;&gt;&gt;&gt;<br>
&gt;&gt;&gt;&gt;&gt;<br>
&gt;&gt;&gt;&gt;&gt; One can imagine on every occasion that the VM updates its notion of the<br>
&gt;&gt;&gt;&gt;&gt; time it accesses both clock_gettime and gettimeofday and computes an offset<br>
&gt;&gt;&gt;&gt;&gt; that is some fraction of the delta between the current clock_gettime and the<br>
&gt;&gt;&gt;&gt;&gt; previous clock_gettime multiplied by the difference between the two clocks.<br>
&gt;&gt;&gt;&gt;&gt; So the VM time is always monotonic, but hunts towards wall time as answered<br>
&gt;&gt;&gt;&gt;&gt; by gettimeofday.<br>
&gt;&gt;&gt;&gt;&gt;<br>
&gt;&gt;&gt;&gt;&gt;<br>
&gt;&gt;&gt;&gt;&gt; Thanks. I was unaware of clock_gettime &amp; mach_absolute_time.  Given<br>
&gt;&gt;&gt;&gt;&gt; these two it shouldn;t be too hard to concoct something that works.  Or is<br>
&gt;&gt;&gt;&gt;&gt; that the approach you&#39;ve taken in Dart?  Or are there standard algorithms<br>
&gt;&gt;&gt;&gt;&gt; out there?  I&#39;ll take a look.<br>
&gt;&gt;&gt;&gt;<br>
&gt;&gt;&gt;&gt;<br>
&gt;&gt;&gt;&gt; I&#39;m not seeing why it needs to be close to wall time. The VM needs make<br>
&gt;&gt;&gt;&gt; both a wall clock and a monotonic clock available to the image.<br>
<br>
<br>
<br>
&gt;&gt;&gt;<br>
&gt;&gt;&gt;<br>
&gt;&gt;&gt; That&#39;s one way, but it&#39;s complex.  I think having a clock that is<br>
&gt;&gt;&gt; flexible, that will deviate by no more than a specified percentage from<br>
&gt;&gt;&gt; clock_gettime in approaching wall time is simpler for the user albeit more<br>
&gt;&gt;&gt; complex for the VM implementor.  It therefore seems to me to be in the<br>
&gt;&gt;&gt; Smalltalk tradition.<br>
&gt;&gt;&gt;<br>
&gt;&gt;&gt;&gt; In Dart, there are three uses of time<br>
&gt;&gt;&gt;&gt;<br>
&gt;&gt;&gt;&gt; Stopwatch measures durations (BlockClosure timeToRun). It uses the<br>
&gt;&gt;&gt;&gt; monotonic clock.<br>
&gt;&gt;&gt;&gt;<br>
&gt;&gt;&gt;&gt; Timer schedules a future notification (Delay wait). It uses the<br>
&gt;&gt;&gt;&gt; monotonic clock.<br>
&gt;&gt;&gt;&gt;<br>
&gt;&gt;&gt;&gt; DateTime gets a timestamp (DateAndTime now). It uses the wall clock.<br>
&gt;&gt;&gt;<br>
&gt;&gt;&gt;<br>
&gt;&gt;&gt; Makes sense, at the cost of having two clocks.<br>
&gt;&gt;&gt;<br>
&gt;&gt;&gt;&gt;<br>
&gt;&gt;&gt;&gt; Smalltalk has the additional complication of handling in-flight Delays<br>
&gt;&gt;&gt;&gt; or timeToRuns as an image moves across processes. There will be a<br>
&gt;&gt;&gt;&gt; discontinuity in both clocks, and both of them can move backwards. The logic<br>
&gt;&gt;&gt;&gt; to deal with the discontinuity must already exist for Delays, though I<br>
&gt;&gt;&gt;&gt; suspect no one has bothered for timeToRun. If I create a thousand Delays<br>
&gt;&gt;&gt;&gt; spaced apart by a minute, snapshot, move the system time forward a day, then<br>
&gt;&gt;&gt;&gt; resume, they remain evenly spaced.<br>
<br>
</div></div>This is because of #save/restoreResumptionTimes on image shutdown/startup.<br>
<span class=""><br>
&gt;&gt;&gt;&gt; If I do this while the image is still<br>
&gt;&gt;&gt;&gt; running, they all fire at once and the VM becomes unresponsive, which is<br>
&gt;&gt;&gt;&gt; what using the monotonic clock would fix.<br>
<br>
</span>Yes, since Delays are currently using gettimeofday() they expire when<br>
the system clock jumps.  But also, with the move of Delay to a<br>
microsecond clock and removal of the clock-wrap checks, perhaps the<br>
algorithm is more susceptible to jitter or ntp moving the clock<br>
backwards.  I would need to think more about that, but anyway<br>
clock_gettime(MONOTONIC) which slews wall-time seems a much better<br>
choice.  I&#39;d be interested in doing some work getting this into the VM<br>
since I&#39;d like it for Pharo also.<br>
<br>
cheers -ben<br>
<div class="HOEnZb"><div class="h5"><br>
&gt;&gt;&gt;<br>
&gt;&gt;&gt;<br>
&gt;&gt;&gt; Yes, but there is another way.  Delays can be implemented to function as<br>
&gt;&gt;&gt; durations, not deadlines.  This is orthogonal to clocks.  If Delays are<br>
&gt;&gt;&gt; deadlines then it is correct that on start-up they all fire.  If they are<br>
&gt;&gt;&gt; durations, it is not.<br>
<br>
</div></div></blockquote></div><br><br clear="all"><div><br></div>-- <br><div class="gmail_signature" data-smartmail="gmail_signature"><div dir="ltr"><div><span style="font-size:small;border-collapse:separate"><div>_,,,^..^,,,_<br></div><div>best, Eliot</div></span></div></div></div>
</div></div>