M gnot/devpipe.c => gnot/devpipe.c +1 -4
@@ 87,10 87,7 @@ pipewalk(Chan *c, char *name)
void
pipestat(Chan *c, char *db)
{
- Dir dir;
-
- devdir(c, c->qid, "pipe", 0, 0, &dir);
- convD2M(&dir, db);
+ streamstat(c, db, "pipe");
}
Chan *
M gnot/fns.h => gnot/fns.h +1 -0
@@ 148,6 148,7 @@ long streamwrite(Chan*, void*, long, int);
Stream* streamnew(Chan*, Qinfo*);
void streamopen(Chan*, Qinfo*);
int streamparse(char*, Block*);
+void streamstat(Chan*, char*, char*);
long stringread(Chan*, void*, long, char*);
long syscall(Ureg*);
int tas(char*);
M gnot/stream.c => gnot/stream.c +31 -0
@@ 6,6 6,7 @@
#include "io.h"
#include "errno.h"
#include "devtab.h"
+#include "fcall.h"
enum {
Nclass=4, /* number of block classes */
@@ 1156,3 1157,33 @@ getfields(char *lp, /* to be parsed */
}
return i;
}
+
+/*
+ * stat a stream. the length is the number of bytes up to the
+ * first delimiter.
+ */
+void
+streamstat(Chan *c, char *db, char *name)
+{
+ Dir dir;
+ Stream *s;
+ Queue *q;
+ Block *bp;
+ long n;
+
+ s = c->stream;
+ if(s == 0)
+ panic("streamstat");
+
+ q = RD(s->procq);
+ lock(q);
+ for(n=0, bp=q->first; bp; bp = bp->next){
+ n += BLEN(bp);
+ if(bp->flags&S_DELIM)
+ break;
+ }
+ unlock(q);
+
+ devdir(c, c->qid, name, n, 0, &dir);
+ convD2M(&dir, db);
+}
M port/devpipe.c => port/devpipe.c +1 -4
@@ 87,10 87,7 @@ pipewalk(Chan *c, char *name)
void
pipestat(Chan *c, char *db)
{
- Dir dir;
-
- devdir(c, c->qid, "pipe", 0, 0, &dir);
- convD2M(&dir, db);
+ streamstat(c, db, "pipe");
}
Chan *
M port/page.c => port/page.c +36 -1
@@ 251,6 251,40 @@ usepage(Page *p, int dolock)
unlock(&palloc);
}
+/*
+ * Move page to tail of list
+ */
+void
+unusepage(Page *p, int dolock)
+{
+return;
+ if(dolock)
+ lock(&palloc);
+ /*
+ * Unlink
+ */
+ if(p->prev)
+ p->prev->next = p->next;
+ else
+ palloc.head = p->next;
+ if(p->next)
+ p->next->prev = p->prev;
+ else
+ palloc.tail = p->prev;
+ /*
+ * Link
+ */
+ p->prev = palloc.tail;
+ p->next = 0;
+ if(p->prev)
+ p->prev->next = p;
+ else
+ palloc.head = p;
+ palloc.tail = p;
+ if(dolock)
+ unlock(&palloc);
+}
+
Orig*
lookorig(ulong va, ulong npte, int flag, Chan *c)
{
@@ 493,7 527,7 @@ segaddr(Seg *s, ulong min, ulong max)
if(max < min)
return 0;
-if(max > 20*1024*1024) pprint("segaddr %lux\n", max);
+if(max > 20*1024*1024) {pprint("segaddr %lux\n", max);print("segaddr %lux\n", max);}
if(min != s->minva) /* can't grow down yet (stacks: fault.c) */
return 0;
max = (max+(BY2PG-1)) & ~(BY2PG-1);
@@ 531,6 565,7 @@ freepage(Orig *o)
for(i=0; i<o->npte; i++,pte++)
if(pg = pte->page){ /* assign = */
if(pg->ref == 1){
+ unusepage(pg, 1);
pte->page = 0;
pg->o = 0;
}
M port/proc.c => port/proc.c +1 -0
@@ 59,6 59,7 @@ schedinit(void) /* never returns */
else if(p->state == Moribund){
p->pid = 0;
unlock(&p->debug);
+ unusepage(p->upage, 1);
p->upage->ref--;
/* procalloc already locked */
p->qnext = procalloc.free;
M port/stream.c => port/stream.c +32 -1
@@ 6,6 6,7 @@
#include "io.h"
#include "errno.h"
#include "devtab.h"
+#include "fcall.h"
enum {
Nclass=4, /* number of block classes */
@@ 72,7 73,7 @@ dumpblocks(Queue *q, char c)
lock(q);
for(bp = q->first; bp; bp = bp->next){
- print("%c%d%c", c, bp->wptr-bp->rptr, (bp->flags&S_DELIM)?'D':' ');
+ print("%c%d%c", c, bp->wptr-bp->rptr, (bp->flags&S_DELIM));
for(cp = bp->rptr; cp<bp->wptr && cp<bp->rptr+10; cp++)
print(" %uo", *cp);
print("\n");
@@ 1156,3 1157,33 @@ getfields(char *lp, /* to be parsed */
}
return i;
}
+
+/*
+ * stat a stream. the length is the number of bytes up to the
+ * first delimiter.
+ */
+void
+streamstat(Chan *c, char *db, char *name)
+{
+ Dir dir;
+ Stream *s;
+ Queue *q;
+ Block *bp;
+ long n;
+
+ s = c->stream;
+ if(s == 0)
+ panic("streamstat");
+
+ q = RD(s->procq);
+ lock(q);
+ for(n=0, bp=q->first; bp; bp = bp->next){
+ n += BLEN(bp);
+ if(bp->flags&S_DELIM)
+ break;
+ }
+ unlock(q);
+
+ devdir(c, c->qid, name, n, 0, &dir);
+ convD2M(&dir, db);
+}
M power/dat.h => power/dat.h +3 -3
@@ 509,12 509,13 @@ struct Nohdr {
* a buffer describing a nonet message
*/
struct Nomsg {
- QLock;
Blist;
+ Rendez r;
int mid; /* sequence number */
int rem; /* remaining */
long time;
int acked;
+ int inuse;
};
/*
@@ 532,13 533,13 @@ struct Noconv {
int rcvcircuit; /* circuit number of incoming packets */
uchar ack[Nnomsg]; /* acknowledgements waiting to be sent */
- long atime[Nnomsg];
int afirst;
int anext;
QLock xlock; /* one trasmitter at a time */
Rendez r; /* process waiting for an output mid */
Nomsg ctl; /* for control messages */
+ QLock mlock; /* lock for out */
Nomsg out[Nnomsg]; /* messages being sent */
int first; /* first unacknowledged message */
int next; /* next message buffer to use */
@@ 547,7 548,6 @@ struct Noconv {
Nohdr *hdr; /* nonet header inside of media header */
Noifc *ifc;
- int kstarted;
char raddr[NAMELEN]; /* remote address */
char ruser[NAMELEN]; /* remote user */
char addr[NAMELEN]; /* local address */
M power/fns.h => power/fns.h +2 -0
@@ 171,6 171,7 @@ long streamwrite(Chan*, void*, long, int);
Stream* streamnew(Chan*, Qinfo*);
void streamopen(Chan*, Qinfo*);
int streamparse(char*, Block*);
+void streamstat(Chan*, char*, char*);
long stringread(Chan*, void*, long, char*);
long syscall(Ureg*);
void sysloginit(void);
@@ 180,6 181,7 @@ void touser(void *);
void tsleep(Rendez*, int (*)(void*), void*, int);
void twakeme(Alarm*);
void unlock(Lock*);
+void unusepage(Page*, int);
void usepage(Page*, int);
void userinit(void);
void urpreset(void);
M power/main.c => power/main.c +2 -2
@@ 39,10 39,9 @@ main(void)
{
int i;
- icflush(0, 64*1024);
+ machinit();
active.exiting = 0;
active.machs = 1;
- machinit();
confinit();
arginit();
lockinit();
@@ 69,6 68,7 @@ machinit(void)
{
int n;
+ icflush(0, 64*1024);
n = m->machno;
memset(m, 0, sizeof(Mach));
m->machno = n;