Porting clock_gettime to windows

匿名 (未验证) 提交于 2019-12-03 08:36:05

问题:

I have the following code running on qnx momemntics.

#define BILLION 1000000000L;  struct timespec start_time; struct timespec stop_time;   void start MyTestFunc() {     //Initialize the Test Start time      clock_gettime(CLOCK_REALTIME,&start_time)     // ... additonal code.      cout 

Now i want to port above code to windows. can any one provide sample code.

Thanks!

回答1:

You can implement a clock_gettime() replacement for windows as follows:

LARGE_INTEGER getFILETIMEoffset() {     SYSTEMTIME s;     FILETIME f;     LARGE_INTEGER t;      s.wYear = 1970;     s.wMonth = 1;     s.wDay = 1;     s.wHour = 0;     s.wMinute = 0;     s.wSecond = 0;     s.wMilliseconds = 0;     SystemTimeToFileTime(&s, &f);     t.QuadPart = f.dwHighDateTime;     t.QuadPart tv_sec = t.QuadPart / 1000000;     tv->tv_usec = t.QuadPart % 1000000;     return (0); } 


回答2:

Avoiding PerformanceCounter mess, simple code:

struct timespec { long tv_sec; long tv_nsec; };    //header part int clock_gettime(int, struct timespec *spec)      //C-file part {  __int64 wintime; GetSystemTimeAsFileTime((FILETIME*)&wintime);    wintime      -=116444736000000000i64;  //1jan1601 to 1jan1970    spec->tv_sec  =wintime / 10000000i64;           //seconds    spec->tv_nsec =wintime % 10000000i64 *100;      //nano-seconds    return 0; } 

...is fast, reliable and correct porting solution when high precision is not so important.

And QPC-based solution with full precision is:

struct timespec { long tv_sec; long tv_nsec; };   //header part #define exp7           10000000i64     //1E+7     //C-file part #define exp9         1000000000i64     //1E+9 #define w2ux 116444736000000000i64     //1.jan1601 to 1.jan1970 void unix_time(struct timespec *spec) {  __int64 wintime; GetSystemTimeAsFileTime((FILETIME*)&wintime);     wintime -=w2ux;  spec->tv_sec  =wintime / exp7;                                      spec->tv_nsec =wintime % exp7 *100; } int clock_gettime(int, timespec *spec) {  static  struct timespec startspec; static double ticks2nano;    static __int64 startticks, tps =0;    __int64 tmp, curticks;    QueryPerformanceFrequency((LARGE_INTEGER*)&tmp); //some strange system can    if (tps !=tmp) { tps =tmp; //init ~~ONCE         //possibly change freq ?                     QueryPerformanceCounter((LARGE_INTEGER*)&startticks);                     unix_time(&startspec); ticks2nano =(double)exp9 / tps; }    QueryPerformanceCounter((LARGE_INTEGER*)&curticks); curticks -=startticks;    spec->tv_sec  =startspec.tv_sec   +         (curticks / tps);    spec->tv_nsec =startspec.tv_nsec  + (double)(curticks % tps) * ticks2nano;          if (!(spec->tv_nsec tv_sec++; spec->tv_nsec -=exp9; }    return 0; } 


回答3:

My improved version of clock_gettime() using QueryPerformanceCounter().

#define BILLION                             (1E9)  static BOOL g_first_time = 1; static LARGE_INTEGER g_counts_per_sec;  int clock_gettime(int dummy, struct timespec *ct) {     LARGE_INTEGER count;      if (g_first_time)     {         g_first_time = 0;          if (0 == QueryPerformanceFrequency(&g_counts_per_sec))         {             g_counts_per_sec.QuadPart = 0;         }     }      if ((NULL == ct) || (g_counts_per_sec.QuadPart tv_sec = count.QuadPart / g_counts_per_sec.QuadPart;     ct->tv_nsec = ((count.QuadPart % g_counts_per_sec.QuadPart) * BILLION) / g_counts_per_sec.QuadPart;      return 0; } 

I think my version is an improvement over the currently accepted answer using QueryPerformanceCounter(), because -

  1. More robust - checks return values of functions, also value returned in pass-by-reference variable.
  2. More robust - checks validity of input parameter.
  3. More streamlined - Uses as few as necessary number of variables (3 vs 7).
  4. More streamlined - Avoids the code-path involving GetSystemTimeAsFileTime() since QueryPerformanceFrequency() and QueryPerformanceCounter() are guaranteed to work on systems that run Windows XP or later.


回答4:

You can use timespec_get to implement simple clock_gettime.
(timespec_get function is available since C11)

int clock_gettime(int, struct timespec *tv) {     return timespec_get(tv, TIME_UTC); } 

... but result timespec has about 10 milisec resolution on my windows7 64bit machine. :(

Here is my version of clock_gettime.

int clock_gettime(int, struct timespec *tv) {     static int initialized = 0;     static LARGE_INTEGER freq, startCount;     static struct timespec tv_start;     LARGE_INTEGER curCount;     time_t sec_part;     long nsec_part;      if (!initialized) {         QueryPerformanceFrequency(&freq);         QueryPerformanceCounter(&startCount);         timespec_get(&tv_start, TIME_UTC);         initialized = 1;     }      QueryPerformanceCounter(&curCount);      curCount.QuadPart -= startCount.QuadPart;     sec_part = curCount.QuadPart / freq.QuadPart;     nsec_part = (long)((curCount.QuadPart - (sec_part * freq.QuadPart))             * 1000000000UL / freq.QuadPart);      tv->tv_sec = tv_start.tv_sec + sec_part;     tv->tv_nsec = tv_start.tv_nsec + nsec_part;     if(tv->tv_nsec >= 1000000000UL) {         tv->tv_sec += 1;         tv->tv_nsec -= 1000000000UL;     }     return 0; } 


标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!