[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