Image* attachimage(int type, Chan *c, ulong base, ulong len) { Image *i, **l; lock(&imagealloc); /* * Search the image cache for remains of the text from a previous * or currently running incarnation */ for(i = ihash(c->qid.path); i; i = i->hash) { if(c->qid.path == i->qid.path) { lock(i); if(eqqid(c->qid, i->qid) && eqqid(c->mqid, i->mqid) && c->mchan == i->mchan && c->type == i->type) { goto found; } unlock(i); } } /* * imagereclaim dumps pages from the free list which are cached by image * structures. This should free some image structures. */ while(!(i = imagealloc.free)) { unlock(&imagealloc); imagereclaim(); if(!imagealloc.free){ freebroken(); /* can use the memory */ resrcwait("no image after reclaim"); } lock(&imagealloc); } imagealloc.free = i->next; lock(i); incref(c); c->flag &= ~CCACHE; i->c = c; i->type = c->type; i->qid = c->qid; i->mqid = c->mqid; i->mchan = c->mchan; l = &ihash(c->qid.path); i->hash = *l; *l = i; found: unlock(&imagealloc); if(i->s == 0) { i->ref++; if(waserror()) { unlock(i); putimage(i); nexterror(); } i->s = newseg(type, base, len); i->s->image = i; poperror(); } else incref(i->s); return i; }
static void pager(void *junk) { int i; Segment *s; Proc *p, *ep; if(waserror()) panic("pager: os error\n"); p = proctab(0); ep = &p[conf.nproc]; loop: up->psstate = "Idle"; sleep(&swapalloc.r, needpages, 0); print("uh oh. someone woke the pager\n"); while(needpages(junk)) { if(swapimage.c) { p++; if(p >= ep) p = proctab(0); if(p->state == Dead || p->noswap) continue; if(!canqlock(&p->seglock)) continue; /* process changing its segments */ for(i = 0; i < NSEG; i++) { if(!needpages(junk)){ qunlock(&p->seglock); goto loop; } if((s = p->seg[i])) { switch(s->type&SG_TYPE) { default: break; case SG_TEXT: pageout(p, s); break; case SG_DATA: case SG_BSS: case SG_STACK: case SG_SHARED: up->psstate = "Pageout"; pageout(p, s); if(ioptr != 0) { up->psstate = "I/O"; executeio(); } break; } } } qunlock(&p->seglock); } else { print("out of physical memory; no swap configured\n"); if(!cpuserver || freebroken() == 0) killbig("out of memory"); /* Emulate the old system if no swap channel */ tsleep(&up->sleep, return0, 0, 5000); wakeup(&palloc.r); } } goto loop; }