home *** CD-ROM | disk | FTP | other *** search
/ InfoMagic Source Code 1993 July / THE_SOURCE_CODE_CD_ROM.iso / X / mit / demos / gpc / stopwatch.c < prev    next >
Encoding:
C/C++ Source or Header  |  1991-04-04  |  9.5 KB  |  315 lines

  1. /* $XConsortium: stopwatch.c,v 5.2 91/04/04 13:33:02 gildea Exp $ */
  2. /***********************************************************
  3. Copyright(c) 1989,1990, 1991 by Sun Microsystems, Inc. and the X Consortium at M.I.T.
  4.  
  5.                         All Rights Reserved
  6.  
  7. Permission to use, copy, modify, and distribute this software and its
  8. documentation for any purpose and without fee is hereby granted,
  9. provided that the above copyright notice appear in all copies and that
  10. both that copyright notice and this permission notice appear in
  11. supporting documentation, and that the names of Sun Microsystems,
  12. the X Consortium, and MIT not be used in advertising or publicity
  13. pertaining to distribution of the software without specific, written
  14. prior permission.
  15.  
  16. SUN MICROSYSTEMS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
  17. INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT
  18. SHALL SUN MICROSYSTEMS BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL
  19. DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
  20. WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
  21. ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
  22. SOFTWARE.
  23.  
  24. ******************************************************************/
  25.  
  26. /*--------------------------------------------------------------------*\
  27. |
  28. |  Copyright (C) 1989,1990, 1991, National Computer Graphics Association
  29. |
  30. |  Permission is granted to any individual or institution to use, copy, or
  31. |  redistribute this software so long as it is not sold for profit, provided
  32. |  this copyright notice is retained.
  33. |
  34. |                         Developed for the
  35. |                National Computer Graphics Association
  36. |                         2722 Merrilee Drive
  37. |                         Fairfax, VA  22031
  38. |                           (703) 698-9600
  39. |
  40. |                                by
  41. |                 SimGraphics Engineering Corporation
  42. |                    1137 Huntington Drive  Unit A
  43. |                      South Pasadena, CA  91030
  44. |                           (213) 255-0900
  45. |---------------------------------------------------------------------
  46. |
  47. | Author        :    jmz / SimGraphics Engineering Corportation
  48. |
  49. | File          :    stopwatch.c
  50. | Date          :    8/27/88
  51. | Project       :    PLB
  52. | Description   :    Stopwatch functions.
  53. | Status        :    Version 1.0
  54. |
  55. | Revisions     :    
  56. |
  57. |      12/90            MFC Tektronix, Inc.: PEX-SI PEX5R1 Release.
  58. |
  59. \*--------------------------------------------------------------------*/
  60.  
  61. /*--------------------------------------------------------------------*\
  62. |    Table of Contents
  63. |
  64. |    float stopwatch(int)
  65. |        :    a standard stop watch with split capabilities
  66. |    double bif_time()
  67. |        :    Get the time (system dependent portion)
  68. |
  69. \*--------------------------------------------------------------------*/
  70.  
  71. /*--------------------------------------------------------------------*\
  72. |    Includes, Defines, and Statics
  73. \*--------------------------------------------------------------------*/
  74.  
  75. #include <X11/Xosdefs.h>
  76. #include <stdio.h>
  77. #include <sys/types.h>
  78. #include <sys/time.h>
  79.  
  80. #include "stopwatch.h"
  81.  
  82. #ifndef X_NOT_STDC_ENV
  83. #include <time.h>
  84. #else /* X_NOT_STDC_ENV */
  85. #ifdef SYSV
  86. #include <time.h>        /* necessary? */
  87. #endif /* SYSV */
  88. struct tm *localtime();
  89. #endif /* X_NOT_STDC_ENV */
  90.  
  91. #ifdef SGI4D
  92. #include <sys/param.h>
  93. #define CLK_TCK HZ
  94. #endif
  95. #ifdef sparc
  96. #include <sys/param.h>
  97. #define CLK_TCK HZ
  98. #else 
  99. #ifdef SYSV
  100. #include <limits.h>
  101. #endif
  102. #endif
  103.  
  104. /* If we don't have a CLK_TCK value, make one up, 60 is reasonable */
  105. #ifndef CLK_TCK
  106. #define CLK_TCK 60
  107. #endif
  108.  
  109. #define real_time(a,b) (float) (a - b) 
  110.  
  111. /* define the watch states */
  112. #define BRAND_NEW 0
  113. #define STOPPED 1
  114. #define RUNNING 2
  115.             
  116. /*--------------------------------------------------------------------*\
  117. | Procedure     :    float stopwatch(int)
  118. |---------------------------------------------------------------------
  119. | Description   :    a standard stop watch with split capabilities
  120. |
  121. |    Returns the the current reading of the watch in seconds
  122. |    Reset returns 0.
  123. |    
  124. |    Precision hands back the smallest unit of time the
  125. |    watch can measure
  126. |    
  127. |    NOTE: stopwatch should be fully portable to other systems
  128. |    as the hardware dependancies have been put in bif_time.
  129. |---------------------------------------------------------------------
  130. | Return        :    The reading from the stopwatch
  131. \*--------------------------------------------------------------------*/
  132.  
  133. float stopwatch(option)
  134. int option;
  135. {
  136. /* what is the watch doing? .... */
  137.     static int watchstate = BRAND_NEW;
  138. /* when was the last start (or reset) */
  139.     static double watchzero = 0.0; /* in real seconds */
  140. /* what is the (offset) current time? */
  141.     static double watchtime = 0.0; /* in real seconds */
  142. /* how much time was run before the last start */
  143.     static double watchsumm = 0.0; /* in system ticks */
  144. /* what is the current time? */
  145.     static double watchreal = 0.0; /* in seconds */
  146.  
  147.     float watchprec = 0.0; /* in seconds */
  148.  
  149.     double bif_time();
  150.  
  151. #ifdef TEST_TIMER
  152.     fprintf(stderr,"Stopwatch called with option %d\n",option);
  153.     fflush(stderr);
  154. #endif
  155.  
  156.     if ( watchstate == BRAND_NEW )
  157.         watchzero = bif_time();
  158.  
  159.     switch (option)
  160.     {
  161.     case WATCH_STOP :
  162.         if ( watchstate != STOPPED )
  163.         {
  164.         /* Report the current time and update the summation */
  165.             watchstate = STOPPED;
  166.             watchtime = bif_time();
  167.             watchreal = real_time(watchtime+watchsumm,watchzero);
  168.             watchsumm += watchtime - watchzero;
  169.         }
  170.         break;
  171.  
  172.     case WATCH_START :
  173.         if ( watchstate != RUNNING )
  174.         {
  175.         /* Give a new base to subtract off */
  176.         /* Report the last reported time */
  177.             watchstate = RUNNING;
  178.             watchzero = bif_time();
  179.         }
  180.         else
  181.         {
  182.         /* A start on a start watch is the same as a split */
  183.             watchtime = bif_time();
  184.             watchreal = real_time(watchtime+watchsumm,watchzero);
  185.         }
  186.         break;
  187.  
  188.     case WATCH_SPLIT :
  189.     /* Give the current time report last calculated time when stopped*/
  190.         if ( watchstate == RUNNING )
  191.         {
  192.         
  193.  
  194.             watchtime = bif_time();
  195.             watchreal = real_time(watchtime+watchsumm,watchzero);
  196.         }
  197.         break;
  198.  
  199.     case WATCH_RESET :
  200.     /* clear the summary reset zero / time /and real time */
  201.         watchsumm = 0;
  202.         watchzero = bif_time();
  203.         watchtime = watchzero;
  204.         watchreal = 0.;
  205.         break;
  206.  
  207.     case WATCH_PRECISION :
  208.     /* Report the smallest measurable unit of time returned by
  209.     the hardware clock. This should be milliseconds for all known
  210.     implimentations of localtime() and gettimeofday(). */
  211.         watchprec = 1000.0/(float)CLK_TCK;
  212.         break;
  213.     }
  214.  
  215.     if ( option != WATCH_PRECISION )
  216.         return ( watchreal );
  217.     else
  218.         return ( watchprec );
  219. }
  220.  
  221.  
  222. /*--------------------------------------------------------------------*\
  223. | Procedure     :    double bif_time()
  224. |---------------------------------------------------------------------
  225. | Description   :    Get the time (system dependent portion)
  226. |
  227. |    PROGRAMMER NOTE. Your system must support localtime() and 
  228. |    gettimeofday() calls. These are standard UNIX system calls. If
  229. |    your system is non-standard, replacements for these calls
  230. |    need to be added to the routine bif_time at the end of this
  231. |    file.
  232. |---------------------------------------------------------------------
  233. | Return        :     The current time.
  234. \*--------------------------------------------------------------------*/
  235. double bif_time()
  236.  
  237. {
  238. #ifdef EXTERNALNOTE
  239.  
  240.  
  241.     ATTENTION END PORT PROGRAMMERS!!!!!!!
  242.  
  243.       This time function routine is based on the function gettimeofday(),
  244.     which is a standard call on most UNIX systems. It uses defines
  245.     in the include file sys/time.h. For non-UNIX systems, the gettimeofday()
  246.     will have to be replaced.
  247.  
  248. #endif /* endif EXTERNALNOTE */
  249.  
  250.     /* Return a double value of seconds and fractions of seconds to the
  251.     greatest accuracy allowed by the particular hardware implimentation.
  252.     System dependant changes or changes to the UNIX time functions
  253.     are all made here. */
  254.      
  255. #ifndef sgi            /* SGI compiler complains about redef */
  256.     int gettimeofday();
  257. #endif
  258.         static struct timeval tval, *tp;
  259.         static struct timezone tzone, *tzp;
  260.         struct tm *clock;
  261.  
  262.     int status;
  263.     int offset;
  264.     double whole;
  265.     double fraction;
  266.     double sum;
  267.  
  268.     tp = &tval;
  269.     tzp = &tzone;
  270.  
  271.     tzone.tz_minuteswest = 0; /* time zone doesn't matter here */
  272.     tzone.tz_dsttime = 0; /* Neither does daylight savings time */
  273.         status = gettimeofday(tp, tzp);
  274.     if(status == -1)
  275.     {
  276.         fprintf(stderr,"OOPS: Failure on gettimeofday.\n");
  277.         fflush(stderr);
  278.         return(-1);
  279.     }
  280.  
  281.     /* you are probably going to ask yourself why we are 
  282.     creating a hold value and subtracting from seconds.
  283.     Well, even if you aren't, here is why. It seems that UNIX, in its
  284.     infinite wisdom, starts their arbitrary seconds clock on 1/1/1970.
  285.     I am writing this code on 1/15/1990, 20 years after the fact. This
  286.     means that tp->tv_sec is returning a long value of roughly 630000000
  287.     which still fits within a 32 bit long word. However, the 
  288.     conversion to float cannot handle this value without
  289.     truncating the least significant digits, which, as a timer device,
  290.     happen to be the only ones we are really interested in!   
  291.     The brute force approach is to subtract 630000000 from the returned
  292.     time and let someone else deal with the sudden bug 
  293.     about the problem in 2010. But, let's
  294.     actually read the date, find how many years have passed
  295.     since 1970, and multiply by 365.25 * 24 * 60 * 60 seconds. 
  296.     This value gets subtracted from the tp->tv_sec return, keeping our
  297.     timer usable, even when it and this machine are running in the
  298.     Smithsonian in 2050. BUG. Don't run this code right on the stroke
  299.     of midnight at New Years.
  300.     */
  301.  
  302.  
  303.     clock = localtime(&tp->tv_sec);
  304.     offset = (clock->tm_year - 70) * 365 * 24 * 60 * 60; 
  305.  
  306.     whole = (float)(tp->tv_sec - offset);
  307.      fraction = (float)tp->tv_usec * .000001;  
  308.     sum = whole + fraction;
  309.  
  310.  
  311.     return(sum);
  312.  
  313. }
  314.  
  315.