V9/sys/dev.old/bufld.c

Compare this file to the similar file:
Show the results in this format:

/*
 * buffering line discipline.
 *  transparent, but saves up characters for a while.
 */

#include "bf.h"
#include "../h/param.h"
#include "../h/systm.h"
#include "../h/stream.h"
#include "../h/map.h"
#include "../h/buf.h"
#include "../h/ubavar.h"
#include "../h/conf.h"

struct bufld {
	struct	queue *queue;
	u_char	rnchar;
	u_char	btime;
	u_char	nchar;
	u_char	nclick;
	u_char	index;
} bufld[NBF];

int	buftimo();
int	bufopen(), bufput(), bufsrv(), bufclose();
long	bufldact;

static	struct qinit bufrinit = { bufput, bufsrv, bufopen, bufclose, 1024, 512 };
static	struct qinit bufwinit = { bufput, bufsrv, bufopen, bufclose, 128, 64 };
struct streamtab bufinfo = { &bufrinit, &bufwinit };

bufopen(q, dev)
register struct queue *q;
{
	register i;
	register struct bufld *fp;

	if (q->ptr)
		return(1);
	for (i=0; bufld[i].queue!=0 && i<NBF; i+= 2)
		;
	if (i >= NBF)
		return(0);
	fp = &bufld[i];
	fp->queue = q;
	(fp+1)->queue = WR(q);
	fp->index = i;
	(fp+1)->index = i+1;
	fp->nclick = 3;
	(fp+1)->nclick = 3;
	fp->nchar = 16;
	(fp+1)->nchar = 16;
	fp->rnchar = 0;
	(fp+1)->rnchar = 0;
	fp->btime = 0;
	(fp+1)->btime = 0;
	q->flag |= q->next->flag & QDELIM;
	WR(q)->flag |= WR(q)->next->flag & QDELIM;
	q->ptr = (caddr_t)fp;
	WR(q)->ptr = (caddr_t)(fp+1);
	q->flag |= QNOENB;
	WR(q)->flag |= QNOENB;
	return(1);
}

bufclose(q)
register struct queue *q;
{

	bufunload(q);
	bufunload(WR(q));
	((struct bufld *)q->ptr)->btime = 0;
	((struct bufld *)WR(q)->ptr)->btime = 0;
	((struct bufld *)q->ptr)->queue = 0;
	((struct bufld *)WR(q)->ptr)->queue = 0;
}

bufput(q, bp)
register struct queue *q;
register struct block *bp;
{
	register struct bufld *fp = (struct bufld *)q->ptr;
	register s = spl6();
	register n, t;

	t = bp->type;
	n = bp->wptr - bp->rptr;
	putq(q, bp);
	fp->rnchar += n;
	if ((t!=M_DATA && t!=M_DELIM) || fp->rnchar >= fp->nchar)
		bufunload(q);
	if (q->first) {
		/* n/2 ~ about 1200 cps */
		fp->btime = fp->nclick + n/2;
		if (bufldact == 0)
			timeout(buftimo, (caddr_t)0, 1);
		bufldact |= 1 << fp->index;
	} else  {
		fp->rnchar = 0;
		fp->btime = 0;
	}
	splx(s);
}

bufsrv(q)
register struct queue *q;
{
	register struct bufld *fp = (struct bufld *)q->ptr;

	if (q->first && fp->btime == 0)
		bufunload(q);
}

bufunload(q)
register struct queue *q;
{
	register struct block *bp;
	register struct bufld *fp = (struct bufld *)q->ptr;

	while ((q->next->flag&QFULL)==0 && (bp = getq(q))) {
		fp->rnchar -= bp->wptr - bp->rptr;
		(*q->next->qinfo->putp)(q->next, bp);
	}
}

buftimo()
{
	register long bact;
	register struct bufld *fp;
	register ish;

	bact = bufldact;
	for (fp = bufld, ish = 1; bact!=0; fp++, ish <<= 1) {
		if (bact & ish) {
			bact &= ~ish;
			if (fp->btime) {
				fp->btime--;
				if (fp->btime == 0 && fp->queue
				 && fp->queue->first) {
					qenable(fp->queue);
					bufldact &= ~ish;
				}
			}
		}
	}
	if (bufldact)
		timeout(buftimo, (caddr_t)0, 1);
}