1
Fork 0
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:
Gavin Matthews 1998-11-24 15:47:01 +00:00
parent 0801501bb6
commit 6ccd23a990
5 changed files with 178 additions and 73 deletions

View file

@ -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);
}
}

View file

@ -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)

View file

@ -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 */

View file

@ -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 @@@@ */

View file

@ -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;