From 41cb1cca55c67dd2aac2afa2f96bdc09a5d50b78 Mon Sep 17 00:00:00 2001 From: eunhhu Date: Wed, 30 Sep 2026 03:19:45 +0100 Subject: Say where a node's memory goes, and the budget it now keeps (104, 013) 104 measures a node's memory under a receiver that is down and under a snapshot held for long (021's run.py: resident memory against what was posted, 30 s a case). A held snapshot grew the node without end (6.4 to 678 MiB, fixed in d1e8f38); a slow receiver grows it by what was sent, 221 B a send, which is state until delivered, so the budget bounds state and refuses past it. 013 is that budget's design: what it counts (state bytes, deterministic), what an event over it does, why an answer takes its send's room, how links and HTTP wait, what it does not count and those bounds, and the checks. With --memory 4000000 the same load fills it in about 4 s and the node stays at 9.6-9.8 MiB (45.9 MiB and growing without). 012 records the hole the budget found in the link (the full flag), and 103 that its clock fix fell short (385754c). CHECKPOINT gains the row. --- research/experiments/021-memory/hold-surface.c | 32 ++++++++++++++++++++++++++ 1 file changed, 32 insertions(+) create mode 100644 research/experiments/021-memory/hold-surface.c (limited to 'research/experiments/021-memory/hold-surface.c') diff --git a/research/experiments/021-memory/hold-surface.c b/research/experiments/021-memory/hold-surface.c new file mode 100644 index 0000000..c1c2d4b --- /dev/null +++ b/research/experiments/021-memory/hold-surface.c @@ -0,0 +1,32 @@ +/* A surface that holds a snapshot until the server stops: a reader that + * never lets go, for run.py's held case (research/experiments/021-memory). + * It holds the first snapshot whose number view VIEW is at least AT (the + * first snapshot at all without them), and lets every other one go. + * + * pure-serve ... --surface hold-surface.so [-- VIEW AT] */ +#include "surface.h" +#include +#include +#include +#include + +int pure_surface_run(const PureSurface *s, int argc, char **argv) { + static PureApp reader; + int view = argc > 2 ? pure_module_view(s->module, argv[1]) : -1; + double at = argc > 2 ? atof(argv[2]) : 0, value = 0; + PureSnapshot *held = NULL; + while (!s->stopping(s->host)) { + struct pollfd wait = {s->changes, POLLIN, 0}; + if (poll(&wait, 1, 20) > 0 && (wait.revents & POLLIN)) { + uint64_t saves; + if (read(s->changes, &saves, sizeof(saves)) < 0) { /* cleared already */ } + } + if (held) continue; + PureSnapshot *read_now = s->read(s->host, &reader); + if (!read_now) continue; + if (view < 0 || (pure_app_view(&reader, (uint32_t)view, &value) && value >= at)) held = read_now; + else s->release(s->host, read_now); + } + if (held) s->release(s->host, held); + return 0; +} -- cgit v1.2.3