void destroy(void *v) { Heap *h; Type *t; if(v == H) return; h = D2H(v); { Bhdr *b; D2B(b, h); } /* consistency check */ if(--h->ref > 0 || gchalt > 64) /* Protect 'C' thread stack */ return; if(heapmonitor != nil) heapmonitor(1, h, 0); t = h->t; if(t != nil) { gclock(); t->free(h, 0); gcunlock(); freetype(t); } poolfree(heapmem, h); }
void freememimage(Memimage *i) { if(i == nil) return; if(i->data->ref-- == 1 && i->data->allocd){ if(i->data->base) poolfree(imagmem, i->data->base); free(i->data); } free(i); }
Memimage* allocmemimage(Rectangle r, ulong chan) { int d; uchar *p; ulong l, nw; Memdata *md; Memimage *i; if((d = chantodepth(chan)) == 0) { werrstr("bad channel descriptor %.8lux", chan); return nil; } l = wordsperline(r, d); nw = l*Dy(r); md = malloc(sizeof(Memdata)); if(md == nil) return nil; md->ref = 1; md->base = poolalloc(imagmem, sizeof(Memdata*)+(1+nw)*sizeof(ulong)); if(md->base == nil){ free(md); return nil; } p = (uchar*)md->base; *(Memdata**)p = md; p += sizeof(Memdata*); *(ulong*)p = getcallerpc(&r); p += sizeof(ulong); /* if this changes, memimagemove must change too */ md->bdata = p; md->allocd = 1; i = allocmemimaged(r, chan, md); if(i == nil){ poolfree(imagmem, md->base); free(md); return nil; } md->imref = i; return i; }
void freelist(Heap *h, int swept) { Type *t; List *l; Heap *th; l = H2D(List*, h); t = l->t; if(t != nil) { if(!swept && t->np) freeptrs(l->data, t); t->ref--; if(t->ref == 0) { free(t->initialize); free(t); } } if(swept) return; l = l->tail; while(l != (List*)H) { t = l->t; th = D2H(l); if(th->ref-- != 1) break; th->t->ref--; /* should be &Tlist and ref shouldn't go to 0 here nor be 0 already */ if(t != nil) { if (t->np) freeptrs(l->data, t); t->ref--; if(t->ref == 0) { free(t->initialize); free(t); } } l = l->tail; if(heapmonitor != nil) heapmonitor(1, th, 0); poolfree(heapmem, th); } }