1
0
mirror of https://github.com/prirun/p50em.git synced 2026-01-16 00:03:55 +00:00

Add async I/O code to devpnc, but disabled for now: there is a delay

problem with remote terminal sessions:

1. netlink to remote Prime
2. a prirun
3. l (list directory)
4. displays a little, then a longish pause up to 30 seconds, then the rest

Does a similar thing with stat us.  Hitting Enter will cause it to
finish, while typing characters does not.  I suspect this is a problem
with Prime's networking code, but not sure.

Also, if async I/O is used, the QUIT. OK, message doesn't appear after
ctrl-p.  I think they are getting wiped out by Primenet's buffer
flushes.

All of this might be subtle timing problems because I changed the
default clock rate from 250/330/500/whatever times per sec to 20 times
per second in this rev 19 version of Primos.
This commit is contained in:
Jim 2011-08-15 17:11:28 -04:00
parent e4dfa3fade
commit 4ddd43debf
2 changed files with 53 additions and 11 deletions

View File

@ -189,7 +189,7 @@
#ifndef HOBBY
/* PNC poll rate is 1/10th of a second */
/* PNC poll rate in ms, mostly for connecting to new nodes */
#define PNCPOLL 100
@ -304,6 +304,15 @@ typedef struct {
} t_dma;
static t_dma rcv, xmit;
static int sawsigio=0, olddevpoll;
void pnchavedata(int s) {
if (sawsigio) return;
olddevpoll = devpoll[7];
devpoll[7] = 1;
sawsigio = 1;
}
/* return pointer to a hex-formatted uid */
char * pnchexuid(char * uid) {
@ -371,14 +380,22 @@ pncinitfd(int fd) {
perror("unable to get ts flags for PNC");
fatal(NULL);
}
fdflags |= O_NONBLOCK;
optval = MAXPKTBYTES;
if (setsockopt(fd, SOL_SOCKET, SO_SNDLOWAT, &optval, sizeof(optval))) {
perror("setsockopt 2 failed for PNC");
fatal(NULL);
}
if (setsockopt(fd, SOL_SOCKET, SO_NOSIGPIPE, &optval, sizeof(optval))) {
perror("setsockopt 3 failed for PNC");
fatal(NULL);
}
fdflags |= O_NONBLOCK+O_ASYNC;
if (fcntl(fd, F_SETFL, fdflags) == -1) {
perror("unable to set fdflags for PNC");
fatal(NULL);
}
optval = MAXPKTBYTES;
if (setsockopt(fd, SOL_SOCKET, SO_SNDLOWAT, &optval, sizeof(optval))) {
perror("setsockopt failed for PNC");
if (fcntl(fd, F_SETOWN, getpid()) == -1) {
perror("unable to SETOWN for PNC");
fatal(NULL);
}
}
@ -872,6 +889,10 @@ int devpnc (int class, int func, int device) {
perror("setsockopt failed for PNC listen");
fatal(NULL);
}
if (setsockopt(pncfd, SOL_SOCKET, SO_NOSIGPIPE, &optval, sizeof(optval))) {
perror("setsockopt 1 failed for PNC");
fatal(NULL);
}
addr.sin_family = AF_INET;
addr.sin_port = htons(nport);
addr.sin_addr.s_addr = INADDR_ANY;
@ -885,6 +906,12 @@ int devpnc (int class, int func, int device) {
}
TRACE(T_RIO, "PNC configured\n");
devpoll[device] = PNCPOLL*gvp->instpermsec;
#ifdef ASYNCIO
if (signal(SIGIO, pnchavedata) == SIG_ERR) {
perror("installing SIGIO handler");
fatal(NULL);
}
#endif
return 0;
case 0:
@ -1122,10 +1149,19 @@ int devpnc (int class, int func, int device) {
case 4:
TRACE(T_RIO, " POLL '%02o%02o\n", func, device);
devpoll[device] = PNCPOLL*gvp->instpermsec;
time(&timenow);
pncaccept(timenow); /* accept 1 new connection each poll */
pncconnect(timenow); /* try to connect to a disconnected node */
/* on SIGPIPE, reset to the previous poll time and just do reads;
otherwise, a regularly scheduled poll */
if (sawsigio) {
devpoll[device] = olddevpoll;
sawsigio = 0;
} else {
devpoll[device] = PNCPOLL*gvp->instpermsec;
time(&timenow);
pncaccept(timenow); /* accept 1 new connection each poll */
pncconnect(timenow); /* try to connect to a disconnected node */
}
intrexit:
if (rcv.state == PNCBSRDY)

10
em.c
View File

@ -6628,12 +6628,18 @@ d_bdx: /* 0140734 */
if (delayusec > 1000) {
if (gettimeofday(&tv0, NULL) != 0)
fatal("em: gettimeofday 0 failed");
/* NOTE: on OSX, a signal (sigio for pnc) will interrupt usleep */
usleep(delayusec);
if (gettimeofday(&tv1, NULL) != 0)
fatal("em: gettimeofday 1 failed");
actualmsec = (tv1.tv_sec-tv0.tv_sec-1)*1000 + (tv1.tv_usec+1000000-tv0.tv_usec)/1000;
// TRACEA(" BDX loop at %o/%o, remainder=%d, owner=%o, utempl=%d, wanted %d us, got %d ms\n", gvp->prevpc>>16, gvp->prevpc&0xffff, crs[X], crs[OWNERL], utempl, delayusec, actualusec);
#if 0
if (actualmsec > delayusec*1.2/1000) {
TRACEA(" BDX loop at %o/%o, remainder=%d, owner=%o, utempl=%d, wanted %d ms, got %d ms\n", gvp->prevpc>>16, gvp->prevpc&0xffff, crs[X], crs[OWNERL], utempl, delayusec/1000, actualmsec);
}
#endif
/* do timer bookkeeping that would have occurred if we had
actually looped on BDX utempl times */