1
Fork 0
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:
Gareth Rees 2015-08-11 12:03:45 +01:00
parent e7663adacb
commit f8a402fa0f
8 changed files with 76 additions and 16 deletions

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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