M pc/devfloppy.c => pc/devfloppy.c +27 -8
@@ 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");
}
M port/devkprof.c => port/devkprof.c +47 -54
@@ 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<KTZERO+MAXPC){
- pc -= KTZERO;
+ kprof.buf[0]++;
+ if(kprof.minpc<=pc && pc<kprof.maxpc){
+ pc -= kprof.minpc;
pc >>= LRES;
- timerbuf[pc]++;
+ kprof.buf[pc]++;
} else
- timerbuf[1]++;
+ kprof.buf[1]++;
}
M port/proc.c => port/proc.c +14 -13
@@ 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 */
M ss/clock.c => ss/clock.c +1 -0
@@ 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)
M ss/l.s => ss/l.s +6 -0
@@ 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