1
Fork 0
mirror of git://git.sv.gnu.org/emacs.git synced 2026-03-10 08:52:40 -07:00
emacs/mps/test/function/eph5.c
Helmut Eller e8b9677acd Handle accesses to protected AMC segments while in ephemeron band
* mps/code/trace.c (TraceRankForAccess): While in the ephemeron band,
use RankFINAL for final segments and RankEXACT for the others.
* mps/test/function/eph5.c: New Test.
* mps/test/testsets/passing: Include eph5.c.
* mps/test/test/testlib/ephfmt.h (union header): Use a one-word header.
* mps/test/test/testlib/ephfmt.c: Update accordingly.
* mps/test/function/eph1.c: Update accordingly.
2026-02-02 17:27:23 +01:00

73 lines
2.1 KiB
C

/*
TEST_HEADER
id = $Id$
summary = test TraceRankForAccess for AMC segments from ephemeron band
language = c
link = testlib.o ephfmt.o
END_HEADER
*/
#include "ephfmt.h"
#include "mpm.h"
#include <stdio.h>
#include <string.h>
static void build_chain(mmp mm, size_t length, size_t tail_idx)
{
size_t i;
oop* loc = &mm->roots[tail_idx];
for (i = 0; i < length; i++)
*loc = make_pair(mm->amc_ap, NULL, *loc);
}
static void test(mmp mm, void* closure)
{
oop* s = mm->roots;
memset(s, 0, sizeof(mm->roots));
s[0] = string_from_cstr(mm->amc_ap, "a");
s[1] = NULL;
/* Build a chain that spans multiple segments in the AMC pool. */
build_chain(mm, 32 * 1024 / sizeof(struct pair), 1);
s[2] = make_weak_pair(mm->eph_ap, s[0], s[1]);
s[0] = NULL;
s[1] = NULL;
die(mps_arena_start_collect(mm->arena), "mps_arena_start_collect");
/* Advance the trace until we reach the ephemeron band. */
{
Arena arena = mm->arena;
TraceStruct* t = &arena->trace[0];
asserts(arena->busyTraces != TraceSetEMPTY, "trace busy");
while (t->band != RankEPHEMERON && mps_arena_step(mm->arena, 0, 0))
asserts(arena->busyTraces != TraceSetEMPTY, "trace busy");
asserts(arena->busyTraces != TraceSetEMPTY, "trace busy");
asserts(t->band == RankEPHEMERON, "in ephemeron band");
}
/* Touch all objects in the chain. */
{
oop chain = s[2]->weak_pair.value;
while (chain && chain->pair.header.s.type == TYPE_PAIR)
chain = chain->pair.cdr;
asserts(mm->arena->busyTraces != TraceSetEMPTY, "trace busy");
asserts(mm->arena->trace[0].band == RankEPHEMERON,
"in ephemeron band");
}
while (mps_arena_step(mm->arena, 0, 0))
;
asserts(mps_arena_step(mm->arena, 0, 0) == 0, "no more work to do");
/* The weak pair is retained for longer than logically necessary
* because we accessed it in the ephemeron band. */
asserts(s[0] == NULL, "s[0] is NULL");
asserts(s[2]->weak_pair.key != NULL, "key reachable");
asserts(s[2]->weak_pair.value != NULL, "value reachable");
}
int main(int argc, char* argv[])
{
run_eph_test(test, NULL);
pass();
return 0;
}