void killbig(char *why) { int i; Segment *s; ulong l, max; Proc *p, *ep, *kp; max = 0; kp = nil; ep = procalloc.arena+conf.nproc; for(p = procalloc.arena; p < ep; p++) { if(p->state == Dead || p->kp) continue; if((p->noswap || (p->procmode & 0222) == 0) && strcmp(eve, p->user) == 0) continue; l = procpagecount(p); if(l > max){ kp = p; max = l; } } if(kp == nil) return; print("%lud: %s killed: %s\n", kp->pid, kp->text, why); qlock(&kp->seglock); for(p = procalloc.arena; p < ep; p++) { if(p->state == Dead || p->kp) continue; if(p != kp && p->seg[BSEG] != nil && p->seg[BSEG] == kp->seg[BSEG]) p->procctl = Proc_exitbig; } kp->procctl = Proc_exitbig; for(i = 0; i < NSEG; i++) { s = kp->seg[i]; if(s == nil) continue; switch(s->type & SG_TYPE){ case SG_SHARED: case SG_PHYSICAL: case SG_FIXED: continue; } qlock(s); mfreeseg(s, s->base, (s->top - s->base)/BY2PG); qunlock(s); } qunlock(&kp->seglock); }
void killbig(char *why) { int i; Segment *s; ulong l, max; Proc *p, *ep, *kp; max = 0; kp = 0; ep = procalloc.arena+conf.nproc; for(p = procalloc.arena; p < ep; p++) { if(p->state == Dead || p->kp) continue; l = 0; for(i=1; i<NSEG; i++) { s = p->seg[i]; if(s != 0) l += s->top - s->base; } if(l > max && ((p->procmode&0222) || strcmp(eve, p->user)!=0)) { kp = p; max = l; } } print("%lud: %s killed: %s\n", kp->pid, kp->text, why); for(p = procalloc.arena; p < ep; p++) { if(p->state == Dead || p->kp) continue; if(p != kp && p->seg[BSEG] && p->seg[BSEG] == kp->seg[BSEG]) p->procctl = Proc_exitbig; } kp->procctl = Proc_exitbig; for(i = 0; i < NSEG; i++) { s = kp->seg[i]; if(s != 0 && canqlock(&s->lk)) { mfreeseg(s, s->base, (s->top - s->base)/BY2PG); qunlock(&s->lk); } } }
long syssegfree(ulong *arg) { Segment *s; ulong from, to; from = arg[0]; s = seg(up, from, 1); if(s == nil) error(Ebadarg); to = (from + arg[1]) & ~(BY2PG-1); from = PGROUND(from); if(to > s->top) { qunlock(&s->lk); error(Ebadarg); } mfreeseg(s, from, (to - from) / BY2PG); qunlock(&s->lk); flushmmu(); return 0; }
long ibrk(ulong addr, int seg) { Segment *s, *ns; ulong newtop, newsize; int i, mapsize; Pte **map; s = up->seg[seg]; if(s == 0) error(Ebadarg); if(addr == 0) return s->base; qlock(&s->lk); /* We may start with the bss overlapping the data */ if(addr < s->base) { if(seg != BSEG || up->seg[DSEG] == 0 || addr < up->seg[DSEG]->base) { qunlock(&s->lk); error(Enovmem); } addr = s->base; } newtop = PGROUND(addr); newsize = (newtop-s->base)/BY2PG; if(newtop < s->top) { /* * do not shrink a segment shared with other procs, as the * to-be-freed address space may have been passed to the kernel * already by another proc and is past the validaddr stage. */ if(s->ref > 1){ qunlock(&s->lk); error(Einuse); } mfreeseg(s, newtop, (s->top-newtop)/BY2PG); s->top = newtop; s->size = newsize; qunlock(&s->lk); flushmmu(); return 0; } for(i = 0; i < NSEG; i++) { ns = up->seg[i]; if(ns == 0 || ns == s) continue; if(newtop >= ns->base && newtop < ns->top) { qunlock(&s->lk); error(Esoverlap); } } if(newsize > (SEGMAPSIZE*PTEPERTAB)) { qunlock(&s->lk); error(Enovmem); } mapsize = ROUND(newsize, PTEPERTAB)/PTEPERTAB; if(mapsize > s->mapsize){ map = smalloc(mapsize*sizeof(Pte*)); memmove(map, s->map, s->mapsize*sizeof(Pte*)); if(s->map != s->ssegmap) free(s->map); s->map = map; s->mapsize = mapsize; } s->top = newtop; s->size = newsize; qunlock(&s->lk); return 0; }
long ibrk(ulong addr, int seg) { Segment *s, *ns; ulong newtop, newsize; int i, mapsize; Pte **map; s = up->seg[seg]; if(s == 0) error(Ebadarg); if(addr == 0) return s->base; qlock(&s->lk); /* We may start with the bss overlapping the data */ if(addr < s->base) { if(seg != BSEG || up->seg[DSEG] == 0 || addr < up->seg[DSEG]->base) { qunlock(&s->lk); error(Enovmem); } addr = s->base; } newtop = PGROUND(addr); newsize = (newtop-s->base)/BY2PG; if(newtop < s->top) { mfreeseg(s, newtop, (s->top-newtop)/BY2PG); s->top = newtop; s->size = newsize; qunlock(&s->lk); flushmmu(); return 0; } if(swapfull()){ qunlock(&s->lk); error(Enoswap); } for(i = 0; i < NSEG; i++) { ns = up->seg[i]; if(ns == 0 || ns == s) continue; if(newtop >= ns->base && newtop < ns->top) { qunlock(&s->lk); error(Esoverlap); } } if(newsize > (SEGMAPSIZE*PTEPERTAB)) { qunlock(&s->lk); error(Enovmem); } mapsize = ROUND(newsize, PTEPERTAB)/PTEPERTAB; if(mapsize > s->mapsize){ map = smalloc(mapsize*sizeof(Pte*)); memmove(map, s->map, s->mapsize*sizeof(Pte*)); if(s->map != s->ssegmap) free(s->map); s->map = map; s->mapsize = mapsize; } s->top = newtop; s->size = newsize; qunlock(&s->lk); return 0; }