1
Fork 0
mirror of git://git.sv.gnu.org/emacs.git synced 2026-03-15 19:31:29 -07:00

Move cbsfindinzones so that diff is cleaner.

Copied from Perforce
 Change: 185578
 ServerID: perforce.ravenbrook.com
This commit is contained in:
Gareth Rees 2014-04-16 10:24:26 +01:00
parent 87b3880405
commit b3a3b0b8fc

View file

@ -925,6 +925,75 @@ static Bool cbsTestTreeInZones(SplayTree splay, Tree tree,
&& ZoneSetInter(zonedBlock->zones, closure->zoneSet) != ZoneSetEMPTY;
}
static Res cbsFindInZones(Range rangeReturn, Range oldRangeReturn,
Land land, Size size,
ZoneSet zoneSet, Bool high)
{
CBS cbs;
Tree tree;
cbsTestNodeInZonesClosureStruct closure;
Res res;
LandFindMethod landFind;
SplayFindMethod splayFind;
AVER(rangeReturn != NULL);
AVER(oldRangeReturn != NULL);
AVERT(Land, land);
cbs = cbsOfLand(land);
AVERT(CBS, cbs);
AVER(IsLandSubclass(cbsLand(cbs), CBSZonedLandClass));
/* AVERT(ZoneSet, zoneSet); */
AVER(BoolCheck(high));
landFind = high ? cbsFindLast : cbsFindFirst;
splayFind = high ? SplayFindLast : SplayFindFirst;
if (zoneSet == ZoneSetEMPTY)
return ResFAIL;
if (zoneSet == ZoneSetUNIV) {
FindDelete fd = high ? FindDeleteHIGH : FindDeleteLOW;
if ((*landFind)(rangeReturn, oldRangeReturn, land, size, fd))
return ResOK;
else
return ResFAIL;
}
if (ZoneSetIsSingle(zoneSet) && size > ArenaStripeSize(LandArena(land)))
return ResFAIL;
/* It would be nice if there were a neat way to eliminate all runs of
zones in zoneSet too small for size.*/
closure.arena = LandArena(land);
closure.zoneSet = zoneSet;
closure.size = size;
closure.high = high;
if (splayFind(&tree, cbsSplay(cbs),
cbsTestNodeInZones,
cbsTestTreeInZones,
&closure, sizeof(closure))) {
CBSBlock block = cbsBlockOfTree(tree);
RangeStruct rangeStruct, oldRangeStruct;
AVER(CBSBlockBase(block) <= closure.base);
AVER(AddrOffset(closure.base, closure.limit) >= size);
AVER(ZoneSetSub(ZoneSetOfRange(LandArena(land), closure.base, closure.limit), zoneSet));
AVER(closure.limit <= CBSBlockLimit(block));
if (!high)
RangeInit(&rangeStruct, closure.base, AddrAdd(closure.base, size));
else
RangeInit(&rangeStruct, AddrSub(closure.limit, size), closure.limit);
res = cbsDelete(&oldRangeStruct, land, &rangeStruct);
if (res == ResOK) { /* enough memory to split block */
RangeCopy(rangeReturn, &rangeStruct);
RangeCopy(oldRangeReturn, &oldRangeStruct);
}
} else
res = ResFAIL;
return res;
}
/* cbsFindLast -- find the last block of at least the given size */
@ -1006,76 +1075,6 @@ static Bool cbsFindLargest(Range rangeReturn, Range oldRangeReturn,
}
static Res cbsFindInZones(Range rangeReturn, Range oldRangeReturn,
Land land, Size size,
ZoneSet zoneSet, Bool high)
{
CBS cbs;
Tree tree;
cbsTestNodeInZonesClosureStruct closure;
Res res;
LandFindMethod landFind;
SplayFindMethod splayFind;
AVER(rangeReturn != NULL);
AVER(oldRangeReturn != NULL);
AVERT(Land, land);
cbs = cbsOfLand(land);
AVERT(CBS, cbs);
AVER(IsLandSubclass(cbsLand(cbs), CBSZonedLandClass));
/* AVERT(ZoneSet, zoneSet); */
AVER(BoolCheck(high));
landFind = high ? cbsFindLast : cbsFindFirst;
splayFind = high ? SplayFindLast : SplayFindFirst;
if (zoneSet == ZoneSetEMPTY)
return ResFAIL;
if (zoneSet == ZoneSetUNIV) {
FindDelete fd = high ? FindDeleteHIGH : FindDeleteLOW;
if ((*landFind)(rangeReturn, oldRangeReturn, land, size, fd))
return ResOK;
else
return ResFAIL;
}
if (ZoneSetIsSingle(zoneSet) && size > ArenaStripeSize(LandArena(land)))
return ResFAIL;
/* It would be nice if there were a neat way to eliminate all runs of
zones in zoneSet too small for size.*/
closure.arena = LandArena(land);
closure.zoneSet = zoneSet;
closure.size = size;
closure.high = high;
if (splayFind(&tree, cbsSplay(cbs),
cbsTestNodeInZones,
cbsTestTreeInZones,
&closure, sizeof(closure))) {
CBSBlock block = cbsBlockOfTree(tree);
RangeStruct rangeStruct, oldRangeStruct;
AVER(CBSBlockBase(block) <= closure.base);
AVER(AddrOffset(closure.base, closure.limit) >= size);
AVER(ZoneSetSub(ZoneSetOfRange(LandArena(land), closure.base, closure.limit), zoneSet));
AVER(closure.limit <= CBSBlockLimit(block));
if (!high)
RangeInit(&rangeStruct, closure.base, AddrAdd(closure.base, size));
else
RangeInit(&rangeStruct, AddrSub(closure.limit, size), closure.limit);
res = cbsDelete(&oldRangeStruct, land, &rangeStruct);
if (res == ResOK) { /* enough memory to split block */
RangeCopy(rangeReturn, &rangeStruct);
RangeCopy(oldRangeReturn, &oldRangeStruct);
}
} else
res = ResFAIL;
return res;
}
/* cbsDescribe -- describe a CBS
*
* See <design/land/#function.describe>.