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

📄 timer.c

📁 早期freebsd实现
💻 C
字号:
/*- * Copyright (c) 1993, 1994 *	The Regents of the University of California.  All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright *    notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright *    notice, this list of conditions and the following disclaimer in the *    documentation and/or other materials provided with the distribution. * 3. All advertising materials mentioning features or use of this software *    must display the following acknowledgement: *	This product includes software developed by the University of *	California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors *    may be used to endorse or promote products derived from this software *    without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */#ifndef lintstatic char sccsid[] = "@(#)timer.c	8.13 (Berkeley) 3/23/94";#endif /* not lint */#include <sys/queue.h>#include <sys/time.h>#include <bitstring.h>#include <limits.h>#include <signal.h>#include <stdio.h>#include <termios.h>#include "compat.h"#include <db.h>#include <regex.h>#include "vi.h"/* * There are two uses of the ITIMER_REAL timer (SIGALRM) in nvi.  The first * is to push the recovery information out to disk at periodic intervals. * The second is to display a "busy" message if an operation takes more time * that users are willing to wait before seeing something happen.  Each of * these uses has a wall clock timer structure in each SCR structure.  Since * the busy timer has a much faster timeout than the recovery timer, most of * the code ignores the recovery timer unless it's the only thing running. * * XXX * It would be nice to reimplement this with two timers, a la POSIX 1003.1, * but not many systems offer them yet. *//*  * busy_on -- *	Set a busy message timer. */intbusy_on(sp, msg)	SCR *sp;	char const *msg;{	struct itimerval value;	struct timeval tod;	/*	 * Give the oldest busy message precedence, since it's	 * the longer running operation.	 */	if (sp->busy_msg != NULL)		return (1);	/* Get the current time of day, and create a target time. */	if (gettimeofday(&tod, NULL))		return (1);#define	USER_PATIENCE_USECS	(8 * 100000L)	sp->busy_tod.tv_sec = tod.tv_sec;	sp->busy_tod.tv_usec = tod.tv_usec + USER_PATIENCE_USECS;	/* We depend on this being an atomic instruction. */	sp->busy_msg = msg;	/*	 * Busy messages turn around fast.  Reset the timer regardless	 * of its current state.	 */	value.it_value.tv_sec = 0;	value.it_value.tv_usec = USER_PATIENCE_USECS;	value.it_interval.tv_sec = 0;	value.it_interval.tv_usec = 0;	if (setitimer(ITIMER_REAL, &value, NULL))		msgq(sp, M_SYSERR, "timer: setitimer");	return (0);}/* * busy_off -- *	Turn off a busy message timer. */voidbusy_off(sp)	SCR *sp;{	/* We depend on this being an atomic instruction. */	sp->busy_msg = NULL;}/* * rcv_on -- *	Turn on recovery timer. */intrcv_on(sp, ep)	SCR *sp;	EXF *ep;{	struct itimerval value;	struct timeval tod;	/* Get the current time of day. */	if (gettimeofday(&tod, NULL))		return (1);	/* Create target time of day. */	ep->rcv_tod.tv_sec = tod.tv_sec + RCV_PERIOD;	ep->rcv_tod.tv_usec = 0;	/*	 * If there's a busy message happening, we're done, the	 * interrupt handler will start our timer as necessary.	 */	if (sp->busy_msg != NULL)		return (0);	value.it_value.tv_sec = RCV_PERIOD;	value.it_value.tv_usec = 0;	value.it_interval.tv_sec = 0;	value.it_interval.tv_usec = 0;	if (setitimer(ITIMER_REAL, &value, NULL)) {		msgq(sp, M_SYSERR, "timer: setitimer");		return (1);	}	return (0);}/* * h_alrm -- *	Handle SIGALRM. */voidh_alrm(signo)	int signo;{	struct itimerval value;	struct timeval ntod, tod;	SCR *sp;	EXF *ep;	/* XXX: Get the current time of day; if this fails, we're dead. */	if (gettimeofday(&tod, NULL))		return;		/*	 * Fire any timers that are past due, or any that are due	 * in a tenth of a second or less.	 */	for (ntod.tv_sec = 0, sp = __global_list->dq.cqh_first;	    sp != (void *)&__global_list->dq; sp = sp->q.cqe_next) {		/* Check the busy timer if the msg pointer is set. */		if (sp->busy_msg == NULL)			goto skip_busy;		if (sp->busy_tod.tv_sec > tod.tv_sec ||		    sp->busy_tod.tv_sec == tod.tv_sec &&		    sp->busy_tod.tv_usec > tod.tv_usec &&		    sp->busy_tod.tv_usec - tod.tv_usec > 100000L) {			if (ntod.tv_sec == 0 ||			    ntod.tv_sec > sp->busy_tod.tv_sec ||			    ntod.tv_sec == sp->busy_tod.tv_sec &&			    ntod.tv_usec > sp->busy_tod.tv_usec)				ntod = sp->busy_tod;		} else {			(void)sp->s_busy(sp, sp->busy_msg);			sp->busy_msg = NULL;		}		/*		 * Check the recovery timer if there's an EXF structure		 * and the recovery bit is set.		 */skip_busy:	if ((ep = sp->ep) == NULL || !F_ISSET(sp->ep, F_RCV_ON))			continue;		if (ep->rcv_tod.tv_sec > tod.tv_sec ||		    ep->rcv_tod.tv_sec == tod.tv_sec &&		    ep->rcv_tod.tv_usec > tod.tv_usec &&		    ep->rcv_tod.tv_usec - tod.tv_usec > 100000L) {			if (ntod.tv_sec == 0 ||			    ntod.tv_sec > ep->rcv_tod.tv_sec ||			    ntod.tv_sec == ep->rcv_tod.tv_sec &&			    ntod.tv_usec > ep->rcv_tod.tv_usec)				ntod = ep->rcv_tod;		} else {			F_SET(sp->gp, G_SIGALRM);			ep->rcv_tod = tod;			ep->rcv_tod.tv_sec += RCV_PERIOD;			if (ntod.tv_sec == 0 ||			    ntod.tv_sec > ep->rcv_tod.tv_sec ||			    ntod.tv_sec == ep->rcv_tod.tv_sec &&			    ntod.tv_usec > ep->rcv_tod.tv_usec)				ntod = ep->rcv_tod;		}	}	if (ntod.tv_sec == 0)		return;	/* XXX: Set the timer; if this fails, we're dead. */	value.it_value.tv_sec = ntod.tv_sec - tod.tv_sec;	value.it_value.tv_usec = ntod.tv_usec - tod.tv_usec;	value.it_interval.tv_sec = 0;	value.it_interval.tv_usec = 0;	(void)setitimer(ITIMER_REAL, &value, NULL);}

⌨️ 快捷键说明

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