[Vm-dev] microsecond timing for GC work

David T. Lewis lewis at mail.msen.com
Thu Jan 21 02:41:23 UTC 2010


OK, attached is an implementation of #primitiveUtcWithOffset. It
answers an array with UTC time in microseconds since the Posix epoch,
and with GMT offset in seconds in the local time zone.

The choice of microsecond precision (rather than milliseconds)
implies a meaningless degree of precision, but it allows time to
be specified to effectivly unlimited precision for centuries to
come. If folks think that millisecond precision is more sensible,
it's a trivial change.

This is intended to be complimentary to (not a replacement for)
John's #primitiveMicrosecondClock primitive.

For a GCC compiler on unix, the support code function is:

  sqInt ioUtcWithOffset(sqLong *microSeconds, int *offset)
  {
    struct timeval timeval;
    if (gettimeofday(&timeval, NULL) == -1) return -1;
    long long seconds = timeval.tv_sec;
    suseconds_t usec = timeval.tv_usec;
    *microSeconds = seconds * 1000000 + usec;
    *offset = localtime(&seconds)->tm_gmtoff;
    return 0;
  }

The above is probably not portable to all unices, but I think
it works with any GCC based system. I have not looked at win32,
though I am sure there is an equivalent implementation.

Dave

On Tue, Jan 19, 2010 at 06:42:27PM -0800, Andreas Raab wrote:
> 
> Hi David -
> 
> Sounds good to me - proceed for truth :-)
> 
> Cheers,
>   - Andreas
> 
> David T. Lewis wrote:
> > 
> >On Tue, Jan 19, 2010 at 05:44:26PM -0800, Andreas Raab wrote:
> >>David T. Lewis wrote:
> >>>On Tue, Jan 19, 2010 at 04:28:47PM -0800, Andreas Raab wrote:
> >>>>>Would anyone object to the addition of a primitive that answers
> >>>>>Posix seconds (to some reasonable precision) plus time zone offset?
> >>>>>This would be a named primitive in addition to John's microsecond
> >>>>>primitive.
> >>>>I'm not sure what the point of it would be. Both of you are speaking in 
> >>>>riddles at this point; it would be good if you could spell out the 
> >>>>issues more clearly.
> >>>The clock in Squeak is done in local time (UTC translated to local
> >>>seconds in the VM before it is reported to the image). Consider a
> >>>Squeak image running in a locale with daylight savings time. Once
> >>>per year in the fall, there is a period of one hour during which the
> >>>Squeak clock has "jumped backwards" one hour. All of the values of the
> >>>Squeak clock are repeated during for the next hour. The values are
> >>>ambiguous, and the calculation of durations and times based on them
> >>>is problematic.
> >>Ah, I see. Thanks for clearing this up. How does that relate to posix 
> >>seconds as stated above? Are posix seconds UTC? If not, shouldn't we 
> >>rather make sure all time in UTC (regardless of epoch) and leave it to 
> >>the image to work out the timezone it's in? That seems the better 
> >>long-term option to me.
> >
> >Wikipedia has a very good overview:
> >  http://en.wikipedia.org/wiki/POSIX_time
> >  http://en.wikipedia.org/wiki/Coordinated_Universal_Time
> >
> >Yes, I meant the same thing by "Posix seconds" and "UTC".
> >
> >The Smalltalk epoch is a constant number of seconds apart from the
> >Posix epoch, although in Squeak it is not clear whether this should
> >be measured from Palo Alto or from London. If you use the Posix epoch
> >as the origin of your timeline and compute local time representation
> >from UTC seconds and an offset corresponding to your own timezone,
> >things just work.
> >
> >Given the history of Squeak as a single user system with no awareness
> >of time zones, it is easiest to think of the current Squeak clock
> >as if the Smalltalk epoch was measured in your own local time zone,
> >and just pretend that daylight savings transitions do not happen.
> >That is perfectly sufficient for a single user computer (i.e.  99%
> >of all Squeak users), but it's wrong if you need to handle time
> >zones or calculate durations properly.
> >
> >Dave
> >
-------------- next part --------------
'From Squeak3.8.2a of ''26 Oct 2007'' [latest update: #6748] on 20 January 2010 at 9:15:57 pm'!
"Change Set:		Interpreter-primitiveUtcWithOffset-dtl
Date:			20 January 2010
Author:			David T. Lewis

Add a primitive to answer an array with UTC microseconds since the Posix epoch, and the current seconds offset from GMT in the local time zone. This is a named (not numbered) primitive in the null module (ie the VM). Current platforms cannot measure time to microsecond resolution, but this numeric precision permits enumeration of time values for many centuries to come at effectively unlimited precision.

Current Squeak images use a local time clock that is problematic for time zone and duration calculations. This primitive supports migration to a UTC clock suitable for use with servers and distributed images.

The corresponding platform support function for a GNU unix system is:

sqInt ioUtcWithOffset(sqLong *microSeconds, int *offset)
{
  struct timeval timeval;
  if (gettimeofday(&timeval, NULL) == -1) return -1;
  long long seconds = timeval.tv_sec;
  suseconds_t usec = timeval.tv_usec;
  *microSeconds = seconds * 1000000 + usec;
  *offset = localtime(&seconds)->tm_gmtoff;
  return 0;
}
"!


!Interpreter methodsFor: 'system control primitives' stamp: 'dtl 1/20/2010 20:54'!
primitiveUtcWithOffset
	"Answer an array with UTC mocroseconds since the Posix epoch and tthe
	current seconds offset from GMT in the local time zone.
	This is a named (not numbered) primitive in the null module (ie the VM)"
	| clock offset resultArray |

	self export: true.
	self var: #clock type: 'sqLong'.
	self var: #offset type: 'int'.
	(self cCode: 'ioUtcWithOffset(&clock, &offset)' inSmalltalk: [-1]) = -1
		ifTrue: [^ self primitiveFail].
	self pushRemappableOop: (self positive64BitIntegerFor: clock).
	resultArray := self instantiateClass: self classArray indexableSize: 2.
	self stObject: resultArray at: 1 put: self popRemappableOop.
	self stObject: resultArray at: 2 put: (self integerObjectOf: offset).
	self pop: 1 thenPush: resultArray
! !



More information about the Vm-dev mailing list