From e3746662f6e2b79fe6cb18fc1f6d01334e14ad5e Mon Sep 17 00:00:00 2001 From: David du Colombier <0intro@gmail.com> Date: Tue, 1 Jun 1993 00:00:00 +0000 Subject: [PATCH] Plan 9 from Bell Labs 1993-06-01 --- boot/boot.c | 13 +++ port/devcons.c | 262 ++++++++++++++++++------------------------------- port/devpipe.c | 4 +- port/portdat.h | 37 +------ port/portfns.h | 21 ++-- port/qio.c | 42 ++++++-- 6 files changed, 153 insertions(+), 226 deletions(-) diff --git a/boot/boot.c b/boot/boot.c index db5d477f11534bef2ace30e1045d4111b1d4d039..31f02f0c94dff0d280169c2f7472647a8f3167c8 100644 --- a/boot/boot.c +++ b/boot/boot.c @@ -24,6 +24,18 @@ static void swapproc(void); static void recover(Method*); static Method *rootserver(char*); +void +intest(void) +{ + int n; + char buf[128]; + + print(">"); + n = read(0, buf, sizeof(buf)-1); +print("read %d bytes\n", n); + write(1, buf, n); +} + void pipetest(void) { @@ -178,6 +190,7 @@ boot(int argc, char *argv[]) print("\n"); #endif DEBUG + intest(); pipetest(); pipetest2(); ethertest(); diff --git a/port/devcons.c b/port/devcons.c index ea1c3dd14eaf00463a4fd9b6cc680e89f07641ec..0c90b337db68d3236498604f2bcf0a94f7d78de7 100644 --- a/port/devcons.c +++ b/port/devcons.c @@ -8,35 +8,34 @@ #include "devtab.h" -struct { - IOQ; /* lock to klogputs */ - QLock; /* qlock to getc */ -}klogq; +Queue *mouseq; +Queue *kbdq; /* unprocessed console input */ +Queue *lineq; /* processed console input */ +Queue *printq; /* console output */ +Queue *klogq; -IOQ mouseq; -IOQ lineq; /* lock to getc; interrupt putc's */ -IOQ printq; -KIOQ kbdq; +static struct +{ + QLock; + + int raw; /* true if we shouldn't process input */ + int ctl; /* number of opens to the control file */ + int x; /* index into line */ + char line[1024]; /* current input line */ + + char c; + int count; + int repeat; +} kbd; -static Ref ctl; /* number of opens to the control file */ -static int raw; /* true if ctl file is raw */ char sysname[NAMELEN]; -/* - * init the queues and set the output routine - */ void printinit(void) { - initq(&printq); - printq.puts = 0; - initq(&lineq); - initq(&kbdq); - kbdq.putc = kbdputc; - initq(&klogq); - initq(&mouseq); - mouseq.putc = mouseputc; + klogq = qopen(32*1024, 0, 0, 0); + lineq = qopen(2*1024, 0, 0, 0); } /* @@ -65,7 +64,7 @@ putstrn(char *str, int n) * put the message there. Tack a carriage return * before new lines. */ - if(printq.puts == 0) + if(printq == 0) return; while(n > 0){ t = memchr(str, '\n', n); @@ -74,62 +73,16 @@ putstrn(char *str, int n) memmove(buf, str, m); buf[m] = '\r'; buf[m+1] = '\n'; - (*printq.puts)(&printq, buf, m+2); + qwrite(printq, buf, m+2, 1); str = t + 1; n -= m + 1; } else { - (*printq.puts)(&printq, str, n); + qwrite(printq, str, n, 1); break; } } } -/* - * Print a string in the kernel log. Ignore overflow. - */ -void -klogputs(char *str, long n) -{ - int s, m; - uchar *nextin; - - s = splhi(); - lock(&klogq); - while(n){ - m = &klogq.buf[NQ] - klogq.in; - if(m > n) - m = n; - memmove(klogq.in, str, m); - n -= m; - str += m; - nextin = klogq.in + m; - if(nextin >= &klogq.buf[NQ]) - klogq.in = klogq.buf; - else - klogq.in = nextin; - } - unlock(&klogq); - splx(s); - wakeup(&klogq.r); -} - -int -isbrkc(KIOQ *q) -{ - uchar *p; - - for(p=q->out; p!=q->in; ){ - if(raw) - return 1; - if(*p==0x04 || *p=='\n') - return 1; - p++; - if(p >= q->buf+sizeof(q->buf)) - p = q->buf; - } - return 0; -} - int sprint(char *s, char *fmt, ...) { @@ -154,7 +107,7 @@ kprint(char *fmt, ...) int n; n = doprint(buf, buf+sizeof(buf), fmt, (&fmt+1)) - buf; - klogputs(buf, n); + qwrite(klogq, buf, n, 1); return n; } @@ -202,7 +155,7 @@ pprint(char *fmt, ...) void prflush(void) { - while(printq.in != printq.out) ; + while(qlen(printq) > 0) ; } void @@ -245,8 +198,12 @@ echo(Rune r, char *buf, int n) return; } ctrlt = 0; - if(raw) + if(kbd.raw) return; + + /* + * finally, the actual echoing + */ if(r == 0x15) putstrn("^U\n", 3); else @@ -254,10 +211,12 @@ echo(Rune r, char *buf, int n) } /* - * turn '\r' into '\n' before putting it into the queue + * Called by a uart interrupt for console input. + * + * turn '\r' into '\n' before putting it into the queue. */ int -kbdcr2nl(IOQ *q, int ch) +kbdcr2nl(Queue *q, int ch) { if(ch == '\r') ch = '\n'; @@ -267,11 +226,13 @@ kbdcr2nl(IOQ *q, int ch) /* * Put character, possibly a rune, into read queue at interrupt time. * Always called splhi from processor 0. + * + * Called at interrupt time to process a character. */ int -kbdputc(IOQ *q, int ch) +kbdputc(Queue *q, int ch) { - int i, n; + int n; char buf[3]; Rune r; @@ -281,42 +242,35 @@ kbdputc(IOQ *q, int ch) if(n == 0) return 0; echo(r, buf, n); - kbdq.c = r; - for(i=0; iHZ){ - kbdq.repeat = 2; - kbdq.count = 0; + if(kbd.repeat==1 && ++kbd.count>HZ){ + kbd.repeat = 2; + kbd.count = 0; return; } - if(++kbdq.count&1) - kbdputc(&kbdq, kbdq.c); + if(++kbd.count&1) + kbdputc(kbdq, kbd.c); } int consactive(void) { - return printq.in != printq.out; + return qlen(printq) > 0; } enum{ @@ -456,7 +410,9 @@ consopen(Chan *c, int omode) case Qconsctl: if(!iseve()) error(Eperm); - incref(&ctl); + qlock(&kbd); + kbd.ctl++; + qunlock(&kbd); break; } return devopen(c, omode, consdir, NCONS, devgen); @@ -476,10 +432,10 @@ consclose(Chan *c) switch(c->qid.path){ case Qconsctl: if(c->flag&COPEN){ - lock(&ctl); - if(--ctl.ref == 0) - raw = 0; - unlock(&ctl); + qlock(&kbd); + if(--kbd.ctl == 0) + kbd.raw = 0; + qunlock(&kbd); } case Qauth: case Qauthcheck: @@ -504,52 +460,41 @@ consread(Chan *c, void *buf, long n, ulong offset) return devdirread(c, buf, n, consdir, NCONS, devgen); case Qcons: - qlock(&kbdq); + qlock(&kbd); if(waserror()){ - qunlock(&kbdq); + qunlock(&kbd); nexterror(); } - while(!cangetc(&lineq)){ - sleep(&kbdq.r, isbrkc, &kbdq); - do{ - lock(&lineq); - ch = getc(&kbdq); - if(raw) - goto Default; - switch(ch){ - case '\b': - if(lineq.in != lineq.out){ - if(lineq.in == lineq.buf) - lineq.in = lineq.buf+sizeof(lineq.buf); - lineq.in--; - } - break; - case 0x15: - lineq.in = lineq.out; - break; - Default: - default: - *lineq.in = ch; - if(lineq.in >= lineq.buf+sizeof(lineq.buf)-1) - lineq.in = lineq.buf; - else - lineq.in++; - } - unlock(&lineq); - }while(raw==0 && ch!='\n' && ch!=0x04); - } - i = 0; - while(n > 0){ - ch = getc(&lineq); - if(ch==-1 || (raw==0 && ch==0x04)) + while(!qcanread(lineq)){ + qread(kbdq, &kbd.line[kbd.x], 1); + ch = kbd.line[kbd.x]; + if(kbd.raw){ + i = splhi(); + qproduce(lineq, &kbd.line[kbd.x], 1); + splx(i); + continue; + } + switch(ch){ + case '\b': + if(kbd.x) + kbd.x--; + break; + case 0x15: + kbd.x = 0; + break; + default: + kbd.line[kbd.x++] = ch; break; - i++; - *cbuf++ = ch; - --n; + } + if(kbd.x == sizeof(kbd.line) || ch == '\n' || ch == 0x04){ + if(ch == 0x04) + kbd.x--; + qwrite(lineq, kbd.line, kbd.x, 1); + } } - poperror(); - qunlock(&kbdq); - return i; + n = qread(lineq, buf, n); + qunlock(&kbd); + return n; case Qcputime: k = offset; @@ -613,21 +558,7 @@ consread(Chan *c, void *buf, long n, ulong offset) return 0; case Qklog: - qlock(&klogq); - if(waserror()){ - qunlock(&klogq); - nexterror(); - } - while(!cangetc(&klogq)) - sleep(&klogq.r, cangetc, &klogq); - for(i=0; iticks), NUMSIZE); @@ -730,7 +661,7 @@ conswrite(Chan *c, void *va, long n, ulong offset) long l, bp; char *a = va; Mach *mp; - int id, fd, ch; + int id, fd; Chan *swc; switch(c->qid.path){ @@ -757,20 +688,15 @@ conswrite(Chan *c, void *va, long n, ulong offset) buf[n] = 0; for(a = buf; a;){ if(strncmp(a, "rawon", 5) == 0){ - lock(&lineq); - while((ch=getc(&kbdq)) != -1){ - *lineq.in++ = ch; - if(lineq.in == lineq.buf+sizeof(lineq.buf)) - lineq.in = lineq.buf; + qlock(&kbd); + if(kbd.x){ + qwrite(kbdq, kbd.line, kbd.x, 1); + kbd.x = 0; } - unlock(&lineq); - lock(&ctl); - raw = 1; - unlock(&ctl); + kbd.raw = 1; + qunlock(&kbd); } else if(strncmp(a, "rawoff", 6) == 0){ - lock(&ctl); - raw = 0; - unlock(&ctl); + kbd.raw = 0; } if(a = strchr(a, ' ')) a++; diff --git a/port/devpipe.c b/port/devpipe.c index c1f1521c48b3a5a9227676643484ac8d16ed6161..4193ae6201282c1e433d7a7e9684915ffa843d5c 100644 --- a/port/devpipe.c +++ b/port/devpipe.c @@ -301,9 +301,9 @@ pipewrite(Chan *c, void *va, long n, ulong offset) switch(NETTYPE(c->qid.path)){ case Qdata0: - return qwrite(p->q[1], va, n); + return qwrite(p->q[1], va, n, 0); case Qdata1: - return qwrite(p->q[0], va, n); + return qwrite(p->q[0], va, n, 0); default: panic("piperead"); } diff --git a/port/portdat.h b/port/portdat.h index 51085e68c9c061d4940496f9580b7f2ccaf0dcef..ebd998d7f63ef666f089e78720182fd42f58ea73 100644 --- a/port/portdat.h +++ b/port/portdat.h @@ -218,36 +218,6 @@ struct Scsi uchar cmdblk[16]; }; -/* character based IO (mouse, keyboard, console screen) */ -#define NQ 4096 -struct IOQ -{ - Lock; - uchar buf[NQ]; - uchar *in; - uchar *out; - int state; - Rendez r; - union{ - void (*puts)(IOQ*, void*, int); /* output */ - int (*putc)(IOQ*, int); /* input */ - }; - union{ - int (*gets)(IOQ*, void*, int); /* input */ - int (*getc)(IOQ*); /* output */ - }; - void *ptr; -}; - -struct KIOQ -{ - QLock; - IOQ; - int repeat; - int c; - int count; -}; - enum { NSMAX = 1000, @@ -654,13 +624,12 @@ extern char eve[]; extern char hostdomain[]; extern uchar initcode[]; extern FPsave initfp; -extern KIOQ kbdq; -extern IOQ lineq; -extern IOQ mouseq; +extern Queue *kbdq; +extern Queue *mouseq; extern Ref noteidalloc; extern int nrdy; extern Palloc palloc; -extern IOQ printq; +extern Queue *printq; extern char* statename[]; extern Image swapimage; extern char sysname[NAMELEN]; diff --git a/port/portfns.h b/port/portfns.h index 7fd1bb151262286a7dd0d5462c1b61d5fae712ff..eb651470edfbaabd298e6e0f02f37f64ac0b1b57 100644 --- a/port/portfns.h +++ b/port/portfns.h @@ -77,10 +77,8 @@ void freechan(Chan*); void freepte(Segment*, Pte*); void freesegs(int); void freesession(Session*); -int getc(IOQ*); void getcolor(ulong, ulong*, ulong*, ulong*); int getfields(char*, char**, int, char); -int gets(IOQ*, void*, int); void gotolabel(Label*); int haswaitq(void*); int hwcursmove(int, int); @@ -88,15 +86,14 @@ int hwcursset(uchar*, uchar*, int, int); void iallocinit(void); long ibrk(ulong, int); int incref(Ref*); -void initq(IOQ*); void initscsi(void); void initseg(void); void invalidateu(void); void isdir(Chan*); int ispages(void*); void kbdclock(void); -int kbdcr2nl(IOQ*, int); -int kbdputc(IOQ*, int); +int kbdcr2nl(Queue*, int); +int kbdputc(Queue*, int); void kbdrepeat(int); void kickpager(void); int kprint(char*, ...); @@ -109,7 +106,6 @@ void lights(int); void lock(Lock*); void lockinit(void); Page* lookpage(Image*, ulong); -int m3mouseputc(IOQ*, int); void machinit(void); void* malloc(ulong); void mmuswitch(Proc*); @@ -123,7 +119,6 @@ void mountfree(Mount*); void mousebuttons(int); void mousectl(char*); void mouseclock(void); -int mouseputc(IOQ*, int); void mousescreenupdate(void); int msize(void*); Chan* namec(char*, int, int, ulong); @@ -159,28 +154,27 @@ void procinit0(void); Proc* proctab(int); Pte* ptealloc(void); Pte* ptecpy(Pte*); -int putc(IOQ*, int); void putimage(Image*); void putmmu(ulong, ulong, Page*); void putpage(Page*); -void puts(IOQ*, void*, int); void putseg(Segment*); void putstr(char*); void putstr(char*); void putstrn(char*, long); void putswap(Page*); ulong pwait(Waitmsg*); +int qcanread(Queue*); void qclose(Queue*); -int qconsume(Queue*, uchar*, int); +int qconsume(Queue*, void*, int); void qhangup(Queue*); int qlen(Queue*); void qlock(QLock*); Queue* qopen(int, int, void (*)(void*), void*); -int qproduce(Queue*, uchar*, int); -long qread(Queue*, char*, int); +int qproduce(Queue*, void*, int); +long qread(Queue*, void*, int); void qreopen(Queue*); void qunlock(QLock*); -long qwrite(Queue*, char*, int); +long qwrite(Queue*, void*, int, int); int readnum(ulong, char*, ulong, ulong, int); int readstr(ulong, char*, ulong, char*); void ready(Proc*); @@ -197,7 +191,6 @@ void savefpregs(FPsave*); void sccclock(void); int sccintr(void); void sccsetup(void*, ulong, int); -void sccspecial(int, IOQ*, IOQ*, int); void sched(void); void schedinit(void); int screenbits(void); diff --git a/port/qio.c b/port/qio.c index 119a7528a2d5c0da4deb801304302918185c0391..dc3c2d27a8ad181e3dcb169ae2d1fcc0e9b696f7 100644 --- a/port/qio.c +++ b/port/qio.c @@ -253,10 +253,11 @@ allocb(int size) * set, any bytes left in a block afer a consume are discarded. */ int -qconsume(Queue *q, uchar *p, int len) +qconsume(Queue *q, void *vp, int len) { Block *b; int n, dowakeup; + uchar *p = vp; /* sync with qwrite */ lock(q); @@ -298,10 +299,11 @@ qconsume(Queue *q, uchar *p, int len) } int -qproduce(Queue *q, uchar *p, int len) +qproduce(Queue *q, void *vp, int len) { Block *b; int dowakeup; + uchar *p = vp; /* sync with qread */ lock(q); @@ -340,8 +342,11 @@ qproduce(Queue *q, uchar *p, int len) dowakeup = 0; unlock(q); - if(dowakeup) + if(dowakeup){ + if(q->kick) + (*q->kick)(q->arg); wakeup(&q->rr); + } return len; } @@ -363,6 +368,7 @@ qopen(int limit, int msg, void (*kick)(void*), void *arg) q->kick = kick; q->arg = arg; q->state = msg ? Qmsg : 0; + q->state |= Qstarve; return q; } @@ -380,10 +386,11 @@ notempty(void *a) * and wait on its Rendez. */ long -qread(Queue *q, char *p, int len) +qread(Queue *q, void *vp, int len) { Block *b; int x, n, dowakeup; + uchar *p = vp; qlock(&q->rlock); if(waserror()){ @@ -467,10 +474,11 @@ qnotfull(void *a) * queue the data. */ long -qwrite(Queue *q, char *p, int len) +qwrite(Queue *q, void *vp, int len, int nowait) { int x, dowakeup; Block *b; + uchar *p = vp; b = allocb(len); memmove(b->wp, p, len); @@ -478,6 +486,8 @@ qwrite(Queue *q, char *p, int len) /* flow control */ while(!qnotfull(q)){ + if(nowait) + return len; qlock(&q->wlock); q->state |= Qflow; sleep(&q->wr, qnotfull, q); @@ -493,8 +503,11 @@ qwrite(Queue *q, char *p, int len) error(Ehungup); } - b->next = q->bfirst; - q->bfirst = b; + if(q->bfirst) + q->blast->next = b; + else + q->bfirst = b; + q->blast = b; q->len += len; if(q->state & Qstarve){ @@ -506,8 +519,11 @@ qwrite(Queue *q, char *p, int len) unlock(q); splx(x); - if(dowakeup) + if(dowakeup){ + if(q->kick) + (*q->kick)(q->arg); wakeup(&q->rr); + } return len; } @@ -570,6 +586,7 @@ void qreopen(Queue *q) { q->state &= ~Qclosed; + q->state |= Qstarve; } /* @@ -580,3 +597,12 @@ qlen(Queue *q) { return q->len; } + +/* + * return true if we can read without blocking + */ +int +qcanread(Queue *q) +{ + return q->bfirst!=0; +}