From 1e4c33b1e845e49f9e2d6eb61154e785edb42a37 Mon Sep 17 00:00:00 2001
From: Tom Lane <tgl@sss.pgh.pa.us>
Date: Thu, 2 Sep 2004 17:55:16 +0000
Subject: [PATCH] Fix getrusage() emulation on Windows.  Magnus Hagander

---
 src/port/getrusage.c | 43 ++++++++++++++++++++++++++++++++++++++-----
 1 file changed, 38 insertions(+), 5 deletions(-)

diff --git a/src/port/getrusage.c b/src/port/getrusage.c
index 1ef199ed02e..c2ffa848d34 100644
--- a/src/port/getrusage.c
+++ b/src/port/getrusage.c
@@ -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;
 }
-- 
GitLab