M port/devip.c => port/devip.c +1 -1
@@ 1063,7 1063,7 @@ nextport(Ipifc *ifc, int priv)
if(priv){
base = PRIVPORTALLOC;
- max = PORTALLOC;
+ max = UNPRIVPORTALLOC;
p = &lastport[1];
} else {
base = PORTALLOC;
M port/devproc.c => port/devproc.c +9 -4
@@ 571,11 571,16 @@ procctlreq(Proc *p, char *va, int n)
if(strncmp(buf, "stop", 4) == 0)
procstopwait(p, Proc_stopme);
else if(strncmp(buf, "kill", 4) == 0) {
- if(p->state == Broken)
+ switch(p->state) {
+ case Broken:
+ unbreak(p);
+ break;
+ case Stopped:
+ postnote(p, 0, "sys: killed", NExit);
+ p->procctl = Proc_exitme;
ready(p);
- else {
- if(p->state == Stopped)
- ready(p);
+ break;
+ default:
postnote(p, 0, "sys: killed", NExit);
p->procctl = Proc_exitme;
}
M port/ipdat.h => port/ipdat.h +1 -0
@@ 422,6 422,7 @@ enum {
/* Protocol port numbers */
PORTALLOC = 5000, /* First automatic allocated port */
PRIVPORTALLOC = 600, /* First priveleged port allocated */
+ UNPRIVPORTALLOC = 1024, /* First unpriveleged port allocated */
PORTMAX = 30000, /* Last port to allocte */
};
M port/portfns.h => port/portfns.h +1 -0
@@ 254,6 254,7 @@ void naildownstream(Stream*);
void swapinit(void);
long syscall(Ureg*);
void tsleep(Rendez*, int (*)(void*), void*, int);
+void unbreak(Proc*);
void uncachepage(Page*);
long unicode(uchar*);
long unionread(Chan*, void*, long);
M port/proc.c => port/proc.c +55 -43
@@ 440,23 440,24 @@ postnote(Proc *p, int dolock, char *n, int flag)
splx(s);
}
+ if(p->state != Rendezvous)
+ return ret;
+
+ /* Try and pull out of a rendezvous */
+ lock(p->pgrp);
if(p->state == Rendezvous) {
- lock(p->pgrp);
- if(p->state == Rendezvous) {
- p->rendval = ~0;
- l = &REND(p->pgrp, p->rendtag);
- for(d = *l; d; d = d->rendhash) {
- if(d == p) {
- *l = p->rendhash;
- break;
- }
- l = &d->rendhash;
+ p->rendval = ~0;
+ l = &REND(p->pgrp, p->rendtag);
+ for(d = *l; d; d = d->rendhash) {
+ if(d == p) {
+ *l = p->rendhash;
+ break;
}
- ready(p);
+ l = &d->rendhash;
}
- unlock(p->pgrp);
+ ready(p);
}
-
+ unlock(p->pgrp);
return ret;
}
@@ 464,36 465,45 @@ postnote(Proc *p, int dolock, char *n, int flag)
* weird thing: keep at most NBROKEN around
*/
#define NBROKEN 4
-struct{
- Lock;
+struct
+{
+ QLock;
int n;
Proc *p[NBROKEN];
}broken;
void
-addbroken(Proc *c)
+addbroken(Proc *p)
{
- int b;
-
- lock(&broken);
- if(broken.n == NBROKEN){
+ qlock(&broken);
+ if(broken.n == NBROKEN) {
ready(broken.p[0]);
memmove(&broken.p[0], &broken.p[1], sizeof(Proc*)*(NBROKEN-1));
--broken.n;
}
- broken.p[broken.n++] = c;
- unlock(&broken);
- c->state = Broken;
- c->psstate = 0;
- sched(); /* until someone lets us go */
- lock(&broken);
- for(b=0; b<NBROKEN; b++)
- if(broken.p[b] == c){
- broken.n--;
- memmove(&broken.p[b], &broken.p[b+1], sizeof(Proc*)*(NBROKEN-(b+1)));
- break;
- }
- unlock(&broken);
+ broken.p[broken.n++] = p;
+ qunlock(&broken);
+
+ p->state = Broken;
+ p->psstate = 0;
+ sched();
+}
+
+void
+unbreak(Proc *p)
+{
+ int b;
+
+ qlock(&broken);
+ for(b=0; b < NBROKEN; b++) {
+ if(broken.p[b] != p)
+ continue;
+
+ broken.n--;
+ memmove(&broken.p[b], &broken.p[b+1], sizeof(Proc*)*(NBROKEN-(b+1)));
+ ready(p);
+ }
+ qunlock(&broken);
}
int
@@ 501,12 511,14 @@ freebroken(void)
{
int i, n;
- lock(&broken);
+ qlock(&broken);
n = broken.n;
- for(i=0; i<n; i++)
+ for(i=0; i<n; i++) {
ready(broken.p[i]);
+ broken.p[i] = 0;
+ }
broken.n = 0;
- unlock(&broken);
+ qunlock(&broken);
return n;
}
@@ 516,7 528,7 @@ pexit(char *exitstr, int freemem)
int n;
long utime, stime;
Proc *p, *c;
- Segment **s, **es, *os;
+ Segment **s, **es;
Waitq *wq, *f, *next;
c = u->p;
@@ 534,7 546,8 @@ pexit(char *exitstr, int freemem)
* do some housekeeping.
*/
if(c->kp == 0) {
- if((p = c->parent) == 0) {
+ p = c->parent;
+ if(p == 0) {
if(exitstr == 0)
exitstr = "unknown";
panic("boot process died: %s", exitstr);
@@ 557,7 570,8 @@ pexit(char *exitstr, int freemem)
if(exitstr && exitstr[0]){
n = sprint(wq->w.msg, "%s %d:", c->text, c->pid);
strncpy(wq->w.msg+n, exitstr, ERRLEN-n);
- }else
+ }
+ else
wq->w.msg[0] = '\0';
lock(&p->exl);
@@ 587,10 601,8 @@ pexit(char *exitstr, int freemem)
es = &c->seg[NSEG];
for(s = c->seg; s < es; s++)
- if(os = *s) {
- *s = 0;
- putseg(os);
- }
+ if(*s)
+ putseg(*s);
lock(&c->exl); /* Prevent my children from leaving waits */
c->pid = 0;
M port/segment.c => port/segment.c +16 -16
@@ 335,6 335,7 @@ ibrk(ulong addr, int seg)
if(newtop < s->top) {
mfreeseg(s, newtop, (s->top-newtop)/BY2PG);
qunlock(&s->lk);
+ flushmmu();
return 0;
}
@@ 371,24 372,24 @@ mfreeseg(Segment *s, ulong start, int pages)
for(i = soff/PTEMAPMEM; i < SEGMAPSIZE; i++) {
if(pages <= 0)
- goto done;
- if(s->map[i]) {
- while(j < PTEPERTAB) {
- if(pg = s->map[i]->pages[j]) {
- putpage(pg);
- s->map[i]->pages[j] = 0;
- }
- if(--pages == 0)
- goto done;
- j++;
+ break;
+ if(s->map[i] == 0) {
+ pages -= PTEPERTAB-j;
+ j = 0;
+ continue;
+ }
+ while(j < PTEPERTAB) {
+ pg = s->map[i]->pages[j];
+ if(pg) {
+ putpage(pg);
+ s->map[i]->pages[j] = 0;
}
+ if(--pages == 0)
+ return;
+ j++;
}
- else
- pages -= PTEPERTAB-j;
j = 0;
}
-done:
- flushmmu();
}
ulong
@@ 407,8 408,7 @@ segattach(Proc *p, ulong attr, char *name, ulong va, ulong len)
vmemchr(name, 0, ~0);
for(sno = 0; sno < NSEG; sno++)
- if(u->p->seg[sno] == 0)
- if(sno != ESEG)
+ if(u->p->seg[sno] == 0 && sno != ESEG)
break;
if(sno == NSEG)
M port/sysproc.c => port/sysproc.c +6 -3
@@ 32,7 32,7 @@ sysrfork(ulong *arg)
*/
int lastvar;
- flag = arg[0];
+ flag = arg[0];
p = u->p;
if((flag&RFPROC) == 0) {
if(flag & (RFNAMEG|RFCNAMEG)) {
@@ 345,7 345,9 @@ sysexec(ulong *arg)
memmove(p->text, elem, NAMELEN);
/*
- * Committed. Free old memory. Special segments are maintained accross exec
+ * Committed.
+ * Free old memory.
+ * Special segments are maintained accross exec
*/
for(i = SSEG; i <= BSEG; i++) {
putseg(p->seg[i]);
@@ 616,6 618,7 @@ syssegfree(ulong *arg)
mfreeseg(s, from, pages);
qunlock(&s->lk);
+ flushmmu();
return 0;
}
@@ 643,7 646,7 @@ sysrendezvous(ulong *arg)
*l = p->rendhash;
val = p->rendval;
p->rendval = arg[1];
-
+ /* Easy race avoidance */
while(p->state != Rendezvous)
;
ready(p);