[Vm-dev] Time primHighResClock truncated to 32 bits in 64 bits VMs.

Eliot Miranda eliot.miranda at gmail.com
Thu Dec 28 17:06:27 UTC 2017


Hi David, Hi Jiuan,

On Thu, Dec 28, 2017 at 8:56 AM, David T. Lewis <lewis at mail.msen.com> wrote:

>
> On Thu, Dec 28, 2017 at 09:32:46AM -0300, Juan Vuletich wrote:
> >
> > Hi Folks,
> >
> > In 32 bit Cog VMs, `Time primHighResClock` answers LargePositiveInteger,
> > presumably up to 64 bits. This would mean a rollover in 167 years on a
> > 3.5GHz machine.
> >
> > But on 64 bit Cog and Stack Spur VMs, it answers a SmallInteger that is
> > truncated to 32 bits. This means a rollover in about one second.
> >
> > I guesss this is a bug. Answering a SmallInteger, truncating the CPU 64
> > bit counter to 60 bits would be ok. I think it makes sense to restrict
> > answer to SmallInteger to avoid allocation, and a rollover every 41
> > years is not too much :)
> >
> > Thanks,
> >
> > --
> > Juan Vuletich
> > www.cuis-smalltalk.org
> > https://github.com/Cuis-Smalltalk/Cuis-Smalltalk-Dev
> > @JuanVuletich
> >
> >
>
> Attached is the #primHighResClock accessor for Squeak/Pharo users.
>
> I don't see anything obviously wrong with the primitive, although maybe it
> involves the handling of positive64BitIntegerFor: in the 64-bit VM.
>
> The primitive is:
>
>
> primitiveHighResClock
>         "Return the value of the high resolution clock if this system has
> any. The exact frequency of the high res clock is undefined specifically so
> that we can use processor dependent instructions (like RDTSC). The only use
> for the high res clock is for profiling where we can allocate time based on
> sub-msec resolution of the high res clock. If no high-resolution counter is
> available, the platform should return zero."
>         <export: true>
>         self pop: 1.
>         self push: (self positive64BitIntegerFor: self ioHighResClock).
>
>
> And the platform support code does this:
>
> sqLong
> ioHighResClock(void)
> {
>   /* return the value of the high performance counter */
>   sqLong value = 0;
> #if defined(__GNUC__) && ( defined(i386) || defined(__i386) ||
> defined(__i386__)  \
>                         || defined(i486) || defined(__i486) || defined
> (__i486__) \
>                         || defined(intel) || defined(x86) ||
> defined(i86pc) )
>     __asm__ __volatile__ ("rdtsc" : "=A"(value));
> #elif defined(__arm__) && (defined(__ARM_ARCH_6__) ||
> defined(__ARM_ARCH_7A__))
>         /* tpr - do nothing for now; needs input from eliot to decide
> further */
> #else
> # error "no high res clock defined"
> #endif
>   return value;
> }
>
>
Ah, OK.  So this is the problem.  This will answer ex on 64-bit systems,
which discard the upper 32-bits.  rdtsc loads %edx:%eax with the 64-bit
time stamp, but on 64-bits the in-line asm will simply move %eax to %rax.
We have to rewrite that in-line assembler to construct %rax correctly from
%edx and %eax.



-- 
_,,,^..^,,,_
best, Eliot
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.squeakfoundation.org/pipermail/vm-dev/attachments/20171228/19a7ef0f/attachment-0001.html>


More information about the Vm-dev mailing list