mirror of
git://git.sv.gnu.org/emacs.git
synced 2026-01-19 01:10:57 -08:00
Change.epcore.brisling.160152.assignment.2 delete while finding
Copied from Perforce Change: 20356 ServerID: perforce.ravenbrook.com
This commit is contained in:
parent
0801501bb6
commit
6ccd23a990
5 changed files with 178 additions and 73 deletions
101
mps/src/cbs.c
101
mps/src/cbs.c
|
|
@ -1,6 +1,6 @@
|
|||
/* impl.c.cbs: COALESCING BLOCK STRUCTURE IMPLEMENTATION
|
||||
*
|
||||
* $HopeName: MMsrc!cbs.c(trunk.9) $
|
||||
* $HopeName: MMsrc!cbs.c(trunk.10) $
|
||||
* Copyright (C) 1998 Harlequin Group plc, all rights reserved.
|
||||
*
|
||||
* .readership: Any MPS developer.
|
||||
|
|
@ -18,7 +18,7 @@
|
|||
#include "mpm.h"
|
||||
|
||||
|
||||
SRCID(cbs, "$HopeName: MMsrc!cbs.c(trunk.9) $");
|
||||
SRCID(cbs, "$HopeName: MMsrc!cbs.c(trunk.10) $");
|
||||
|
||||
typedef void **CBSEmergencyBlock; /* next, limit */
|
||||
typedef void **CBSEmergencyGrain; /* next */
|
||||
|
|
@ -1268,11 +1268,74 @@ void CBSSetMinSize(CBS cbs, Size minSize) {
|
|||
}
|
||||
|
||||
|
||||
static Bool CBSFindDeleteCheck(CBSFindDelete findDelete)
|
||||
{
|
||||
CHECKL(findDelete == CBSFindDeleteNONE ||
|
||||
findDelete == CBSFindDeleteLOW ||
|
||||
findDelete == CBSFindDeleteHIGH ||
|
||||
findDelete == CBSFindDeleteENTIRE);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
typedef (*CBSDeleteMethod)(CBS cbs, Addr base, Addr limit);
|
||||
|
||||
static void CBSFindDeleteRange(Addr *baseReturn, Addr *limitReturn,
|
||||
CBS cbs, Addr base, Addr limit, Size size,
|
||||
CBSDeleteMethod delete,
|
||||
CBSFindDelete findDelete)
|
||||
{
|
||||
Bool callDelete = TRUE;
|
||||
|
||||
AVER(baseReturn != NULL);
|
||||
AVER(limitReturn != NULL);
|
||||
AVERT(CBS, cbs);
|
||||
AVER(base < limit);
|
||||
AVER(size > 0);
|
||||
AVER(AddrOffset(base, limit) >= size);
|
||||
AVER(FUNCHECK(delete));
|
||||
AVERT(CBSFindDelete, findDelete);
|
||||
|
||||
switch(findDelete) {
|
||||
|
||||
case CBSFindDeleteNONE: {
|
||||
callDelete = FALSE;
|
||||
} break;
|
||||
|
||||
case CBSFindDeleteLOW: {
|
||||
limit = AddrAdd(base, size);
|
||||
} break;
|
||||
|
||||
case CBSFindDeleteHIGH: {
|
||||
base = AddrSub(limit, size);
|
||||
} break;
|
||||
|
||||
case CBSFindDeleteENTIRE: {
|
||||
/* do nothing */
|
||||
} break;
|
||||
|
||||
default: {
|
||||
NOTREACHED;
|
||||
} break;
|
||||
}
|
||||
|
||||
if(callDelete) {
|
||||
Res res;
|
||||
res = (*delete)(cbs, base, limit);
|
||||
AVER(res == ResOK);
|
||||
}
|
||||
|
||||
*baseReturn = base;
|
||||
*limitReturn = limit;
|
||||
}
|
||||
|
||||
|
||||
Bool CBSFindFirst(Addr *baseReturn, Addr *limitReturn,
|
||||
CBS cbs, Size size)
|
||||
CBS cbs, Size size, CBSFindDelete findDelete)
|
||||
{
|
||||
Bool found;
|
||||
Addr base = (Addr)0, limit = (Addr)0; /* only defined when found is TRUE */
|
||||
CBSDeleteMethod deleteMethod = NULL;
|
||||
|
||||
AVERT(CBS, cbs);
|
||||
CBSEnter(cbs);
|
||||
|
|
@ -1282,6 +1345,7 @@ Bool CBSFindFirst(Addr *baseReturn, Addr *limitReturn,
|
|||
AVER(size > 0);
|
||||
AVER(sizeof(unsigned long) >= sizeof(Size));
|
||||
AVER(cbs->fastFind);
|
||||
AVERT(CBSFindDelete, findDelete);
|
||||
|
||||
/* might do some good. */
|
||||
CBSFlushEmergencyLists(cbs);
|
||||
|
|
@ -1299,6 +1363,7 @@ Bool CBSFindFirst(Addr *baseReturn, Addr *limitReturn,
|
|||
AVER(CBSBlockSize(block) >= size);
|
||||
base = CBSBlockBase(block);
|
||||
limit = CBSBlockLimit(block);
|
||||
deleteMethod = &CBSDeleteFromTree;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -1313,6 +1378,7 @@ Bool CBSFindFirst(Addr *baseReturn, Addr *limitReturn,
|
|||
found = TRUE;
|
||||
base = CBSEmergencyBlockBase(block);
|
||||
limit = CBSEmergencyBlockLimit(block);
|
||||
deleteMethod = &CBSDeleteFromEmergencyBlockList;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
|
@ -1327,13 +1393,14 @@ Bool CBSFindFirst(Addr *baseReturn, Addr *limitReturn,
|
|||
found = TRUE;
|
||||
base = CBSEmergencyGrainBase(grain);
|
||||
limit = CBSEmergencyGrainLimit(cbs, grain);
|
||||
deleteMethod = &CBSDeleteFromEmergencyGrainList;
|
||||
}
|
||||
}
|
||||
|
||||
if(found) {
|
||||
AVER(AddrOffset(base, limit) >= size);
|
||||
*baseReturn = base;
|
||||
*limitReturn = limit;
|
||||
CBSFindDeleteRange(baseReturn, limitReturn, cbs, base, limit, size,
|
||||
deleteMethod, findDelete);
|
||||
}
|
||||
|
||||
CBSLeave(cbs);
|
||||
|
|
@ -1342,7 +1409,7 @@ Bool CBSFindFirst(Addr *baseReturn, Addr *limitReturn,
|
|||
|
||||
|
||||
Bool CBSFindLast(Addr *baseReturn, Addr *limitReturn,
|
||||
CBS cbs, Size size)
|
||||
CBS cbs, Size size, CBSFindDelete findDelete)
|
||||
{
|
||||
Bool found;
|
||||
Addr base = (Addr)0, limit = (Addr)0; /* only defined in found is TRUE */
|
||||
|
|
@ -1355,6 +1422,7 @@ Bool CBSFindLast(Addr *baseReturn, Addr *limitReturn,
|
|||
AVER(size > 0);
|
||||
AVER(sizeof(unsigned long) >= sizeof(Size));
|
||||
AVER(cbs->fastFind);
|
||||
AVERT(CBSFindDelete, findDelete);
|
||||
|
||||
/* might do some good. */
|
||||
CBSFlushEmergencyLists(cbs);
|
||||
|
|
@ -1369,8 +1437,9 @@ Bool CBSFindLast(Addr *baseReturn, Addr *limitReturn,
|
|||
|
||||
block = CBSBlockOfSplayNode(node);
|
||||
AVER(CBSBlockSize(block) >= size);
|
||||
base = CBSBlockBase(block);
|
||||
limit = CBSBlockLimit(block);
|
||||
CBSFindDeleteRange(&base, &limit, cbs,
|
||||
CBSBlockBase(block), CBSBlockLimit(block),
|
||||
size, &CBSDeleteFromTree, findDelete);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -1383,8 +1452,12 @@ Bool CBSFindLast(Addr *baseReturn, Addr *limitReturn,
|
|||
if(CBSEmergencyBlockSize(block) >= size &&
|
||||
(!found || CBSEmergencyBlockBase(block) > base)) {
|
||||
found = TRUE;
|
||||
base = CBSEmergencyBlockBase(block);
|
||||
limit = CBSEmergencyBlockLimit(block);
|
||||
/* @@@ could be done more efficiently */
|
||||
CBSFindDeleteRange(&base, &limit, cbs,
|
||||
CBSEmergencyBlockBase(block),
|
||||
CBSEmergencyBlockLimit(block),
|
||||
size, &CBSDeleteFromEmergencyBlockList,
|
||||
findDelete);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1401,8 +1474,12 @@ Bool CBSFindLast(Addr *baseReturn, Addr *limitReturn,
|
|||
|
||||
if(!found || CBSEmergencyGrainBase(grain) > base) {
|
||||
found = TRUE;
|
||||
base = CBSEmergencyGrainBase(grain);
|
||||
limit = CBSEmergencyGrainLimit(cbs, grain);
|
||||
/* @@@ could be done more efficiently */
|
||||
CBSFindDeleteRange(&base, &limit, cbs,
|
||||
CBSEmergencyGrainBase(grain),
|
||||
CBSEmergencyGrainLimit(cbs, grain),
|
||||
size, &CBSDeleteFromEmergencyGrainList,
|
||||
findDelete);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
/* impl.c.cbstest: COALESCING BLOCK STRUCTURE TEST
|
||||
*
|
||||
* $HopeName: MMsrc!cbstest.c(trunk.4) $
|
||||
* $HopeName: MMsrc!cbstest.c(trunk.5) $
|
||||
* Copyright (C) 1998 Harlequin Group plc. All rights reserved.
|
||||
*/
|
||||
|
||||
|
|
@ -15,7 +15,7 @@
|
|||
#include "mpsaan.h" /* ANSI arena for BTCreate and BTDestroy */
|
||||
#include "testlib.h"
|
||||
|
||||
SRCID(cbstest, "$HopeName: MMsrc!cbstest.c(trunk.4) $");
|
||||
SRCID(cbstest, "$HopeName: MMsrc!cbstest.c(trunk.5) $");
|
||||
|
||||
#define ArraySize ((Size)123456)
|
||||
#define NOperations ((Size)125000)
|
||||
|
|
@ -454,32 +454,70 @@ static void deallocate(CBS cbs, Addr block, BT allocTable,
|
|||
}
|
||||
}
|
||||
|
||||
static void find(CBS cbs, void *block, BT alloc, Size size, Bool high)
|
||||
static void find(CBS cbs, void *block, BT alloc, Size size, Bool high,
|
||||
CBSFindDelete findDelete)
|
||||
{
|
||||
Bool expected, found;
|
||||
Index expectedBase, expectedLimit;
|
||||
Addr foundBase, foundLimit;
|
||||
Addr foundBase, foundLimit, remainderBase, remainderLimit;
|
||||
Size oldSize, newSize;
|
||||
|
||||
if(high) {
|
||||
expected = BTFindLongResRangeHigh(&expectedBase, &expectedLimit,
|
||||
alloc,
|
||||
(Index)0, (Index)ArraySize,
|
||||
(unsigned long)size);
|
||||
checkExpectations();
|
||||
|
||||
found = CBSFindLast(&foundBase, &foundLimit, cbs, size * Alignment);
|
||||
} else {
|
||||
expected = BTFindLongResRange(&expectedBase, &expectedLimit,
|
||||
alloc,
|
||||
(Index)0, (Index)ArraySize,
|
||||
(unsigned long)size);
|
||||
expected = (high ? BTFindLongResRangeHigh : BTFindLongResRange)
|
||||
(&expectedBase, &expectedLimit, alloc,
|
||||
(Index)0, (Index)ArraySize, (unsigned long)size);
|
||||
|
||||
found = CBSFindFirst(&foundBase, &foundLimit, cbs, size * Alignment);
|
||||
if(expected) {
|
||||
oldSize = (expectedLimit - expectedBase) * Alignment;
|
||||
remainderBase = AddrOfIndex(block, expectedBase);
|
||||
remainderLimit = AddrOfIndex(block, expectedLimit);
|
||||
|
||||
switch(findDelete) {
|
||||
case CBSFindDeleteNONE: {
|
||||
/* do nothing */
|
||||
} break;
|
||||
case CBSFindDeleteENTIRE: {
|
||||
remainderBase = remainderLimit;
|
||||
} break;
|
||||
case CBSFindDeleteLOW: {
|
||||
expectedLimit = expectedBase + size;
|
||||
remainderBase = AddrOfIndex(block, expectedLimit);
|
||||
} break;
|
||||
case CBSFindDeleteHIGH: {
|
||||
expectedBase = expectedLimit - size;
|
||||
remainderLimit = AddrOfIndex(block, expectedBase);
|
||||
} break;
|
||||
}
|
||||
|
||||
if(findDelete != CBSFindDeleteNONE) {
|
||||
newSize = AddrOffset(remainderBase, remainderLimit);
|
||||
|
||||
if(oldSize >= MinSize) {
|
||||
if(newSize == 0)
|
||||
expectCallback(&CallbackDelete, oldSize, (Addr)0, (Addr)0);
|
||||
else if(newSize < MinSize)
|
||||
expectCallback(&CallbackDelete, oldSize,
|
||||
remainderBase, remainderLimit);
|
||||
else
|
||||
expectCallback(&CallbackShrink, oldSize,
|
||||
remainderBase, remainderLimit);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
found = (high ? CBSFindLast : CBSFindFirst)
|
||||
(&foundBase, &foundLimit, cbs, size * Alignment, findDelete);
|
||||
|
||||
AVER(found == expected);
|
||||
|
||||
if(found) {
|
||||
AVER(expectedBase == IndexOfAddr(block, foundBase));
|
||||
AVER(expectedLimit == IndexOfAddr(block, foundLimit));
|
||||
checkExpectations();
|
||||
|
||||
if(findDelete != CBSFindDeleteNONE)
|
||||
BTSetRange(alloc, expectedBase, expectedLimit);
|
||||
}
|
||||
|
||||
return;
|
||||
|
|
@ -498,6 +536,7 @@ extern int main(int argc, char *argv[])
|
|||
BT allocTable;
|
||||
Size size;
|
||||
Bool high;
|
||||
CBSFindDelete findDelete = CBSFindDeleteNONE;
|
||||
|
||||
testlib_unused(argc);
|
||||
testlib_unused(argv);
|
||||
|
|
@ -548,7 +587,15 @@ extern int main(int argc, char *argv[])
|
|||
case 2: {
|
||||
size = random(ArraySize / 10) + 1;
|
||||
high = random(2) ? TRUE : FALSE;
|
||||
find(cbs, dummyBlock, allocTable, size, high);
|
||||
switch(random(6)) {
|
||||
case 0:
|
||||
case 1:
|
||||
case 2: findDelete = CBSFindDeleteNONE; break;
|
||||
case 3: findDelete = CBSFindDeleteLOW; break;
|
||||
case 4: findDelete = CBSFindDeleteHIGH; break;
|
||||
case 5: findDelete = CBSFindDeleteENTIRE; break;
|
||||
}
|
||||
find(cbs, dummyBlock, allocTable, size, high, findDelete);
|
||||
} break;
|
||||
}
|
||||
if(i % 5000 == 0)
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
/* impl.h.mpm: MEMORY POOL MANAGER DEFINITIONS
|
||||
*
|
||||
* $HopeName: MMsrc!mpm.h(trunk.113) $
|
||||
* $HopeName: MMsrc!mpm.h(trunk.114) $
|
||||
* Copyright (C) 1998. Harlequin Group plc. All rights reserved.
|
||||
*/
|
||||
|
||||
|
|
@ -1034,8 +1034,8 @@ extern Addr (CBSBlockLimit)(CBSBlock block);
|
|||
(AddrOffset(CBSBlockBase((block)), CBSBlockLimit((block)))))
|
||||
extern Size (CBSBlockSize)(CBSBlock block);
|
||||
extern Bool CBSFindFirst(Addr *baseReturn, Addr *limitReturn,
|
||||
CBS cbs, Size size);
|
||||
CBS cbs, Size size, CBSFindDelete findDelete);
|
||||
extern Bool CBSFindLast(Addr *baseReturn, Addr *limitReturn,
|
||||
CBS cbs, Size size);
|
||||
CBS cbs, Size size, CBSFindDelete findDelete);
|
||||
|
||||
#endif /* mpm_h */
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
/* impl.h.mpmtypes: MEMORY POOL MANAGER TYPES
|
||||
*
|
||||
* $HopeName: MMsrc!mpmtypes.h(trunk.67) $
|
||||
* $HopeName: MMsrc!mpmtypes.h(trunk.68) $
|
||||
* Copyright (C) 1997, 1998 Harlequin Group plc. All rights reserved.
|
||||
*
|
||||
* .readership: MM developers.
|
||||
|
|
@ -115,6 +115,13 @@ typedef void (*CBSChangeSizeMethod)(CBS cbs, CBSBlock block,
|
|||
Size oldSize, Size newSize);
|
||||
typedef Bool (*CBSIterateMethod)(CBS cbs, CBSBlock block,
|
||||
void *closureP, unsigned long closureS);
|
||||
typedef unsigned CBSFindDelete;
|
||||
enum {
|
||||
CBSFindDeleteNONE, /* don't delete after finding */
|
||||
CBSFindDeleteLOW, /* delete precise size from low end */
|
||||
CBSFindDeleteHIGH, /* delete precise size from high end */
|
||||
CBSFindDeleteENTIRE /* delete entire range */
|
||||
};
|
||||
|
||||
|
||||
/* Arena*Method -- see @@@@ */
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
/* impl.c.poolmvff: First Fit Manual Variable Pool
|
||||
*
|
||||
* $HopeName: MMsrc!poolmvff.c(trunk.9) $
|
||||
* $HopeName: MMsrc!poolmvff.c(trunk.10) $
|
||||
* Copyright (C) 1998 Harlequin Group plc. All rights reserved.
|
||||
*
|
||||
* .purpose: This is a pool class for manually managed objects of
|
||||
|
|
@ -17,7 +17,7 @@
|
|||
#include "mpscmvff.h"
|
||||
#include "dbgpool.h"
|
||||
|
||||
SRCID(poolmvff, "$HopeName: MMsrc!poolmvff.c(trunk.9) $");
|
||||
SRCID(poolmvff, "$HopeName: MMsrc!poolmvff.c(trunk.10) $");
|
||||
|
||||
|
||||
/* Would go in poolmvff.h if the class had any MPS-internal clients. */
|
||||
|
|
@ -96,26 +96,6 @@ static void MVFFAddToFreeList(Addr *baseIO, Addr *limitIO, MVFF mvff) {
|
|||
}
|
||||
|
||||
|
||||
/* MVFFRemoveFromFreeList -- Remove given range from free list
|
||||
*
|
||||
* Updates MVFF counters for reduced free space.
|
||||
* Cannot(!) fail.
|
||||
*/
|
||||
|
||||
static void MVFFRemoveFromFreeList(MVFF mvff, Addr base, Addr limit) {
|
||||
Res res;
|
||||
|
||||
AVERT(MVFF, mvff);
|
||||
AVER(limit > base);
|
||||
|
||||
res = CBSDelete(CBSOfMVFF(mvff), base, limit);
|
||||
AVER(res == ResOK);
|
||||
mvff->free -= AddrOffset(base, limit);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
/* MVFFFreeSegs -- Free segments from given range
|
||||
*
|
||||
* Given a free range, attempts to find entire segments within
|
||||
|
|
@ -133,6 +113,7 @@ static void MVFFFreeSegs(MVFF mvff, Addr base, Addr limit)
|
|||
Bool b;
|
||||
Addr segLimit; /* limit of the current segment when iterating */
|
||||
Addr segBase; /* base of the current segment when iterating */
|
||||
Res res;
|
||||
|
||||
AVERT(MVFF, mvff);
|
||||
AVER(base < limit);
|
||||
|
|
@ -154,7 +135,9 @@ static void MVFFFreeSegs(MVFF mvff, Addr base, Addr limit)
|
|||
if(segBase >= base) { /* segment starts in range */
|
||||
/* Must remove from free list first, in case free list */
|
||||
/* is using inline datastructures. */
|
||||
MVFFRemoveFromFreeList(mvff, segBase, segLimit);
|
||||
res = CBSDelete(CBSOfMVFF(mvff), segBase, segLimit);
|
||||
AVER(res == ResOK);
|
||||
mvff->free -= AddrOffset(base, limit);
|
||||
mvff->total -= AddrOffset(segBase, segLimit);
|
||||
SegFree(seg);
|
||||
}
|
||||
|
|
@ -259,7 +242,7 @@ static Bool MVFFFindFirstFree(Addr *baseReturn, Addr *limitReturn,
|
|||
MVFF mvff, Size size)
|
||||
{
|
||||
Bool foundBlock;
|
||||
Addr base, limit;
|
||||
CBSFindDelete findDelete;
|
||||
|
||||
AVER(baseReturn != NULL);
|
||||
AVER(limitReturn != NULL);
|
||||
|
|
@ -267,22 +250,14 @@ static Bool MVFFFindFirstFree(Addr *baseReturn, Addr *limitReturn,
|
|||
AVER(size > 0);
|
||||
AVER(SizeIsAligned(size, PoolAlignment(MVFFPool(mvff))));
|
||||
|
||||
if(mvff->firstFit) {
|
||||
foundBlock = CBSFindFirst(&base, &limit, CBSOfMVFF(mvff), size);
|
||||
} else {
|
||||
foundBlock = CBSFindLast(&base, &limit, CBSOfMVFF(mvff), size);
|
||||
}
|
||||
findDelete = mvff->slotHigh ? CBSFindDeleteHIGH : CBSFindDeleteLOW;
|
||||
|
||||
/* CBSFind* returns a possibly larger block. */
|
||||
if(foundBlock) {
|
||||
if(mvff->slotHigh) { /* allocate in top of block */
|
||||
*limitReturn = limit;
|
||||
*baseReturn = AddrSub(limit, size);
|
||||
} else { /* allocate in bottom of block */
|
||||
*baseReturn = base;
|
||||
*limitReturn = AddrAdd(base, size);
|
||||
}
|
||||
}
|
||||
foundBlock =
|
||||
(mvff->firstFit ? CBSFindFirst : CBSFindLast)
|
||||
(baseReturn, limitReturn, CBSOfMVFF(mvff), size, findDelete);
|
||||
|
||||
if(foundBlock)
|
||||
mvff->free -= size;
|
||||
|
||||
return foundBlock;
|
||||
}
|
||||
|
|
@ -330,7 +305,6 @@ static Res MVFFAlloc(Addr *aReturn, Pool pool, Size size,
|
|||
AVER(foundBlock);
|
||||
AVER(AddrOffset(base, limit) == size);
|
||||
|
||||
MVFFRemoveFromFreeList(mvff, base, limit);
|
||||
*aReturn = base;
|
||||
|
||||
return ResOK;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue