ns-precision monotonic clock in C on Linux and OS X

后端 未结 2 411
再見小時候
再見小時候 2021-01-06 10:38

clock_gettime(CLOCK_MONOTONIC, ...) is available in Linux but not OS X. The Mach timers are available in OS X but not in Linux.

How can I get a ns-preci

相关标签:
2条回答
  • 2021-01-06 11:21
    /* 
    This is based on the snippet current_utc_time.c from:
    https://gist.github.com/jbenet/1087739
    
    On OS X, compile with: gcc get_monotonic_time.c
       Linux, compile with: gcc get_monotonic_time.c -lrt
    */
    
    #include <time.h>
    #include <sys/time.h>
    #include <stdio.h>
    
    #ifdef __MACH__
    #include <mach/clock.h>
    #include <mach/mach.h>
    #endif
    
    // Use clock_gettime in linux, clock_get_time in OS X.
    void get_monotonic_time(struct timespec *ts){
    #ifdef __MACH__
      clock_serv_t cclock;
      mach_timespec_t mts;
      host_get_clock_service(mach_host_self(), SYSTEM_CLOCK, &cclock);
      clock_get_time(cclock, &mts);
      mach_port_deallocate(mach_task_self(), cclock);
      ts->tv_sec = mts.tv_sec;
      ts->tv_nsec = mts.tv_nsec;
    #else
      clock_gettime(CLOCK_MONOTONIC, ts);
    #endif
    }
    
    double get_elapsed_time(struct timespec *before, struct timespec *after){
      double deltat_s  = after->tv_sec - before->tv_sec;
      double deltat_ns = after->tv_nsec - before->tv_nsec;
      return deltat_s + deltat_ns*1e-9;
    }
    
    int main(){
    
      // Do something and time how long it takes.
      struct timespec before, after;
      get_monotonic_time(&before);
      double sum=0.;
      unsigned u;
      for(u=1; u<100000000; u++)
        sum += 1./u/u;
      get_monotonic_time(&after);
      printf("sum = %e\n", sum);
      printf("deltaT = %e s\n", get_elapsed_time(&before,&after));
    
    }
    
    0 讨论(0)
  • 2021-01-06 11:38

    I used the answer by Douglas (accepted answer), his references and other examples floating around the internet (such as this question).

    This answer is to include my version of the code which emulates the clock_gettime for CLOCK_REALTIME and CLOCK_MONOTONIC. It also emulates the function clock_nanosleep() for absolute monotonic time. The code is hosted on GitHub here.

    For it to work, the only additional bit needed in your code is

    #ifdef __MACH__
    timing_mach_init();
    #endif
    

    then use clock_gettime() and clock_nanosleep_abstime() as if you were using a system that is actually POSIX compliant (with realtime extensions).

    0 讨论(0)
自定义标题
段落格式
字体
字号
代码语言
提交回复
热议问题