home *** CD-ROM | disk | FTP | other *** search
/ Source Code 1992 March / Source_Code_CD-ROM_Walnut_Creek_March_1992.iso / usenet / altsrcs / 1 / 1675 < prev    next >
Text File  |  1990-12-28  |  7KB  |  190 lines

  1. Newsgroups: alt.sources
  2. From: hakanson@CSE.OGI.EDU (Marion Hakanson)
  3. Subject: [comp.protocols.time.ntp] Unix system clock resolution (precision)
  4. Message-ID: <1990Aug15.205349.12566@math.lsa.umich.edu>
  5. Date: Wed, 15 Aug 90 20:53:49 GMT
  6.  
  7. Archive-name: clockres/15-Aug-90
  8. Original-posting-by: hakanson@CSE.OGI.EDU (Marion Hakanson)
  9. Original-subject: Unix system clock resolution (precision)
  10. Reposted-by: emv@math.lsa.umich.edu (Edward Vielmetti)
  11.  
  12. [Reposted from comp.protocols.time.ntp.
  13. Comments on this service to emv@math.lsa.umich.edu (Edward Vielmetti).]
  14.  
  15. Below find clockres.c, source to a program which will tell you (most of
  16. the time) the resolution of your gettimeofday(2) system call, and thus
  17. probably the precision of your system's underlying clock.  It has uses
  18. other than satisfying curiosity:  you may be able to use it to tell
  19. an ntp server what precision to use, or to find out how accurate various
  20. performance measurements might be.  Do keep in mind that ntpd's estimate
  21. using the kernel HZ value is probably best for most machines.
  22.  
  23. Bug reports would be welcome to me, though it's pretty simple.  I
  24. don't really care to create an archive of the results on various and
  25. sundry computer systems -- it takes less time to compile and run the
  26. program than it does to ftp a list from somewhere to look up your
  27. machine.  But perhaps such an archive would be of use to prospective
  28. purchasers of hardware.  I certainly ran into some surprises (like
  29. maybe 2^-6 isn't "bad" enough for an NTP precision).  Here's a list of
  30. what I've encountered so far, in no particular order (the "or better"
  31. is explained in the program header commentary).
  32.  
  33. =============
  34. Hardware        O/S software        Resolution (microseconds)
  35.  
  36. HP-9000/320        4.3bsd/Univ.Utah    336 or better (prob. 4)
  37. HP-9000/200        4.3bsd/Berkeley        830 or better (prob. 4)
  38.  
  39. DEC-DS2100        Ultrix-3.1 (UWS-2.2)    3906
  40. DEC-uVAX/II        4.3bsd/MtXinu        10000
  41.  
  42. Sun-4/60        SunOS-4.0.3c        53 or better (maybe 1?)
  43. Sun-4/60        SunOS-4.1(c)        62 or better (maybe 1?)
  44. Sun-4/65        SunOS-4.1(c)        10000
  45. Sun-4/110        SunOS-4.0.3        10000
  46. Sun-4/280        SunOS-4.0.3        10000
  47. Sun-3/50        SunOS-4.0.3        20000
  48. Sun-3/60        SunOS-4.1        20000
  49.  
  50. Sequent-S81        DYNIX-3.0.12        10000
  51. Sequent-B21        DYNIX-3.1.alpha1    10000
  52.  
  53. Tek-431[57]        UTek-3.1        50000 (missed the boat again)
  54. =============
  55.  
  56.  
  57. =============
  58. #ifndef lint
  59. char rcsid[] = "$Id: clockres.c,v 1.9 90/08/14 23:41:21 hakanson Exp $";
  60. #endif /* lint */
  61.  
  62. /*
  63.  * Determine the resolution of the system clock (gettimeofday(2)).
  64.  *   Marion Hakanson (hakanson@cse.ogi.edu)
  65.  *   Oregon Graduate Institute of Science and Technology
  66.  *
  67.  * The idea is to call gettimeofday(2), then repeatedly call it again
  68.  * until you get a different value.  The difference between the two
  69.  * values should be the resolution (precision) of the system clock.
  70.  * A little noise sometimes creeps in, due to adjtime(2)'s being done,
  71.  * but in practice this appears rarely and can be factored out by running
  72.  * this test program repeatedly (say 10 times).  There is a "-v" option
  73.  * to print out the two differing timestamps (and the number of calls
  74.  * it took before a difference was detected).  You may occasionally
  75.  * see two (but never more) of these printed out before a result is
  76.  * announced -- this is to avoid anomalies with comparing microseconds
  77.  * when a wrap to the next full second has occurred.
  78.  *
  79.  * The big flaw to this approach is that most 4.3bsd-based systems have
  80.  * in their kernels a microtime() routine which is supposed to return
  81.  * the current time to the microsecond.  A "good" implementation would
  82.  * (e.g.) read a hardware interval timer to determine how many usec's
  83.  * had passed since the last clock tick.  But much hardware seems to
  84.  * lack such a timer, and as a result, most implementations of microtime()
  85.  * fake it by adding a microsecond to the current time for each subsequent
  86.  * call to microtime() -- just to ensure that two invocations never return
  87.  * exactly the same value (the fake microseconds go away at the next clock
  88.  * tick) .  Since most machines (known to mortals) these days cannot make
  89.  * a system call in one microsecond, this program has a hack in it to
  90.  * detect these "fake" microtime() implementations by adding the number
  91.  * of gettimeofday(2) calls to the initial timestamp before comparing
  92.  * with the most recent timestamp.  A ">=" test is used to work with
  93.  * older bsd's (like 4.2), where two subsequent timestamps often are
  94.  * the same (within the value of a tick), and the "-f" option disables
  95.  * the "fake" microtime() workaround.  More irregular "fakes" will no
  96.  * doubt be reported as terrific (but erroneous) clock resolutions.
  97.  *
  98.  * A small flaw is that if a machine has a clock resolution finer than
  99.  * the time it takes to make a single pass through the loop, then the
  100.  * program reports that value as the resolution of the clock, rather
  101.  * than the actual resolution.  A warning about this is printed when
  102.  * a real difference is detected after only one pass (it says "... XX
  103.  * microseconds or better" instead of just "... XX microseconds").
  104.  * Again, repeated runs can show this condition if the value seems to
  105.  * fluctuate by a few microseconds and/or vary with system load (a
  106.  * "genuine" result seems to stay rock solid across invocations).
  107.  * In practice, few real machines seem to encounter this behavior,
  108.  * and you should count yourself lucky if you have one.
  109.  */
  110.  
  111. #include <stdio.h>
  112. #include <sys/time.h>
  113.  
  114. extern int getopt();
  115.  
  116. main(argc, argv)
  117.     int argc;  char *argv[];
  118. {
  119. int verbose;
  120. register int fakemicro;
  121. int again;
  122. struct timeval t1, t2;
  123. register int calls;
  124. int c;
  125.  
  126.  
  127. verbose = 0;
  128. fakemicro = 1;
  129.  
  130. while ( (c = getopt(argc, argv, "fv")) != EOF ) {
  131.   switch ( c ) {
  132.     case 'f':
  133.       fakemicro = 0;
  134.       break;
  135.     case 'v':
  136.       verbose = 1;
  137.       break;
  138.     case '?':
  139.       fprintf(stderr, "usage: %s [-fv]\n", argv[0]);
  140.       exit(1);
  141.   }
  142. }
  143.    
  144.  
  145. again = 0;
  146.  
  147. top:
  148.  
  149. if (again > 1) {
  150.   fprintf (stderr, "%s: More than one second passed, giving up.\n", argv[0]);
  151.   exit(1);
  152. }
  153.  
  154. again++;
  155.  
  156. calls = 0;
  157.  
  158. (void) gettimeofday(&t1, NULL);
  159.  
  160. do {
  161.   calls++;
  162.   (void) gettimeofday(&t2, NULL);
  163. } while ( (t1.tv_sec == t2.tv_sec)
  164.      && ( fakemicro ? ((t1.tv_usec+calls) >= t2.tv_usec)
  165.              : (t1.tv_usec == t2.tv_usec) ) );
  166.  
  167. if (verbose) {
  168.   printf ("t1 %d.%06.6d t2 %d.%06.6d calls %d\n",
  169.     t1.tv_sec, t1.tv_usec, t2.tv_sec, t2.tv_usec, calls);
  170. }
  171.  
  172. /* Check for wrap to next second */
  173. if (t1.tv_sec != t2.tv_sec)
  174.   goto top;
  175.  
  176. printf ("Clock step resolution %d microseconds", t2.tv_usec - t1.tv_usec);
  177.  
  178. if ( calls == 1 )
  179.   printf (" or better");
  180.  
  181. printf("\n");
  182.  
  183. exit(0);
  184. }
  185. =============
  186.  
  187. -- 
  188. Marion Hakanson         Domain: hakanson@cse.ogi.edu
  189.                         UUCP  : {hp-pcd,tektronix}!ogicse!hakanson
  190.