1
Fork 0
mirror of git://git.sv.gnu.org/emacs.git synced 2025-12-18 03:40:47 -08:00

Added a pool argument to cbs creation so that cbss can share a pool. in particular, per-zone allocation cbss for the arena can share a single special block pool.

Copied from Perforce
 Change: 184469
 ServerID: perforce.ravenbrook.com
This commit is contained in:
Richard Brooksby 2014-02-15 15:00:39 +00:00
parent 2151d00c7f
commit f0b07f7bbe
7 changed files with 74 additions and 29 deletions

View file

@ -197,11 +197,22 @@ Res ArenaInit(Arena arena, ArenaClass class, Align alignment)
arena->sig = ArenaSig; arena->sig = ArenaSig;
MPS_ARGS_BEGIN(piArgs) {
MPS_ARGS_ADD(piArgs, MPS_KEY_MFS_UNIT_SIZE, sizeof(CBSBlockStruct));
MPS_ARGS_ADD(piArgs, MPS_KEY_EXTEND_BY, arena->alignment);
MPS_ARGS_ADD(piArgs, MFSExtendSelf, FALSE); /* FIXME: Explain why */
MPS_ARGS_DONE(piArgs);
res = PoolInit(&arena->cbsBlockPoolStruct.poolStruct, arena,
PoolClassMFS(), piArgs);
} MPS_ARGS_END(piArgs);
AVER(res == ResOK);
if (res != ResOK)
goto failMFSInit;
/* Initialise the freeCBS after the rest is initialised so that the CBS /* Initialise the freeCBS after the rest is initialised so that the CBS
code can check the arena and pick up the alignment. */ code can check the arena and pick up the alignment. */
MPS_ARGS_BEGIN(cbsiArgs) { MPS_ARGS_BEGIN(cbsiArgs) {
MPS_ARGS_ADD(cbsiArgs, MPS_KEY_CBS_EXTEND_BY, arena->alignment); MPS_ARGS_ADD(cbsiArgs, CBSBlockPool, &arena->cbsBlockPoolStruct.poolStruct);
MPS_ARGS_ADD(cbsiArgs, MFSExtendSelf, FALSE); /* FIXME: Explain why */
MPS_ARGS_DONE(cbsiArgs); MPS_ARGS_DONE(cbsiArgs);
res = CBSInit(arena, &arena->freeCBS, arena, arena->alignment, TRUE, cbsiArgs); res = CBSInit(arena, &arena->freeCBS, arena, arena->alignment, TRUE, cbsiArgs);
} MPS_ARGS_END(cbsiArgs); } MPS_ARGS_END(cbsiArgs);
@ -221,6 +232,8 @@ Res ArenaInit(Arena arena, ArenaClass class, Align alignment)
failReservoirInit: failReservoirInit:
CBSFinish(&arena->freeCBS); CBSFinish(&arena->freeCBS);
failCBSInit: failCBSInit:
PoolFinish(&arena->cbsBlockPoolStruct.poolStruct);
failMFSInit:
GlobalsFinish(ArenaGlobals(arena)); GlobalsFinish(ArenaGlobals(arena));
failGlobalsInit: failGlobalsInit:
return res; return res;
@ -338,17 +351,18 @@ void ArenaDestroy(Arena arena)
so manually get rid of all its tracts first. Ought to reset the so manually get rid of all its tracts first. Ought to reset the
CBS tree first, so that there are no dangling pointers. */ CBS tree first, so that there are no dangling pointers. */
{ {
Pool pool = &arena->freeCBS.blockPoolStruct.poolStruct; Pool pool = &arena->cbsBlockPoolStruct.poolStruct;
Tract tract = arena->freeCBS.blockPoolStruct.tractList; Tract tract = arena->cbsBlockPoolStruct.tractList;
Size size = ArenaAlign(arena); Size size = ArenaAlign(arena);
while(tract != NULL) { while(tract != NULL) {
Tract nextTract = (Tract)TractP(tract); /* .tract.chain */ Tract nextTract = (Tract)TractP(tract); /* .tract.chain */
(*arena->class->free)(TractBase(tract), size, pool); (*arena->class->free)(TractBase(tract), size, pool);
tract = nextTract; tract = nextTract;
} }
arena->freeCBS.blockPoolStruct.tractList = NULL; arena->cbsBlockPoolStruct.tractList = NULL;
} }
CBSFinish(&arena->freeCBS); CBSFinish(&arena->freeCBS);
PoolFinish(&arena->cbsBlockPoolStruct.poolStruct);
/* Call class-specific finishing. This will call ArenaFinish. */ /* Call class-specific finishing. This will call ArenaFinish. */
(*arena->class->finish)(arena); (*arena->class->finish)(arena);
@ -565,6 +579,8 @@ Res ControlDescribe(Arena arena, mps_lib_FILE *stream)
* This is a primitive allocator used to allocate pages for the arena CBS. * This is a primitive allocator used to allocate pages for the arena CBS.
* It is called rarely and can use a simple search. It may not use the * It is called rarely and can use a simple search. It may not use the
* CBS or any pool, because it is used as part of the bootstrap. * CBS or any pool, because it is used as part of the bootstrap.
*
* FIXME: Might this allocate a page that is in a free CBS?
*/ */
static Res arenaAllocPageInChunk(Addr *baseReturn, Chunk chunk, Pool pool) static Res arenaAllocPageInChunk(Addr *baseReturn, Chunk chunk, Pool pool)
@ -622,7 +638,7 @@ static Res arenaAllocPage(Addr *baseReturn, Arena arena, Pool pool)
Res ArenaFreeCBSInsert(Arena arena, Addr base, Addr limit) Res ArenaFreeCBSInsert(Arena arena, Addr base, Addr limit)
{ {
Pool pool = &arena->freeCBS.blockPoolStruct.poolStruct; Pool pool = &arena->cbsBlockPoolStruct.poolStruct;
RangeStruct range; RangeStruct range;
Res res; Res res;
@ -946,7 +962,7 @@ void ArenaFree(Addr base, Size size, Pool pool)
/* The CBS's MFS doesn't have enough space to describe the free memory. /* The CBS's MFS doesn't have enough space to describe the free memory.
Give it some of the memory we're about to free and try again. */ Give it some of the memory we're about to free and try again. */
Tract tract = TractOfBaseAddr(arena, base); Tract tract = TractOfBaseAddr(arena, base);
Pool mfs = &arena->freeCBS.blockPoolStruct.poolStruct; Pool mfs = &arena->cbsBlockPoolStruct.poolStruct;
AVER(size >= ArenaAlign(arena)); AVER(size >= ArenaAlign(arena));
TractFinish(tract); TractFinish(tract);
TractInit(tract, mfs, base); TractInit(tract, mfs, base);

View file

@ -99,6 +99,11 @@ Bool ArgCheckdouble(Arg arg) {
return TRUE; return TRUE;
} }
Bool ArgCheckPool(Arg arg) {
CHECKD(Pool, arg->val.pool);
return TRUE;
}
ARG_DEFINE_KEY(args_end, Shouldnt); ARG_DEFINE_KEY(args_end, Shouldnt);

View file

@ -54,6 +54,7 @@ extern Bool ArgCheckPointer(Arg arg);
extern Bool ArgCheckRankSet(Arg arg); extern Bool ArgCheckRankSet(Arg arg);
extern Bool ArgCheckRank(Arg arg); extern Bool ArgCheckRank(Arg arg);
extern Bool ArgCheckdouble(Arg arg); extern Bool ArgCheckdouble(Arg arg);
extern Bool ArgCheckPool(Arg arg);
#endif /* arg_h */ #endif /* arg_h */

View file

@ -21,15 +21,6 @@
SRCID(cbs, "$Id$"); SRCID(cbs, "$Id$");
typedef struct CBSBlockStruct *CBSBlock;
typedef struct CBSBlockStruct {
SplayNodeStruct splayNode;
Addr base;
Addr limit;
Size maxSize; /* accurate maximum block size of sub-tree */
ZoneSet zones; /* union zone set of all ranges in sub-tree */
} CBSBlockStruct;
#define CBSBlockBase(block) ((block)->base) #define CBSBlockBase(block) ((block)->base)
#define CBSBlockLimit(block) ((block)->limit) #define CBSBlockLimit(block) ((block)->limit)
#define CBSBlockSize(block) AddrOffset((block)->base, (block)->limit) #define CBSBlockSize(block) AddrOffset((block)->base, (block)->limit)
@ -41,7 +32,7 @@ typedef struct CBSBlockStruct {
#define splayNodeOfCBSBlock(block) (&((block)->splayNode)) #define splayNodeOfCBSBlock(block) (&((block)->splayNode))
#define keyOfCBSBlock(block) ((void *)&((block)->base)) #define keyOfCBSBlock(block) ((void *)&((block)->base))
#define cbsBlockPool(cbs) MFSPool(&(cbs)->blockPoolStruct) #define cbsBlockPool(cbs) RVALUE((cbs)->blockPool)
/* cbsEnter, cbsLeave -- Avoid re-entrance /* cbsEnter, cbsLeave -- Avoid re-entrance
@ -78,10 +69,11 @@ Bool CBSCheck(CBS cbs)
CHECKL(cbs != NULL); CHECKL(cbs != NULL);
CHECKL(SplayTreeCheck(splayTreeOfCBS(cbs))); CHECKL(SplayTreeCheck(splayTreeOfCBS(cbs)));
/* nothing to check about splayTreeSize */ /* nothing to check about splayTreeSize */
CHECKD(MFS, &cbs->blockPoolStruct); CHECKD(Pool, cbs->blockPool);
CHECKU(Arena, cbs->arena); CHECKU(Arena, cbs->arena);
CHECKL(BoolCheck(cbs->fastFind)); CHECKL(BoolCheck(cbs->fastFind));
CHECKL(BoolCheck(cbs->inCBS)); CHECKL(BoolCheck(cbs->inCBS));
CHECKL(BoolCheck(cbs->ownPool));
/* No MeterCheck */ /* No MeterCheck */
return TRUE; return TRUE;
@ -220,6 +212,7 @@ static void cbsUpdateNode(SplayTree tree, SplayNode node,
*/ */
ARG_DEFINE_KEY(cbs_extend_by, Size); ARG_DEFINE_KEY(cbs_extend_by, Size);
ARG_DEFINE_KEY(cbs_block_pool, Pool);
Res CBSInit(Arena arena, CBS cbs, void *owner, Align alignment, Res CBSInit(Arena arena, CBS cbs, void *owner, Align alignment,
Bool fastFind, ArgList args) Bool fastFind, ArgList args)
@ -228,9 +221,12 @@ Res CBSInit(Arena arena, CBS cbs, void *owner, Align alignment,
Bool extendSelf = TRUE; Bool extendSelf = TRUE;
ArgStruct arg; ArgStruct arg;
Res res; Res res;
Pool blockPool = NULL;
AVERT(Arena, arena); AVERT(Arena, arena);
if (ArgPick(&arg, args, CBSBlockPool))
blockPool = arg.val.pool;
if (ArgPick(&arg, args, MPS_KEY_CBS_EXTEND_BY)) if (ArgPick(&arg, args, MPS_KEY_CBS_EXTEND_BY))
extendBy = arg.val.size; extendBy = arg.val.size;
if (ArgPick(&arg, args, MFSExtendSelf)) if (ArgPick(&arg, args, MFSExtendSelf))
@ -239,15 +235,24 @@ Res CBSInit(Arena arena, CBS cbs, void *owner, Align alignment,
cbs->arena = arena; cbs->arena = arena;
SplayTreeInit(splayTreeOfCBS(cbs), &cbsSplayCompare, SplayTreeInit(splayTreeOfCBS(cbs), &cbsSplayCompare,
fastFind ? &cbsUpdateNode : NULL); fastFind ? &cbsUpdateNode : NULL);
MPS_ARGS_BEGIN(piArgs) {
MPS_ARGS_ADD(piArgs, MPS_KEY_MFS_UNIT_SIZE, sizeof(CBSBlockStruct)); if (blockPool != NULL) {
MPS_ARGS_ADD(piArgs, MPS_KEY_EXTEND_BY, extendBy); cbs->blockPool = blockPool;
MPS_ARGS_ADD(piArgs, MFSExtendSelf, extendSelf); cbs->ownPool = FALSE;
MPS_ARGS_DONE(piArgs); } else {
res = PoolInit(&cbs->blockPoolStruct.poolStruct, arena, PoolClassMFS(), piArgs); MPS_ARGS_BEGIN(pcArgs) {
} MPS_ARGS_END(piArgs); MPS_ARGS_ADD(pcArgs, MPS_KEY_MFS_UNIT_SIZE, sizeof(CBSBlockStruct));
MPS_ARGS_ADD(pcArgs, MPS_KEY_EXTEND_BY, extendBy);
MPS_ARGS_ADD(pcArgs, MFSExtendSelf, extendSelf);
MPS_ARGS_DONE(pcArgs);
res = PoolCreate(&cbs->blockPool, arena, PoolClassMFS(), pcArgs);
} MPS_ARGS_END(pcArgs);
if (res != ResOK) if (res != ResOK)
return res; return res;
cbs->ownPool = TRUE;
}
cbs->blockPool = blockPool;
cbs->splayTreeSize = 0; cbs->splayTreeSize = 0;
cbs->fastFind = fastFind; cbs->fastFind = fastFind;
@ -280,7 +285,8 @@ void CBSFinish(CBS cbs)
cbs->sig = SigInvalid; cbs->sig = SigInvalid;
SplayTreeFinish(splayTreeOfCBS(cbs)); SplayTreeFinish(splayTreeOfCBS(cbs));
PoolFinish(cbsBlockPool(cbs)); if (cbs->ownPool)
PoolDestroy(cbsBlockPool(cbs));
} }

View file

@ -16,12 +16,26 @@
#include "splay.h" #include "splay.h"
typedef struct CBSBlockStruct *CBSBlock;
typedef struct CBSBlockStruct {
SplayNodeStruct splayNode;
Addr base;
Addr limit;
Size maxSize; /* accurate maximum block size of sub-tree */
ZoneSet zones; /* union zone set of all ranges in sub-tree */
} CBSBlockStruct;
typedef struct CBSStruct *CBS; typedef struct CBSStruct *CBS;
typedef Bool (*CBSIterateMethod)(CBS cbs, Range range, typedef Bool (*CBSIterateMethod)(CBS cbs, Range range,
void *closureP, Size closureS); void *closureP, Size closureS);
extern Bool CBSCheck(CBS cbs); extern Bool CBSCheck(CBS cbs);
extern const struct mps_key_s _mps_key_cbs_block_pool;
#define CBSBlockPool (&_mps_key_cbs_block_pool)
#define CBSBlockPool_FIELD pool
extern Res CBSInit(Arena arena, CBS cbs, void *owner, extern Res CBSInit(Arena arena, CBS cbs, void *owner,
Align alignment, Bool fastFind, ArgList args); Align alignment, Bool fastFind, ArgList args);
extern void CBSFinish(CBS cbs); extern void CBSFinish(CBS cbs);

View file

@ -614,11 +614,12 @@ typedef struct GlobalsStruct {
typedef struct CBSStruct { typedef struct CBSStruct {
SplayTreeStruct splayTree; SplayTreeStruct splayTree;
STATISTIC_DECL(Count splayTreeSize); STATISTIC_DECL(Count splayTreeSize);
MFSStruct blockPoolStruct; /* FIXME: ref to why this is inlined */ Pool blockPool;
Arena arena; /* needed by update method */ Arena arena; /* needed by update method */
Align alignment; Align alignment;
Bool fastFind; Bool fastFind;
Bool inCBS; /* prevent reentrance */ Bool inCBS; /* prevent reentrance */
Bool ownPool; /* did we create blockPool? */
/* meters for sizes of search structures at each op */ /* meters for sizes of search structures at each op */
METER_DECL(splaySearch); METER_DECL(splaySearch);
Sig sig; /* sig at end because embeded */ Sig sig; /* sig at end because embeded */
@ -660,6 +661,7 @@ typedef struct mps_arena_s {
ChunkCacheEntryStruct chunkCache; /* just one entry */ ChunkCacheEntryStruct chunkCache; /* just one entry */
Bool hasFreeCBS; /* Is freeCBS available? */ Bool hasFreeCBS; /* Is freeCBS available? */
MFSStruct cbsBlockPoolStruct; /* Shared pool for CBS blocks */
CBSStruct freeCBS; /* CBS of free address space */ CBSStruct freeCBS; /* CBS of free address space */
ZoneSet freeZones; /* zones not yet allocated */ ZoneSet freeZones; /* zones not yet allocated */

View file

@ -142,6 +142,7 @@ typedef struct mps_arg_s {
mps_fmt_isfwd_t fmt_isfwd; mps_fmt_isfwd_t fmt_isfwd;
mps_fmt_pad_t fmt_pad; mps_fmt_pad_t fmt_pad;
mps_fmt_class_t fmt_class; mps_fmt_class_t fmt_class;
mps_pool_t pool;
} val; } val;
} mps_arg_s; } mps_arg_s;