From cdc029fc77e36fffe9b7ccc1d64299759fe98c77 Mon Sep 17 00:00:00 2001 From: David du Colombier <0intro@gmail.com> Date: Sun, 6 Oct 1991 00:00:00 +0000 Subject: [PATCH] Plan 9 from Bell Labs 1991-10-06 --- pc/devfloppy.c | 35 +++++++++++++---- port/devkprof.c | 101 ++++++++++++++++++++++-------------------------- port/proc.c | 27 ++++++------- ss/clock.c | 1 + ss/l.s | 6 +++ 5 files changed, 95 insertions(+), 75 deletions(-) diff --git a/pc/devfloppy.c b/pc/devfloppy.c index 6809c2c30f86ec71af1bd7de9385881ac4f23fa5..d0984cd7d591dd7ac728f08a520db90cbe222aaa 100644 --- a/pc/devfloppy.c +++ b/pc/devfloppy.c @@ -175,6 +175,7 @@ static long floppyseek(Drive*, long); static int floppysense(void); static void floppywait(void); static long floppyxfer(Drive*, int, void*, long, long); +static long floppythrice(Drive*, int, void*, long, long); static int cmddone(void*); void Xdelay(int); @@ -387,7 +388,7 @@ floppyread(Chan *c, void *a, long n) */ if(dp->ccyl!=cyl || dp->chead!=head){ dp->ccyl = -1; - i = floppyxfer(dp, Fread, dp->cache, + i = floppythrice(dp, Fread, dp->cache, (cyl*dp->t->heads+head)*nn, nn); if(i != nn){ if(i == 0) @@ -420,7 +421,6 @@ floppywrite(Chan *c, void *a, long n) long rv, i; char *aa = a; int dev; -extern void vgaset(char*); rv = 0; dp = &fl.d[c->qid.path & ~Qmask]; @@ -438,10 +438,12 @@ extern void vgaset(char*); floppypos(dp, c->offset+rv); if(dp->tcyl == dp->ccyl) dp->ccyl = -1; - i = floppyxfer(dp, Fwrite, aa+rv, c->offset+rv, + i = floppythrice(dp, Fwrite, aa+rv, c->offset+rv, n-rv); - if(i <= 0) + if(i < 0) break; + if(i == 0) + error(Eio); } qunlock(&fl); poperror(); @@ -453,8 +455,6 @@ extern void vgaset(char*); } else if(SNCMP(aa, "reset") == 0){ fl.confused = 1; floppyon(dp); - } else if(SNCMP(aa, "v") == 0){ - vgaset(aa+1); } qunlock(&fl); break; @@ -755,6 +755,27 @@ floppyseek(Drive *dp, long off) return dp->cyl; } +/* + * since floppies are so flakey, try 3 times before giving up + */ +static long +floppythrice(Drive *dp, int cmd, void *a, long off, long n) +{ + int tries; + long rv; + + for(tries = 0; ; tries++){ + if(waserror()){ + if(strcmp(u->error, errstrtab[Eintr])==0 || tries > 3) + nexterror(); + } else { + rv = floppyxfer(dp, cmd, a, off, n); + poperror(); + return rv; + } + } +} + static long floppyxfer(Drive *dp, int cmd, void *a, long off, long n) { @@ -830,8 +851,6 @@ floppyxfer(Drive *dp, int cmd, void *a, long off, long n) offset = offset*dp->t->sectors + fl.stat[5] - 1; offset = offset * c2b[fl.stat[6]]; if(offset != off+dp->len){ - print("new offset %d instead of %d\n", offset, off+dp->len); - print(" %d %d %d\n", fl.stat[3], fl.stat[4], fl.stat[5]); dp->confused = 1; errors("floppy drive lost"); } diff --git a/port/devkprof.c b/port/devkprof.c index 680986450445660df6831831741795c01d777546..bf9cf4257abf49fcc226e532a8cbe91b17b8ca27 100644 --- a/port/devkprof.c +++ b/port/devkprof.c @@ -7,27 +7,26 @@ #include "devtab.h" -#define MAXPC (100*1024L) -#define RES 8 -#define LRES 3 -#define NBUF (MAXPC>>LRES) +#define LRES 3 /* log of PC resolution */ -long timerbuf[NBUF]; +struct{ + int minpc; + int maxpc; + int nbuf; + int time; + ulong *buf; +}kprof; enum{ Kprofdirqid, Kprofdataqid, - Kprofstartqid, - Kprofstartclrqid, - Kprofstopqid, - Nkproftab=Kprofstopqid, + Kprofctlqid, + Nkproftab=Kprofctlqid, Kprofmaxqid, }; Dirtab kproftab[Nkproftab]={ - "kpdata", {Kprofdataqid}, NBUF*sizeof timerbuf[0], 0600, - "kpstart", {Kprofstartqid}, 0, 0600, - "kpstartclr", {Kprofstartclrqid}, 0, 0600, - "kpstop", {Kprofstopqid}, 0, 0600, + "kpdata", {Kprofdataqid}, 0, 0600, + "kpctl", {Kprofctlqid}, 0, 0600, }; void kproftimer(ulong); @@ -35,21 +34,22 @@ void kproftimer(ulong); void kprofreset(void) { - kprofp = kproftimer; + kprof.minpc = KTZERO; + kprof.maxpc = (ulong)&etext; + kprof.nbuf = (kprof.maxpc-kprof.minpc) >> LRES; + kprof.buf = ialloc(kprof.nbuf*sizeof kprof.buf[0], 0); + kproftab[0].length = kprof.nbuf*sizeof kprof.buf[0]; } void kprofinit(void) { - extern void *etext; - if((((unsigned long)&etext)-KTZERO)>MAXPC) - print("kernel profiling limited to %lud\n", MAXPC); } Chan * kprofattach(char *spec) { - return devattach('t', spec); + return devattach('T', spec); } Chan * kprofclone(Chan *c, Chan *nc) @@ -72,9 +72,9 @@ kprofstat(Chan *c, char *db) Chan * kprofopen(Chan *c, int omode) { - if(c->qid == CHDIR){ + if(c->qid.path == CHDIR){ if(omode != OREAD) - error(0, Eperm); + error(Eperm); } c->mode = openmode(omode); c->flag |= COPEN; @@ -85,19 +85,19 @@ kprofopen(Chan *c, int omode) void kprofcreate(Chan *c, char *name, int omode, ulong perm) { - error(0, Eperm); + error(Eperm); } void kprofremove(Chan *c) { - error(0, Eperm); + error(Eperm); } void kprofwstat(Chan *c, char *dp) { - error(0, Eperm); + error(Eperm); } void @@ -105,32 +105,22 @@ kprofclose(Chan *c) { } -void -kprofuserstr(Error *e, char *buf) -{ - consuserstr(e, buf); -} - -void -kproferrstr(Error *e, char *buf) -{ - rooterrstr(e, buf); -} - long kprofread(Chan *c, void *a, long n, ulong offset) { - switch((int)(c->qid&~CHDIR)){ + ulong end; + switch((int)(c->qid.path&~CHDIR)){ case Kprofdirqid: return devdirread(c, a, n, kproftab, Nkproftab, devgen); case Kprofdataqid: - if(offset >= NBUF*sizeof timerbuf[0]){ + end = kprof.nbuf*sizeof kprof.buf[0]; + if(offset >= end){ n = 0; break; } - if(offset+n > NBUF*sizeof timerbuf[0]) - n = NBUF*sizeof timerbuf[0]-offset; - memmove(a, ((char *)timerbuf)+offset, n); + if(offset+n > end) + n = end-offset; + memmove(a, ((char *)kprof.buf)+offset, n); break; default: n=0; @@ -142,17 +132,18 @@ kprofread(Chan *c, void *a, long n, ulong offset) long kprofwrite(Chan *c, char *a, long n, ulong offset) { - switch((int)(c->qid&~CHDIR)){ - case Kprofstartclrqid: - memset((char *)timerbuf, 0, NBUF*sizeof timerbuf[0]); - case Kprofstartqid: - duartstarttimer(); - break; - case Kprofstopqid: - duartstoptimer(); + switch((int)(c->qid.path&~CHDIR)){ + case Kprofctlqid: + if(strncmp(a, "startclr", 8) == 0){ + memset((char *)kprof.buf, 0, kprof.nbuf*sizeof kprof.buf[0]); + kprof.time = 1; + }else if(strncmp(a, "start", 5) == 0) + kprof.time = 1; + else if(strncmp(a, "stop", 4) == 0) + kprof.time = 0; break; default: - error(0, Ebadusefd); + error(Ebadusefd); } return n; } @@ -160,6 +151,8 @@ kprofwrite(Chan *c, char *a, long n, ulong offset) void kproftimer(ulong pc) { + if(kprof.time == 0) + return; /* * if the pc is coming out of slplo pr splx, then use * the pc saved when we went splhi. @@ -167,11 +160,11 @@ kproftimer(ulong pc) if(pc>=(ulong)spllo && pc<=(ulong)spldone) pc = m->splpc; - timerbuf[0]++; - if(KTZERO<=pc && pc>= LRES; - timerbuf[pc]++; + kprof.buf[pc]++; } else - timerbuf[1]++; + kprof.buf[1]++; } diff --git a/port/proc.c b/port/proc.c index af62434879631063a065d9e9c19e20b9a11d56ee..7474e30190cb5781a9798eb6092495b9f10a7e4e 100644 --- a/port/proc.c +++ b/port/proc.c @@ -522,19 +522,19 @@ pexit(char *exitstr, int freemem) if(c->fgrp) closefgrp(c->fgrp); - wq = newwaitq(); - wq->w.pid = c->pid; - wq->w.time[TUser] = TK2MS(c->time[TUser]); - wq->w.time[TCUser] = TK2MS(c->time[TCUser]); - wq->w.time[TSys] = TK2MS(c->time[TSys]); - wq->w.time[TCSys] = TK2MS(c->time[TCSys]); - wq->w.time[TReal] = TK2MS(MACHP(0)->ticks - c->time[TReal]); - if(exitstr) - strncpy(wq->w.msg, exitstr, ERRLEN); - else - wq->w.msg[0] = '\0'; - if(c->kp == 0) { + wq = newwaitq(); + wq->w.pid = c->pid; + wq->w.time[TUser] = TK2MS(c->time[TUser]); + wq->w.time[TCUser] = TK2MS(c->time[TCUser]); + wq->w.time[TSys] = TK2MS(c->time[TSys]); + wq->w.time[TCSys] = TK2MS(c->time[TCSys]); + wq->w.time[TReal] = TK2MS(MACHP(0)->ticks - c->time[TReal]); + if(exitstr) + strncpy(wq->w.msg, exitstr, ERRLEN); + else + wq->w.msg[0] = '\0'; + /* Find my parent */ p = c->parent; lock(&p->exl); @@ -568,7 +568,8 @@ pexit(char *exitstr, int freemem) putseg(os); } closepgrp(c->pgrp); - closeegrp(c->egrp); + if(c->egrp) + closeegrp(c->egrp); close(u->dot); lock(&c->exl); /* Prevent my children from leaving waits */ diff --git a/ss/clock.c b/ss/clock.c index e102b96f8c57c5a36970f960014d1a852f501f70..d66bf8ce76810b01f4261026cd0c7130e1624e58 100644 --- a/ss/clock.c +++ b/ss/clock.c @@ -57,6 +57,7 @@ clock(Ureg *ur) kbdclock(); mouseclock(); sccclock(); + kproftimer(ur->pc); if((ur->psr&SPL(0xF))==0 && p && p->state==Running){ if(anyready()){ if(p->hasspin) diff --git a/ss/l.s b/ss/l.s index dfdbc0c5016128fff29a1cb33703eef6f3c72259..04d668ff4a119a3a937385f9fb3ab7a29441cbd3 100644 --- a/ss/l.s +++ b/ss/l.s @@ -98,6 +98,7 @@ TEXT spllo(SB), $0 TEXT splhi(SB), $0 + MOVW R15, 4(R(MACH)) /* save PC in m->splpc */ MOVW PSR, R7 MOVW R7, R10 AND $~PSRET, R10 /* BUG: book says this is buggy */ @@ -109,6 +110,7 @@ TEXT splhi(SB), $0 TEXT splx(SB), $0 + MOVW R15, 4(R(MACH)) /* save PC in m->splpc */ MOVW psr+0(FP), R7 MOVW R7, PSR /* BUG: book says this is buggy */ OR R0, R0 @@ -116,6 +118,10 @@ TEXT splx(SB), $0 OR R0, R0 RETURN +TEXT spldone(SB), $0 + + RETURN + TEXT touser(SB), $-4 MOVW $(SYSPSR&~PSREF), R7 MOVW R7, PSR