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/eph2.c
Helmut Eller cc1aa65f17 Add a pool for ephemerons
Ephemerons solve the key-in-value problem for weak key/value pairs.  It
seems that it's not possible to solve that problem with weak pointers or
finalizers.  Basically we want a weak key/value pair that implements the
rule:

  The value is reachable, if the key is reachable.

The key-in-value problem occurs if all paths to the key go through the
value.  In this situation, the key is considered reachable only if the
value is "externally reachable", i.e. the value is reachable through a
path other than through the weak pair.

Such weak pairs seem to need an extra phase in the GC algorithm.  See
[1] for some variants of the algorithm.

https://www.haible.de/bruno/papers/cs/weak/WeakDatastructures-writeup.html

* mps/code/mpmst.h (SegStruct): Add fields propagationNeeded,
marksChanged, and propagationFinished.
* mps/code/mpmtypes.h (RANK_LIST): Add EPHEMERON rank.
* mps/code/mps.s (mps_rank_ephemeron): New prototype.
* mps/code/mpscawl.h (mps_class_aeph, mps_fix_weak_pair)
(mps_fix_weak_or_pair, mps_fix_weak_and_pair): New prototypes.
* mps/code/mpsi.c (mps_rank_ephemeron): New function.
* mps/code/poolawl.c (AEPHSegStruct, AEPHPoolStruct): New. The
implementation the ephemeron pool.
* mps/code/seg.c (segAbsInit): Initialize propagationNeeded,
marksChanged, and propagationFinished.
* mps/code/trace.c (traceBandRetreat, tracePropagateToLowerRanks)
(moveSegToEndOfGreyRing): New helpers.
(TraceRankForAccess): Handle the RankEPHEMERON.
(traceFindGrey, traceScanSegRes): Add special handling for ephemeron
segments.
* mps/test/function/eph1.c: New test file.
* mps/test/function/eph2.c: New test file.
* mps/test/function/eph3.c: New test file.
* mps/test/function/eph4.c: New test file.
* mps/test/test/testlib/ephfmt.c: New file.
* mps/test/test/testlib/ephfmt.h: New file.
* mps/test/test/testlib/manifest: Add ephfmt.c.
* mps/test/testsets/passing: Include eph{1,2,3,4}.c.
2026-01-23 08:48:40 +01:00

55 lines
1.5 KiB
C

/*
TEST_HEADER
id = $Id$
summary = test TraceRankForAccess for ephemeron pool
language = c
link = testlib.o ephfmt.o
END_HEADER
*/
#include "ephfmt.h"
#include <stdio.h>
#include <string.h>
static void test(mmp mm, void* closure)
{
int i, j;
oop* s = mm->roots;
memset(s, 0, sizeof(mm->roots));
s[99] = string_from_cstr(mm->amc_ap, "x");
s[0] = string_from_cstr(mm->amc_ap, "a");
s[1] = string_from_cstr(mm->amc_ap, "b");
s[2] = make_pair(mm->amc_ap, s[0], s[1]);
s[3] = make_weak_pair(mm->eph_ap, s[0], s[2]);
s[0] = NULL;
s[1] = NULL;
s[2] = NULL;
/* The first mps_arena_step scans the AMC segment. The second step
* scans the AEPH segment. The trace is finished after two steps, if
* we access the AEPH segment before the third step; otherwise the
* trace finishes after the third step.
*
* Starting the loop at j=0 triggers the "unreachable code" assertion
* in trace.c:1047.
*/
for (j = 1; j < 3; j++) {
die(mps_arena_start_collect(mm->arena), "mps_arena_start_collect");
for (i = 0; i < j; i++)
cdie(mps_arena_step(mm->arena, 0, 0) == 0, "some work done");
cdie(s[3]->weak_pair.key == NULL, "key reachable");
cdie(s[3]->weak_pair.value == NULL, "value reachable");
while (mps_arena_step(mm->arena, 0, 0))
;
cdie(mps_arena_step(mm->arena, 0, 0) != 0, "no more work to do");
cdie(s[3]->weak_pair.key == NULL, "key reachable");
cdie(s[3]->weak_pair.value == NULL, "value reachable");
}
}
int main(int argc, char* argv[])
{
run_eph_test(test, NULL);
pass();
return 0;
}