nanosleep()の精度

usleepに続いてnanosleepの精度を確認。
gettimeofdayはマイクロ秒単位までしか測定できませんが、ナノ秒単位の精度がでることはなさそうなので気にしません。

検証プログラム
#include <stdio.h>
#include <sys/time.h>

double get_time_sec(){
  struct timeval tv;
  gettimeofday(&tv, NULL);
  return tv.tv_sec + (double)tv.tv_usec*1e-6;
}

int main(){
  long ns;
  puts("       指定          停止          誤差");
  for(ns=1;ns<(long)10e8;ns*=10){
    double start,end;
    struct timespec tc;
    tc.tv_sec = 0;    /* sec */
    tc.tv_nsec = ns;  /* nano sec */

    start = get_time_sec();
    nanosleep(&tc, NULL);
    end = get_time_sec();

    printf("%.9f : %.9f : %.9f sec\n",
      ns/1.0e9, end - start, end - start - ns/1.0e9);
  }

  return 0;
}

実行結果

Linux
[mikeda@cent c]$ ./nanosleep_check 
       指定          停止          誤差
0.000000001 : 0.000766993 : 0.000766992 sec
0.000000010 : 0.000874043 : 0.000874033 sec
0.000000100 : 0.000933886 : 0.000933786 sec
0.000001000 : 0.000940084 : 0.000939084 sec
0.000010000 : 0.000939131 : 0.000929131 sec
0.000100000 : 0.000941038 : 0.000841038 sec
0.001000000 : 0.001937866 : 0.000937866 sec
0.010000000 : 0.010936975 : 0.000936975 sec
0.100000000 : 0.100923061 : 0.000923061 sec
[mikeda@cent c]$ ./nanosleep_check 
       指定          停止          誤差
0.000000001 : 0.002135038 : 0.002135037 sec
0.000000010 : 0.001869202 : 0.001869192 sec
0.000000100 : 0.001936913 : 0.001936813 sec
0.000001000 : 0.001938105 : 0.001937105 sec
0.000010000 : 0.001939058 : 0.001929058 sec
0.000100000 : 0.001938105 : 0.001838105 sec
0.001000000 : 0.002938032 : 0.001938032 sec
0.010000000 : 0.011937141 : 0.001937141 sec
0.100000000 : 0.101919174 : 0.001919174 sec

繰り返すと1ms、2msの2パターンの誤差がでる。
なぜそんなことになるのか。
ここは伊藤直也ばりのカーネル解析で・・・すみません、今はできません。

MacBook
air:timer mikeda$ ./nanosleep_check 
       指定          停止          誤差
0.000000001 : 0.000029087 : 0.000029086 sec
0.000000010 : 0.000018835 : 0.000018825 sec
0.000000100 : 0.000018120 : 0.000018020 sec
0.000001000 : 0.000017881 : 0.000016881 sec
0.000010000 : 0.000122070 : 0.000112070 sec
0.000100000 : 0.000231028 : 0.000131028 sec
0.001000000 : 0.001104832 : 0.000104832 sec
0.010000000 : 0.010083914 : 0.000083914 sec
0.100000000 : 0.100172997 : 0.000172997 sec

やっぱりMacBookのほうが精度がいい。