From 71846a3ea365e3fdc749716d515237af4588fb30 Mon Sep 17 00:00:00 2001 From: stansmith Date: Thu, 9 Jul 2009 17:56:49 +0000 Subject: [PATCH] [ETC] Provide a common implementation for gettimeofday(). git-svn-id: svn://openib.tc.cornell.edu/gen1@2280 ad392aa1-c5ef-ae45-8dd8-e69d62a5ef86 --- trunk/etc/user/gtod.c | 111 ++++++++++++++++++++++++++++++++ trunk/inc/user/linux/sys/time.h | 14 ++++ 2 files changed, 125 insertions(+) create mode 100644 trunk/etc/user/gtod.c create mode 100644 trunk/inc/user/linux/sys/time.h diff --git a/trunk/etc/user/gtod.c b/trunk/etc/user/gtod.c new file mode 100644 index 00000000..5207a268 --- /dev/null +++ b/trunk/etc/user/gtod.c @@ -0,0 +1,111 @@ +#ifndef _GTOD_C_ +#define _GTOD_C_ + +/* + * int gettimeofday(struct timeval *ptv, void *ignored) + */ + +#include +#include + + +static __inline +void FileTimeToTimeval(LPFILETIME pft, struct timeval * ptv) +{ /* Note that LONGLONG is a 64-bit value */ + LONGLONG ll; + + if(!pft || !ptv) { + ptv->tv_sec = 0; + ptv->tv_usec = 0; + return; + } + + ll = ((LONGLONG) pft->dwHighDateTime << 32); + ll += (LONGLONG) pft->dwLowDateTime; + ll -= 116444736000000000; + + ptv->tv_sec = (long) (ll / 10000000); + ptv->tv_usec = (long) (ll - ((LONGLONG)(ptv->tv_sec) * 10000000)) / 10; +} + + +// static __inline +int gettimeofday(struct timeval *ptv, void *ignored) +{ + static int QueryCounter = 2; + FILETIME CurrentTime; + UNREFERENCED_PARAMETER(ignored); + + if(!ptv) return -1; + + if(QueryCounter) + { + static LARGE_INTEGER Frequency; + static LARGE_INTEGER Offset; /* counter offset for right time*/ + static LARGE_INTEGER LastCounter; + LARGE_INTEGER Time; + LARGE_INTEGER Counter; + + GetSystemTimeAsFileTime(&CurrentTime); + QueryPerformanceCounter(&Counter); + + if(QueryCounter == 2) + { + QueryCounter = 1; + if(!QueryPerformanceFrequency(&Frequency)) + { + QueryCounter = 0; + Frequency.QuadPart = 10000000; /* prevent division by 0 */ + } + + /* get time as a large integer */ + Counter.HighPart &= 0x7FL; /* Clear high bits to prevent overflow */ + Offset.LowPart = CurrentTime.dwLowDateTime; + Offset.HighPart = (LONG) CurrentTime.dwHighDateTime; + Offset.QuadPart -= Counter.QuadPart * 10000000 / Frequency.QuadPart; + } + + /* Convert counter to a 100 nanoseconds resolution timer value. */ + + Counter.HighPart &= 0x7FL; /* Clear high bits to prevent overflows */ + Counter.QuadPart *= 10000000; /* need time stamp in 100 ns units */ + Counter.QuadPart /= Frequency.QuadPart;/* counter of 0.1 microseconds */ + + if(LastCounter.QuadPart > Counter.QuadPart) + { /* Counter value wrapped */ + Offset.QuadPart += (0x7F00000000*10000000) / Frequency.QuadPart; + } + LastCounter = Counter; + + /* Add the in previous call calculated offset */ + Counter.QuadPart += Offset.QuadPart; + + /* get time as a large integer */ + Time.LowPart = CurrentTime.dwLowDateTime; + Time.HighPart = (LONG) CurrentTime.dwHighDateTime; + + /* keep time difference within an interval of +- 0.1 seconds + relative to the time function by adjusting the counters offset */ + + if( ((Time.QuadPart + 1000000) < Counter.QuadPart) || + ((Time.QuadPart - 1000000) > Counter.QuadPart) ) + { /* Adjust the offset */ + Offset.QuadPart += Time.QuadPart - Counter.QuadPart; + Counter.QuadPart = Time.QuadPart; + } + + /* use the adjusted performance counter time for the time stamp */ + CurrentTime.dwLowDateTime = Counter.LowPart; + CurrentTime.dwHighDateTime = Counter.HighPart; + } + else + { + GetSystemTimeAsFileTime(&CurrentTime); + } + + FileTimeToTimeval(&CurrentTime,ptv); + + return(0); +} + +#endif /* _GTOD_C_ */ diff --git a/trunk/inc/user/linux/sys/time.h b/trunk/inc/user/linux/sys/time.h new file mode 100644 index 00000000..50ba78eb --- /dev/null +++ b/trunk/inc/user/linux/sys/time.h @@ -0,0 +1,14 @@ +#ifndef _SYS_TIME_H_ +#define _SYS_TIME_H_ + +#include + +struct timezone { + int tz_minuteswest; /* minutes west of Greenwich */ + int tz_dsttime; /* type of dst correction */ +}; + + +extern int gettimeofday(struct timeval *ptv, void *ignored); + +#endif -- 2.41.0