Author: eliot Date: 2011-06-01 10:56:27 -0700 (Wed, 01 Jun 2011) New Revision: 2388 Added: branches/Cog/platforms/win32/vm/sqWin32Time.c Log: Add straggler Added: branches/Cog/platforms/win32/vm/sqWin32Time.c =================================================================== --- branches/Cog/platforms/win32/vm/sqWin32Time.c (rev 0) +++ branches/Cog/platforms/win32/vm/sqWin32Time.c 2011-06-01 17:56:27 UTC (rev 2388) @@ -0,0 +1,146 @@ +/**************************************************************************** +* sqWin32Time.c +* Time functions for non-heartbeat (non STACK) VMs, extracted from +* trunk sqWin32Window.c +*****************************************************************************/ + +#include <windows.h> + +#include "sq.h" + +#if !STACKVM +/* + * Win32 FILETIMEs are 10th's of microseconds since 1601. Smalltalk times + * are seconds from 1901. Let's call a 10th of a microsecond a "tock". + */ + +#if _MSC_VER +# define SecondsFrom1601To1901 9467020800i64 /*See PRINT_TIME_CONSTANTS below*/ +# define MicrosecondsFrom1601To1901 9467020800000000i64 + +# define MicrosecondsPerSecond 1000000i64 +# define MillisecondsPerSecond 1000i64 + +# define MicrosecondsPerMillisecond 1000000i64 + +# define TocksPerSecond 10000000i64 +# define TocksPerMillisecond 10000i64 +# define TocksPerMicrosecond 10i64 +# define LLFMT "I64d" +#else +# define SecondsFrom1601To1901 9467020800LL /*See PRINT_TIME_CONSTANTS below*/ +# define MicrosecondsFrom1601To1901 9467020800000000LL + +# define MicrosecondsPerSecond 1000000LL +# define MillisecondsPerSecond 1000LL + +# define MicrosecondsPerMillisecond 1000LL + +# define TocksPerSecond 10000000LL +# define TocksPerMillisecond 10000LL +# define TocksPerMicrosecond 10LL +# define LLFMT "lld" +#endif + +/* returns the local wall clock time */ +int ioSeconds(void) +{ SYSTEMTIME sysTime; + GetLocalTime(&sysTime); + return convertToSqueakTime(sysTime); +} + +int ioMSecs() +{ + /* Make sure the value fits into Squeak SmallIntegers */ +#ifndef _WIN32_WCE + return timeGetTime() & 0x3FFFFFFF; +#else + return GetTickCount() &0x3FFFFFFF; +#endif +} + +/* Note: ioMicroMSecs returns *milli*seconds */ +int ioMicroMSecs(void) +{ + /* Make sure the value fits into Squeak SmallIntegers */ + return timeGetTime() &0x3FFFFFFF; +} + +/* Compute the current VM time basis, the number of microseconds from 1901. + * + * Alas Windows' system time functions GetSystemTime et al have low resolution; + * 15 ms. So we use timeGetTime for higher resolution and use it as an offset to + * the system time, resetting when timeGetTime wraps. Since timeGetTime wraps we + * need some basis information which is passed in as pointers to provide us with + * both the heartbeat clock and an instantaneous clock for the VM thread. + * This is still insufficient since timeGetTime driefts relative to wall time. + * We should apply some periodic adjustment but for now just drift aimlessly. + */ + +/* The bases that relate timeGetTime's 32-bit wrapping millisecond clock to the + * non-wrapping 64-bit microsecond clocks. + */ +static unsigned __int64 utcTickBaseMicroseconds; +static DWORD lastTick = (DWORD)-1; +static DWORD baseTick; + +static unsigned __int64 +currentUTCMicroseconds(unsigned __int64 *utcTickBaseUsecsp, DWORD *lastTickp, DWORD *baseTickp) +{ + FILETIME utcNow; + DWORD currentTick = timeGetTime(); + DWORD prevTick = *lastTickp; + + *lastTickp = currentTick; + + /* If the timeGetTime millisecond clock wraps (as it will every 49.71 days) + * resync to the system time. + */ + if (currentTick < prevTick) { + + *baseTickp = currentTick; + GetSystemTimeAsFileTime(&utcNow); + *utcTickBaseUsecsp = *(unsigned __int64 *)&utcNow + / TocksPerMicrosecond + - MicrosecondsFrom1601To1901; + return *utcTickBaseUsecsp; + } + return *utcTickBaseUsecsp + + (currentTick - *baseTickp) * MicrosecondsPerMillisecond; +} + +usqLong +ioUTCMicroseconds() { return currentUTCMicroseconds(&utcTickBaseMicroseconds, &lastTick, &baseTick); } + +/* This is an expensive interface for use by profiling code that wants the time + * now rather than as of the last heartbeat. + */ +usqLong +ioUTCMicrosecondsNow() { return currentUTCMicroseconds(&utcTickBaseMicroseconds, &lastTick, &baseTick); } + +static DWORD dwTimerPeriod; + +void +ioInitTime() +{ +# if !defined(_WIN32_WCE) + TIMECAPS tCaps; + + dwTimerPeriod = 0; + if(timeGetDevCaps(&tCaps,sizeof(tCaps)) != 0) + return; + dwTimerPeriod = tCaps.wPeriodMin; + if (timeBeginPeriod(dwTimerPeriod) != 0) + return; +# endif +} + +void +ioReleaseTime(void) +{ +# if !defined(_WIN32_WCE) + if (dwTimerPeriod) + timeEndPeriod(dwTimerPeriod); +# endif /* !defined(_WIN32_WCE) */ +} +#endif /* STACKVM */ |
Free forum by Nabble | Edit this page |