Fix getrusage() emulation on Windows. Magnus Hagander
authorTom Lane
Thu, 2 Sep 2004 17:55:16 +0000 (17:55 +0000)
committerTom Lane
Thu, 2 Sep 2004 17:55:16 +0000 (17:55 +0000)
src/port/getrusage.c

index 1ef199ed02eab8c1379a5f8a3cbd11243a9917b2..c2ffa848d34d2e575ac1321e76b8fd8d02f99fbc 100644 (file)
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *   $PostgreSQL: pgsql/src/port/getrusage.c,v 1.6 2004/08/29 04:13:12 momjian Exp $
+ *   $PostgreSQL: pgsql/src/port/getrusage.c,v 1.7 2004/09/02 17:55:16 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -26,6 +26,7 @@
  *     solaris_sparc
  *     svr4
  *     hpux 9.*
+ *     win32
  * which currently is all the supported platforms that don't have a
  * native version of getrusage().  So, if configure decides to compile
  * this file at all, we just use this version unconditionally.
@@ -35,9 +36,39 @@ int
 getrusage(int who, struct rusage * rusage)
 {
 #ifdef WIN32
-   if (rusage)
-       memset(rusage, 0, sizeof(rusage));
-#else
+
+   FILETIME starttime;
+   FILETIME exittime;
+   FILETIME kerneltime;
+   FILETIME usertime;
+   ULARGE_INTEGER li;
+
+   if (rusage == (struct rusage *)NULL)
+   {
+       errno = EFAULT;
+       return -1;
+   }
+   memset(rusage, 0, sizeof(struct rusage));
+   if (GetProcessTimes(GetCurrentProcess(),
+                       &starttime, &exittime, &kerneltime, &usertime) == 0)
+   {
+       _dosmaperr(GetLastError());
+       return -1;
+   }
+
+   /* Convert FILETIMEs (0.1 us) to struct timeval */
+   memcpy(&li, &kerneltime, sizeof(FILETIME));
+   li.QuadPart /= 10L; /* Convert to microseconds */
+   rusage->ru_stime.tv_sec  = li.QuadPart / 1000000L;
+   rusage->ru_stime.tv_usec = li.QuadPart % 1000000L;
+
+   memcpy(&li, &usertime, sizeof(FILETIME));
+   li.QuadPart /= 10L; /* Convert to microseconds */
+   rusage->ru_utime.tv_sec  = li.QuadPart / 1000000L;
+   rusage->ru_utime.tv_usec = li.QuadPart % 1000000L;
+
+#else /* all but WIN32 */
+
    struct tms  tms;
    int         tick_rate = CLK_TCK;    /* ticks per second */
    clock_t     u,
@@ -73,6 +104,8 @@ getrusage(int who, struct rusage * rusage)
    rusage->ru_utime.tv_usec = TICK_TO_USEC(u, tick_rate);
    rusage->ru_stime.tv_sec = TICK_TO_SEC(s, tick_rate);
    rusage->ru_stime.tv_usec = TICK_TO_USEC(u, tick_rate);
-#endif
+
+#endif /* WIN32 */
+
    return 0;
 }