/* * convert malloced or non-malloced buffer to a Block. * used to build custom Block allocators. * * buf must be at least blocksize(usable) bytes. */ Block * mem2block(void *buf, ulong usable, int malloced) { Block *b; if(buf == nil) return nil; b = (Block *)buf; b->next = nil; b->list = nil; b->free = 0; b->flag = 0; b->ref = 0; b->magic = Bmagic; _xinc(&b->ref); /* align start of data portion by rounding up */ b->base = (uchar*)ALIGNUP((ulong)b + sizeof(Block)); /* align end of data portion by rounding down */ b->lim = (uchar*)b + (malloced? msize(b): blocksize(usable)); b->lim = (uchar*)((ulong)b->lim & ~(BLOCKALIGN-1)); /* leave sluff at beginning for added headers */ b->wp = b->rp = b->lim - ALIGNUP(usable); if(b->rp < b->base) panic("mem2block: b->rp < b->base"); if(b->lim > (uchar*)b + (malloced? msize(b): blocksize(usable))) panic("mem2block: b->lim beyond Block end"); return b; }
static void rxfreeb(Block *b) { /* freeb(b) will have previously decremented b->ref to 0; raise to 1 */ _xinc(&b->ref); b->wp = b->rp = (uchar*)((uintptr)(b->lim - Rxblklen) & ~(Bufalign - 1)); assert(((uintptr)b->rp & (Bufalign - 1)) == 0); b->free = rxfreeb; ilock(&freeblocks); b->next = freeblocks.head; freeblocks.head = b; iunlock(&freeblocks); }
static void inccnt(Ref *r) { _xinc(&r->ref); }