static Res MFSAlloc(Addr *pReturn, Pool pool, Size size, Bool withReservoirPermit) { Header f; Res res; MFS mfs; AVERT(Pool, pool); mfs = PoolPoolMFS(pool); AVERT(MFS, mfs); AVER(pReturn != NULL); AVER(size == mfs->unroundedUnitSize); AVERT(Bool, withReservoirPermit); f = mfs->freeList; /* If the free list is empty then extend the pool with a new region. */ if(f == NULL) { Addr base; if (!mfs->extendSelf) return ResLIMIT; /* Create a new region and attach it to the pool. */ res = ArenaAlloc(&base, SegPrefDefault(), mfs->extendBy, pool, withReservoirPermit); if(res != ResOK) return res; MFSExtend(pool, base, mfs->extendBy); /* The first unit in the region is now the head of the new free list. */ f = mfs->freeList; } AVER(f != NULL); /* Detach the first free unit from the free list and return its address. */ mfs->freeList = f->next; AVER(mfs->free >= mfs->unitSize); mfs->free -= mfs->unitSize; *pReturn = (Addr)f; return ResOK; }
static Res MVFFInit(Pool pool, va_list arg) { Size extendBy, avgSize, align; Bool slotHigh, arenaHigh, firstFit; MVFF mvff; Arena arena; Res res; void *p; ZoneSet zones; AVERT(Pool, pool); /* .arg: class-specific additional arguments; see */ /* <design/poolmvff/#method.init> */ /* .arg.check: we do the same checks here and in MVFFCheck */ /* except for arenaHigh, which is stored only in the segPref. */ extendBy = va_arg(arg, Size); avgSize = va_arg(arg, Size); align = va_arg(arg, Size); slotHigh = va_arg(arg, Bool); arenaHigh = va_arg(arg, Bool); firstFit = va_arg(arg, Bool); AVER(extendBy > 0); /* .arg.check */ AVER(avgSize > 0); /* .arg.check */ AVER(avgSize <= extendBy); /* .arg.check */ AVER(BoolCheck(slotHigh)); AVER(BoolCheck(arenaHigh)); AVER(BoolCheck(firstFit)); mvff = Pool2MVFF(pool); arena = PoolArena(pool); mvff->extendBy = extendBy; if (extendBy < ArenaAlign(arena)) mvff->minSegSize = ArenaAlign(arena); else mvff->minSegSize = extendBy; mvff->avgSize = avgSize; pool->alignment = align; mvff->slotHigh = slotHigh; mvff->firstFit = firstFit; res = ControlAlloc(&p, arena, sizeof(SegPrefStruct), FALSE); if (res != ResOK) return res; mvff->segPref = (SegPref)p; *mvff->segPref = *SegPrefDefault(); SegPrefExpress(mvff->segPref, arenaHigh ? SegPrefHigh : SegPrefLow, NULL); /* If using zoneset placement, just put it apart from the others. */ zones = ZoneSetComp(ArenaDefaultZONESET); SegPrefExpress(mvff->segPref, SegPrefZoneSet, (void *)&zones); mvff->total = 0; mvff->free = 0; res = CBSInit(arena, CBSOfMVFF(mvff), (void *)mvff, NULL, NULL, NULL, NULL, mvff->extendBy, align, TRUE, TRUE); if (res != ResOK) goto failInit; mvff->sig = MVFFSig; AVERT(MVFF, mvff); EVENT8(PoolInitMVFF, pool, arena, extendBy, avgSize, align, slotHigh, arenaHigh, firstFit); return ResOK; failInit: ControlFree(arena, p, sizeof(SegPrefStruct)); return res; }