Relay-Version: version B 2.10 5/3/83; site utzoo.UUCP
Posting-Version: version B 2.10.1 6/24/83; site umcp-cs.UUCP
Path: utzoo!linus!decvax!mcnc!akgua!sdcsvax!sdcrdcf!hplabs!hao!seismo!rlgvax!cvl!umcp-cs!chris
From: chris@umcp-cs.UUCP
Newsgroups: net.bugs.uucp
Subject: Re: Discrepancies in UUCP SYSLOG timings
Message-ID: <8085@umcp-cs.UUCP>
Date: Thu, 9-Aug-84 20:41:23 EDT
Article-I.D.: umcp-cs.8085
Posted: Thu Aug  9 20:41:23 1984
Date-Received: Tue, 14-Aug-84 07:47:19 EDT
References: <745@dual.UUCP>
Distribution: net
Organization: U of Maryland, Computer Science Dept., College Park, MD
Lines: 79

It's probably due to all the context switching that goes on when UUCP
is receiving data at low baud rates.  The ``4.2'' UUCP has a hack in it
to do sleep()s to cut down on the overhead, but this raises the overall
time since a sleep(1) is on the average 1 second too long for a 64 byte
packet at 1200 baud (if you assume that a sleep(1) takes between .5 and
1.5 seconds; I haven't figured out what sleep(1) really does under 4.2,
what with alarm being a subroutine that calls setitimer which...).

I stuck some code into pk1.c to use the select system call for
fractional timeouts based on how much data is expected.  It seems to
works pretty well.  Here's the modified pkcget() routine.  (Note that
it needs to #include  and ; also note that
it is blatantly 4.2-and-int-is-32-bits-dependent.)

/***
 *	pkcget(fn, b, n)	get n characters from input
 *	char *b;		- buffer for characters
 *	int fn;			- file descriptor
 *	int n;			- requested number of characters
 *
 *	return codes:
 *		0  - ok
 *		-1 - timeout or EOF
 */

jmp_buf Getjbuf;
cgalarm() { longjmp(Getjbuf, 1); }

pkcget (fn, b, n)
int fn;
register int n;
register char *b;
{
    register int r;
    struct timeval tv;
    register int itime = 100000;/* as a guess, it's been 1/10th sec
				   since we last read the line */
    extern int linebaudrate;

    if (setjmp (Getjbuf)) {
	Ntimeout++;
	PKDEBUG (4, "alarm %d\n", Ntimeout);
	return -1;
    }
    signal (SIGALRM, cgalarm);

    alarm (PKTIME);
    while (n > 0) {
	if (linebaudrate > 0) {
	    r = n * 100000;
	    r = r / linebaudrate;
	    r = (r * 100) - itime;
	    itime = 0;
	    if (r > 20000) {	/* we predict that more than 1/50th of a
				   second will go by before the read will
				   give back all that we want. */
		tv.tv_sec = r / 1000000;
		tv.tv_usec = r % 1000000;
		PKDEBUG (9, "PKCGET stall for %d", tv.tv_sec);
		PKDEBUG (9, ".%06d sec\n", tv.tv_usec);
		(void) select (0, (int *)0, (int *)0, (int *)0, &tv);
	    }
	}
	r = read (fn, b, n);
	if (r == 0) {
	    alarm (0);
	    return -1;
	}
	PKASSERT (r > 0, "PKCGET READ", "", r);
	b += r;
	n -= r;
    }
    alarm (0);
    return 0;
}
-- 
In-Real-Life: Chris Torek, Univ of MD Comp Sci (301) 454-7690
UUCP:	{seismo,allegra,brl-bmd}!umcp-cs!chris
CSNet:	chris@umcp-cs		ARPA:	chris@maryland