summaryrefslogtreecommitdiff
path: root/rts
diff options
context:
space:
mode:
authorDuncan Coutts <duncan@well-typed.com>2011-10-25 18:41:46 +0100
committerDuncan Coutts <duncan@well-typed.com>2011-10-26 12:00:42 +0100
commitece21ea00b8681b09c9eedbebbac1af764864367 (patch)
treec46d45e42baf9cad94ed2eb40e34865830ef7d60 /rts
parent17c166232cf2a547a9b0a4fce5f38307ae64f157 (diff)
downloadhaskell-ece21ea00b8681b09c9eedbebbac1af764864367.tar.gz
Add rts time util getUnixEpochTime
The other existing time utilities give us time elapsed since process or thread start. This is for wall clock time, using the common Unix epoch interpretation.
Diffstat (limited to 'rts')
-rw-r--r--rts/GetTime.h5
-rw-r--r--rts/posix/GetTime.c16
-rw-r--r--rts/win32/GetTime.c40
3 files changed, 61 insertions, 0 deletions
diff --git a/rts/GetTime.h b/rts/GetTime.h
index 7b89c05822..b8d402db7c 100644
--- a/rts/GetTime.h
+++ b/rts/GetTime.h
@@ -22,6 +22,11 @@ Ticks getThreadCPUTime (void);
Ticks getProcessElapsedTime (void);
void getProcessTimes (Ticks *user, Ticks *elapsed);
+/* Get the current date and time.
+ Uses seconds since the Unix epoch, plus nanoseconds
+ */
+void getUnixEpochTime (StgWord64 *sec, StgWord32 *nsec);
+
// Not strictly timing, but related
nat getPageFaults (void);
diff --git a/rts/posix/GetTime.c b/rts/posix/GetTime.c
index 15643b8319..eab7177fe5 100644
--- a/rts/posix/GetTime.c
+++ b/rts/posix/GetTime.c
@@ -181,6 +181,22 @@ Ticks getThreadCPUTime(void)
return getProcessCPUTime();
}
+void getUnixEpochTime(StgWord64 *sec, StgWord32 *nsec)
+{
+#if defined(HAVE_GETTIMEOFDAY)
+ struct timeval tv;
+ gettimeofday(&tv, (struct timezone *) NULL);
+ *sec = tv.tv_sec;
+ *nsec = tv.tv_usec * 1000;
+#else
+ /* Sigh, fall back to second resolution. */
+ time_t t;
+ time(&t);
+ *sec = t;
+ *nsec = 0;
+#endif
+}
+
nat
getPageFaults(void)
{
diff --git a/rts/win32/GetTime.c b/rts/win32/GetTime.c
index 9699bd69f4..13fb5ab22d 100644
--- a/rts/win32/GetTime.c
+++ b/rts/win32/GetTime.c
@@ -92,6 +92,46 @@ getThreadCPUTime(void)
return fileTimeToTicks(userTime);
}
+void
+getUnixEpochTime(StgWord64 *sec, StgWord32 *nsec)
+{
+ /* Windows has a bunch of time APIs but none that directly give
+ us unix epoch time, so we have to do a little dance. */
+
+ SYSTEMTIME systime;
+ FILETIME filetime;
+ ULARGE_INTEGER unixtime;
+
+ /* Windows SYSTEMTIME is a big struct with fields for
+ year, month, day, hour, minute, second, millisecond. */
+ GetSystemTime(&systime);
+ /* Windows FILETIME timestamps use an epoch-based time,
+ using a 64bit unsigned word. The time is measured in
+ units of 100 nanoseconds since an epoch of 1601. */
+ SystemTimeToFileTime(&systime, &filetime);
+
+ /* FILETIME isn't directly a 64bit word, but a struct with
+ a pair of 32bit words, so we have to convert via a
+ ULARGE_INTEGER struct which is a handy union type */
+ unixtime.LowPart = filetime.dwLowDateTime;
+ unixtime.HighPart = filetime.dwHighDateTime;
+
+ /* We have to do an epoch conversion, since FILETIME uses 1601
+ while we want unix epoch of 1970. In case you were wondering,
+ there were 11,644,473,600 seconds between 1601 and 1970, then
+ multiply by 10^7 for units of 100 nanoseconds. */
+ unixtime.QuadPart = unixtime.QuadPart - 116444736000000000ull;
+
+ /* For the seconds part we use integer division by 10^7 */
+ *sec = unixtime.QuadPart / 10000000ull;
+
+ /* The remainder from integer division by 10^7 gives us
+ the sub-second component in units of 100 nanoseconds.
+ So for nanoseconds we just multiply by 100.
+ Note that nanoseconds always fits in a 32bit word */
+ *nsec = ((unsigned long)(unixtime.QuadPart % 10000000ull)) * 100ul;
+}
+
nat
getPageFaults(void)
{