M gnot/dat.h => gnot/dat.h +0 -15
@@ 339,20 339,6 @@ struct Proc
ulong pc; /* DEBUG only */
};
-struct MMU
-{
- ulong va;
- ulong pa;
- int pid;
-};
-
-#define NMMU 16
-struct MMUCache
-{
- ulong next;
- MMU mmu[NMMU];
-};
-
#define NERR 15
#define NNOTE 5
#define NFD 100
@@ 376,7 362,6 @@ struct User
short nnote;
short notified; /* sysnoted is due */
int (*notify)(void*, char*);
- MMUCache mc;
void *ureg;
};
M gnot/main.c => gnot/main.c +0 -1
@@ 155,7 155,6 @@ userinit(void)
k = kmap(p->upage);
up = (User*)VA(k);
up->p = p;
- up->mc.next = 0;
kunmap(k);
/*
A gnot/malloc.h => gnot/malloc.h +15 -0
@@ 0,0 1,15 @@
+struct tbl_entry {
+ struct tbl_entry *next; /* free list */
+ int *data; /* data */
+};
+
+struct table {
+ int size; /* # entries */
+ struct tbl_entry *entries; /* the entries */
+ struct tbl_entry *free; /* the free list */
+};
+
+void *tbl_alloc(struct table *, int);
+void tbl_free(struct table *, void *);
+int tbl_index(struct table *, void *);
+void *tbl_data(struct table *, int);
M gnot/mmu.c => gnot/mmu.c +0 -39
@@ 12,17 12,6 @@ struct
KMap arena[4*1024*1024/BY2PG]; /* kernel mmu maps up to 4MB */
}kmapalloc;
-void
-putxmmu(ulong tlbvirt, ulong tlbphys, int pid)
-{
- if(pid != u->p->pid)
- panic("putxmmu %ld %ld\n", pid, u->p->pid);
- if(tlbvirt&KZERO)
- panic("putmmu");
- tlbphys |= VTAG(tlbvirt)<<24;
- UMAP[(tlbvirt&0x003FE000L)>>2] = tlbphys;
-}
-
/*
* Called splhi, not in Running state
*/
@@ 39,18 28,6 @@ mapstack(Proc *p)
putkmmu(tlbvirt, tlbphys);
flushmmu();
u = (User*)USERADDR;
-
- /*
- * preload the MMU with the last (up to) NMMU user entries
- * previously faulted into it for this process.
- */
- if(u->mc.next >= NMMU){
- u->mc.next &= NMMU - 1;
- for(i = u->mc.next; i < NMMU; i++)
- putxmmu(u->mc.mmu[i].va, u->mc.mmu[i].pa, u->mc.mmu[i].pid);
- }
- for(i = 0; i < u->mc.next; i++)
- putxmmu(u->mc.mmu[i].va, u->mc.mmu[i].pa, u->mc.mmu[i].pid);
}
void
@@ 67,14 44,6 @@ putmmu(ulong tlbvirt, ulong tlbphys)
{
if(tlbvirt&KZERO)
panic("putmmu");
- if(u){
- MMU *mp;
- mp = &(u->mc.mmu[u->mc.next&(NMMU-1)]);
- mp->pa = tlbphys;
- mp->va = tlbvirt;
- mp->pid = u->p->pid;
- u->mc.next++;
- }
tlbphys |= VTAG(tlbvirt)<<24;
UMAP[(tlbvirt&0x003FE000L)>>2] = tlbphys;
}
@@ 88,14 57,6 @@ flushmmu(void)
}
void
-clearmmucache(void)
-{
- if(u == 0)
- panic("flushmmucache");
- u->mc.next = 0;
-}
-
-void
kmapinit(void)
{
KMap *k;
M gnot/proc.c => gnot/proc.c +0 -1
@@ 621,7 621,6 @@ kproc(char *name, void (*func)(void *), void *arg)
/*
* Save time: only copy u-> data and useful stack
*/
- clearmmucache();
memcpy(up, u, sizeof(User));
n = USERADDR+BY2PG - (ulong)&lastvar;
n = (n+32) & ~(BY2WD-1); /* be safe & word align */
M gnot/stream.c => gnot/stream.c +35 -28
@@ 878,6 878,28 @@ stringread(Chan *c, uchar *buf, long n, char *str)
}
/*
+ * return the stream id
+ */
+long
+streamctlread(Chan *c, void *vbuf, long n)
+{
+ uchar *buf = vbuf;
+ char num[32];
+ Stream *s;
+
+ s = c->stream;
+ if(STREAMTYPE(c->qid) == Sctlqid){
+ sprint(num, "%d", s->id);
+ return stringread(c, buf, n, num);
+ } else {
+ if(CHDIR & c->qid)
+ return devdirread(c, vbuf, n, 0, 0, streamgen);
+ else
+ panic("streamctlread");
+ }
+}
+
+/*
* return true if there is an output buffer available
*/
static int
@@ 895,28 917,16 @@ streamread(Chan *c, void *vbuf, long n)
Block *bp;
Stream *s;
Queue *q;
- long rv = 0;
- int left, i, x;
+ int left, i;
uchar *buf = vbuf;
- char num[32];
- s = c->stream;
- switch(STREAMTYPE(c->qid)){
- case Sdataqid:
- break;
- case Sctlqid:
- sprint(num, "%d", s->id);
- return stringread(c, buf, n, num);
- default:
- if(CHDIR & c->qid)
- return devdirread(c, vbuf, n, 0, 0, streamgen);
- else
- panic("streamread");
- }
+ if(STREAMTYPE(c->qid) != Sdataqid)
+ return streamctlread(c, vbuf, n);
/*
* one reader at a time
*/
+ s = c->stream;
qlock(&s->rdlock);
if(waserror()){
qunlock(&s->rdlock);
@@ 974,10 984,15 @@ streamread(Chan *c, void *vbuf, long n)
* This routing is entrered with s->wrlock'ed and must unlock.
*/
static long
-streamctlwrite(Stream *s, void *a, long n)
+streamctlwrite(Chan *c, void *a, long n)
{
Qinfo *qi;
Block *bp;
+ Stream *s;
+
+ if(STREAMTYPE(c->qid) != Sctlqid)
+ panic("streamctlwrite %lux", c->qid);
+ s = c->stream;
/*
* package
@@ 1040,15 1055,8 @@ streamwrite(Chan *c, void *a, long n, int docopy)
/*
* decode the qid
*/
- switch(STREAMTYPE(c->qid)){
- case Sdataqid:
- break;
- case Sctlqid:
- n = streamctlwrite(s, a, n);
- goto out;
- default:
- panic("bad stream qid\n");
- }
+ if(STREAMTYPE(c->qid) != Sdataqid)
+ return streamctlwrite(c, a, n);
/*
* No writes allowed on hungup channels
@@ 1057,7 1065,7 @@ streamwrite(Chan *c, void *a, long n, int docopy)
if(q->other->flag & QHUNGUP)
error(0, Ehungup);
- if((GLOBAL(a) && !docopy) || n==0){
+ if(!docopy && GLOBAL(a)){
/*
* `a' is global to the whole system, just create a
* pointer to it and pass it on.
@@ 1094,7 1102,6 @@ streamwrite(Chan *c, void *a, long n, int docopy)
}
}
}
-out:
return n;
}
M gnot/sturp.c => gnot/sturp.c +63 -35
@@ 33,6 33,7 @@ struct urpstat {
} urpstat;
struct Urp {
+ QLock;
short state; /* flags */
Rendez r; /* process waiting for close */
@@ 51,11 52,11 @@ struct Urp {
int maxout; /* maximum outstanding unacked blocks */
int maxblock; /* max block size */
int next; /* next block to send */
- int tofree; /* first block to be freed (unacked is first not to) */
int unechoed; /* first unechoed block */
int unacked; /* first unacked block */
int nxb; /* next xb to use */
Block *xb[8]; /* the xmit window buffer */
+ QLock xl[8];
ulong timer; /* timeout for xmit */
int rexmit;
@@ 96,7 97,6 @@ struct Urp {
#define CLOSING 0x10
Urp *urp;
-Lock urpalloc;
/*
* predeclared
@@ 112,7 112,7 @@ static void sendblock(Urp*, int);
static void rcvack(Urp*, int);
static void flushinput(Urp*);
static void sendctl(Urp*, int);
-static void sendack(Urp*, int);
+static void sendack(Urp*);
static void sendrej(Urp*);
static void initoutput(Urp*, int);
static void initinput(Urp*, int);
@@ 139,14 139,15 @@ urpopen(Queue *q, Stream *s)
/*
* find a free urp structure
*/
- lock(&urpalloc);
- for(up = urp; up < &urp[conf.nurp]; up++)
+ for(up = urp; up < &urp[conf.nurp]; up++){
+ qlock(up);
if(up->state == 0)
break;
+ qunlock(up);
+ }
if(up == &urp[conf.nurp]){
q->ptr = 0;
WR(q)->ptr = 0;
- unlock(&urpalloc);
error(0, Egreg);
}
@@ 154,7 155,7 @@ urpopen(Queue *q, Stream *s)
up->rq = q;
up->wq = q->other;
up->state = OPEN;
- unlock(&urpalloc);
+ qunlock(up);
initinput(up, 0);
initoutput(up, 0);
@@ 339,8 340,12 @@ urpciput(Queue *q, Block *bp)
case SEQ+0: case SEQ+1: case SEQ+2: case SEQ+3:
case SEQ+4: case SEQ+5: case SEQ+6: case SEQ+7:
+ qlock(&up->ack);
+ i = ctl & Nmask;
+ if(!QFULL(q->next))
+ sendctl(up, up->lastecho = ECHO+i);
up->iseq = i;
- sendack(up, ECHO);
+ qunlock(&up->ack);
break;
}
}
@@ 510,8 515,11 @@ urpiput(Queue *q, Block *bp)
/*
* acknowledge receipt
*/
+ qlock(&up->ack);
up->iseq = i;
- sendack(up, ECHO);
+ if(!QFULL(q->next))
+ sendctl(up, up->lastecho = ECHO|i);
+ qunlock(&up->ack);
break;
}
}
@@ 591,7 599,8 @@ output(Urp *up)
int n;
int i;
- qlock(&up->xmit);
+ if(!canqlock(&up->xmit))
+ return;
if(waserror()){
print("urp output error\n");
@@ 656,26 665,22 @@ output(Urp *up)
}
/*
- * free any blocks that can be freed
- */
- while(up->tofree != up->unacked){
- if(up->xb[up->tofree] == 0)
- urpvomit("output2", up);
- else
- freeb(up->xb[up->tofree]);
- up->xb[up->tofree] = 0;
- up->tofree = NEXT(up->tofree);
- }
-
- /*
* if there's a window open, push some blocks out
*
* the lock is to synchronize with acknowledges that free
* blocks.
*/
while(WINDOW(up)>0 && up->next!=up->nxb){
- sendblock(up, up->next);
+ i = up->next;
+ qlock(&up->xl[i]);
+ if(waserror()){
+ qunlock(&up->xl[i]);
+ nexterror();
+ }
+ sendblock(up, i);
+ qunlock(&up->xl[i]);
up->next = NEXT(up->next);
+ poperror();
}
out:
qunlock(&up->xmit);
@@ 708,10 713,9 @@ static void
sendrej(Urp *up)
{
Queue *q = up->wq;
-
flushinput(up);
qlock(&up->ack);
- if(!QFULL(up->rq->next) && (up->lastecho&~Nmask)==ECHO){
+ if((up->lastecho&~Nmask) == ECHO){
DPRINT("REJ %d\n", up->iseq);
sendctl(up, up->lastecho = REJ|up->iseq);
}
@@ 722,13 726,31 @@ sendrej(Urp *up)
* send an acknowledge
*/
static void
-sendack(Urp *up, int type)
+sendack(Urp *up)
{
Block *bp;
- qlock(&up->ack);
- if(!QFULL(up->rq->next) && (up->lastecho&Nmask)!=up->iseq)
- sendctl(up, up->lastecho = type|up->iseq);
+ /*
+ * check the precondition for acking
+ */
+ if(QFULL(up->rq->next) || (up->lastecho&Nmask)==up->iseq)
+ return;
+
+ if(!canqlock(&up->ack))
+ return;
+
+ /*
+ * check again now that we've locked
+ */
+ if(QFULL(up->rq->next) || (up->lastecho&Nmask)==up->iseq){
+ qunlock(&up->ack);
+ return;
+ }
+
+ /*
+ * send the ack
+ */
+ sendctl(up, up->lastecho = ECHO|up->iseq);
qunlock(&up->ack);
}
@@ 792,8 814,16 @@ rcvack(Urp *up, int msg)
* release any acknowledged blocks
*/
if(IN(seqno, up->unacked, up->next)){
- for(; up->unacked != next; up->unacked = NEXT(up->unacked))
+ for(; up->unacked != next; up->unacked = NEXT(up->unacked)){
i = up->unacked;
+ qlock(&up->xl[i]);
+ if(up->xb[i])
+ freeb(up->xb[i]);
+ else
+ urpvomit("rcvack", up);
+ up->xb[i] = 0;
+ qunlock(&up->xl[i]);
+ }
}
switch(msg & 0370){
@@ 849,7 879,6 @@ initoutput(Urp *up, int window)
{
int i;
- qlock(&up->xmit);
/*
* set output window
*/
@@ 862,7 891,6 @@ initoutput(Urp *up, int window)
/*
* set sequence varialbles
*/
- up->tofree = 1;
up->unechoed = 1;
up->unacked = 1;
up->next = 1;
@@ 873,9 901,11 @@ initoutput(Urp *up, int window)
* free any outstanding blocks
*/
for(i = 0; i < 8; i++){
+ qlock(&up->xl[i]);
if(up->xb[i])
freeb(up->xb[i]);
up->xb[i] = 0;
+ qunlock(&up->xl[i]);
}
/*
@@ 883,7 913,6 @@ initoutput(Urp *up, int window)
*/
up->state |= INITING;
up->timer = NOW + MSrexmit;
- qunlock(&up->xmit);
sendctl(up, INIT1);
}
@@ 916,7 945,6 @@ todo(void *arg)
return (up->state&INITING)
? NOW>up->timer /* time to INIT1 */
: ((up->unacked!=up->next && NOW>up->timer) /* time to ENQ */
- || up->tofree != up->unacked
|| WINDOW(up)>0 && up->next!=up->nxb
|| (!QFULL(up->rq->next) && up->iseq!=(up->lastecho&7))); /* time to ECHO */
}
@@ 938,7 966,7 @@ urpkproc(void *arg)
if(up->state & HUNGUP)
break;
if(!QFULL(up->rq->next))
- sendack(up, ECHO);
+ sendack(up);
output(up);
sleep(&up->rq->r, todo, up);
}
M gnot/sysfile.c => gnot/sysfile.c +3 -3
@@ 31,12 31,12 @@ fdtochan(int fd, int mode)
if(fd<0 || NFD<=fd || (c=u->fd[fd])==0)
error(0, Ebadfd);
- if(mode<0 || c->mode == 2)
+ if(mode<0 || c->mode==ORDWR)
return c;
- if((mode&16) && c->mode==0)
+ if((mode&OTRUNC) && c->mode==OREAD)
err:
error(0, Ebadusefd);
- if((mode&~16) != c->mode)
+ if((mode&~OTRUNC) != c->mode)
goto err;
return c;
}
M gnot/sysproc.c => gnot/sysproc.c +0 -2
@@ 41,7 41,6 @@ sysfork(ulong *arg)
/*
* Save time: only copy u-> data and useful stack
*/
- clearmmucache();
memcpy((void*)upa, u, sizeof(User));
n = USERADDR+BY2PG - (ulong)&lastvar;
n = (n+32) & ~(BY2WD-1); /* be safe & word align */
@@ 362,7 361,6 @@ sysexec(ulong *arg)
unlock(o);
flushmmu();
- clearmmucache();
((Ureg*)UREGADDR)->pc = exec.entry;
sp = (ulong*)(USTKTOP - ssize);
*--sp = nargs;
M port/devcons.c => port/devcons.c +23 -14
@@ 36,6 36,18 @@ struct IOQ{
IOQ kbdq; /* qlock to getc; interrupt putc's */
IOQ lineq; /* lock to getc; interrupt putc's */
+#define SYSLOGMAGIC 0x23456789
+#define SYSLOG ((Syslog *)(UNCACHED | KZERO | 0x1B00))
+typedef struct Syslog Syslog;
+struct Syslog
+{
+ ulong magic;
+ char *start;
+ char *next;
+ char buf[2*BY2PG - 3*BY2WD];
+};
+
+
void
printinit(void)
{
@@ 55,6 67,7 @@ printinit(void)
unlock(&lineq);
duartinit();
+ sysloginit(); /* must be at the end of printinit */
}
/*
@@ 164,12 177,15 @@ panic(char *fmt, ...)
{
char buf[PRINTSIZE];
int n;
+ Syslog *s;
strcpy(buf, "panic: ");
n = doprint(buf+7, buf+sizeof(buf), fmt, (&fmt+1)) - buf;
buf[n] = '\n';
putstrn(buf, n+1);
dumpstack();
+ s = SYSLOG;
+ print("start/next is %lux/%lux\n", s->start, s->next);
exit();
}
@@ 598,30 614,23 @@ consuserstr(Error *e, char *buf)
/*
* kernel based system log, passed between crashes
*/
-#define SYSLOGMAGIC 0x23456789
-#define SYSLOG ((Syslog *)(UNCACHED | KZERO | 0x1B00))
-typedef struct Syslog Syslog;
-struct Syslog
-{
- ulong magic;
- char *start;
- char *next;
- char buf[BY2PG - 3*BY2WD];
-};
-
void
sysloginit(void)
{
Syslog *s;
- char *p;
+ char *start, *next;
s = SYSLOG;
- if(s->magic!=SYSLOGMAGIC || s->next>=&s->buf[sizeof(s->buf)]
- || s->start>=&s->buf[sizeof(s->buf)] || s->next<s->buf){
+ next = s->next;
+ start = s->start;
+ if(s->magic!=SYSLOGMAGIC || next>=&s->buf[sizeof(s->buf)]
+ || start>=&s->buf[sizeof(s->buf)] || next<s->buf){
s->start = s->buf;
s->next = s->buf;
s->magic = SYSLOGMAGIC;
}
+ print("start/next is %lux/%lux was %lux/%lux\n", s->start, s->next,
+ start, next);
}
void
M port/devkprof.c => port/devkprof.c +2 -0
@@ 157,6 157,8 @@ kprofwrite(Chan *c, char *a, long n)
void
kproftimer(ulong pc)
{
+ extern ulong splpc;
+
timerbuf[0]++;
if(KTZERO<=pc && pc<KTZERO+MAXPC){
pc -= KTZERO;
M port/pgrp.c => port/pgrp.c +1 -0
@@ 103,6 103,7 @@ loop:
if(m = mountalloc.free){ /* assign = */
mountalloc.free = m->next;
m->ref = 1;
+ m->next = 0;
m->mountid = ++mountalloc.mountid;
unlock(&mountalloc);
return m;
M power/main.c => power/main.c +0 -1
@@ 47,7 47,6 @@ main(void)
active.machs = 1;
confinit();
arginit();
- sysloginit();
lockinit();
printinit();
tlbinit();