|
|
1.1 root 1: /*
2: * buffering line discipline.
3: * transparent, but saves up characters for a while.
4: */
5:
6: #include "sys/param.h"
7: #include "sys/stream.h"
8: #include "sys/conf.h"
9: #include "sys/bufld.h"
10:
11: extern int bufldcnt;
12: extern struct bufld bufld[];
13:
14: int buftimo();
15: long bufopen();
16: int bufput(), bufsrv(), bufclose();
17: long bufldact;
18: #define MAXINDEX 32 /* this is a bit silly */
19:
20: static struct qinit bufrinit = { bufput, bufsrv, bufopen, bufclose, 1024, 512 };
21: static struct qinit bufwinit = { bufput, bufsrv, bufopen, bufclose, 128, 64 };
22: struct streamtab bufldstream = { &bufrinit, &bufwinit };
23:
24: long
25: bufopen(q, dev)
26: register struct queue *q;
27: {
28: register i;
29: register struct bufld *fp;
30:
31: if (q->ptr)
32: return(1);
33: for (i=0; bufld[i].queue!=0 && i<bufldcnt; i+= 2)
34: ;
35: if (i >= bufldcnt || i >= MAXINDEX)
36: return(0);
37: fp = &bufld[i];
38: fp->queue = q;
39: (fp+1)->queue = WR(q);
40: fp->index = i;
41: (fp+1)->index = i+1;
42: fp->nclick = 3;
43: (fp+1)->nclick = 3;
44: fp->nchar = 16;
45: (fp+1)->nchar = 16;
46: fp->rnchar = 0;
47: (fp+1)->rnchar = 0;
48: fp->btime = 0;
49: (fp+1)->btime = 0;
50: q->flag |= q->next->flag & QDELIM;
51: WR(q)->flag |= WR(q)->next->flag & QDELIM;
52: q->ptr = (caddr_t)fp;
53: WR(q)->ptr = (caddr_t)(fp+1);
54: q->flag |= QNOENB;
55: WR(q)->flag |= QNOENB;
56: return(1);
57: }
58:
59: bufclose(q)
60: register struct queue *q;
61: {
62:
63: bufunload(q);
64: bufunload(WR(q));
65: ((struct bufld *)q->ptr)->btime = 0;
66: ((struct bufld *)WR(q)->ptr)->btime = 0;
67: ((struct bufld *)q->ptr)->queue = 0;
68: ((struct bufld *)WR(q)->ptr)->queue = 0;
69: }
70:
71: bufput(q, bp)
72: register struct queue *q;
73: register struct block *bp;
74: {
75: register struct bufld *fp = (struct bufld *)q->ptr;
76: register s = spl6();
77: register n, t;
78:
79: t = bp->type;
80: n = bp->wptr - bp->rptr;
81: putq(q, bp);
82: fp->rnchar += n;
83: if ((t!=M_DATA) || fp->rnchar >= fp->nchar)
84: bufunload(q);
85: if (q->first) {
86: /* n/2 ~ about 1200 cps */
87: fp->btime = fp->nclick + n/2;
88: if (bufldact == 0)
89: timeout(buftimo, (caddr_t)0, 1);
90: bufldact |= 1 << fp->index;
91: } else {
92: fp->rnchar = 0;
93: fp->btime = 0;
94: }
95: splx(s);
96: }
97:
98: bufsrv(q)
99: register struct queue *q;
100: {
101: register struct bufld *fp = (struct bufld *)q->ptr;
102:
103: if (q->first && fp->btime == 0)
104: bufunload(q);
105: }
106:
107: bufunload(q)
108: register struct queue *q;
109: {
110: register struct block *bp;
111: register struct bufld *fp = (struct bufld *)q->ptr;
112:
113: while ((q->next->flag&QFULL)==0 && (bp = getq(q))) {
114: fp->rnchar -= bp->wptr - bp->rptr;
115: (*q->next->qinfo->putp)(q->next, bp);
116: }
117: }
118:
119: buftimo()
120: {
121: register long bact;
122: register struct bufld *fp;
123: register ish;
124:
125: bact = bufldact;
126: for (fp = bufld, ish = 1; bact!=0; fp++, ish <<= 1) {
127: if (bact & ish) {
128: bact &= ~ish;
129: if (fp->btime) {
130: fp->btime--;
131: if (fp->btime == 0 && fp->queue
132: && fp->queue->first) {
133: qenable(fp->queue);
134: bufldact &= ~ish;
135: }
136: }
137: }
138: }
139: if (bufldact)
140: timeout(buftimo, (caddr_t)0, 1);
141: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.