Image* attachimage(int type, Chan *c, int color, uintptr base, usize len) { Image *i, **l; /* reclaim any free channels from reclaimed segments */ if(imagealloc.nfreechan) imagechanreclaim(); 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->dev->dc == i->dc) { //subtype 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 = lruimage())) { unlock(&imagealloc); imagereclaim(); sched(); lock(&imagealloc); } lock(i); incref(c); i->c = c; i->dc = c->dev->dc; //subtype i->qid = c->qid; i->mqid = c->mqid; i->mchan = c->mchan; i->color = color; l = &ihash(c->qid.path); i->hash = *l; *l = i; found: imageused(i); unlock(&imagealloc); if(i->s == 0) { /* Disaster after commit in exec */ if(waserror()) { unlock(i); pexit(Enovmem, 1); } i->s = newseg(type, base, len); i->s->image = i; i->s->color = color; i->ref++; poperror(); } else incref(i->s); return i; }
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; }
Image* attachimage(int type, Chan *c, ulong base, ulong len) { Image *i, **l; /* reclaim any free channels from reclaimed segments */ if(imagealloc.nfreechan) imagechanreclaim(); lock(&imagealloc.lk); /* * 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->ref.lk); if(eqqid(c->qid, i->qid) && eqqid(c->mqid, i->mqid) && c->mchan == i->mchan && c->type == i->type) { goto found; } unlock(&i->ref.lk); } } /* * 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.lk); imagereclaim(); sched(); lock(&imagealloc.lk); } imagealloc.free = i->next; lock(&i->ref.lk); incref(&c->ref); 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.lk); if(i->s == 0) { /* Disaster after commit in exec */ if(waserror()) { unlock(&i->ref.lk); pexit(Enovmem, 1); } i->s = newseg(type, base, len); i->s->image = i; i->ref.ref++; poperror(); } else incref(&i->s->ref); return i; }