⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 timerlib.c

📁 the vxworks system kernel souce packeg.there may be something you need .
💻 C
📖 第 1 页 / 共 2 页
字号:
/* timerLib.c - timer library (POSIX) *//* Copyright 1991-2002 Wind River Systems, Inc. */#include "copyright_wrs.h"/*modification history--------------------02w,09may02,wsl  add definition of timespec to nanosleep comments; SPR 2608602v,08aug00,jgn  move alarm from sigLib to timerLib02u,17jul00,jgn  merge DOT-4 pthreads code02t,19oct01,dcb  Fix the routine title line to match the coding conventions.02s,21sep99,cno  check return from wdDelete (SPR20611)02r,15sep99,pfl  fixed compile error02q,09jul99,cno  timer_settime returns timer_gettime remaining time (SPR27189)02p,21feb99,jdi  doc: listed errnos.02o,05feb96,dbt  added a test in timer_settime to detect if the time has		 already passed (SPR #7463).02n,30oct96,dgp  doc: change INTERNAL comment to external for timer_settime		  per SPR #652502m,09oct06,dgp  doc: correct timer_settime() reference per SPR 7323 & 361202l,28mar95,kdl  return timer reload value during timer_gettime() (SPR #3299).02k,20jan95,jdi  doc cleanup, including new number for POSIX standard.02j,08apr94,dvs  added check for disarmed timer in timer_gettime() (SPR #3100).02i,08dec93,dvs  added fix of timer_gettime() for interval timer as well.02h,06dec93,dvs  timer_gettime() now returns amt of time remaining on the timer		 (SPR #2673)02g,29nov93,dvs  brought up to POSIX draft 14 specification02f,14mar93,jdi  fixed typo in code example for timer_connect().02e,11feb93,gae  clockLibInit() installed before using timers (#1834).		 made sure wdStart() not invoked with 0 delay when		 interval less than clock resolution (#2006).02d,02oct92,jdi  documentation cleanup.02c,23sep92,kdl  changed include to private/timerLibP.h; deleted signal		 function prototypes, now in sigLibP.h.02b,19aug92,gae  fixed nanosleep() to return correct amount of underrun.02a,22jul92,gae  Draft 12 revision.  fixed timer_getoverrun(), nanosleep().		 Removed timerLibInit() and timer_object_create().		 Got rid of objects.01d,25jul92,smb  changed time.h to timers.h01d,26may92,rrr  the tree shuffle01c,30apr92,rrr  some preparation for posix signals.01b,04feb92,gae  fixed copyright include; revised according to DEC review.		     added ability to delete timers from exiting tasks;		     timer_create() tests for valid signal number;		     timer_getoverrun() always returns -1 as no support;		     timer_settime() no longer arms timer with 0 delay.		     nanosleep() no longer returns +1 on "success";		     documentation touchup.01a,16oct91,gae  written.*//*DESCRIPTIONThis library provides a timer interface, as defined in the IEEE standard,POSIX 1003.1b.Timers are mechanisms by which tasks signal themselves after a designatedinterval.  Timers are built on top of the clock and signal facilities.  Theclock facility provides an absolute time-base.  Standard timer functionssimply consist of creation, deletion and setting of a timer.  When a timerexpires, sigaction() (see sigLib) must be in place in order for the userto handle the event.  The "high resolution sleep" facility, nanosleep(),allows sub-second sleeping to the resolution of the clock.The clockLib library should be installed and clock_settime() setbefore the use of any timer routines.ADDITIONSTwo non-POSIX functions are provided for user convenience:       timer_cancel() quickly disables a timer by calling timer_settime().    timer_connect() easily hooks up a user routine by calling sigaction().CLARIFICATIONSThe task creating a timer with timer_create() will receive thesignal no matter which task actually arms the timer.When a timer expires and the task has previously exited, logMsg()indicates the expected task is not present.  Similarly, logMsg() indicateswhen a task arms a timer without installing a signal handler.  Timers maybe armed but not created or deleted at interrupt level.IMPLEMENTATIONThe actual clock resolution is hardware-specific and in many cases is1/60th of a second.  This is less than _POSIX_CLOCKRES_MIN, which isdefined as 20 milliseconds (1/50th of a second).INTERNAL1. The <timespec> key calculation is limited by the amount of timerepresented (years?) and the resolution of the clock (1/1000's?).2. Request for option of timer deletion when task is deleted.However, the task that created the timer is not necessarily thetask that is going to receive it (set in timer_settime()).This could be cleared up, if the task calling timer_create()was the task to receive the signal.INCLUDE FILES: timers.hSEE ALSO: clockLib, sigaction(), POSIX 1003.1b documentation,.pG "Basic\ OS"*/#include "vxWorks.h"#include "errno.h"#include "memLib.h"#include "logLib.h"#include "stdio.h"#include "stdlib.h"#include "string.h"#include "taskLib.h"#include "wdLib.h"#include "intLib.h"#include "time.h"#include "tickLib.h"#include "private/sigLibP.h"#include "private/timerLibP.h"#define __PTHREAD_SRC#include "pthread.h"extern int clockLibInit ();int timerLibLog = TRUE;	/* log warning messages from wd handler */#define	TIMER_RELTIME	(~TIMER_ABSTIME)	/* relative time *//********************************************************************************* timer_cancel - cancel a timer** This routine is a shorthand method of invoking timer_settime(), which stops* a timer.** NOTE* Non-POSIX.** RETURNS: 0 (OK), or -1 (ERROR) if <timerid> is invalid.** ERRNO: EINVAL*/int timer_cancel    (    timer_t timerid	/* timer ID */    )    {    struct itimerspec value;    bzero ((char*)&value, sizeof (value));    return (timer_settime (timerid, TIMER_RELTIME, &value, NULL));    }/********************************************************************************* timerConHandler - default 'connect' timer handler** User routine wrapper called from timerWdHandler().** RETURNS: N/A*/LOCAL void timerConHandler    (    int     sig,		/* caught signal */    timer_t timerid,		/* "int code" */    struct sigcontext *pContext	/* unused */    )    {    if (timerid == NULL)	{	/* sometimes caused by a pended signal ('code' lost when unblocked) */	if (timerLibLog)	    {	    logMsg ("timerConHandler: bad timer %#x, signal %d\n",		    (int)timerid, sig, 0, 0, 0, 0);	    }	}    else if (timerid->routine == NULL)	{	if (timerLibLog)	    {	    logMsg ("timerConHandler: expired %#x, signal %d\n",		    (int)timerid, sig, 0, 0, 0, 0);	    }	}    else	{	(*timerid->routine) (timerid, timerid->arg);	}    }/********************************************************************************* timer_connect - connect a user routine to the timer signal** This routine sets the specified <routine> to be invoked with <arg> when* fielding a signal indicated by the timer's <evp> signal number, or* if <evp> is NULL, when fielding the default signal (SIGALRM).** The signal handling routine should be declared as:* .ne 5* .CS*     void my_handler*         (*         timer_t timerid,	/@ expired timer ID @/*         int arg               /@ user argument    @/*         )* .CE** NOTE* Non-POSIX.** RETURNS: 0 (OK), or -1 (ERROR) if the timer is invalid or cannot bind the * signal handler.** ERRNO: EINVAL*/int timer_connect    (    timer_t     timerid,	/* timer ID      */    VOIDFUNCPTR routine,	/* user routine  */    int         arg		/* user argument */    )    {    static struct sigaction timerSig;    if (timerSig.sa_handler == 0)	{	/* just the first time */	timerSig.sa_handler = (void (*)(int))timerConHandler;	(void) sigemptyset (&timerSig.sa_mask);	timerSig.sa_flags = 0;	/* !SA_SIGINFO: cause timerid to be passed */	}    if (intContext ())	return (ERROR);    if (timerid == NULL)	{	errno = EINVAL;	return (ERROR);	}    timerid->routine = routine;    timerid->arg     = arg;    timerid->sevent.sigev_signo = SIGALRM;    timerid->sevent.sigev_value.sival_ptr = timerid;	/* !SA_SIGINFO */    if (sigaction (SIGALRM, &timerSig, NULL) == ERROR)	return (ERROR);    else	return (OK);    }/********************************************************************************* timer_create - allocate a timer using the specified clock for a timing base (POSIX)** This routine returns a value in <pTimer> that identifies the timer * in subsequent timer requests.  The <evp> argument, if non-NULL, points to * a `sigevent' structure, which is allocated by the application and defines * the signal number and application-specific data to be sent to the task when * the timer expires.  If <evp> is NULL, a default signal (SIGALRM) is queued * to the task, and the signal data is set to the timer ID.  Initially, the * timer is disarmed.** RETURNS:* 0 (OK), or -1 (ERROR) if too many timers already are allocated or the signal * number is invalid.** ERRNO: EMTIMERS, EINVAL, ENOSYS, EAGAIN, S_memLib_NOT_ENOUGH_MEMORY** SEE ALSO: timer_delete()*/int timer_create    (    clockid_t clock_id,		/* clock ID (always CLOCK_REALTIME) */    struct sigevent *evp,	/* user event handler               */    timer_t * pTimer		/* ptr to return value 		    */    )    {    timer_t timerid;    struct sigevent sevp;    if (intContext ())	return (ERROR);    (void)clockLibInit (); /* make sure clock "running" */    timerid = (timer_t) calloc (1, sizeof(*timerid));    if (timerid == NULL)	{	/* errno = EMTIMERS;  * S_memLib_NOT_ENOUGH_MEMORY will be lost */	return (ERROR);	}    if ((timerid->wdog = wdCreate ()) == NULL)        {	free ((char *) timerid);	return (ERROR);        }    timerid->active = FALSE;    timerid->taskId = taskIdSelf ();    timerid->clock_id = clock_id;	/* should check for known clock_id? */    if (evp == NULL)	{	sevp.sigev_signo = SIGALRM;	/* remember value possibly set in timer_connect() */	/* XXX	sevp.sigev_value.sival_int = timerid->sevent.sigev_value.sival_int;	*/	sevp.sigev_value.sival_ptr = timerid;	}    else	{	if (evp->sigev_signo < 1 || evp->sigev_signo > _NSIGS)	    {	    errno = EINVAL;	    return (ERROR);	    }	sevp = *evp;	}    timerid->sevent = sevp;    timerid->sigpend.sigp_info.si_signo = sevp.sigev_signo;    timerid->sigpend.sigp_info.si_code  = SI_TIMER;    timerid->sigpend.sigp_info.si_value = sevp.sigev_value;    sigPendInit (&timerid->sigpend);    TV_ZERO(timerid->exp.it_interval);    TV_ZERO(timerid->exp.it_value);    *pTimer = timerid;    return (OK);    }/********************************************************************************* timer_delete - remove a previously created timer (POSIX)** This routine removes a timer.** RETURNS: 0 (OK), or -1 (ERROR) if <timerid> is invalid.** ERRNO: EINVAL** SEE ALSO: timer_create()*/int timer_delete    (    timer_t timerid	/* timer ID */    )    {    if (intContext ())	return (ERROR);    if (timerid == NULL)	{	errno = EINVAL;	return (ERROR);	}    if (timer_cancel (timerid) != 0)	return (ERROR);    if (wdDelete (timerid->wdog) != OK)    return (ERROR);    (void)sigPendDestroy (&timerid->sigpend);    free ((char *) timerid);    return (OK);    }/********************************************************************************* timer_gettime - get the remaining time before expiration and the reload value (POSIX)** This routine gets the remaining time and reload value of a specified timer.* Both values are copied to the <value> structure.** RETURNS: 0 (OK), or -1 (ERROR) if <timerid> is invalid.** ERRNO: EINVAL*/int timer_gettime    (    timer_t           timerid,	 /* timer ID                       */    struct itimerspec *value	 /* where to return remaining time */    )    {    struct timespec now; 	 /* current time */     struct timespec timerExpire; /* absolute time that timer will go off */    if (timerid == NULL || value == NULL)	{	errno = EINVAL;	return (ERROR);	}    if (timerid->clock_id != CLOCK_REALTIME)	{	errno = EINVAL;	return (ERROR);	}    /* if timer is disarmed simply set value to 0 */    if (timerid->active == FALSE)        {        value->it_value.tv_sec = 0;        value->it_value.tv_nsec = 0;        value->it_interval.tv_sec = 0;        value->it_interval.tv_nsec = 0;        return (OK);        }    /* get current time */    if (clock_gettime (CLOCK_REALTIME, &now) == ERROR)	return (ERROR);;    /* use time stamp and get absolute time that timer will go off */    timerExpire.tv_sec = timerid->timeStamp.tv_sec + timerid->exp.it_value.tv_sec;    timerExpire.tv_nsec = timerid->timeStamp.tv_nsec + timerid->exp.it_value.tv_nsec;    TV_NORMALIZE (timerExpire);    /* compute difference using current time */    value->it_value.tv_sec = timerExpire.tv_sec - now.tv_sec;    value->it_value.tv_nsec = timerExpire.tv_nsec - now.tv_nsec;    TV_NORMALIZE (value->it_value);    /* get reload value */    value->it_interval.tv_sec = timerid->exp.it_interval.tv_sec;    value->it_interval.tv_nsec = timerid->exp.it_interval.tv_nsec;    TV_NORMALIZE (value->it_interval);    return (OK);    }/********************************************************************************* timer_getoverrun - return the timer expiration overrun (POSIX)

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -