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

📄 timerlib.c

📁 the vxworks system kernel souce packeg.there may be something you need .
💻 C
📖 第 1 页 / 共 2 页
字号:
** This routine returns the timer expiration overrun count for <timerid>,* when called from a timer expiration signal catcher.  The overrun count is* the number of extra timer expirations that have occurred, up to the* implementation-defined maximum _POSIX_DELAYTIMER_MAX.  If the count is* greater than the maximum, it returns the maximum.** RETURNS:* The number of overruns, or _POSIX_DELAYTIMER_MAX if the count equals or is* greater than _POSIX_DELAYTIMER_MAX, or -1 (ERROR) if <timerid> is invalid.** ERRNO: EINVAL, ENOSYS*/int timer_getoverrun    (    timer_t timerid	/* timer ID */    )    {    if (timerid == NULL)	{	errno = EINVAL;	return (ERROR);	}    return (timerid->sigpend.sigp_overruns);    }/********************************************************************************* timerWdHandler - wd handler used by timer_settime** RETURNS: */LOCAL void timerWdHandler    (    timer_t timerid    )    {    ULONG delayTicks;    int status;    if (timerid == NULL)	{	if (timerLibLog)	    logMsg ("timerWdHandler: NULL timerid!\n", 0, 0, 0, 0, 0, 0);	return;	}    status = sigPendKill (timerid->taskId, &timerid->sigpend);    if (status != OK && timerLibLog)	{	logMsg ("timerWdHandler: kill failed (timer=%#x, tid=%#x, errno=%#x)\n",		(int)timerid, timerid->taskId, errno, 0, 0, 0);	}    if (TV_ISZERO(timerid->exp.it_interval))	{	timerid->active = FALSE;	}    else	{	/* interval timer needs reloading */	TV_CONVERT_TO_TICK (delayTicks, timerid->exp.it_interval);	if (delayTicks < 1)	    delayTicks = 1;	/* delay of 0 will cause recursion! */	/* time stamp when we arm interval timer */	(void) clock_gettime (CLOCK_REALTIME, &(timerid->timeStamp));	wdStart (timerid->wdog, (int)delayTicks, (FUNCPTR)timerWdHandler,		(int)timerid);	}    }/********************************************************************************* timer_settime - set the time until the next expiration and arm timer (POSIX)** This routine sets the next expiration of the timer, using the `.it_value'* of <value>, thus arming the timer.  If the timer is already armed, this* call resets the time until the next expiration.  If `.it_value' is zero,* the timer is disarmed.** If <flags> is not equal to TIMER_ABSTIME, the interval is relative to the* current time, the interval being the `.it_value' of the <value> parameter.* If <flags> is equal to TIMER_ABSTIME, the expiration is set to* the difference between the absolute time of `.it_value' and the current* value of the clock associated with <timerid>.  If the time has already* passed, then the timer expiration notification is made immediately.* The task that sets the timer receives the signal; in other words, the taskId* is noted.  If a timer is set by an ISR, the signal is delivered to the* task that created the timer.** The reload value of the timer is set to the value specified by* the `.it_interval' field of <value>.  When a timer is* armed with a nonzero `.it_interval' a periodic timer is set up.** Time values that are between two consecutive non-negative integer* multiples of the resolution of the specified timer are rounded up to* the larger multiple of the resolution.** If <ovalue> is non-NULL, the routine stores a value representing the* previous amount of time before the timer would have expired.  Or if the* timer is disarmed, the routine stores zero, together with the previous* timer reload value.  The <ovalue> parameter is the same value as that * returned by timer_gettime() and is subject to the timer resolution.** WARNING* If clock_settime() is called to reset the absolute clock time after a timer* has been set with timer_settime(), and if <flags> is equal to TIMER_ABSTIME, * then the timer will behave unpredictably.  If you must reset the absolute* clock time after setting a timer, do not use <flags> equal to TIMER_ABSTIME.** RETURNS:* 0 (OK), or -1 (ERROR) if <timerid> is invalid, the number of nanoseconds * specified by <value> is less than 0 or greater than or equal to * 1,000,000,000, or the time specified by <value> exceeds the maximum * allowed by the timer.** ERRNO: EINVAL*/int timer_settime    (    timer_t                 timerid,	/* timer ID                           */    int                     flags,	/* absolute or relative               */    const struct itimerspec *value,	/* time to be set                     */    struct itimerspec       *ovalue	/* previous time set (NULL=no result) */    )    {    struct timespec now;    struct timespec timerExpire; /* absolute time that timer will go off */    ULONG delayTicks;    if (timerid == NULL)	{	errno = EINVAL;	return (ERROR);	}    if (timerid->clock_id != CLOCK_REALTIME || !TV_VALID(value->it_value))	{	errno = EINVAL;	return (ERROR);	}    if (ovalue != NULL)	{    /* if timer is disarmed, simply set value to 0 */        if (timerid->active == FALSE)        {            ovalue->it_value.tv_sec = 0;            ovalue->it_value.tv_nsec = 0;        }        else        {    /* 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 */            ovalue->it_value.tv_sec = timerExpire.tv_sec - now.tv_sec;            ovalue->it_value.tv_nsec = timerExpire.tv_nsec - now.tv_nsec;            TV_NORMALIZE (ovalue->it_value);        }    /* get reload value */        ovalue->it_interval.tv_sec = timerid->exp.it_interval.tv_sec;        ovalue->it_interval.tv_nsec = timerid->exp.it_interval.tv_nsec;        TV_NORMALIZE (ovalue->it_interval);    }    if (TV_ISZERO(value->it_value))	{	if (timerid->active)	    {	    timerid->active = FALSE;	    wdCancel (timerid->wdog);	    }	return (OK);	}    TV_SET(timerid->exp.it_interval, value->it_interval);    TV_SET(timerid->exp.it_value, value->it_value);    if (flags == TIMER_ABSTIME)	{	/* convert current to relative time */	(void) clock_gettime (CLOCK_REALTIME, &now);	/* could be in the past */	if (TV_GT(now, timerid->exp.it_value))	    {	    TV_ZERO(timerid->exp.it_value);	    }	else	    {    	    TV_SUB(timerid->exp.it_value, now);	    }	/* time stamp when timer is armed */	TV_SET (timerid->timeStamp, now);	}    else	/* time stamp when timer is armed */	(void) clock_gettime (CLOCK_REALTIME, &(timerid->timeStamp));    TV_CONVERT_TO_TICK (delayTicks, timerid->exp.it_value);    if (timerid->active)	wdCancel (timerid->wdog);    else	timerid->active = TRUE;    wdStart (timerid->wdog, delayTicks, (FUNCPTR)timerWdHandler, (int)timerid);    return (OK);    }/********************************************************************************* timer_show - show information on a specified timer** WARNING* Non-POSIX.** RETURNS: 0 (OK), or -1 (ERROR) if <timerid> is invalid, or the context is * invalid.** ERRNO: EINVAL** NOMANUAL*/int timer_show    (    timer_t timerid	/* timer ID */    )    {    static char *title1 = "task       timerid    evp        routine\n";    static char *title2 = "---------- ---------- ---------- ----------\n";    if (intContext ())	return (ERROR);    if (timerid == NULL)	return (OK);    printf (title1);    printf (title2);    printf ("%#10x %#10x %#10x %#10x\n", timerid->taskId, (unsigned int)timerid,		(unsigned int)&timerid->sevent, (unsigned int)timerid->routine);    return (OK);    }/********************************************************************************* nanosleep - suspend the current task until the time interval elapses (POSIX)** This routine suspends the current task for a specified time <rqtp>* or until a signal or event notification is made.** The suspension may be longer than requested due to the rounding up of the* request to the timer's resolution or to other scheduling activities (e.g.,* a higher priority task intervenes).** The `timespec' structure is defined as follows:** \cs* struct timespec*     {*                                /@ interval = tv_sec*10**9 + tv_nsec @/*      time_t tv_sec;            /@ seconds @/*      long tv_nsec;             /@ nanoseconds (0 - 1,000,000,000) @/*      };* \ce** If <rmtp> is non-NULL, the `timespec' structure is updated to contain the* amount of time remaining.  If <rmtp> is NULL, the remaining time is not* returned.  The <rqtp> parameter is greater than 0 or less than or equal to* 1,000,000,000.** RETURNS:* 0 (OK), or -1 (ERROR) if the routine is interrupted by a signal or an * asynchronous event notification, or <rqtp> is invalid.** ERRNO: EINVAL, EINTR** SEE ALSO: sleep(), taskDelay()*/int nanosleep    (    const struct timespec *rqtp,	/* time to delay                     */    struct timespec       *rmtp		/* premature wakeup (NULL=no result) */    )    {    int status;    /* int oldErrno; */    ULONG delayTicks;    struct timespec then;    struct timespec now;    int returnStatus;    int savtype;    if (rqtp == NULL || !TV_VALID(*rqtp))	{	errno = EINVAL;	return (ERROR);	}    if (TV_ISZERO(*rqtp))	return (OK);    if (_func_pthread_setcanceltype != NULL)        {        _func_pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, &savtype);        }    (void)clockLibInit (); /* make sure clock "running" */    (void)clock_gettime (CLOCK_REALTIME, &then);    TV_CONVERT_TO_TICK (delayTicks, *rqtp);    /* return's 1 (RESTART) if interrupted sleep */    status = taskDelay (delayTicks);    if (status == 0)	returnStatus = 0;    else	returnStatus = -1;    if (rmtp != NULL)	{	(void)clock_gettime (CLOCK_REALTIME, &now);	TV_SUB (now, then);	/* make time relative to start */	if (TV_LT(now, *rqtp))	    {	    TV_SET(*rmtp, *rqtp);	    TV_SUB(*rmtp, now);	    }	else	    TV_ZERO((*rmtp));	}    if (_func_pthread_setcanceltype != NULL)        {        _func_pthread_setcanceltype(savtype, NULL);        }    return (returnStatus);    }/********************************************************************************* sleep - delay for a specified amount of time** This routine causes the calling task to be blocked for <secs> seconds.** The time the task is blocked for may be longer than requested due to the* rounding up of the request to the timer's resolution or to other scheduling* activities (e.g., a higher priority task intervenes).** RETURNS: Zero if the requested time has elapsed, or the number of seconds* remaining if it was interrupted.** ERRNO: EINVAL, EINTR** SEE ALSO: nanosleep(), taskDelay()*/ unsigned int sleep    (    unsigned int secs    )    {    struct timespec ntp, otp;     ntp.tv_sec = secs;    ntp.tv_nsec = 0;     nanosleep(&ntp, &otp);     return(otp.tv_sec);    }/********************************************************************************* alarm - set an alarm clock for delivery of a signal** This routine arranges for a 'SIGALRM' signal to be delivered to the* calling task after <secs> seconds.** If <secs> is zero, no new alarm is scheduled. In all cases, any previously* set alarm is cancelled.** RETURNS: Time remaining until a previously scheduled alarm was due to be* delivered, zero if there was no previous alarm, or ERROR in case of an* error.*/ unsigned int alarm    (    unsigned int secs    )    {    static timer_t timer_id = NULL;    struct itimerspec tspec, tremain;     /* if first time, create a timer */     if (!timer_id)        {        if (timer_create(CLOCK_REALTIME, NULL, &timer_id) == ERROR)            return(ERROR);        }     /* set new time*/     tspec.it_interval.tv_sec = 0;    tspec.it_interval.tv_nsec = 0;    tspec.it_value.tv_sec = secs;    tspec.it_value.tv_nsec = 0;     /* save off timer remaining from previous for return */     timer_gettime(timer_id, &tremain);    timer_settime(timer_id, CLOCK_REALTIME, &tspec, NULL);     return((unsigned int)tremain.it_value.tv_sec);    }

⌨️ 快捷键说明

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