mirror of
git://git.sv.gnu.org/emacs.git
synced 2026-02-07 08:00:48 -08:00
New macro arenachunkring encapsulates getting the chunk ring for an arena.
RingLength now returns Count, not Size. New test case checks that chunks are added and removed from the arena as memory is allocated and freed. Copied from Perforce Change: 188133 ServerID: perforce.ravenbrook.com
This commit is contained in:
parent
e7663adacb
commit
f8a402fa0f
8 changed files with 76 additions and 16 deletions
|
|
@ -164,7 +164,7 @@ Bool ArenaCheck(Arena arena)
|
|||
if (arena->primary != NULL) {
|
||||
CHECKD(Chunk, arena->primary);
|
||||
}
|
||||
CHECKD_NOSIG(Ring, &arena->chunkRing);
|
||||
CHECKD_NOSIG(Ring, ArenaChunkRing(arena));
|
||||
/* Can't use CHECKD_NOSIG because TreeEMPTY is NULL. */
|
||||
CHECKL(TreeCheck(ArenaChunkTree(arena)));
|
||||
/* TODO: check that the chunkRing and chunkTree have identical members */
|
||||
|
|
@ -225,7 +225,7 @@ Res ArenaInit(Arena arena, ArenaClass class, Size grainSize, ArgList args)
|
|||
arena->zoned = zoned;
|
||||
|
||||
arena->primary = NULL;
|
||||
RingInit(&arena->chunkRing);
|
||||
RingInit(ArenaChunkRing(arena));
|
||||
arena->chunkTree = TreeEMPTY;
|
||||
arena->chunkSerial = (Serial)0;
|
||||
|
||||
|
|
@ -372,7 +372,7 @@ void ArenaFinish(Arena arena)
|
|||
arena->sig = SigInvalid;
|
||||
GlobalsFinish(ArenaGlobals(arena));
|
||||
LocusFinish(arena);
|
||||
RingFinish(&arena->chunkRing);
|
||||
RingFinish(ArenaChunkRing(arena));
|
||||
AVER(ArenaChunkTree(arena) == TreeEMPTY);
|
||||
}
|
||||
|
||||
|
|
@ -587,7 +587,7 @@ Res ArenaDescribeTracts(Arena arena, mps_lib_FILE *stream, Count depth)
|
|||
if (stream == NULL)
|
||||
return ResFAIL;
|
||||
|
||||
RING_FOR(node, &arena->chunkRing, next) {
|
||||
RING_FOR(node, ArenaChunkRing(arena), next) {
|
||||
Chunk chunk = RING_ELT(Chunk, arenaRing, node);
|
||||
res = arenaDescribeTractsInChunk(chunk, stream, depth);
|
||||
if (res != ResOK)
|
||||
|
|
@ -678,7 +678,7 @@ void ArenaChunkInsert(Arena arena, Chunk chunk) {
|
|||
AVER(updatedTree);
|
||||
TreeBalance(&updatedTree);
|
||||
arena->chunkTree = updatedTree;
|
||||
RingAppend(&arena->chunkRing, &chunk->arenaRing);
|
||||
RingAppend(ArenaChunkRing(arena), &chunk->arenaRing);
|
||||
|
||||
arena->reserved += ChunkReserved(chunk);
|
||||
|
||||
|
|
@ -707,7 +707,7 @@ void ArenaChunkRemoved(Arena arena, Chunk chunk)
|
|||
|
||||
if (chunk == arena->primary) {
|
||||
/* The primary chunk must be the last chunk to be removed. */
|
||||
AVER(RingIsSingle(&arena->chunkRing));
|
||||
AVER(RingIsSingle(ArenaChunkRing(arena)));
|
||||
AVER(arena->reserved == 0);
|
||||
arena->primary = NULL;
|
||||
}
|
||||
|
|
@ -762,7 +762,7 @@ static Res arenaAllocPage(Addr *baseReturn, Arena arena, Pool pool)
|
|||
res = arenaAllocPageInChunk(baseReturn, arena->primary, pool);
|
||||
if (res != ResOK) {
|
||||
Ring node, next;
|
||||
RING_FOR(node, &arena->chunkRing, next) {
|
||||
RING_FOR(node, ArenaChunkRing(arena), next) {
|
||||
Chunk chunk = RING_ELT(Chunk, arenaRing, node);
|
||||
if (chunk != arena->primary) {
|
||||
res = arenaAllocPageInChunk(baseReturn, chunk, pool);
|
||||
|
|
|
|||
|
|
@ -248,8 +248,7 @@ static void arena_setup(gcthread_fn_t fn,
|
|||
} MPS_ARGS_END(args);
|
||||
watch(fn, name);
|
||||
mps_arena_park(arena);
|
||||
printf("%u chunks\n", (unsigned)TreeDebugCount(ArenaChunkTree(arena),
|
||||
ChunkCompare, ChunkKey));
|
||||
printf("%u chunks\n", (unsigned)RingLength(ArenaChunkRing(arena)));
|
||||
mps_pool_destroy(pool);
|
||||
mps_fmt_destroy(format);
|
||||
if (ngen > 0)
|
||||
|
|
|
|||
|
|
@ -528,6 +528,7 @@ extern Ring GlobalsRememberedSummaryRing(Globals);
|
|||
#define ArenaGreyRing(arena, rank) (&(arena)->greyRing[rank])
|
||||
#define ArenaPoolRing(arena) (&ArenaGlobals(arena)->poolRing)
|
||||
#define ArenaChunkTree(arena) RVALUE((arena)->chunkTree)
|
||||
#define ArenaChunkRing(arena) RVALUE(&(arena)->chunkRing)
|
||||
|
||||
extern Bool ArenaGrainSizeCheck(Size size);
|
||||
#define AddrArenaGrainUp(addr, arena) AddrAlignUp(addr, ArenaGrainSize(arena))
|
||||
|
|
|
|||
|
|
@ -65,14 +65,14 @@ Bool RingIsSingle(Ring ring)
|
|||
* See <design/ring/#length>
|
||||
*/
|
||||
|
||||
Size RingLength(Ring ring)
|
||||
Count RingLength(Ring ring)
|
||||
{
|
||||
Size size = 0;
|
||||
Count length = 0;
|
||||
Ring node, next;
|
||||
AVERT(Ring, ring);
|
||||
RING_FOR(node, ring, next)
|
||||
++ size;
|
||||
return size;
|
||||
++ length;
|
||||
return length;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -30,7 +30,7 @@ typedef struct RingStruct { /* double-ended queue structure */
|
|||
extern Bool RingCheck(Ring ring);
|
||||
extern Bool RingCheckSingle(Ring ring);
|
||||
extern Bool RingIsSingle(Ring ring);
|
||||
extern Size RingLength(Ring ring);
|
||||
extern Count RingLength(Ring ring);
|
||||
|
||||
/* .ring.init: See <design/ring/#init> */
|
||||
extern void (RingInit)(Ring ring);
|
||||
|
|
|
|||
|
|
@ -112,7 +112,7 @@ additionally checks that ``ring`` is a singleton (see
|
|||
_`.is.single`: Return ``TRUE`` if ``ring`` is a singleton (see
|
||||
`.def.singleton`_).
|
||||
|
||||
``Size RingLength(Ring ring)``
|
||||
``Count RingLength(Ring ring)``
|
||||
|
||||
_`.length`: Return the number of elements in the ring, not counting
|
||||
``ring`` itself. This therefore returns 0 for singleton rings, and for
|
||||
|
|
|
|||
59
mps/test/function/232.c
Normal file
59
mps/test/function/232.c
Normal file
|
|
@ -0,0 +1,59 @@
|
|||
/*
|
||||
TEST_HEADER
|
||||
id = $Id: //info.ravenbrook.com/project/mps/branch/2015-08-11/compact/test/function/229.c#1 $
|
||||
summary = test arena extension and compaction
|
||||
language = c
|
||||
link = testlib.o
|
||||
parameters = SIZE=1024*1024 ITERATIONS=100
|
||||
END_HEADER
|
||||
*/
|
||||
|
||||
#include "mpm.h"
|
||||
#include "mpscmvff.h"
|
||||
#include "testlib.h"
|
||||
|
||||
static void check_chunks(mps_arena_t arena, unsigned expected)
|
||||
{
|
||||
unsigned chunks = (unsigned)RingLength(ArenaChunkRing((Arena)arena));
|
||||
asserts(chunks == expected, "expected %u chunks, got %u", expected, chunks);
|
||||
}
|
||||
|
||||
static void test(void)
|
||||
{
|
||||
mps_arena_t arena;
|
||||
mps_pool_t pool;
|
||||
mps_addr_t block[ITERATIONS];
|
||||
unsigned i;
|
||||
|
||||
MPS_ARGS_BEGIN(args) {
|
||||
MPS_ARGS_ADD(args, MPS_KEY_ARENA_SIZE, SIZE);
|
||||
die(mps_arena_create_k(&arena, mps_arena_class_vm(), args), "arena_create");
|
||||
} MPS_ARGS_END(args);
|
||||
|
||||
MPS_ARGS_BEGIN(args) {
|
||||
MPS_ARGS_ADD(args, MPS_KEY_SPARE, 0);
|
||||
die(mps_pool_create_k(&pool, arena, mps_class_mvff(), args), "pool_create");
|
||||
} MPS_ARGS_END(args);
|
||||
check_chunks(arena, 1);
|
||||
|
||||
for (i = 0; i < ITERATIONS; ++i) {
|
||||
die(mps_alloc(&block[i], pool, SIZE), "mps_alloc");
|
||||
check_chunks(arena, i + 2);
|
||||
}
|
||||
|
||||
for (i = ITERATIONS; i > 0; --i) {
|
||||
mps_free(pool, block[i - 1], SIZE);
|
||||
mps_arena_collect(arena); /* ensure ArenaCompact called via TraceReclaim */
|
||||
check_chunks(arena, i);
|
||||
}
|
||||
|
||||
mps_pool_destroy(pool);
|
||||
mps_arena_destroy(arena);
|
||||
}
|
||||
|
||||
int main(void)
|
||||
{
|
||||
easy_tramp(test);
|
||||
pass();
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -168,4 +168,5 @@ function/224.c
|
|||
% 225 -- no such test
|
||||
function/226.c
|
||||
function/227.c
|
||||
function/229.c
|
||||
function/229.c
|
||||
function/232.c
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue