From d8afa7c91f1e6658937cb2e89cfeff6408361699 Mon Sep 17 00:00:00 2001 From: simonmar Date: Thu, 3 Nov 2005 16:22:15 +0000 Subject: [PATCH] [project @ 2005-11-03 16:22:15 by simonmar] Improve the Win32 implementation of the time-measurement stuff. Now supports per-thread CPU time, and the elapsed time should be correct (previously it was the sum of user time & kernel time, which isn't what we want). --- ghc/rts/win32/GetTime.c | 124 +++++++++++++++++++++++------------------------ 1 file changed, 61 insertions(+), 63 deletions(-) diff --git a/ghc/rts/win32/GetTime.c b/ghc/rts/win32/GetTime.c index 6b50211..584b994 100644 --- a/ghc/rts/win32/GetTime.c +++ b/ghc/rts/win32/GetTime.c @@ -15,87 +15,85 @@ # include #endif -/* elapsedtime() -- The current elapsed time in seconds */ - #define HNS_PER_SEC 10000000LL /* FILETIMES are in units of 100ns */ /* Convert FILETIMEs into secs */ -#define FT2longlong(ll,ft) \ - (ll)=(ft).dwHighDateTime; \ - (ll) <<= 32; \ - (ll) |= (ft).dwLowDateTime; \ - (ll) /= (unsigned long long) (HNS_PER_SEC / CLOCKS_PER_SEC) -/* cygwin32 or mingw32 version */ -void -getProcessTimes( Ticks *user, Ticks *elapsed ) +static INLINE_ME Ticks +fileTimeToTicks(FILETIME ft) { - static int is_win9x = -1; - static Ticks elapsed_start = 0; + Ticks t; + t = ((Ticks)ft.dwHighDateTime << 32) | ft.dwLowDateTime; + t = (t * TICKS_PER_SECOND) / HNS_PER_SEC; + return t; +} - FILETIME creationTime, exitTime, userTime, kernelTime = {0,0}; - long long int kT, uT; - - if (is_win9x < 0) { - /* figure out whether we're on a Win9x box or not. */ - OSVERSIONINFO oi; - BOOL b; +static int is_win9x = -1; - /* Need to init the size field first.*/ - oi.dwOSVersionInfoSize = sizeof(OSVERSIONINFO); - b = GetVersionEx(&oi); +static INLINE_ME rtsBool +isWin9x(void) +{ + if (is_win9x < 0) { + /* figure out whether we're on a Win9x box or not. */ + OSVERSIONINFO oi; + BOOL b; + + /* Need to init the size field first.*/ + oi.dwOSVersionInfoSize = sizeof(OSVERSIONINFO); + b = GetVersionEx(&oi); - is_win9x = ( (b && (oi.dwPlatformId & VER_PLATFORM_WIN32_WINDOWS)) ? 1 : 0); - } - - if (is_win9x) { - /* On Win9x, just attribute all running time to the user. */ - SYSTEMTIME st; - - GetSystemTime(&st); - SystemTimeToFileTime(&st,&userTime); - } else { - /* ToDo: pin down elapsed times to just the OS thread(s) that - are evaluating/managing Haskell code. - */ - if (!GetProcessTimes (GetCurrentProcess(), &creationTime, - &exitTime, &kernelTime, &userTime)) { - /* Probably on a Win95 box..*/ - *elapsed = 0; - *user = 0; - return; - } + is_win9x = ( (b && (oi.dwPlatformId & VER_PLATFORM_WIN32_WINDOWS)) ? 1 : 0); } + return is_win9x; +} + - FT2longlong(kT,kernelTime); - FT2longlong(uT,userTime); - *elapsed = uT + kT; - *user = uT; - - if (is_win9x) { - /* User time is assumed to start at zero, so adjust for the fact - that we're using system time & not process time on Win9x. */ - if (elapsed_start == 0) { - elapsed_start = *elapsed; - } - *user -= elapsed_start; +void +getProcessTimes(Ticks *user, Ticks *elapsed) +{ + *user = getProcessCPUTime(); + *elapsed = getProcessElapsedTime(); +} + +Ticks +getProcessCPUTime(void) +{ + FILETIME creationTime, exitTime, userTime, kernelTime = {0,0}; + + if (isWin9x()) return getProcessElapsedTime(); + + if (!GetProcessTimes(GetCurrentProcess(), &creationTime, + &exitTime, &kernelTime, &userTime)) { + return 0; } + + return fileTimeToTicks(userTime); } -Ticks getProcessCPUTime(void) +Ticks +getProcessElapsedTime(void) { - Ticks user, elapsed; - getProcessTimes(&user,&elapsed); - return user; + FILETIME system_time; + GetSystemTimeAsFileTime(&system_time); + return fileTimeToTicks(system_time); } -Ticks getProcessElapsedTime(void) +Ticks +getThreadCPUTime(void) { - Ticks user, elapsed; - getProcessTimes(&user,&elapsed); - return elapsed; + FILETIME creationTime, exitTime, userTime, kernelTime = {0,0}; + + if (isWin9x()) return getProcessCPUTime(); + + if (!GetThreadTimes(GetCurrentThread(), &creationTime, + &exitTime, &kernelTime, &userTime)) { + return 0; + } + + return fileTimeToTicks(userTime); } -nat getPageFaults(void) +nat +getPageFaults(void) { /* ToDo (on NT): better, get this via the performance data that's stored in the registry. */ -- 1.7.10.4