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

📄 nap.c

📁 一个通讯程序源码
💻 C
字号:
/* CHK=0x24D1 *//*+-------------------------------------------------------------------------	nap.c - nap() support	wht@n4hgf.Mt-Park.GA.US--------------------------------------------------------------------------*//*+:EDITS:*//*:09-10-1992-14:00-wht@n4hgf-ECU release 3.20 *//*:08-22-1992-15:39-wht@n4hgf-ECU release 3.20 BETA *//*:08-10-1992-03:04-wht@n4hgf-add init_Nap *//*:07-17-1992-18:19-wht@n4hgf-creation of common module for all binaries */#include "ecu.h"#undef NULL	/* some stdio and param.h define these differently */#include <sys/param.h>#ifndef NULL		/* fake usual sys/param.h value */#define NULL 0#endifint hz;					/* HZ from environ or sys/param.h */ulong hzmsec;			/* clock period in msec rounded up *//*+-------------------------------------------------------------------------	Nap(msec) - wrapper for nap()early/most ISC and SCO UNIX nap() misbehave.  This kludge doesn't return theproper value (the actual time slept), but at least it does not makea mockery of the manual page.  It says:     NAP(S)		       UNIX System V			NAP(S)     Name	  nap -	suspends execution for a short interval     Syntax	  long nap(period)	  long period;     Description	  The current process is suspended from	execution for at least	  the number of	milliseconds specified by period, or until a	  signal is received.     Return Value	  On successful	completion, a long integer indicating the	  number of milliseconds actually slept	is returned. If	the	  process received a signal while napping, the return value	  will be -1, and errno	will be	set to EINTR.     See Also	  sleep(S)     Notes	  This function	is driven by the system	clock, which in	most	  cases	has a granularity of tens of milliseconds.  This	  function must	be linked with the linker option -lx.It appears nap() under UNIX 3.2.x has departed virtually entirely fromthe manual page.  I'm beginning to look rather silly in severalmilleus since I keep telling people SCO UNIX is a viable upgrade fromXENIX.  But process control people need some kind of timing capabilityless than one second and we can't do it with nap or select.nap(msec) is supposed to nap *at least* msec milliseconds.  However,if msec is specified less than 1000/HZ + 1, it will not nap at all.This was true for 3.2.0 and 3.2.1.It is supposed to return the number of milliseconds it actuallyslept.  Instead, it appears to "save up" the values and return them inlots of 1000. This behavior is true for 3.2.2.As it is nap() is nearly useless for accurate timing.  I believeselect() suffers from the same deficiency (< 1000 msec timeoutbecomes 1000 msec) but I haven't "proven" it yet.  [[ It was laterproven for SCO 3.2v2 at least ... see READMEs and *HISTORY ]]On systems with a working select(), we use a relatively complex selectarrangement to accomplish the nap requirement, but with an improvement.The "nap" survives any EINTR except for SIGINT (as indicated by sigintgetting set).  On SIGINT, the nap is aborted.A "working select" means1. the system tries to support it (all but XENIX 286)2. it is in libc.a (all but XENIX; see directory xsel386 to fix XENIX 386)3. it is not broken (XENIX 386 select fails on ttys, but can be      fixed: see xsel386; even an "unfixed" XENIX select would work      here because we are only interested in timeouts)4. it times out properly (SCO UNIX 3.2.[1-2] screws up by ROUNDING      timeouts UP to ONE SECOND).select() and nap() works very well on SCO 3.2v4--------------------------------------------------------------------------*/longNap(msec)long msec;{#if defined(M_XENIX) || defined(SCO32v4) || defined(WORKING_NAP)	return(nap(msec));#else#if defined(WORKING_SELECT)/* precision guard */#define SECDELTA 684300000L	/* sometime in 9/91 *//* * Compute  A -= B for timeval structs A, B (thanks to ping.c) */#ifdef USE_GETTIMEOFDAY#define tvsub(A, B) \	if(1) { \		(A)->tv_sec -= (B)->tv_sec ;\		if (((A)->tv_usec -= (B)->tv_usec) < 0)\			{ (A)->tv_sec--; (A)->tv_usec += 1000000; } \	} else /* ; supplied by invocation */	struct timeval timer;	struct timeval start;	struct timeval now;	struct timezone trash;	gettimeofday(&start,&trash);	start.tv_sec -= SECDELTA;	timer.tv_sec = msec / 1000;	timer.tv_usec = (msec % 1000L) * 1000L;	while(((timer.tv_sec * 1000000) + timer.tv_usec) > 0)	{		if(!select(0,0,0,0,&timer))			break;		if(errno != EINTR)			break;		if(sigint)		/* if SIGINT posted, exit now */			return(-1);		gettimeofday(&now,&trash);		now.tv_sec -= SECDELTA;		tvsub(&now,&start);		timer.tv_sec = msec / 1000;		timer.tv_usec = (msec % 1000L) * 1000L;		tvsub(&timer,&now);	}	gettimeofday(&now,&trash);	now.tv_sec -= SECDELTA;	tvsub(&now,&start);	msec = (now.tv_sec * 1000) + (now.tv_usec / 1000);#else#define tbsub(t, t0) \	if(1) { \		register long delta_msec = ((((t)->time * 1000L) + ( t)->millitm) - \                                   (((t0)->time * 1000L) + (t0)->millitm)); \		(t)->time = delta_msec / 1000; \		(t)->millitm = delta_msec % 1000; \	} else /* ; supplied by invoker */	struct timeb timer;	struct timeb start;	struct timeb now;	ftime(&start);	start.time -= SECDELTA;	timer.time = msec / 1000;	timer.millitm = msec % 1000;	while(((timer.time * 1000) + timer.millitm) > 0)	{		struct timeval tval;		tval.tv_sec = timer.time;		tval.tv_usec = timer.millitm * 1000;		if(!select(0,0,0,0,&tval))			break;		if(errno != EINTR)			break;		if(sigint)		/* if SIGINT posted, exit now */			return(-1);		ftime(&now);		now.time -= SECDELTA;		tbsub(&now,&start);		timer.time = msec / 1000;		timer.millitm = msec % 1000;		tbsub(&timer,&now);	}	ftime(&now);	now.time -= SECDELTA;	tbsub(&now,&start);	msec = (now.time * 1000) + now.millitm;#endif /* USE_GETTIMEOFDAY */	return(msec);#else#if defined(M_UNIX) || defined(ISC) 	if(msec < hzmsec)		msec = hzmsec;	if(nap(msec) < 0)		return(-1);	return(msec);#elseporting_attention_needed_here;#endif /* use hacked nap */#endif /* WORKING_SELECT */#endif /* working nap */}	/* end of Nap *//*+-------------------------------------------------------------------------	init_Nap()--------------------------------------------------------------------------*/voidinit_Nap(){	/*	 * learn tick rate for various timers	 */	if(getenv("HZ"))		hz = (ulong)atoi(getenv("HZ"));	else		hz = HZ;	hzmsec = (ulong)(1000 / hz) + 2;}	/* end of init_Nap *//* vi: set tabstop=4 shiftwidth=4: *//* end of nap.c */

⌨️ 快捷键说明

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