summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-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)
{