[project @ 2005-11-03 16:22:15 by simonmar]
authorsimonmar <unknown>
Thu, 3 Nov 2005 16:22:15 +0000 (16:22 +0000)
committersimonmar <unknown>
Thu, 3 Nov 2005 16:22:15 +0000 (16:22 +0000)
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

index 6b50211..584b994 100644 (file)
 # include <time.h>
 #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. */