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/eph1.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

164 lines
5.2 KiB
C

/*
TEST_HEADER
id = $Id$
summary = tests for ephemerons
language = c
link = testlib.o ephfmt.o
END_HEADER
*/
#include "ephfmt.h"
#include <stdio.h>
#include <string.h>
static void test_reachable_key(mmp mm, oop s[ROOT_COUNT])
{
comment("test_reachable_key");
s[0] = string_from_cstr(mm->amc_ap, "a");
s[1] = string_from_cstr(mm->amc_ap, "b");
make_pair(mm->amc_ap, s[0], s[1]);
s[3] = make_weak_pair(mm->eph_ap, s[0], s[1]);
s[1] = NULL;
asserts(s[3]->weak_pair.key == s[0], "key == s[0]");
die(mps_arena_collect(mm->arena), "mps_arena_collect");
asserts(s[3]->weak_pair.key != NULL, "key reachable");
asserts(s[3]->weak_pair.key == s[0], "key == s[0]");
asserts(s[3]->weak_pair.value != NULL, "value reachable");
check_string(s[3]->weak_pair.key, "a");
check_string(s[3]->weak_pair.value, "b");
}
static void test_unreachable_key(mmp mm, oop s[ROOT_COUNT])
{
comment("test_unreachable_key");
s[0] = string_from_cstr(mm->amc_ap, "a");
s[1] = string_from_cstr(mm->amc_ap, "b");
make_pair(mm->amc_ap, s[0], s[1]);
s[3] = make_weak_pair(mm->eph_ap, s[0], s[1]);
s[0] = NULL;
die(mps_arena_collect(mm->arena), "mps_arena_collect");
asserts(s[3]->weak_pair.key == NULL, "key unreachable");
asserts(s[3]->weak_pair.value == NULL, "value unreachable");
}
static void test_key_eq_value(mmp mm, oop s[ROOT_COUNT])
{
comment("test_key_eq_value");
s[0] = string_from_cstr(mm->amc_ap, "a");
make_pair(mm->amc_ap, s[0], s[0]);
s[3] = make_weak_pair(mm->eph_ap, s[0], s[0]);
s[0] = NULL;
die(mps_arena_collect(mm->arena), "mps_arena_collect");
asserts(s[3]->weak_pair.key == NULL, "key unreachable");
asserts(s[3]->weak_pair.value == NULL, "value unreachable");
}
static void test_value_unreachable(mmp mm, oop s[ROOT_COUNT])
{
comment("test_value_unreachable");
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[1] = NULL;
s[2] = NULL;
die(mps_arena_collect(mm->arena), "mps_arena_collect");
asserts(s[3]->weak_pair.key != NULL, "key reachable");
asserts(s[3]->weak_pair.value != NULL, "value reachable");
check_string(s[3]->weak_pair.key, "a");
asserts(s[3]->weak_pair.value->header.s.type == TYPE_PAIR,
"val->header.type == TYPE_PAIR");
asserts(s[3]->weak_pair.value->pair.car == s[0],
"s[3]->weak_pair.value->pair.car == s[0]");
check_string(s[3]->weak_pair.value->pair.cdr, "b");
}
static void test_chain(mmp mm, oop s[ROOT_COUNT])
{
/* Create a ring where only one key is externally reachable. All
* other keys are only reachable through a value of a weak pair. */
unsigned n = 5;
unsigned i;
comment("test_chain");
for (i = 0; i < n; i++) {
char keyname[10];
char valname[10];
sprintf(keyname, "key%u", i);
sprintf(valname, "val%u", i);
s[4 * i + 0] = string_from_cstr(mm->amc_ap, keyname);
s[4 * i + 1] = string_from_cstr(mm->amc_ap, valname);
}
for (i = 0; i < n; i++) {
s[4 * i + 2] =
make_pair(mm->amc_ap, s[4 * i + 1], s[4 * ((i + 1) % n)]);
s[4 * i + 3] = make_weak_pair(mm->eph_ap, s[4 * i], s[4 * i + 2]);
}
for (i = 0; i < n; i++) {
if (i != (n - 1) / 2)
s[4 * i + 0] = NULL;
s[4 * i + 1] = NULL;
s[4 * i + 2] = NULL;
}
die(mps_arena_collect(mm->arena), "mps_arena_collect");
for (i = 0; i < n; i++) {
oop eph = s[4 * i + 3];
asserts(eph->weak_pair.key != NULL, "key reachable");
asserts(eph->weak_pair.value != NULL, "value reachable");
{
char buf[10];
sprintf(buf, "key%u", i);
check_string(eph->weak_pair.key, buf);
}
{
char val[10];
char key[10];
sprintf(val, "val%u", i);
sprintf(key, "key%u", (i + 1) % n);
asserts(eph->weak_pair.value->header.s.type == TYPE_PAIR,
"TYPE_PAIR");
check_string(eph->weak_pair.value->pair.car, val);
check_string(eph->weak_pair.value->pair.cdr, key);
}
}
}
static void test_two_pairs(mmp mm, oop s[ROOT_COUNT])
{
comment("test_two_pairs");
s[0] = string_from_cstr(mm->amc_ap, "a");
s[1] = string_from_cstr(mm->amc_ap, "b");
s[2] = string_from_cstr(mm->amc_ap, "c");
s[3] = make_weak_pair(mm->eph_ap, s[0], s[1]);
s[4] = make_weak_pair(mm->eph_ap, s[2], s[0]);
s[0] = NULL;
s[1] = NULL;
die(mps_arena_collect(mm->arena), "mps_arena_collect");
asserts(s[3]->weak_pair.key != NULL, "key1 reachable");
asserts(s[3]->weak_pair.value != NULL, "value1 reachable");
asserts(s[4]->weak_pair.key != NULL, "key2 reachable");
asserts(s[4]->weak_pair.value != NULL, "value2 reachable");
check_string(s[3]->weak_pair.key, "a");
check_string(s[3]->weak_pair.value, "b");
check_string(s[4]->weak_pair.key, "c");
check_string(s[4]->weak_pair.value, "a");
}
static void test(mmp mm, void* closure)
{
typedef void (*fun)(mmp, oop s[ROOT_COUNT]);
fun funs[] = { test_reachable_key, test_unreachable_key,
test_key_eq_value, test_value_unreachable,
test_chain, test_two_pairs };
size_t i;
for (i = 0; i < sizeof funs / sizeof funs[0]; i++) {
memset(mm->roots, 0, sizeof mm->roots);
funs[i](mm, mm->roots);
}
}
int main(int argc, char* argv[])
{
run_eph_test(test, NULL);
pass();
return 0;
}