plan 9 kernel history: overview | file list | diff list

1990/1206/port/sturp.c (diff list | history)

1990/11211/sys/src/9/port/sturp.c:33,411990/1206/sys/src/9/port/sturp.c:33,41 (short | long | prev | next)
1990/0227    
} urpstat; 
 
struct Urp { 
1990/1004    
	Lock; 
1990/1206    
	QLock; 
1990/0227    
	short	state;		/* flags */ 
1990/0312    
	Rendez	r;		/* process waiting for close */ 
1990/1206    
	Rendez	r;		/* process waiting for output to finish */ 
1990/0227    
 
	/* input */ 
1990/0321    
	QLock	ack;		/* ack lock */ 
1990/11211/sys/src/9/port/sturp.c:59,671990/1206/sys/src/9/port/sturp.c:59,71
1990/0312    
	QLock	xl[8]; 
	ulong	timer;		/* timeout for xmit */ 
1990/0511    
	int	rexmit; 
1990/0312    
                 
	int	kstarted; 
1990/0227    
}; 
1990/1206    
Urp	*urp; 
 
Rendez	urpkr; 
QLock	urpkl; 
int	urpkstarted; 
 
1990/0331    
#define WINDOW(u) ((u)->unechoed>(u)->next ? (u)->unechoed+(u)->maxout-(u)->next-8 :\ 
			(u)->unechoed+(u)->maxout-(u)->next) 
1990/0629    
#define IN(x, f, n) (f<=n ? (x>=f && x<n) : (x<n || x>=f)) 
1990/11211/sys/src/9/port/sturp.c:96,1031990/1206/sys/src/9/port/sturp.c:100,105
1990/0312    
#define	OPEN		0x8 
#define CLOSING		0x10 
1990/0227    
 
1990/0717    
Urp	*urp; 
1990/0227    
                 
/* 
 *  predeclared 
 */ 
1990/11211/sys/src/9/port/sturp.c:117,1231990/1206/sys/src/9/port/sturp.c:119,124
1990/0227    
static void	initoutput(Urp*, int); 
static void	initinput(Urp*, int); 
1990/0312    
static void	urpkproc(void *arg); 
1990/0725    
static void	urptimer(Alarm*); 
1990/0629    
static void	urpvomit(char*, Urp*); 
1990/0227    
 
1990/11151    
Qinfo urpinfo = 
1990/11211/sys/src/9/port/sturp.c:134,1401990/1206/sys/src/9/port/sturp.c:135,140
1990/0717    
urpreset(void) 
{ 
	urp = (Urp *)ialloc(conf.nurp*sizeof(Urp), 0); 
1990/0728    
	alarm(500, urptimer, 0); 
1990/0717    
} 
 
1990/0312    
static void 
1990/11211/sys/src/9/port/sturp.c:144,1571990/1206/sys/src/9/port/sturp.c:144,166
1990/0227    
	int i; 
1990/0312    
	char name[128]; 
1990/0227    
 
1990/1206    
	if(!urpkstarted){ 
		qlock(&urpkl); 
		if(!urpkstarted){ 
			urpkstarted = 1; 
			kproc("urpkproc", urpkproc, 0); 
		} 
		qunlock(&urpkl); 
	} 
 
1990/0227    
	/* 
	 *  find a free urp structure 
	 */ 
1990/0717    
	for(up = urp; up < &urp[conf.nurp]; up++){ 
1990/1004    
		lock(up); 
1990/1206    
		qlock(up); 
1990/0227    
		if(up->state == 0) 
			break; 
1990/1004    
		unlock(up); 
1990/1206    
		qunlock(up); 
1990/0227    
	} 
1990/0717    
	if(up == &urp[conf.nurp]){ 
		q->ptr = 0; 
1990/11211/sys/src/9/port/sturp.c:163,1771990/1206/sys/src/9/port/sturp.c:172,180
1990/0227    
	up->rq = q; 
1990/0312    
	up->wq = q->other; 
	up->state = OPEN; 
1990/1004    
	unlock(up); 
1990/1206    
	qunlock(up); 
1990/0227    
	initinput(up, 0); 
	initoutput(up, 0); 
1990/0312    
                 
	/* 
	 *  start the ack/(re)xmit process 
	 */ 
1990/0728    
	sprint(name, "urp%d", up - urp); 
	kproc(name, urpkproc, up); 
1990/0227    
} 
 
/* 
1990/11211/sys/src/9/port/sturp.c:178,1911990/1206/sys/src/9/port/sturp.c:181,186
1990/0312    
 *  Shut down the connection and kill off the kernel process 
1990/0227    
 */ 
static int 
1990/0728    
isdead(void *a) 
{ 
	Urp *up; 
                 
	up = (Urp *)a; 
	return up->kstarted==0; 
} 
static int 
1990/0312    
isflushed(void *a) 
1990/0227    
{ 
	Urp *up; 
1990/11211/sys/src/9/port/sturp.c:212,2231990/1206/sys/src/9/port/sturp.c:207,213
1990/0227    
	 */ 
1990/0312    
	up->state |= CLOSING; 
1990/0509    
	tsleep(&up->r, isflushed, up, 2*60*1000); 
1990/0312    
                 
	/* 
1990/0728    
	 *  tell kernel process to die 
1990/0312    
	 */ 
	up->state |= HUNGUP; 
1990/0509    
	wakeup(&up->rq->r); 
 
	qlock(&up->xmit); 
	/* 
1990/11211/sys/src/9/port/sturp.c:238,2531990/1206/sys/src/9/port/sturp.c:228,236
1990/0509    
		} 
	qunlock(&up->xmit); 
1990/0403    
 
1990/0728    
	/* 
	 *  wait for kernel process to die 
	 */ 
	while(up->kstarted) 
		sleep(&up->r, isdead, up); 
                 
1990/1004    
	lock(up); 
1990/1206    
	qlock(up); 
1990/0728    
	up->state = 0; 
1990/1004    
	up->rq = 0; 
	unlock(up); 
1990/1206    
	qunlock(up); 
1990/0227    
} 
 
/* 
1990/11211/sys/src/9/port/sturp.c:260,2661990/1206/sys/src/9/port/sturp.c:243,248
1990/0227    
	case M_HANGUP: 
1990/0312    
		up->state |= HUNGUP; 
		wakeup(&up->r); 
		wakeup(&up->rq->r); 
		break; 
1990/0227    
	} 
	PUTNEXT(q, bp); 
1990/11211/sys/src/9/port/sturp.c:319,3251990/1206/sys/src/9/port/sturp.c:301,307
1990/0227    
	case AINIT: 
		up->state &= ~INITING; 
		flushinput(up); 
1990/0312    
		wakeup(&up->rq->r); 
1990/1206    
		wakeup(&urpkr); 
1990/0227    
		break; 
 
	case INIT0: 
1990/11211/sys/src/9/port/sturp.c:440,4461990/1206/sys/src/9/port/sturp.c:422,428
1990/0227    
	case AINIT: 
		up->state &= ~INITING; 
		flushinput(up); 
1990/0312    
		wakeup(&up->rq->r); 
1990/1206    
		wakeup(&urpkr); 
1990/0227    
		break; 
 
	case INIT0: 
1990/11211/sys/src/9/port/sturp.c:873,8791990/1206/sys/src/9/port/sturp.c:855,861
1990/0227    
		break; 
	} 
1990/0312    
 
	wakeup(&up->rq->r); 
1990/1206    
	wakeup(&urpkr); 
1990/0227    
} 
 
/* 
1990/11211/sys/src/9/port/sturp.c:950,10181990/1206/sys/src/9/port/sturp.c:932,960
1990/0227    
	flushinput(up); 
1990/0312    
} 
 
/* 
 *  do retransmissions etc 
 */ 
static int 
todo(void *arg) 
{ 
	Urp *up; 
                 
	up = (Urp *)arg; 
1990/0804    
                 
	return (up->state&INITING) 
	? NOW>up->timer					/* time to INIT1 */ 
1990/0930    
	: ((up->unechoed!=up->next && NOW>up->timer)	/* time to ENQ */ 
1990/1004    
	  || (WINDOW(up)>0 && (up->next!=up->nxb || up->wq->first)) /* open xmit window */ 
	  || (up->iseq!=(up->lastecho&7) && !QFULL(up->rq->next))); /* time to ECHO */ 
1990/0312    
} 
static void 
urpkproc(void *arg) 
{ 
1990/0728    
	Urp *up; 
1990/1206    
	Urp *up, *eup; 
1990/0312    
 
	up = (Urp *)arg; 
1990/0728    
	up->kstarted = 1; 
1990/1206    
	if(waserror()) 
		; 
1990/0312    
 
1990/0403    
	if(waserror()){ 
1990/0511    
		print("urpkproc error %ux\n", up); 
1990/0403    
		up->kstarted = 0; 
		wakeup(&up->r); 
		return; 
	} 
1990/1206    
	eup = urp + conf.nurp; 
1990/0312    
	for(;;){ 
1990/0728    
		if(up->state & HUNGUP) 
1990/0511    
			break; 
		if(!QFULL(up->rq->next)) 
			sendack(up); 
1990/0312    
		output(up); 
1990/0725    
		sleep(&up->rq->r, todo, up); 
1990/0312    
	} 
1990/0403    
	up->kstarted = 0; 
1990/0728    
	wakeup(&up->r); 
	poperror(); 
1990/0725    
} 
                 
/* 
 *  timer to wakeup urpkproc's for retransmissions 
 */ 
static void 
urptimer(Alarm *a) 
{ 
	Urp *up; 
	Urp *last; 
                 
1990/0726    
	cancel(a); 
1990/0728    
	alarm(500, urptimer, 0); 
1990/0725    
	for(up = urp, last = &urp[conf.nurp]; up < last; up++){ 
		if(up->state==0) 
			continue; 
1990/1004    
		if(up->rq && canlock(up)){ 
			if(up->rq && NOW>up->timer 
			   && ((up->state&INITING) || up->unechoed!=up->next)) 
				wakeup(&up->rq->r); 
			unlock(up); 
1990/1206    
		for(up = urp; up < eup; up++){ 
			if(up->state==0 || (up->state&HUNGUP)) 
				break; 
			if(!canqlock(up)) 
				continue; 
			if(up->state==0 || (up->state&HUNGUP)) 
				break; 
			if(up->iseq!=(up->lastecho&7) && !QFULL(up->rq->next)) 
				sendack(up); 
			output(up); 
			qunlock(up); 
1990/1004    
		} 
1990/1206    
		tsleep(&urpkr, return0, 0, 1000); 
1990/0725    
	} 
1990/0629    
} 
 


source code copyright © 1990-2005 Lucent Technologies; see license
Plan 9 distribution
comments to russ cox (rsc@swtch.com)