diff options
-rw-r--r-- | rts/GetTime.h | 5 | ||||
-rw-r--r-- | rts/posix/GetTime.c | 16 | ||||
-rw-r--r-- | rts/win32/GetTime.c | 40 |
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) { |