[Vm-dev] microsecond timing for GC work

Bert Freudenberg bert at freudenbergs.de
Thu Jan 21 10:46:29 UTC 2010


On 21.01.2010, at 03:41, David T. Lewis wrote:
> 
> 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

I was about to comment that gettimeofday() answers UTC while ioSeconds() currently uses time() which is "seconds since 0:00:00, Jan 1, 1970, Coordinated Universal Time, *without including leap seconds*" according to the BSD man page, but apparently it was later redefined in terms of UTC:
http://en.wikipedia.org/wiki/Unix_time

In any case, in the LocalePlugin I took care to have the timezone offset match the behavior of convertToSqueakTime() which in turn is used by ioSeconds():

platforms/unix/vm/sqUnixMain.c:

time_t convertToSqueakTime(time_t unixTime)
{
#ifdef HAVE_TM_GMTOFF
  unixTime+= localtime(&unixTime)->tm_gmtoff;
#else
# ifdef HAVE_TIMEZONE
  unixTime+= ((daylight) * 60*60) - timezone;
# else
#  error: cannot determine timezone correction
# endif
#endif
  /* Squeak epoch is Jan 1, 1901.  Unix epoch is Jan 1, 1970: 17 leap years
     and 52 non-leap years later than Squeak. */
  return unixTime + ((52*365UL + 17*366UL) * 24*60*60UL);
}

platforms/unix/plugins/LocalePlugin/sqUnixLocale.c:

/* Answer the offset to (number of minutes EAST of) GMT.
 */
sqInt sqLocGetTimezoneOffset(void)
{
  /* Match the behaviour of convertToSqueakTime(). */
#ifdef HAVE_TM_GMTOFF
  time_t now= time(0);
  return localtime(&now)->tm_gmtoff / 60;
#else
# ifdef HAVE_TIMEZONE
  extern long timezone;
  extern int daylight;
  return daylight * 60 - timezone / 60;
# else
#  error: cannot determine timezone correction
# endif
#endif
}

I think we should arrange to have ioUtcWithOffset() be used in all the other places to ensure a consistent interpretation of time ...

- Bert -




More information about the Vm-dev mailing list