M gnot/chan.c => gnot/chan.c +1 -1
@@ 447,7 447,7 @@ namec(char *name, int amode, int omode, ulong perm)
mntok = 0;
if(!((ulong)name & KZERO))
validaddr((ulong)(name+1), 2, 0);
- if(name[1]=='|' || ('A'<=name[1] && name[1]<='Z'))
+ if(name[1]=='|' || name[1]=='M')
error(0, Enonexist);
t = devno(name[1], 1);
if(t == -1)
M gnot/dat.h => gnot/dat.h +2 -0
@@ 80,6 80,8 @@ struct Alarm
};
#define CHDIR 0x80000000L
+#define CHAPPEND 0x40000000L
+#define CHEXCL 0x20000000L
#define QPATH 0x0000FFFFL
struct Chan
{
M gnot/devcons.c => gnot/devcons.c +48 -21
@@ 17,7 17,7 @@ static struct
typedef struct IOQ IOQ;
-#define NQ 1024
+#define NQ 2048
struct IOQ{
union{
Lock;
@@ 100,8 100,9 @@ putstrn(char *str, long n)
}
int
-cangetc(IOQ *q)
+cangetc(void *arg)
{
+ IOQ *q = (IOQ *)arg;
int n = q->in - q->out;
if (n < 0)
n += sizeof(q->buf);
@@ 109,14 110,16 @@ cangetc(IOQ *q)
}
int
-canputc(IOQ *q)
+canputc(void *arg)
{
+ IOQ *q = (IOQ *)arg;
return sizeof(q->buf)-cangetc(q)-1;
}
int
-isbrkc(IOQ *q)
+isbrkc(void *arg)
{
+ IOQ *q = (IOQ *)arg;
uchar *p;
for(p=q->out; p!=q->in; ){
@@ 352,21 355,25 @@ enum{
Qtime,
Quser,
Qklog,
+ Qmsec,
+ Qclock,
};
Dirtab consdir[]={
- "cons", Qcons, 0, 0600,
- "cputime", Qcputime, 72, 0600,
- "null", Qnull, 0, 0600,
- "pgrpid", Qpgrpid, 12, 0600,
- "pid", Qpid, 12, 0600,
- "ppid", Qppid, 12, 0600,
- "rcons", Qrcons, 0, 0600,
- "rs232", Qrs232, 0, 0600,
- "rs232ctl", Qrs232ctl, 0, 0600,
- "time", Qtime, 12, 0600,
- "user", Quser, 0, 0600,
- "klog", Qklog, 0, 0400,
+ "cons", Qcons, 0, 0600,
+ "cputime", Qcputime, 6*NUMSIZE, 0600,
+ "null", Qnull, 0, 0600,
+ "pgrpid", Qpgrpid, NUMSIZE, 0600,
+ "pid", Qpid, NUMSIZE, 0600,
+ "ppid", Qppid, NUMSIZE, 0600,
+ "rcons", Qrcons, 0, 0600,
+ "rs232", Qrs232, 0, 0600,
+ "rs232ctl", Qrs232ctl, 0, 0600,
+ "time", Qtime, NUMSIZE, 0600,
+ "user", Quser, 0, 0600,
+ "klog", Qklog, 0, 0400,
+ "msec", Qmsec, NUMSIZE, 0400,
+ "clock", Qclock, 2*NUMSIZE, 0400,
};
#define NCONS (sizeof consdir/sizeof(Dirtab))
@@ 520,7 527,7 @@ consread(Chan *c, void *buf, long n)
nexterror();
}
while(!cangetc(&lineq)){
- sleep(&kbdq.r, (int(*)(void*))isbrkc, &kbdq);
+ sleep(&kbdq.r, isbrkc, &kbdq);
do{
lock(&lineq);
ch = getc(&kbdq);
@@ 567,12 574,13 @@ consread(Chan *c, void *buf, long n)
nexterror();
}
while(!cangetc(&rs232iq))
- sleep(&rs232iq.r, (int(*)(void*))cangetc, &rs232iq);
+ sleep(&rs232iq.r, cangetc, &rs232iq);
for(i=0; i<n; i++){
if((ch=getc(&rs232iq)) == -1)
break;
*cbuf++ = ch;
}
+ poperror();
qunlock(&rs232iq);
return i;
@@ 606,7 614,20 @@ consread(Chan *c, void *buf, long n)
return readnum(c->offset, buf, n, u->p->parentpid, NUMSIZE);
case Qtime:
- return readnum(c->offset, buf, n, boottime+TK2SEC(MACHP(0)->ticks), 12);
+ return readnum(c->offset, buf, n, boottime+TK2SEC(MACHP(0)->ticks), NUMSIZE);
+
+ case Qmsec:
+ return readnum(c->offset, buf, n, TK2MS(MACHP(0)->ticks), NUMSIZE);
+ case Qclock:
+ k = c->offset;
+ if(k >= 2*NUMSIZE)
+ return 0;
+ if(k+n > 2*NUMSIZE)
+ n = 2*NUMSIZE - k;
+ readnum(0, tmp, NUMSIZE, MACHP(0)->ticks, NUMSIZE);
+ readnum(0, tmp+NUMSIZE, NUMSIZE, HZ, NUMSIZE);
+ memcpy(buf, tmp+k, n);
+ return n;
case Quser:
return readstr(c->offset, buf, n, u->p->pgrp->user);
@@ 621,12 642,13 @@ consread(Chan *c, void *buf, long n)
nexterror();
}
while(!cangetc(&klogq))
- sleep(&klogq.r, (int(*)(void*))cangetc, &klogq);
+ sleep(&klogq.r, cangetc, &klogq);
for(i=0; i<n; i++){
if((ch=getc(&klogq)) == -1)
break;
*cbuf++ = ch;
}
+ poperror();
qunlock(&klogq);
return i;
@@ 664,10 686,14 @@ conswrite(Chan *c, void *va, long n)
case Qrs232:
qlock(&rs232oq);
+ if(waserror()){
+ qunlock(&rs232oq);
+ nexterror();
+ }
l = n;
while(--l >= 0) {
while (putc(&rs232oq, *a) < 0)
- sleep(&rs232oq.r, (int(*)(void*))canputc, &rs232oq);
+ sleep(&rs232oq.r, canputc, &rs232oq);
a++;
if(rs232oq.state == 0){
splhi();
@@ 678,6 704,7 @@ conswrite(Chan *c, void *va, long n)
spllo();
}
}
+ poperror();
qunlock(&rs232oq);
break;
M gnot/devdk.c => gnot/devdk.c +10 -4
@@ 6,8 6,9 @@
#include "io.h"
#include "errno.h"
-#define NOW (MACHP(0)->ticks)
-#define DPRINT if(0)
+#define DPRINT if(0) /*kprint*/
+
+#define NOW (MACHP(0)->ticks)
enum {
/*
@@ 477,6 478,8 @@ dkmuxconfig(Dk *dp, Block *bp)
dp->lines = 16;
error(0, Ebadarg);
}
+ DPRINT("dkmuxconfig: ncsc=%d, lines=%d, restart=%d, name=\"%s\"\n",
+ dp->ncsc, dp->lines, dp->restart, dp->name);
/*
* open a stream for the csc and push urp onto it
@@ 495,7 498,7 @@ dkmuxconfig(Dk *dp, Block *bp)
/*
* start a process to deal with it
*/
- sprint(buf, "csckproc%d", dp->ncsc);
+ sprint(buf, "csc.%s.%d", dp->name, dp->ncsc);
kproc(buf, dkcsckproc, dp);
poperror();
@@ 1316,8 1319,11 @@ dkcsckproc(void *a)
/*
* tell datakit we've rebooted. It should close all channels.
*/
- if(dp->restart)
+ if(dp->restart) {
+ DPRINT("dkcsckproc: restart %s\n", dp->name);
dkmesg(dp, T_ALIVE, D_RESTART, 0, 0);
+ }
+ DPRINT("dkcsckproc: closeall %s\n", dp->name);
dkmesg(dp, T_CHG, D_CLOSEALL, 0, 0);
/*
M gnot/fault.c => gnot/fault.c +3 -3
@@ 79,6 79,7 @@ fault(Ureg *ur, FFrame *f)
panic("prefetch pagefault");
}else
panic("prefetch format");
+ addr &= VAMASK;
badvaddr = addr;
addr &= ~(BY2PG-1);
user = !(ur->sr&SUPER);
@@ 99,7 100,7 @@ fault(Ureg *ur, FFrame *f)
}
u->p->state = MMUing;
dumpregs(ur);
- panic("fault");
+ panic("fault: 0x%lux", badvaddr);
exit();
}
s = &u->p->seg[SSEG];
@@ 108,15 109,14 @@ fault(Ureg *ur, FFrame *f)
/* grow stack */
o = s->o;
n = o->npte;
- lock(o);
if(waserror()){
- unlock(o);
pprint("can't allocate stack page\n");
goto cant;
}
growpte(o, (s->maxva-addr)>>PGSHIFT);
poperror();
/* stacks grown down, sigh */
+ lock(o);
memcpy(o->pte+(o->npte-n), o->pte, n*sizeof(PTE));
memset(o->pte, 0, (o->npte-n)*sizeof(PTE));
unlock(o);
M gnot/fns.h => gnot/fns.h +1 -0
@@ 49,6 49,7 @@ void flushcpucache(void);
void flushmmu(void);
void forkmod(Seg*, Seg*, Proc*);
void freeb(Block*);
+void freenextmod(PTE*);
void freepage(Orig*);
void freepte(Orig*);
void freesegs(int);
M gnot/mem.h => gnot/mem.h +6 -4
@@ 18,10 18,11 @@
/*
* Time
*/
-#define MS2HZ (1000/60) /* millisec per clock tick */
-#define TK2SEC(t) ((t)/60) /* ticks to seconds */
-#define TK2MS(t) (((t)*1000)/60) /* ticks to milliseconds */
-#define MS2TK(t) (((t)*60)/1000) /* milliseconds to ticks */
+#define HZ (60) /* clock frequency */
+#define MS2HZ (1000/HZ) /* millisec per clock tick */
+#define TK2SEC(t) ((t)/HZ) /* ticks to seconds */
+#define TK2MS(t) (((t)*1000)/HZ) /* ticks to milliseconds */
+#define MS2TK(t) (((t)*HZ)/1000) /* milliseconds to ticks */
/*
* SR bits
@@ 59,6 60,7 @@
* MMU
*/
+#define VAMASK 0xCFFFFFFF /* clear balu bits in address */
#define KUSEG 0x00000000
#define KSEG 0x80000000
M gnot/page.c => gnot/page.c +25 -42
@@ 311,16 311,13 @@ loop:
o->mqid = -1;
o->mchan = 0;
}
- lock(o);
if(u && u->p && waserror()){
- unlock(o);
unlock(&origalloc);
nexterror();
}
growpte(o, npte);
if(u && u->p)
poperror();
- unlock(o);
unlock(&origalloc);
return o;
}
@@ 515,15 512,8 @@ segaddr(Seg *s, ulong min, ulong max)
* Grow
*/
/* BUG: check spill onto other segments */
- lock(o);
- if(waserror()){
- unlock(o);
- nexterror();
- }
if(o->va+BY2PG*o->npte < max)
growpte(o, (max-o->va)>>PGSHIFT);
- unlock(o);
- poperror();
s->maxva = max;
return 1;
}
@@ 568,6 558,10 @@ freepte(Orig *o) /* o is locked */
p->o = 0;
}
+/*
+ * o is locked. this will always do a grow; if n<=o->npte someone
+ * else got here first and we can just return.
+ */
void
growpte(Orig *o, ulong n)
{
@@ 575,43 569,30 @@ growpte(Orig *o, ulong n)
ulong nfree;
lock(&ptealloc);
+ lock(o);
if(o->pte){
- if(o->npte == n){
-if(u && u->p) print("%s: ", u->p->text);
- print("growpte pointless\n");
+ if(o->npte >= n)
goto Return;
- }
p = (PTEA*)(o->pte - 1);
- if(o->npte > n){
- print("growpte shrink");
- goto Return;
- nfree = o->npte - n;
- p->n -= nfree;
- o->npte -= nfree;
- p += p->n;
- p->o = 0;
- p->n = nfree;
+ n++;
+ if(p+p->n == ptealloc.free){
+ if(!compactpte(o, n - p->n))
+ goto Trouble;
+ p = (PTEA*)(o->pte - 1);
+ ptealloc.free += n - p->n;
}else{
- n++;
- if(p+p->n == ptealloc.free){
- if(!compactpte(o, n - p->n))
- goto Trouble;
- p = (PTEA*)(o->pte - 1);
- ptealloc.free += n - p->n;
- }else{
- if(!compactpte(o, n))
- goto Trouble;
- p = ptealloc.free;
- ptealloc.free += n;
- memcpy(p+1, o->pte, o->npte*sizeof(PTE));
- p->o = o;
- ((PTEA*)(o->pte-1))->o = 0;
- o->pte = p+1;
- }
- memset(p+1+o->npte, 0, (n-(1+o->npte))*sizeof(PTE));
- p->n = n;
- o->npte = n-1;
+ if(!compactpte(o, n))
+ goto Trouble;
+ p = ptealloc.free;
+ ptealloc.free += n;
+ memcpy(p+1, o->pte, o->npte*sizeof(PTE));
+ p->o = o;
+ ((PTEA*)(o->pte-1))->o = 0;
+ o->pte = p+1;
}
+ memset(p+1+o->npte, 0, (n-(1+o->npte))*sizeof(PTE));
+ p->n = n;
+ o->npte = n-1;
goto Return;
}
n++;
@@ 626,10 607,12 @@ if(u && u->p) print("%s: ", u->p->text);
o->npte = n-1;
Return:
unlock(&ptealloc);
+ unlock(o);
return;
Trouble:
unlock(&ptealloc);
+ unlock(o);
if(u && u->p)
error(0, Enovmem);
panic("growpte fails %d %lux %d\n", n, o->va, o->npte);
M gnot/screen.c => gnot/screen.c +1 -2
@@ 65,8 65,7 @@ screenputc(int c)
bitblt(&screen, Pt(0, out.pos.y), &screen,
Rect(0, out.pos.y, screen.r.max.x, out.pos.y+2*defont0.height), 0);
}else if(c == '\t'){
- nx = out.pos.x + (8-(out.pos.x/out.bwid&7))*out.bwid;
- out.pos.x = nx;
+ out.pos.x += (8-((out.pos.x-MINX)/out.bwid&7))*out.bwid;
if(out.pos.x >= screen.r.max.x)
screenputc('\n');
}else if(c == '\b'){
M gnot/sturp.c => gnot/sturp.c +1 -3
@@ 771,10 771,8 @@ sendblock(Urp *up, int bn)
* message 1, the BOT and the data
*/
bp = up->xb[bn];
- if(bp == 0){
- urpvomit("sendblock", up);
+ if(bp == 0)
return;
- }
m = allocb(1);
m->rptr = m->lim - 1;
m->wptr = m->lim;
M port/devbit.c => port/devbit.c +14 -0
@@ 973,11 973,24 @@ bitfree(Bitmap *bp)
bit.free = bp;
}
+QLock bitlock;
+
+Bitmap *
+id2bit(int k)
+{
+ Bitmap *bp;
+ bp = &bit.map[k];
+ if(k<0 || k>=conf.nbitmap || bp->ldepth < 0)
+ error(0, Ebadbitmap);
+ return bp;
+}
+
void
bitcompact(void)
{
ulong *p1, *p2;
+ qlock(&bitlock);
p1 = p2 = bit.words;
while(p2 < bit.wfree){
if(p2[1] == 0){
@@ 992,6 1005,7 @@ bitcompact(void)
p1 += 2 + p1[0];
}
bit.wfree = p1;
+ qunlock(&bitlock);
}
void
M port/fault.c => port/fault.c +1 -2
@@ 43,15 43,14 @@ fault(Ureg *ur, int user, int code)
/* grow stack */
o = s->o;
n = o->npte;
- lock(o);
if(waserror()){
- unlock(o);
pprint("can't allocate stack page\n");
goto cant;
}
growpte(o, (s->maxva-addr)>>PGSHIFT);
poperror();
/* stacks grown down, sigh */
+ lock(o);
memcpy(o->pte+(o->npte-n), o->pte, n*sizeof(PTE));
memset(o->pte, 0, (o->npte-n)*sizeof(PTE));
unlock(o);
M port/page.c => port/page.c +25 -42
@@ 339,16 339,13 @@ o->nmod = 0;
o->mqid = -1;
o->mchan = 0;
}
- lock(o);
if(u && u->p && waserror()){
- unlock(o);
unlock(&origalloc);
nexterror();
}
growpte(o, npte);
if(u && u->p)
poperror();
- unlock(o);
unlock(&origalloc);
return o;
}
@@ 547,15 544,8 @@ segaddr(Seg *s, ulong min, ulong max)
* Grow
*/
/* BUG: check spill onto other segments */
- lock(o);
- if(waserror()){
- unlock(o);
- nexterror();
- }
if(o->va+BY2PG*o->npte < max)
growpte(o, (max-o->va)>>PGSHIFT);
- unlock(o);
- poperror();
s->maxva = max;
return 1;
}
@@ 601,6 591,10 @@ freepte(Orig *o) /* o is locked */
p->o = 0;
}
+/*
+ * o is locked. this will always do a grow; if n<=o->npte someone
+ * else got here first and we can just return.
+ */
void
growpte(Orig *o, ulong n)
{
@@ 608,43 602,30 @@ growpte(Orig *o, ulong n)
ulong nfree;
lock(&ptealloc);
+ lock(o);
if(o->pte){
- if(o->npte == n){
-if(u && u->p) print("%s: ", u->p->text);
- print("growpte pointless\n");
+ if(o->npte >= n)
goto Return;
- }
p = (PTEA*)(o->pte - 1);
- if(o->npte > n){
- print("growpte shrink");
- goto Return;
- nfree = o->npte - n;
- p->n -= nfree;
- o->npte -= nfree;
- p += p->n;
- p->o = 0;
- p->n = nfree;
+ n++;
+ if(p+p->n == ptealloc.free){
+ if(!compactpte(o, n - p->n))
+ goto Trouble;
+ p = (PTEA*)(o->pte - 1);
+ ptealloc.free += n - p->n;
}else{
- n++;
- if(p+p->n == ptealloc.free){
- if(!compactpte(o, n - p->n))
- goto Trouble;
- p = (PTEA*)(o->pte - 1);
- ptealloc.free += n - p->n;
- }else{
- if(!compactpte(o, n))
- goto Trouble;
- p = ptealloc.free;
- ptealloc.free += n;
- memcpy(p+1, o->pte, o->npte*sizeof(PTE));
- p->o = o;
- ((PTEA*)(o->pte-1))->o = 0;
- o->pte = p+1;
- }
- memset(p+1+o->npte, 0, (n-(1+o->npte))*sizeof(PTE));
- p->n = n;
- o->npte = n-1;
+ if(!compactpte(o, n))
+ goto Trouble;
+ p = ptealloc.free;
+ ptealloc.free += n;
+ memcpy(p+1, o->pte, o->npte*sizeof(PTE));
+ p->o = o;
+ ((PTEA*)(o->pte-1))->o = 0;
+ o->pte = p+1;
}
+ memset(p+1+o->npte, 0, (n-(1+o->npte))*sizeof(PTE));
+ p->n = n;
+ o->npte = n-1;
goto Return;
}
n++;
@@ 659,10 640,12 @@ if(u && u->p) print("%s: ", u->p->text);
o->npte = n-1;
Return:
unlock(&ptealloc);
+ unlock(o);
return;
Trouble:
unlock(&ptealloc);
+ unlock(o);
if(u && u->p)
error(0, Enovmem);
panic("growpte fails %d %lux %d\n", n, o->va, o->npte);
M port/sturp.c => port/sturp.c +2 -3
@@ 771,10 771,8 @@ sendblock(Urp *up, int bn)
* message 1, the BOT and the data
*/
bp = up->xb[bn];
- if(bp == 0){
- urpvomit("sendblock", up);
+ if(bp == 0)
return;
- }
m = allocb(1);
m->rptr = m->lim - 1;
m->wptr = m->lim;
@@ 947,6 945,7 @@ todo(void *arg)
return (up->state&INITING)
? NOW>up->timer /* time to INIT1 */
: ((up->unacked!=up->next && NOW>up->timer) /* time to ENQ */
+ || WINDOW(up)>0 && up->next!=up->nxb
|| (!QFULL(up->rq->next) && up->iseq!=(up->lastecho&7))); /* time to ECHO */
}
static void