M port/devmux.c => port/devmux.c +47 -47
@@ 292,6 292,53 @@ muxcreate(Chan *c, char *name, int omode, ulong perm)
}
void
+muxclose(Chan *c)
+{
+ Block *f1, *f2;
+ Con *cm, *e;
+ Mux *m;
+ int nc;
+
+ if(c->qid.path&CHDIR)
+ return;
+
+ m = &muxes[NMUX(c)];
+ if(!(c->flag&COPEN) || m->srv)
+ return;
+
+ nc = NCON(c);
+ f1 = 0;
+ f2 = 0;
+ switch(nc) {
+ case Qhead:
+ m->headopen = 0;
+ cm = m->connects;
+ for(e = &cm[Nmux]; cm < e; cm++)
+ if(cm->ref)
+ wakeup(&cm->conq.r);
+ lock(m);
+ if(--m->ref == 0)
+ f1 = muxclq(&m->headq);
+ unlock(m);
+ break;
+ case Qclone:
+ break;
+ default:
+ lock(m);
+ cm = &m->connects[nc-Qoffset];
+ if(--cm->ref == 0)
+ f1 = muxclq(&cm->conq);
+ if(--m->ref == 0)
+ f1 = muxclq(&m->headq);
+ unlock(m);
+ }
+ if(f1)
+ freeb(f1);
+ if(f2)
+ freeb(f2);
+}
+
+void
muxremove(Chan *c)
{
Mux *m;
@@ 355,53 402,6 @@ muxwstat(Chan *c, char *db)
}
}
-void
-muxclose(Chan *c)
-{
- Block *f1, *f2;
- Con *cm, *e;
- Mux *m;
- int nc;
-
- if(c->qid.path&CHDIR)
- return;
-
- m = &muxes[NMUX(c)];
- if(!(c->flag&COPEN) || m->srv)
- return;
-
- nc = NCON(c);
- f1 = 0;
- f2 = 0;
- switch(nc) {
- case Qhead:
- m->headopen = 0;
- cm = m->connects;
- for(e = &cm[Nmux]; cm < e; cm++)
- if(cm->ref)
- wakeup(&cm->conq.r);
- lock(m);
- if(--m->ref == 0)
- f1 = muxclq(&m->headq);
- unlock(m);
- break;
- case Qclone:
- break;
- default:
- lock(m);
- cm = &m->connects[nc-Qoffset];
- if(--cm->ref == 0)
- f1 = muxclq(&cm->conq);
- if(--m->ref == 0)
- f1 = muxclq(&m->headq);
- unlock(m);
- }
- if(f1)
- freeb(f1);
- if(f2)
- freeb(f2);
-}
-
long
muxread(Chan *c, void *va, long n, ulong offset)
{
M port/devwren.c => port/devwren.c +1 -0
@@ 326,5 326,6 @@ wrenpart(int dev)
dp->npart = pp - dp->p;
poperror();
scsifree(b);
+ poperror();
qunlock(dp);
}
M port/fault.c => port/fault.c +2 -0
@@ 170,6 170,7 @@ pio(Segment *s, ulong addr, ulong soff, Page **p)
new = lookpage(s->image, daddr);
}
else {
+print("reclaim\n");
daddr = swapaddr(loadrec);
new = lookpage(&swapimage, daddr);
if(new)
@@ 221,6 222,7 @@ pio(Segment *s, ulong addr, ulong soff, Page **p)
putpage(new);
}
else { /* This is paged out */
+print("SWAPIN\n");
c = swapimage.c;
qlock(&c->rdl);
M port/ipdat.h => port/ipdat.h +3 -0
@@ 98,6 98,8 @@ struct Ilcb /* Control block */
{
int state; /* Connection state */
+ Rendez syncer; /* where syncer waits for a connect */
+
QLock ackq; /* Unacknowledged queue */
Block *unacked;
Block *unackedtail;
@@ 247,6 249,7 @@ struct Tcpctl
{
QLock;
struct Tctl;
+ Rendez syner;
};
struct Tcp
M port/page.c => port/page.c +24 -14
@@ 103,7 103,7 @@ void
pageinit(void)
{
ulong np, addr, lim;
- ulong i, vmem, pmem;
+ ulong i, vmem, pmem, hw, hr;
Page *p;
/*
@@ 150,7 150,15 @@ pageinit(void)
palloc.user = palloc.freecount = p - palloc.head;
pmem = palloc.user*BY2PG/1024;
vmem = pmem + ((conf.nswap)*BY2PG)/1024;
- print("%lud free pages, %dK bytes, swap %dK bytes\n", palloc.user, pmem, vmem);
+
+ /* Pageing numbers */
+ swapalloc.highwater = (palloc.freecount*5)/100;
+ swapalloc.headroom = swapalloc.highwater + (swapalloc.highwater/4);
+ hw = (swapalloc.highwater*BY2PG)/1024;
+ hr = (swapalloc.headroom*BY2PG)/1024;
+
+ print("%lud free pages, %dK bytes, swap %dK bytes, highwater %dK, headroom %dK\n",
+ palloc.user, pmem, vmem, hw, hr);
}
Page*
@@ 166,7 174,7 @@ newpage(int clear, Segment **s, ulong va)
lock(&palloc);
/* The kp test is a poor guard against the pager deadlocking */
- while((palloc.freecount < HIGHWATER && u->p->kp == 0) || palloc.freecount == 0) {
+ while((palloc.freecount < swapalloc.highwater && u->p->kp == 0)||palloc.freecount == 0) {
palloc.wanted++;
unlock(&palloc);
if(s && *s) {
@@ 223,53 231,54 @@ int
ispages(void *p)
{
USED(p);
- return palloc.freecount >= HIGHWATER;
+ return palloc.freecount >= swapalloc.highwater;
}
void
putpage(Page *p)
{
- int count;
+ int wake;
if(onswap(p)) {
putswap(p);
return;
}
+ wake = 0;
lockpage(p);
if(--p->ref == 0) {
lock(&palloc);
- if(p->image) {
+ if(p->image && p->image != &swapimage) {
if(palloc.tail) {
p->prev = palloc.tail;
palloc.tail->next = p;
- palloc.tail = p;
}
else {
- palloc.head = palloc.tail = p;
+ palloc.head = p;
p->prev = 0;
}
+ palloc.tail = p;
p->next = 0;
}
else {
if(palloc.head) {
p->next = palloc.head;
palloc.head->prev = p;
- palloc.head = p;
}
else {
- palloc.head = palloc.tail = p;
+ palloc.tail = p;
p->next = 0;
}
+ palloc.head = p;
p->prev = 0;
}
+ wake = 1;
palloc.freecount++; /* Release people waiting for memory */
unlock(&palloc);
}
unlockpage(p);
-
- if(palloc.wanted)
+ if(wake && palloc.wanted)
wakeup(&palloc.r);
}
@@ 297,8 306,9 @@ duppage(Page *p) /* Always call with p locked */
lock(&palloc);
- if(palloc.freecount < HIGHWATER || /* No freelist cache when memory is very low */
- p->image == &swapimage) { /* No dup for swap pages */
+ /* No freelist cache when memory is very low, No dup for swap pages */
+ if(palloc.freecount < swapalloc.highwater ||
+ p->image == &swapimage) {
unlock(&palloc);
uncachepage(p);
return;
M port/portdat.h => port/portdat.h +3 -3
@@ 311,6 311,8 @@ struct Swapalloc
char *alloc; /* Round robin allocator */
char *top; /* Top of swap map */
Rendez r; /* Pager kproc idle sleep */
+ ulong highwater; /* Threshold beyond which we must page */
+ ulong headroom; /* Space pager attempts to clear below highwater */
}swapalloc;
struct Image
@@ 343,10 345,8 @@ struct Pte
#define SG_SHARED 004
#define SG_PHYSICAL 005
/* Segment flags */
-#define SG_RONLY 040 /* Segment is read only */
+#define SG_RONLY 040 /* Segment is read only */
-#define HIGHWATER ((conf.npage*5)/100)
-#define MAXHEADROOM HIGHWATER*2 /* Silly but OK for debug */
#define PG_ONSWAP 1
#define pagedout(s) (((ulong)s)==0 || (((ulong)s)&PG_ONSWAP))
#define swapaddr(s) (((ulong)s)&~PG_ONSWAP)
M port/proc.c => port/proc.c +4 -1
@@ 522,7 522,10 @@ pexit(char *exitstr, int freemem)
* if not a kernel process and have a parent,
* do some housekeeping.
*/
- if(c->kp == 0 && (p = c->parent)) {
+ if(c->kp == 0) {
+ if((p = c->parent) == 0)
+ panic("boot process died");
+
wq = newwaitq();
wq->w.pid = c->pid;
utime = c->time[TUser] + c->time[TCUser];
M port/stil.c => port/stil.c +26 -25
@@ 257,8 257,8 @@ ilrcvmsg(Ipconv *ipc, Block *bp)
dst = nhgetl(ih->src);
if(ilcksum && ptcl_csum(bp, IL_EHSIZE, illen) != 0) {
- st = (ih->iltype < 0 || ih->iltype > Ilclose) ? "?" : iltype[ih->iltype];
-/* print("il: cksum error, pkt(%s id %lud ack %lud %d.%d.%d.%d/%d->%d)\n",
+/* st = (ih->iltype < 0 || ih->iltype > Ilclose) ? "?" : iltype[ih->iltype];
+ print("il: cksum error, pkt(%s id %lud ack %lud %d.%d.%d.%d/%d->%d)\n",
st, nhgetl(ih->ilid), nhgetl(ih->ilack), fmtaddr(dst), sp, dp); /**/
goto drop;
}
@@ 343,24 343,21 @@ _ilprocess(Ipconv *s, Ilhdr *h, Block *bp)
default:
break;
case Ilsync:
- if(ack != ic->start) {
- ic->state = Ilclosed;
+ if(ack != ic->start)
ilhangup(s, "connection rejected");
- }
else {
ic->recvd = id;
ic->rstart = id;
ilsendctl(s, 0, Ilack, ic->next, ic->recvd);
ic->state = Ilestablished;
+ wakeup(&ic->syncer);
ilpullup(s);
Starttimer(ic);
}
break;
case Ilclose:
- if(ack == ic->start) {
- ic->state = Ilclosed;
+ if(ack == ic->start)
ilhangup(s, "remote close");
- }
break;
}
freeb(bp);
@@ 386,10 383,8 @@ _ilprocess(Ipconv *s, Ilhdr *h, Block *bp)
}
break;
case Ilclose:
- if(id == ic->next) {
- ic->state = Ilclosed;
+ if(id == ic->next)
ilhangup(s, "remote close");
- }
break;
}
freeb(bp);
@@ 397,10 392,8 @@ _ilprocess(Ipconv *s, Ilhdr *h, Block *bp)
case Ilestablished:
switch(h->iltype) {
case Ilsync:
- if(id != ic->start) {
- ic->state = Ilclosed;
+ if(id != ic->start)
ilhangup(s, "remote close");
- }
else {
ilsendctl(s, 0, Ilack, ic->next, ic->rstart);
Starttimer(ic);
@@ 458,10 451,8 @@ _ilprocess(Ipconv *s, Ilhdr *h, Block *bp)
case Ilclose:
ic->recvd = id;
ilsendctl(s, 0, Ilclose, ic->next, ic->recvd);
- if(ack == ic->next) {
- ic->state = Ilclosed;
+ if(ack == ic->next)
ilhangup(s, 0);
- }
Starttimer(ic);
break;
default:
@@ 522,8 513,14 @@ ilhangup(Ipconv *s, char *msg)
{
Block *nb;
int l;
+ Ilcb *ic;
+ int callout;
DBG("hangup! %s %d/%d\n", msg ? msg : "??", s->psrc, s->pdst);
+
+ ic = &s->ilctl;
+ callout = ic->state == Ilsyncer;
+ ic->state = Ilclosed;
if(s->readq) {
if(msg) {
l = strlen(msg);
@@ 537,6 534,8 @@ ilhangup(Ipconv *s, char *msg)
nb->flags |= S_DELIM;
PUTNEXT(s->readq, nb);
}
+ if(callout)
+ wakeup(&ic->syncer);
s->psrc = 0;
s->pdst = 0;
s->dst = 0;
@@ 697,10 696,8 @@ ilackproc(void *a)
ilsendctl(s, 0, Ilclose, ic->next, ic->recvd);
ilbackoff(ic);
}
- if(ic->timeout >= ic->slowtime) {
- ic->state = Ilclosed;
+ if(ic->timeout >= ic->slowtime)
ilhangup(s, 0);
- }
break;
case Ilsyncee:
case Ilsyncer:
@@ 708,10 705,8 @@ ilackproc(void *a)
ilsendctl(s, 0, Ilsync, ic->start, ic->recvd);
ilbackoff(ic);
}
- if(ic->timeout >= ic->slowtime) {
- ic->state = Ilclosed;
+ if(ic->timeout >= ic->slowtime)
ilhangup(s, etime);
- }
break;
case Ilestablished:
ic->acktime -= Iltickms;
@@ 721,7 716,6 @@ ilackproc(void *a)
if(ic->querytime <= 0){
ic->deathtime -= Querytime;
if(ic->deathtime < 0){
- ic->state = Ilclosed;
ilhangup(s, etime);
break;
}
@@ 737,7 731,6 @@ ilackproc(void *a)
ilbackoff(ic);
}
if(ic->timeout >= ic->slowtime) {
- ic->state = Ilclosed;
ilhangup(s, etime);
break;
}
@@ 756,6 749,11 @@ ilbackoff(Ilcb *ic)
ic->fasttime = (ic->fasttime)*3/2;
}
+static int
+notsyncer(void *ic)
+{
+ return ((Ilcb*)ic)->state != Ilsyncer;
+}
void
ilstart(Ipconv *ipc, int type, int window)
{
@@ 783,6 781,9 @@ ilstart(Ipconv *ipc, int type, int window)
case IL_ACTIVE:
ic->state = Ilsyncer;
ilsendctl(ipc, 0, Ilsync, ic->start, ic->recvd);
+ sleep(&ic->syncer, notsyncer, ic);
+ if(ic->state == Ilclosed)
+ error(Etimedout);
break;
}
}
D port/stnoether.c => port/stnoether.c +0 -289
@@ 1,289 0,0 @@
-/*
- * ethernet specific multiplexor for nonet
- *
- * this line discipline gets pushed onto an ethernet channel
- * to demultiplex/multiplex nonet conversations.
- */
-#include "u.h"
-#include "lib.h"
-#include "mem.h"
-#include "dat.h"
-#include "fns.h"
-#include "io.h"
-#include "../port/error.h"
-#include "../port/nonet.h"
-
-#define DPRINT if(pnonet)print
-extern int pnonet;
-
-static void etherparse(uchar*, char*);
-static void noetherclose(Queue*);
-static void noetheriput(Queue*, Block*);
-static void noetheropen(Queue*, Stream*);
-static void noetheroput(Queue*, Block*);
-
-/*
- * ethernet header of a packet
- */
-#define EHDRSIZE (ETHERHDRSIZE + NO_HDRSIZE)
-#define EMAXBODY (ETHERMAXTU - EHDRSIZE) /* maximum ethernet packet body */
-#define ETHER_TYPE 0x900 /* most significant byte last */
-
-/*
- * the ethernet multiplexor stream module definition
- */
-Qinfo noetherinfo =
-{
- noetheriput,
- noetheroput,
- noetheropen,
- noetherclose,
- "noether"
-};
-
-/*
- * perform the ether specific part of nonetconnect. just stick
- * the address into the prototype header.
- */
-void
-noetherconnect(Noconv *cp, char *ea)
-{
- Etherpkt *eh;
-
- eh = (Etherpkt*)cp->media->rptr;
- etherparse(eh->d, ea);
- eh->type[0] = ETHER_TYPE>>8;
- eh->type[1] = ETHER_TYPE & 0xff;
-}
-
-/*
- * set up an ether interface
- */
-static void
-noetheropen(Queue *q, Stream *s)
-{
- streamenter(s);
- nonetnewifc(q, s, ETHERMAXTU, ETHERMINTU, ETHERHDRSIZE, noetherconnect);
-}
-
-/*
- * tear down an ether interface
- */
-static void
-noetherclose(Queue *q)
-{
- Noifc *ifc;
-
- ifc = (Noifc*)q->ptr;
- nonetfreeifc(ifc);
-}
-
-/*
- * configure the system
- */
-static void
-noetheroput(Queue *q, Block *bp)
-{
- Noifc *ifc;
-
- ifc = (Noifc*)q->ptr;
- if(bp->type != M_DATA){
- if(streamparse("config", bp)){
- if(*bp->rptr == 0)
- strcpy(ifc->name, "nonet");
- else
- strncpy(ifc->name, (char *)bp->rptr, sizeof(ifc->name));
- } else
- PUTNEXT(q, bp);
- return;
- }
-
- PUTNEXT(q, bp);
-}
-
-/*
- * respond to a misaddressed message with a close
- */
-void
-noetherbad(Noifc *ifc, Block *bp, int circuit)
-{
- Etherpkt *eh, *neh;
- Nohdr *nh, *nnh;
- Block *nbp;
- int r;
- Noconv *cp, *ep;
-
- /*
- * crack the packet header
- */
- eh = (Etherpkt*)bp->rptr;
- nh = (Nohdr*)eh->data;
-/* print("bad %.2ux%.2ux%.2ux%.2ux%.2ux%.2ux c %d m %d f %d\n",
- eh->s[0], eh->s[1], eh->s[2], eh->s[3], eh->s[4],
- eh->s[5], circuit, nh->mid, nh->flag); /**/
- if(nh->flag & NO_RESET)
- goto out;
-
- /*
- * only one reset per message
- */
- r = (nh->remain[1]<<8) | nh->remain[0];
- if(r<0)
- goto out;
-
- /*
- * craft an error reply
- */
-/* print("sending reset\n"); /**/
- nbp = allocb(60);
- nbp->flags |= S_DELIM;
- nbp->wptr = nbp->rptr + 60;
- memset(bp->rptr, 0, 60);
- neh = (Etherpkt *)nbp->rptr;
- nnh = (Nohdr*)neh->data;
- memmove(neh, eh, EHDRSIZE);
- nnh->circuit[0] ^= 1;
- nnh->remain[0] = nnh->remain[1] = 0;
- nnh->flag = NO_HANGUP | NO_RESET;
- nnh->ack = nh->mid;
- nnh->mid = nh->ack;
- memmove(neh->s, eh->d, sizeof(neh->s));
- memmove(neh->d, eh->s, sizeof(neh->d));
- nonetcksum(nbp, ETHERHDRSIZE);
- PUTNEXT(ifc->wq, nbp);
-out:
- freeb(bp);
-}
-
-/*
- * Input a packet and use the ether address to select the correct
- * nonet device to pass it to.
- *
- * Simplifying assumption: one put == one packet && the complete header
- * is in the first block. If this isn't true, demultiplexing will not work.
- */
-static void
-noetheriput(Queue *q, Block *bp)
-{
- Noifc *ifc;
- int circuit;
- Noconv *cp, *ep;
- Etherpkt *eh, *peh;
- Nohdr *nh;
- ulong s;
- Block *nbp;
- int next;
- Nocall *clp;
-
- if(bp->type != M_DATA){
- PUTNEXT(q, bp);
- return;
- }
-
- ifc = (Noifc*)q->ptr;
- eh = (Etherpkt*)bp->rptr;
- nh = (Nohdr*)eh->data;
- circuit = (nh->circuit[2]<<16) | (nh->circuit[1]<<8) | nh->circuit[0];
- s = (nh->sum[1]<<8) | nh->sum[0];
- if(s && s!=nonetcksum(bp, ETHERHDRSIZE)){
- print("checksum error %ux %ux\n", s, (nh->sum[1]<<8) | nh->sum[0]); /**/
- freeb(bp);
- return;
- }
-
- /*
- * look for an existing circuit.
- */
- ep = &ifc->conv[conf.nnoconv];
- for(cp = &ifc->conv[0]; cp < ep; cp++){
- nbp = cp->media;
- if(nbp == 0)
- continue;
- peh = (Etherpkt*)nbp->rptr;
- if(circuit==cp->rcvcircuit && memcmp(peh->d, eh->s, sizeof(eh->s))==0){
- if(!canqlock(cp)){
- freeb(bp);
- return;
- }
- peh = (Etherpkt*)nbp->rptr;
- if(circuit==cp->rcvcircuit
- && memcmp(peh->d, eh->s, sizeof(eh->s))==0){
- bp->rptr += ifc->hsize;
- nonetrcvmsg(cp, bp);
- qunlock(cp);
- return;
- }
- qunlock(cp);
- }
- }
-
- /*
- * if not a new call, then its misaddressed
- */
- if((nh->flag & NO_NEWCALL) == 0 || nh->mid != 1){
- noetherbad(ifc, bp, circuit);
- return;
- }
-
- /*
- * Queue call in a circular queue and wakeup a listener.
- */
- lock(&ifc->lock);
- next = (ifc->wptr + 1) % Nnocalls;
- if(next == ifc->rptr){
- /* no room in the queue */
- unlock(&ifc->lock);
- freeb(bp);
- return;
- }
- clp = &ifc->call[ifc->wptr];
- sprint(clp->raddr, "%.2ux%.2ux%.2ux%.2ux%.2ux%.2ux",
- eh->s[0], eh->s[1], eh->s[2], eh->s[3], eh->s[4], eh->s[5]);
- clp->circuit = circuit^1;
- bp->rptr += ifc->hsize;
- clp->msg = bp;
- ifc->wptr = next;
- unlock(&ifc->lock);
- wakeup(&ifc->listenr);
- DPRINT("call from %s wptr %d\n", clp->raddr, ifc->wptr);
-}
-
-/*
- * parse an ethernet address (assumed to be 12 ascii hex digits)
- */
-static void
-etherparse(uchar *to, char *from)
-{
- ulong ip;
- uchar nip[4];
- int tdig;
- int fdig;
- int i;
-
-#ifdef MAGNUM
- /* Dot means ip address */
- if(strchr(from, '.')) {
- ip = ipparse(from);
- if(ip == 0)
- error(Enetaddr);
-
- hnputl(nip, ip);
- if(arp_lookup(nip, to))
- return;
- }
-#endif
-
- if(strlen(from) != 12)
- error(Enetaddr);
-
- for(i = 0; i < 6; i++){
- fdig = (*from++)&0x7f;
- tdig = fdig >= 'a' ? ((fdig - 'a') + 10)
- : (fdig >= 'A' ? ((fdig - 'A') + 10) : (fdig - '0'));
- fdig = (*from++)&0x7f;
- tdig <<= 4;
- tdig |= fdig >= 'a' ? ((fdig - 'a') + 10)
- : (fdig >= 'A' ? ((fdig - 'A') + 10) : (fdig - '0'));
- *to++ = tdig;
- }
-}
A port/streboot.c => port/streboot.c +47 -0
@@ 0,0 1,47 @@
+#include "u.h"
+#include "lib.h"
+#include "mem.h"
+#include "dat.h"
+#include "fns.h"
+#include "../port/error.h"
+
+/*
+ * reboot stream module definition
+ */
+static void rebootopen(Queue*, Stream*);
+static void rebootiput(Queue*, Block*);
+static void rebootoput(Queue*, Block*);
+static void rebootreset(void);
+Qinfo rebootinfo =
+{
+ rebootiput,
+ rebootoput,
+ rebootopen,
+ 0,
+ "reboot",
+ 0
+};
+
+static void
+rebootopen(Queue *q, Stream *s)
+{
+ USED(q);
+ if(strcmp(u->p->user, eve) != 0)
+ error(Eperm);
+}
+
+void
+rebootoput(Queue *q, Block *bp)
+{
+ PUTNEXT(q, bp);
+}
+
+static void
+rebootiput(Queue *q, Block *bp)
+{
+ if(bp->type == M_HANGUP){
+ print("lost connection to fs, rebooting");
+ exit();
+ }
+ PUTNEXT(q, bp);
+}
M port/swap.c => port/swap.c +55 -53
@@ 15,9 15,11 @@ int canflush(Proc *p, Segment*);
enum
{
- Maxpages = 100, /* Max number of pageouts per segment pass */
+ Maxpages = 500, /* Max number of pageouts per segment pass */
};
+#define DBG if(1)print
+
Image swapimage;
static int swopen;
Page *iolist[Maxpages];
@@ 103,43 105,49 @@ pager(void *junk)
Segment *s;
int i;
+ if(waserror())
+ panic("pager: os error\n");
+
USED(junk);
p = proctab(0);
ep = &p[conf.nproc];
- for(;;) {
- if(waserror())
- panic("pager: os error\n");
- u->p->psstate = "Idle";
- sleep(&swapalloc.r, needpages, 0);
- u->p->psstate = "Pageout";
+loop:
+ u->p->psstate = "Idle";
+ sleep(&swapalloc.r, needpages, 0);
+ u->p->psstate = "Pageout";
- for(p = proctab(0); p < ep; p++) {
- if(p->state == Dead || p->kp)
- continue;
+ for(;;) {
+ p++;
+ if(p > ep)
+ p = proctab(0);
- if(swapimage.c) {
- for(i = 0; i < NSEG; i++)
- if(s = p->seg[i]) {
- pageout(p, s);
- executeio();
- }
- }
- else
- if(palloc.freecount < HIGHWATER) {
- /* Rob made me do it ! */
- if(conf.cntrlp == 0)
- freebroken();
-
- /* Emulate the old system if no swap channel */
- print("no physical memory\n");
- tsleep(&swapalloc.r, return0, 0, 1000);
- wakeup(&palloc.r);
+ if(p->state == Dead || p->kp)
+ continue;
+
+ if(swapimage.c) {
+ for(i = 0; i < NSEG; i++) {
+ if(!needpages(junk))
+ goto loop;
+ if(s = p->seg[i]) {
+ pageout(p, s);
+ executeio();
+ }
}
}
-
- poperror();
+ else
+ if(palloc.freecount < swapalloc.highwater) {
+ /* Rob made me do it ! */
+ if(conf.cntrlp == 0)
+ freebroken();
+
+ /* Emulate the old system if no swap channel */
+ print("no physical memory\n");
+ tsleep(&swapalloc.r, return0, 0, 1000);
+ wakeup(&palloc.r);
+ }
}
+ goto loop;
}
void
@@ 147,13 155,20 @@ pageout(Proc *p, Segment *s)
{
Pte **sm, **endsm, *l;
Page **pg, *entry;
- int type;
+ int type, nr;
extern char *sname[];
+
if(!canqlock(&s->lk)) /* We cannot afford to wait, we will surely deadlock */
return;
- if(!canflush(p, s) || s->steal) {
+ if(s->steal) {
+ qunlock(&s->lk);
+ putseg(s);
+ return;
+ }
+
+ if(!canflush(p, s)) {
qunlock(&s->lk);
putseg(s);
return;
@@ 166,6 181,7 @@ extern char *sname[];
}
scavenge = 0;
+ nr = 0;
/* Pass through the pte tables looking for memory pages to swap out */
type = s->type&SG_TYPE;
@@ 175,13 191,13 @@ extern char *sname[];
if(l == 0)
continue;
for(pg = l->first; pg < l->last; pg++) {
+ nr++;
entry = *pg;
if(pagedout(entry))
continue;
- if(entry->modref & PG_REF) {
- print("MODREF\n");
+
+ if(entry->modref & PG_REF)
entry->modref &= ~PG_REF;
- }
else
pagepte(type, s, pg);
@@ 190,8 206,9 @@ extern char *sname[];
}
}
out:
-
- print("%s: %d: type %s %d pages\n", p->text, p->pid, sname[type], scavenge);
+ DBG("%s: %d: %5s s %d nr %d fr %d\n",
+ p->text, p->pid, sname[type], scavenge, nr, palloc.freecount);
+
poperror();
qunlock(&s->lk);
putseg(s);
@@ 235,14 252,9 @@ int
pagepte(int type, Segment *s, Page **pg)
{
ulong daddr;
- char *kaddr;
- int n;
- Chan *c;
Page *outp;
- KMap *k;
outp = *pg;
-print("outp: %lux\n", *pg);
switch(type) {
case SG_TEXT: /* Revert to demand load */
putpage(outp);
@@ 290,17 302,7 @@ executeio(void)
for(i = 0; i < ioptr; i++) {
out = iolist[i];
-#ifdef asdf
- if(out->ref > 2) {
- lockpage(out);
- if(out->ref > 2) {
- out->ref -= 2;
- unlockpage(out);
- continue;
- }
- unlockpage(out);
- }
-#endif
+
k = kmap(out);
kaddr = (char*)VA(k);
qlock(&c->wrl);
@@ 330,7 332,7 @@ int
needpages(void *p)
{
USED(p);
- return palloc.freecount < HIGHWATER+MAXHEADROOM;
+ return palloc.freecount < swapalloc.headroom;
}
void
M port/tcpif.c => port/tcpif.c +12 -0
@@ 15,6 15,7 @@ state_upcall(Ipconv *s, char oldstate, char newstate)
{
Block *bp;
int len;
+ Tcpctl *tcb = &s->tcpctl;
DPRINT("state_upcall: %s -> %s err %s\n",
tcpstate[oldstate], tcpstate[newstate], s->err);
@@ 48,8 49,16 @@ state_upcall(Ipconv *s, char oldstate, char newstate)
qunlock(s);
break;
}
+
+ if(oldstate == Syn_sent)
+ wakeup(&tcb->syner);
}
+static int
+notsyner(void *ic)
+{
+ return ((Tcpctl*)ic)->state != Syn_sent;
+}
void
tcpstart(Ipconv *s, int mode, ushort window, char tos)
{
@@ 76,6 85,9 @@ tcpstart(Ipconv *s, int mode, ushort window, char tos)
setstate(s, Syn_sent);
tcp_output(s);
qunlock(tcb);
+ sleep(&tcb->syner, notsyner, tcb);
+ if(tcb->state != Established && tcb->state != Syn_received)
+ error(Etimedout);
break;
}
}