Unix to Windows Porting Dictionary for HPC |
|
|
RSS
LinksFunction List
|
Table of Contents The gettimeofday() function obtain the current time, expressed as seconds and microseconds since the Epoch, and stores it in the timeval structure given in the parameters. There is no direct analog of the gettimeofday() in Windows; developers porting codes that use this function must provide a conversion. The typical conversion utilizes the Microsoft Windows GetSystemTimeAsFileTime function, but there are some conversion issues. One, the Windows routine returns the number of 100 nanosecond intervals, not the number of microseconds. Two, the Windows function defines the starting Epoch as January 1, 1601 where the Unix gettimeofday() function defines the starting Epoch as January 1, 1970. Below is an example of wrapping GetSystemTimeAsFileTime that deals with both of these issues, allowing developers to provide a replacement gettimeofday() without requiring any other changes.
#include "stdafx.h"
#include <time.h>
#include <windows.h>
#include <iostream>
using namespace System;
using namespace std;
#if defined(_MSC_VER) || defined(_MSC_EXTENSIONS)
#define DELTA_EPOCH_IN_MICROSECS 11644473600000000Ui64
#else
#define DELTA_EPOCH_IN_MICROSECS 11644473600000000ULL
#endif
struct timezone
{
int tz_minuteswest; /* minutes W of Greenwich */
int tz_dsttime; /* type of dst correction */
};
// Definition of a gettimeofday function
int gettimeofday(struct timeval *tv, struct timezone *tz)
{
// Define a structure to receive the current Windows filetime
FILETIME ft;
// Initialize the present time to 0 and the timezone to UTC
unsigned __int64 tmpres = 0;
static int tzflag = 0;
if (NULL != tv)
{
GetSystemTimeAsFileTime(&ft);
// The GetSystemTimeAsFileTime returns the number of 100 nanosecond
// intervals since Jan 1, 1601 in a structure. Copy the high bits to
// the 64 bit tmpres, shift it left by 32 then or in the low 32 bits.
tmpres |= ft.dwHighDateTime;
tmpres <<= 32;
tmpres |= ft.dwLowDateTime;
// Convert to microseconds by dividing by 10
tmpres /= 10;
// The Unix epoch starts on Jan 1 1970. Need to subtract the difference
// in seconds from Jan 1 1601.
tmpres -= DELTA_EPOCH_IN_MICROSECS;
// Finally change microseconds to seconds and place in the seconds value.
// The modulus picks up the microseconds.
tv->tv_sec = (long)(tmpres / 1000000UL);
tv->tv_usec = (long)(tmpres % 1000000UL);
}
if (NULL != tz)
{
if (!tzflag)
{
_tzset();
tzflag++;
}
// Adjust for the timezone west of Greenwich
tz->tz_minuteswest = _timezone / 60;
tz->tz_dsttime = _daylight;
}
return 0;
}
Example usage to for interval timing:
// Test routine for calculating a time difference
int main()
{
struct timeval timediff;
char dummychar;
// Do some interval timing
gettimeofday(&timediff, NULL);
double t1=timediff.tv_sec+(timediff.tv_usec/1000000.0);
// Waste a bit of time here
cout << "Give me a keystroke and press Enter." << endl;
cin >> dummychar;
cout << "Thanks." << endl;
//Now that you have measured the user's reaction time, display the results in seconds
gettimeofday(&timediff, NULL);
double t2=timediff.tv_sec+(timediff.tv_usec/1000000.0);
cout << t2-t1 << " seconds have elapsed" << endl;
return 0;
}
|
|
|
|