<div dir="ltr">Hi Dave,<div class="gmail_extra"><br><div class="gmail_quote">On Wed, Mar 23, 2016 at 4:12 PM, David T. Lewis <span dir="ltr">&lt;<a href="mailto:lewis@mail.msen.com" target="_blank">lewis@mail.msen.com</a>&gt;</span> wrote:<br><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex">Hi Levente,<br>
<span class=""><br>
On Wed, Mar 23, 2016 at 05:01:35PM +0100, Levente Uzonyi wrote:<br>
&gt;<br>
&gt; On Sun, 20 Mar 2016, David T. Lewis wrote:<br>
&gt; &gt;<br>
</span><span class="">&gt; &gt;The four policies are:<br>
&gt; &gt;<br>
&gt; &gt;#acceptPlatformTime - Accept the time value provided by the system<br>
&gt; &gt;platform, even in this allows time to appear to move backwards when the<br>
&gt; &gt;clock is adjusted. Simple, fast, and no hidden side effects.<br>
&gt; &gt;<br>
&gt; &gt;#monotonicAllowDuplicates - Accept the time value provided by the system<br>
&gt; &gt;platform unless it is less that the last clock tick. This protects for<br>
&gt; &gt;system clock adjustments. Side effects unlikely. Does not ensure unique<br>
&gt; &gt;values on repeated calls.<br>
&gt; &gt;<br>
&gt; &gt;#monotonicForceMicrosecondIncrement - If the time value is less than or<br>
&gt; &gt;equal to the value from the last call, force increment by one microsecond.<br>
&gt; &gt;This ensures integral values of UTC time, but increments the time value by<br>
&gt; &gt;a full microsecond.<br>
&gt; &gt;<br>
&gt; &gt;#monotonicForceNanosecondIncrement - If the time value is less than or<br>
&gt; &gt;equal to the value from the last call, force increment by one nanosecond.<br>
&gt; &gt;This it functionally compatible with previous Squeak practice, but is<br>
&gt; &gt;computationally expensive and results in time values represented as<br>
&gt; &gt;fractions, which might be a problem for some database applications.<br>
&gt;<br>
&gt; I think this covers most possible use cases. What I was originally<br>
&gt; thinking about was the addition of another field to hold the nanosecond<br>
&gt; part, since that would have only been set by the image itself, so the<br>
&gt; primitive could still have been used to initialize the rest. That we we<br>
&gt; could have avoided the use of fractions at the cost of having another<br>
&gt; field per object even when there&#39;s no need for high accuracy.<br>
<br>
</span>I&#39;m actually quite happy with the idea of the value being a Number that<br>
is an Integer for all reasonable values that could ever be supplied by<br>
the VM, but that might be a Fraction if we want to represent time values<br>
at some higher precision. Mainly I like it because it seems good conceptually<br>
to think of time as continuous, and not as discreet ticks of a clock.<br>
<br>
It also works well computationally, because the normal case uses integer<br>
values (immediates in 64-bit Spur), and because Fractions involve two<br>
integer values, which presumably would be no worse than a design that<br>
added another field. But given that none of our computers or VMs can<br>
report time to a precision greater than microseconds, I think that we<br>
can safely ignore the issue for another 20 years or so ;-)<br>
<span class=""><br>
&gt;<br>
&gt; One more thing that I noticed is that this primitive still uses the &quot;quick<br>
&gt; but inaccurate&quot; way to get the current time, which only updates every two<br>
&gt; milliseconds (I think once per heartbeat). Eliot has changed primitive 240<br>
&gt; a while ago to always provide the accurate time:<br>
&gt;<br>
&gt; | start end |<br>
&gt; start := DateAndTime now.<br>
&gt; [ (end := DateAndTime now) = start ] whileTrue.<br>
&gt; { start. end. end - start }<br>
&gt;  {2016-03-23T16:53:33.637835+01:00 . 2016-03-23T16:53:33.639844+01:00 .<br>
&gt; 0:00:00:00.002009}<br>
&gt;<br>
&gt; | start end |<br>
&gt; start := Time utcMicrosecondClock.<br>
&gt; [ (end := Time utcMicrosecondClock) = start ] whileTrue.<br>
&gt; { start. end. end - start }<br>
&gt;  #(3636201206461149 3636201206461150 1)<br>
&gt;<br>
<br>
</span>There is a good implementation of the primitive in the trunk SVN branch<br>
that needs to be added to the oscog branch. I think that will take care<br>
of the problem. I promised Eliot I would move the code over, but it might<br>
be a couple of weeks before I can get to it. We need to add this to the<br>
platform code to provide a true atomic primitive (from sq.h):<br>
<br>
  sqInt ioUtcWithOffset(sqLong*, int*);   /* primitiveUtcWithOffset */<br>
<br>
And then the primitive (slang) can be updated to match. I am afraid that<br>
I am responsible for some of the confusion, because when this was added<br>
to Cog a number of years ago, I did not want to touch the platform code,<br>
and I implemented a rather kludgy workaround just to get it working. Sorry.<br></blockquote><div><br></div><div>Turns out this isn&#39;t needed for Cog.  I have ioLocalSecondsOffset which answers a value determined at start-up and only changed via ioUpdateVMTimezone, which itself is controlled by primitiveUpdateTimezone, #243.  So ioUTCMicroseconds is all that&#39;s needed to get at the clock and timezone atomically.</div><div><br></div><div>If I had had half a brain when I implemented the 64-bit microsecond clock I would have done it as a primitive to answer UTC and a primitive to answer timezone offset, but instead I chose to hide timezone in local microseconds.  Live and learn.  But the existence of primitiveUpdateTimezone, #243, means I could make it answer the timezone offset if invoked with zero arguments.  And that way we&#39;ll have every possible combination of 64-bit clock access we could wish for :-) (not)</div><div><br></div><div><br></div><div>VMMaker.oscog-eem.1739</div><div>Author: eem</div><div>Time: 23 March 2016, 12:41:48.73939 pm</div><div>UUID: e9e980a3-1fc0-4425-acb8-f1f02f1977b0</div><div>Ancestors: VMMaker.oscog-eem.1738</div><div><br></div><div>Fix a slip in my correction of primitiveUtcWithOffset (wrong arg count check), and use ioLocalSecondsOffset to get the timezone, hence avoiding the need for the atomic accessor for both clock and timezone offset (the offset can only be changed from the system, and hence won&#39;t change while this primitive is executing).</div><div><br></div><div>Add a Smalltalk epoch version primitiveUtcAndTimezoneOffset and give it primitive #244.</div><div> </div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex">Dave</blockquote><div> </div></div><div class="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>