msはマイクロソフトではなく1000分の1秒。

ここらへんの続き。
今こんな感じ。

#include <X11/Xlib.h>
#include <stdio.h>
#include <stdlib.h>

// nanosleep用。
#include <time.h>

// gettimeofday用。
#include <sys/time.h>

#define WIDTH 400	 // ウィンドウの幅。
#define HEIGHT 200	 // ウィンドウの高さ。
#define R 10		 // 円の半径。
#define V 5		 // 1回の移動の距離。
#define INTERVAL 20	 // 移動の間隔。(ms)
#define MAX 250		 // 最大間隔。(ms)
#define MIN 10		 // MINms単位で間隔を変える。MAX > 間隔 > MINという訳ではない。ややこし。
#define N 10		 // 繰り返し回数。

main(){
  Display *d;
  int screen;
  Window root, window;
  unsigned long black, white;
  XGCValues xgcv;
  GC gc;
  char s[5];
  Window circle[2];	 // 0が右、1が左。
  int cx[2], cy[2];
  struct timespec interval, rand_int;
  struct timeval start_time, end_time;
  int i = N;		 // i回繰り返す。

  interval.tv_sec = 0;
  interval.tv_nsec = INTERVAL * 1000 * 1000;

  if( (d = XOpenDisplay( NULL )) == NULL ){
    fprintf( stderr, "can't open display.\n" );
    exit(1);
  }

  screen = DefaultScreen(d);
  root = DefaultRootWindow(d);
  white = WhitePixel(d, screen);
  black = BlackPixel(d, screen);

  window = XCreateSimpleWindow(d, root, 0, 0, WIDTH, HEIGHT, 1, black, white);
  gc = XCreateGC(d, window, 0, NULL);

  cx[0] = WIDTH - 2*R;
  cy[0] = HEIGHT/2 - R;
  cx[1] = WIDTH/2 - 2*R;
  cy[1] = HEIGHT/2 - R;
  circle[0] = XCreateSimpleWindow(d, window, cx[0], cy[0], 2*R, 2*R, 0, black, white);
  circle[1] = XCreateSimpleWindow(d, window, cx[1], cy[1], 2*R, 2*R, 0, black, white);

  XMapWindow(d, window);
  XMapWindow(d, circle[0]);
  XMapWindow(d, circle[1]);
  XFlush(d);
  fgets(s, 5, stdin);

  XFillArc(d, circle[0], gc, 0, 0, 2*R, 2*R, 0, 360*64);
  XFillArc(d, circle[1], gc, 0, 0, 2*R, 2*R, 0, 360*64);
  XFlush(d);

  do{
    if( i-- <= 0 ){ break; }
    srand( time(NULL) );
    rand_int.tv_nsec = (int)( MAX/MIN * ( rand()/(double)RAND_MAX ) ) * MIN * 1000*1000;
    rand_int.tv_sec = 0;

    cx[0] = WIDTH - 2*R;
    cx[1] = WIDTH/2 - 2*R;
    XMoveWindow(d, circle[1], cx[1], cy[1]);
    XFlush(d);

    while( cx[0] > WIDTH/2 ){
      nanosleep( &interval, NULL );
      cx[0] -= V;
      XMoveWindow(d, circle[0], cx[0], cy[0]);
      XFlush(d);
    }
    gettimeofday( &start_time, NULL );

    nanosleep( &rand_int, NULL );

    cx[1] -= V;
    XMoveWindow(d, circle[1], cx[1], cy[1]);
    XFlush(d);

    gettimeofday( &end_time, NULL );
    while( cx[1] > 0 ){
      nanosleep( &interval, NULL );
      cx[1] -= V;
      XMoveWindow(d, circle[1], cx[1], cy[1]);
      XFlush(d);
    }
    printf( "sleep( %d.%03d %03d %03ds )\n",
	    rand_int.tv_sec,
	    rand_int.tv_nsec/(1000*1000),
	    (rand_int.tv_nsec/1000)%1000,
	    rand_int.tv_nsec%1000 );
    if( end_time.tv_usec - start_time.tv_usec >= 0 ){
      printf( "sleep  %d.%03d %03ds\n",
	      end_time.tv_sec - start_time.tv_sec,
	      (end_time.tv_usec - start_time.tv_usec )/1000,
	      (end_time.tv_usec - start_time.tv_usec )%1000 );
    }else{
      printf( "sleep  %d.%03d %03ds\n",
	      end_time.tv_sec - start_time.tv_sec -1,
	      (end_time.tv_usec - start_time.tv_usec +1000*1000 )/1000,
	      (end_time.tv_usec - start_time.tv_usec +1000*1000 )%1000 );
    }
    fgets(s, 5, stdin);
  }while( s[0]=='1' || s[0]=='2' || s[0]=='3' );
}

nanosleepで間隔をあけるようにした*1。その前後でgettimeofdayで時間を手に入れて、差を出してみた。その出力。

$ ./hi-3.a-2

sleep( 0.020 000 000s )
sleep  0.029 993s
1
sleep( 0.040 000 000s )
sleep  0.049 995s
1
sleep( 0.180 000 000s )
sleep  0.189 968s
2
sleep( 0.160 000 000s )
sleep  0.169 967s
2
sleep( 0.060 000 000s )
sleep  0.069 968s
1
sleep( 0.200 000 000s )
sleep  0.209 951s
3
sleep( 0.220 000 000s )
sleep  0.229 962s
3
sleep( 0.110 000 000s )
sleep  0.119 977s
2
sleep( 0.170 000 000s )
sleep  0.179 963s
2
sleep( 0.060 000 000s )
sleep  0.069 975s
1

sleep( …s )がnanosleepで指定した値。sleep …s がgettimeofdayの差で出した実際の値。*2
10ms程、長くかかってる。10msがsleepできる単位、ってことですな。なんかOS論でやったような。
そんなことより、これってグラフ書く時どっちの値使えばいいんですかい。実際の値の方がいいような気がするけど、パーセント出すときに10ms単位に四捨五入するんだったら、指定した値を使うか、+10msして使うかした方がよさそうな気がするんですが。
+10msがいい感じかな。

*1:usleepのmanを見たら、古いからこっち使え、とか言われて。

*2:分かりづらっ。分かりづらいといえば、rand_intってのも分かりづらそう。randomなintegerじゃなくて、randomなinterval。M-% rand_int rand_intervalしようか。