clockLib.c
上传用户:nvosite88
上传日期:2007-01-17
资源大小:4983k
文件大小:8k
源码类别:

VxWorks

开发平台:

C/C++

  1. /* clockLib.c - clock library (POSIX) */
  2. /* Copyright 1991-2002 Wind River Systems, Inc. */
  3. #include "copyright_wrs.h"
  4. /*
  5. modification history
  6. --------------------
  7. 02n,22may02,gls  changed to use 64 bit ticks (SPR #70255)
  8. 02m,25sep01,gls  changed clock_gettime() to load sysTicks from tickGet() 
  9.                  to prevent the compiler from optimizing it out (SPR #64367)
  10. 02l,15mar99,elg  add informations on clock_gettime() parameters (SPR 5412).
  11. 02k,21feb99,jdi  doc: listed errnos.
  12. 02j,16oct95,jdi  doc: clarified action of clock_setres() (SPR 4283).
  13. 02i,28mar95,kdl  made clock_gettime() keep local copy of vxTicks (SPR #3595).
  14. 02h,07feb95,jdi  doc: changed clock_setres() to clarify the action.
  15. 02g,23jan95,jdi  doc cleanup.
  16. 02f,08apr94,kdl  fixed alignment in clock_show() display.
  17. 02e,23nov93,dvs  updated for POSIX 1003.4 draft 14 compliance.
  18. 02d,02oct92,jdi  documentation cleanup.
  19. 02c,23sep92,kdl  changed include to private/timerLibP.h.
  20. 02b,09sep92,gae  fixed clock_show() format.
  21. 02a,23jun92,gae  Draft 12 revision. Deleted clock_getdrift() & clock_setdrift().
  22.  Added non-POSIX clock_setres().  Arranged that clockLibInit()
  23.  needn't be explicitly called.
  24. 01d,25jul92,smb  changed time.h to timers.h
  25. 01c,26may92,rrr  the tree shuffle
  26. 01b,04feb92,gae  fixed copyright include; revised according to DEC review.
  27.    clockLibInit() tests for initial system clock rate > 0;
  28.    clock_gettime() returns EFAULT for NULL time pointer;
  29.    clock_settime() checks nanosecond range properly.
  30. 01a,16oct91,gae  written.
  31. */
  32. /*
  33. DESCRIPTION
  34. This library provides a clock interface, as defined in the IEEE standard,
  35. POSIX 1003.1b.
  36. A clock is a software construct that keeps time in seconds and
  37. nanoseconds.  The clock has a simple interface with three routines:
  38. clock_settime(), clock_gettime(), and clock_getres().  The non-POSIX routine
  39. clock_setres() that was provided so that clockLib could be informed if there
  40. were changes in the system clock rate is no longer necessary. This routine
  41. is still present for backward compatibility, but does nothing.
  42. Times used in these routines are stored in the timespec structure:
  43. .CS
  44. struct timespec
  45.     {
  46.     time_t tv_sec; /@ seconds @/
  47.     long tv_nsec; /@ nanoseconds (0 -1,000,000,000) @/
  48.     };
  49. .CE
  50. IMPLEMENTATION
  51. Only one <clock_id> is supported, the required CLOCK_REALTIME.
  52. Conceivably, additional "virtual" clocks could be supported, or support
  53. for additional auxiliary clock hardware (if available) could be added.
  54. INCLUDE FILES: timers.h
  55. SEE ALSO: IEEE 
  56. .pG "Basic OS,"
  57. POSIX 1003.1b documentation
  58. INTERNAL
  59. 1. Access to clockRealtime should be intLock'ed during task usage?
  60. 2. What is, is not, accessable at interrupt level?
  61. */
  62. #include "vxWorks.h"
  63. #include "errno.h"
  64. #include "memLib.h"
  65. #include "tickLib.h"
  66. #include "stdio.h"
  67. #include "string.h"
  68. #include "sysLib.h"
  69. #include "timers.h"
  70. #include "private/timerLibP.h"
  71. #include "private/windLibP.h"
  72. struct clock _clockRealtime;
  73. /*******************************************************************************
  74. *
  75. * clockLibInit - initialize clock facility
  76. *
  77. * This routine initializes the POSIX timer/clock facilities.
  78. * It should be called by usrRoot() in usrConfig.c before any other
  79. * routines in this module.
  80. *
  81. * WARNING
  82. * Non-POSIX.
  83. *
  84. * RETURNS:
  85. * 0 (OK), or -1 (ERROR) on failure or already initialized or clock rate 
  86. * less than 1 Hz.
  87. *
  88. * NOMANUAL
  89. */
  90. int clockLibInit (void)
  91.     {
  92.     static BOOL libInstalled = FALSE;
  93.     if (libInstalled)
  94. return (ERROR);
  95.     if (sysClkRateGet () < 1)
  96. return (ERROR);
  97.     libInstalled = TRUE;
  98.     bzero ((char*)&_clockRealtime, sizeof (_clockRealtime));
  99.     _clockRealtime.tickBase = tick64Get();
  100.     return (OK);
  101.     }
  102. /*******************************************************************************
  103. *
  104. * clock_getres - get the clock resolution (POSIX)
  105. *
  106. * This routine gets the clock resolution, in nanoseconds, based on the
  107. * rate returned by sysClkRateGet().  If <res> is non-NULL, the resolution is
  108. * stored in the location pointed to.
  109. *
  110. * INTERNAL
  111. * Resolution is always assumed to be less than 1 second -- only
  112. * the tv_nsec field is filled in.
  113. *
  114. * RETURNS:
  115. * 0 (OK), or -1 (ERROR) if <clock_id> is invalid.
  116. *
  117. * ERRNO: EINVAL
  118. *
  119. * SEE ALSO: clock_settime(), sysClkRateGet(), clock_setres()
  120. */
  121. int clock_getres
  122.     (
  123.     clockid_t clock_id, /* clock ID (always CLOCK_REALTIME) */
  124.     struct timespec * res /* where to store resolution */
  125.     )
  126.     {
  127.     (void)clockLibInit ();
  128.     if (clock_id != CLOCK_REALTIME)
  129. {
  130. errno = EINVAL;
  131. return (ERROR);
  132. }
  133.     if (res != NULL)
  134. {
  135. /* assume that clock resolution is <= 1 second */
  136. res->tv_sec  = 0;
  137. res->tv_nsec = (BILLION / sysClkRateGet());
  138. }
  139.     return (OK);
  140.     }
  141. /*******************************************************************************
  142. *
  143. * clock_setres - set the clock resolution
  144. *
  145. * This routine is obsolete. It will always return OK.
  146. *
  147. * NOTE
  148. * Non-POSIX.
  149. *
  150. * INTERNAL
  151. * This routine is no longer needed; the underlying system clock resolution
  152. * will always be used directly.
  153. *
  154. * RETURNS:
  155. * OK always.
  156. *
  157. * ERRNO: EINVAL
  158. *
  159. * SEE ALSO: clock_getres(), sysClkRateSet()
  160. */
  161. int clock_setres
  162.     (
  163.     clockid_t clock_id, /* clock ID (always CLOCK_REALTIME) */
  164.     struct timespec * res /* resolution to be set */
  165.     )
  166.     {
  167.     return (OK);
  168.     }
  169. /*******************************************************************************
  170. *
  171. * clock_gettime - get the current time of the clock (POSIX)
  172. *
  173. * This routine gets the current value <tp> for the clock.
  174. *
  175. * INTERNAL
  176. * The standard doesn't indicate when <tp> is NULL (an invalid address)
  177. * whether errno should be EINVAL or EFAULT.
  178. *
  179. * RETURNS: 0 (OK), or -1 (ERROR) if <clock_id> is invalid or <tp> is NULL.
  180. *
  181. * ERRNO: EINVAL, EFAULT
  182. */
  183. int clock_gettime
  184.     (
  185.     clockid_t clock_id, /* clock ID (always CLOCK_REALTIME) */
  186.     struct timespec * tp /* where to store current time */
  187.     )
  188.     {
  189.     UINT64     diffTicks; /* system clock tick count */
  190.     (void)clockLibInit ();
  191.     if (clock_id != CLOCK_REALTIME)
  192. {
  193. errno = EINVAL;
  194. return (ERROR);
  195. }
  196.     if (tp == NULL)
  197. {
  198. errno = EFAULT;
  199. return (ERROR);
  200. }
  201.     diffTicks = tick64Get() - _clockRealtime.tickBase;
  202.     TV_CONVERT_TO_SEC(*tp, diffTicks);
  203.     TV_ADD (*tp, _clockRealtime.timeBase);
  204.     return (OK);
  205.     }
  206. /*******************************************************************************
  207. *
  208. * clock_settime - set the clock to a specified time (POSIX)
  209. *
  210. * This routine sets the clock to the value <tp>, which should be a multiple
  211. * of the clock resolution.  If <tp> is not a multiple of the resolution, it
  212. * is truncated to the next smallest multiple of the resolution.
  213. *
  214. * RETURNS:
  215. * 0 (OK), or -1 (ERROR) if <clock_id> is invalid, <tp> is outside the supported 
  216. * range, or the <tp> nanosecond value is less than 0 or equal to or greater than
  217. * 1,000,000,000.
  218. *
  219. * ERRNO: EINVAL
  220. *
  221. * SEE ALSO: clock_getres()
  222. */
  223. int clock_settime
  224.     (
  225.     clockid_t clock_id, /* clock ID (always CLOCK_REALTIME) */
  226.     const struct timespec * tp /* time to set */
  227.     )
  228.     {
  229.     (void)clockLibInit ();
  230.     if (clock_id != CLOCK_REALTIME)
  231. {
  232. errno = EINVAL;
  233. return (ERROR);
  234. }
  235.     if (tp == NULL ||
  236. tp->tv_nsec < 0 || tp->tv_nsec >= BILLION)
  237. {
  238. errno = EINVAL;
  239. return (ERROR);
  240. }
  241.     /* convert timespec to vxTicks XXX use new kernel time */
  242.     _clockRealtime.tickBase = tick64Get();
  243.     _clockRealtime.timeBase = *tp;
  244.     return (OK);
  245.     }
  246. /*******************************************************************************
  247. *
  248. * clock_show - show info on a clock
  249. *
  250. * WARNING
  251. * Non-POSIX.
  252. *
  253. * RETURNS:
  254. * 0 (OK), or -1 (ERROR) if <clock_id> is invalid
  255. *
  256. * ERRNO: EINVAL
  257. *
  258. * NOMANUAL
  259. */
  260. int clock_show
  261.     (
  262.     clockid_t clock_id /* clock ID (always CLOCK_REALTIME) */
  263.     )
  264.     {
  265.     static char *title1 = "  seconds    nanosecs  freq (hz)  resolutionn";
  266.     static char *title2 = "---------- ----------- ---------- ----------n";  
  267.     static char *title3 = "n  base ticks          base secs  base nsecsn";
  268.     static char *title4 = "--------------------  ---------- ----------n";
  269.     struct timespec tp;
  270.     (void)clockLibInit ();
  271.     if (clock_id != CLOCK_REALTIME)
  272. {
  273. errno = EINVAL;
  274. return (ERROR);
  275. }
  276.     (void) clock_gettime (clock_id, &tp);
  277.     printf (title1);
  278.     printf (title2);
  279.     printf (" %8.8ld   %9.9ld   %8.8d   %8.8dn",
  280.     tp.tv_sec, tp.tv_nsec, sysClkRateGet(), BILLION / sysClkRateGet());
  281.     printf (title3);
  282.     printf (title4);
  283.     printf(" 0x%08x%08x    %8.8ld   %9.9ldn",
  284.    (UINT) (_clockRealtime.tickBase >> 32),
  285.    (UINT)  _clockRealtime.tickBase, 
  286.    _clockRealtime.timeBase.tv_sec, 
  287.    _clockRealtime.timeBase.tv_nsec);
  288.     return (OK);
  289.     }