📄 clocklib.c
字号:
/* clockLib.c - clock library (POSIX) *//* Copyright 1991-1999 Wind River Systems, Inc. */#include "copyright_wrs.h"/*modification history--------------------02l,15mar99,elg add informations on clock_gettime() parameters (SPR 5412).02k,21feb99,jdi doc: listed errnos.02j,16oct95,jdi doc: clarified action of clock_setres() (SPR 4283).02i,28mar95,kdl made clock_gettime() keep local copy of vxTicks (SPR #3595).02h,07feb95,jdi doc: changed clock_setres() to clarify the action.02g,23jan95,jdi doc cleanup.02f,08apr94,kdl fixed alignment in clock_show() display.02e,23nov93,dvs updated for POSIX 1003.4 draft 14 compliance.02d,02oct92,jdi documentation cleanup.02c,23sep92,kdl changed include to private/timerLibP.h.02b,09sep92,gae fixed clock_show() format.02a,23jun92,gae Draft 12 revision. Deleted clock_getdrift() & clock_setdrift(). Added non-POSIX clock_setres(). Arranged that clockLibInit() needn't be explicitly called.01d,25jul92,smb changed time.h to timers.h01c,26may92,rrr the tree shuffle01b,04feb92,gae fixed copyright include; revised according to DEC review. clockLibInit() tests for initial system clock rate > 0; clock_gettime() returns EFAULT for NULL time pointer; clock_settime() checks nanosecond range properly.01a,16oct91,gae written.*//*DESCRIPTIONThis library provides a clock interface, as defined in the IEEE standard,POSIX 1003.1b.A clock is a software construct that keeps time in seconds andnanoseconds. The clock has a simple interface with three routines:clock_settime(), clock_gettime(), and clock_getres(). The non-POSIX routineclock_setres() is provided (temporarily) so that clockLib is informed if thereare changes in the system clock rate (e.g., after a call tosysClkRateSet()).Times used in these routines are stored in the timespec structure:.CSstruct timespec { time_t tv_sec; /@ seconds @/ long tv_nsec; /@ nanoseconds (0 -1,000,000,000) @/ };.CEIMPLEMENTATIONOnly one <clock_id> is supported, the required CLOCK_REALTIME.Conceivably, additional "virtual" clocks could be supported, or supportfor additional auxiliary clock hardware (if available) could be added.INCLUDE FILES: timers.hSEE ALSO: IEEE .pG "Basic OS,"POSIX 1003.1b documentationINTERNAL1. Access to clockRealtime should be intLock'ed during task usage?2. What is, is not, accessable at interrupt level?*/#include "vxWorks.h"#include "errno.h"#include "memLib.h"#include "tickLib.h"#include "stdio.h"#include "string.h"#include "sysLib.h"#include "timers.h"#include "private/timerLibP.h"struct clock _clockRealtime;/********************************************************************************* clockLibInit - initialize clock facility** This routine initializes the POSIX timer/clock facilities.* It should be called by usrRoot() in usrConfig.c before any other* routines in this module.** WARNING* Non-POSIX.** RETURNS:* 0 (OK), or -1 (ERROR) on failure or already initialized or clock rate * less than 1 Hz.** NOMANUAL*/int clockLibInit (void) { static BOOL libInstalled = FALSE; if (libInstalled) return (ERROR); if (sysClkRateGet () < 1) return (ERROR); libInstalled = TRUE; bzero ((char*)&_clockRealtime, sizeof (_clockRealtime)); _clockRealtime.hz = sysClkRateGet (); /* 60hz=16666666.7nsec */ _clockRealtime.resolution = BILLION / _clockRealtime.hz; _clockRealtime.tickBase = vxTicks; return (OK); }/********************************************************************************* clock_getres - get the clock resolution (POSIX)** This routine gets the clock resolution, in nanoseconds, based on the* rate returned by sysClkRateGet(). If <res> is non-NULL, the resolution is* stored in the location pointed to.** INTERNAL* Resolution is always assumed to be less than 1 second -- only* the tv_nsec field is filled in.** RETURNS:* 0 (OK), or -1 (ERROR) if <clock_id> is invalid.** ERRNO: EINVAL** SEE ALSO: clock_settime(), sysClkRateGet(), clock_setres()*/int clock_getres ( clockid_t clock_id, /* clock ID (always CLOCK_REALTIME) */ struct timespec * res /* where to store resolution */ ) { (void)clockLibInit (); if (clock_id != CLOCK_REALTIME) { errno = EINVAL; return (ERROR); } if (res != NULL) { /* assume that clock resolution is <= 1 second */ res->tv_sec = 0; res->tv_nsec = _clockRealtime.resolution; } return (OK); }/********************************************************************************* clock_setres - set the clock resolution** This routine sets the clock resolution in the POSIX timers data structures.* It does not affect the system clock or auxiliary clocks.* This routine should be called to inform the POSIX timers of the new clock* resolution if sysClkRateSet() has been called after this library has been* initialized.** If <res> is non-NULL, the resolution to be set is stored in the location* pointed to; otherwise, this routine has no effect.** NOTE* Non-POSIX.** INTERNAL* Resolution is always assumed to be less than 1 second -- only* the tv_nsec field is used.** RETURNS:* 0 (OK), or -1 (ERROR) if <clock_id> is invalid or the resolution is greater * than 1 second.** ERRNO: EINVAL** SEE ALSO: clock_getres(), sysClkRateSet()*/int clock_setres ( clockid_t clock_id, /* clock ID (always CLOCK_REALTIME) */ struct timespec * res /* resolution to be set */ ) { (void)clockLibInit (); if (clock_id != CLOCK_REALTIME) { errno = EINVAL; return (ERROR); } if (res != NULL) { /* clock resolution must be <= 1 second */ if (res->tv_sec != 0 || res->tv_nsec == 0) { errno = EINVAL; return (ERROR); } /* XXX check nsec <= BILLION */ _clockRealtime.resolution = res->tv_nsec; _clockRealtime.hz = BILLION / _clockRealtime.resolution; } return (OK); }/********************************************************************************* clock_gettime - get the current time of the clock (POSIX)** This routine gets the current value <tp> for the clock.** INTERNAL* The standard doesn't indicate when <tp> is NULL (an invalid address)* whether errno should be EINVAL or EFAULT.** RETURNS: 0 (OK), or -1 (ERROR) if <clock_id> is invalid or <tp> is NULL.** ERRNO: EINVAL, EFAULT*/int clock_gettime ( clockid_t clock_id, /* clock ID (always CLOCK_REALTIME) */ struct timespec * tp /* where to store current time */ ) { ULONG sysTicks; /* system clock tick count */ (void)clockLibInit (); if (clock_id != CLOCK_REALTIME) { errno = EINVAL; return (ERROR); } if (tp == NULL) { errno = EFAULT; return (ERROR); } /* convert vxTicks to timespec XXX use new kernel time */ sysTicks = vxTicks; /* local copy, TV_CONVERT_TO_SEC reads twice! */ TV_CONVERT_TO_SEC(*tp, sysTicks - _clockRealtime.tickBase); TV_ADD (*tp, _clockRealtime.timeBase); return (OK); }/********************************************************************************* clock_settime - set the clock to a specified time (POSIX)** This routine sets the clock to the value <tp>, which should be a multiple* of the clock resolution. If <tp> is not a multiple of the resolution, it* is truncated to the next smallest multiple of the resolution.** RETURNS:* 0 (OK), or -1 (ERROR) if <clock_id> is invalid, <tp> is outside the supported * range, or the <tp> nanosecond value is less than 0 or equal to or greater than* 1,000,000,000.** ERRNO: EINVAL** SEE ALSO: clock_getres()*/int clock_settime ( clockid_t clock_id, /* clock ID (always CLOCK_REALTIME) */ const struct timespec * tp /* time to set */ ) { (void)clockLibInit (); if (clock_id != CLOCK_REALTIME) { errno = EINVAL; return (ERROR); } if (tp == NULL || tp->tv_nsec < 0 || tp->tv_nsec >= BILLION) { errno = EINVAL; return (ERROR); } /* convert timespec to vxTicks XXX use new kernel time */ _clockRealtime.tickBase = vxTicks; _clockRealtime.timeBase = *tp; return (OK); }/********************************************************************************* clock_show - show info on a clock** WARNING* Non-POSIX.** RETURNS:* 0 (OK), or -1 (ERROR) if <clock_id> is invalid** ERRNO: EINVAL** NOMANUAL*/int clock_show ( clockid_t clock_id /* clock ID (always CLOCK_REALTIME) */ ) { static char *title1 =" seconds nanosecs freq (hz) resolution base ticks base secs base nsecs\n"; static char *title2 ="---------- ----------- ---------- ---------- ---------- ---------- ----------\n"; struct timespec tp; (void)clockLibInit (); if (clock_id != CLOCK_REALTIME) { errno = EINVAL; return (ERROR); } (void) clock_gettime (clock_id, &tp); printf (title1); printf (title2); printf (" %8.8d %9.9d %8.8d %8.8d %8.8d %8.8d %9.9d\n", tp.tv_sec, tp.tv_nsec, _clockRealtime.hz, _clockRealtime.resolution, _clockRealtime.tickBase, _clockRealtime.timeBase.tv_sec, _clockRealtime.timeBase.tv_nsec); return (OK); }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -