fix(v4.0.0): POST leaves nothing, as v3 really does; and what the review of step 6b found
Captain Bob was told that v3 leaves the words POST's cases define in the
dictionary, and ruled that v4 should. That was false: v3's run_test_suite
puts the dictionary back after each word's cases (test_common.c:333,
:365). Shown that, he ruled that POST leaves nothing. The boot now
seals the system, runs POST, and has the node do COLD, whose printing is
not shown; PARITY:V4_SYSTEM is the system as sealed.
A case the node does not come back from ends POST there, named, with how
many were not run: it would have stalled the boot for hours, where the
capsule had ended it. The runner's test of it now uses a word that
really never ends.
hosted-check also requires that RS1 and T{ are unknown after boot, and
boots a program whose POST has failing cases (tests/post_cases_fail.c):
PARITY:FAIL, POST: FAILED, no prompt, none of a case's printing shown.
Comments and documents that still named the POST capsule or its two
hooks are brought up to date; NUCLEUS.md 6.3 says what v3 does, with the
lines, and how the wrong ruling came about.
make -C v4 test, sanitize and hosted-check pass; amd64, aarch64 and
riscv64 boot, POST 538 of 538, word_count=314, dict_hash
0x220ab283a504a3b3 on all six: logs/20261007-112638, -112901, -113220.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 5.5
parent
eda6577a53
commit
18adf59091
+21
-6
@@ -19,8 +19,9 @@ static const char *const boot_capsules[] = {
|
||||
};
|
||||
|
||||
/* POST is part of the boot, and is the kernel's (v4/include/v4/post.h;
|
||||
* docs/v4.0.0/NUCLEUS.md 6.3): when the capsules are in, the kernel feeds
|
||||
* its cases to the node and judges them, and the boot passes only if none
|
||||
* docs/v4.0.0/NUCLEUS.md 6.3): when the capsules are in and the system is
|
||||
* sealed, the kernel feeds its cases to the node and judges them, puts the
|
||||
* node back to the system as sealed, and the boot passes only if none
|
||||
* failed. -DV4_POST_AT_BOOT=0 leaves it out, for work on a vocabulary
|
||||
* that does not pass yet. */
|
||||
#ifndef V4_POST_AT_BOOT
|
||||
@@ -367,22 +368,36 @@ int v4_boot_run(const v4_boot *b)
|
||||
|
||||
for (i = 0; i < sizeof boot_capsules / sizeof boot_capsules[0]; i++)
|
||||
if (!load_capsule(b, boot_capsules[i])) { say(b, "PARITY:FAIL\nPOST: FAILED\n"); return 0; }
|
||||
/* The kernel's words and the capsules are the system: COLD comes back
|
||||
* to here, and FORGET will not go below it. */
|
||||
v4_image_seal(b->n, b->im);
|
||||
|
||||
#if V4_POST_AT_BOOT
|
||||
{
|
||||
static const char cold[] = "COLD";
|
||||
v4_post_host host;
|
||||
v4_post_tally tally;
|
||||
unsigned printed = 0;
|
||||
int how;
|
||||
|
||||
host.self = (void *)b; host.n = b->n; host.line = post_line; host.say = post_say;
|
||||
if (!v4_post_run(&host, v4_post_cases, v4_post_case_count, &tally)) {
|
||||
say(b, "V4: POST reported failures\nPARITY:FAIL\nPOST: FAILED\n");
|
||||
return 0;
|
||||
}
|
||||
/* POST leaves nothing: the node is put back to the system as it was
|
||||
* sealed, as v3 puts the dictionary back after each of its suites
|
||||
* (v3/src/test_runner/test_common.c, run_test_suite). What COLD
|
||||
* prints is not shown. */
|
||||
v4_dstack_reset(&b->n->ds);
|
||||
how = run_line(b, cold, (unsigned)sizeof cold - 1u, (char *)cold, 0u, &printed);
|
||||
if (how != V4_TEXT_COMPLETED && how != V4_TEXT_QUIT) {
|
||||
say(b, "V4: the node did not come back to the system after POST\nPARITY:FAIL\nPOST: FAILED\n");
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
/* The kernel's words, the capsules and what POST's cases defined are
|
||||
* the system, as in v3: COLD comes back to here, and FORGET will not go
|
||||
* below it. */
|
||||
v4_image_seal(b->n, b->im);
|
||||
say(b, "PARITY:V4_SYSTEM word_count="); say_dec(b, word_count(b->n, b->im));
|
||||
say(b, " dict_hash="); say_hex(b, v4_boot_dict_hash(b->n, b->im));
|
||||
say(b, "\n");
|
||||
|
||||
+12
-2
@@ -44,18 +44,19 @@ int v4_post_run(const v4_post_host *h, const v4_post_case *cases, unsigned count
|
||||
for (i = 0; i < count; i++) {
|
||||
const v4_post_case *c = &cases[i];
|
||||
unsigned kept = 0, total = 0, len = 0, depth;
|
||||
int errored = 0, came_back = 1, ok, how;
|
||||
int errored = 0, came_back = 1, lost = 0, ok, how;
|
||||
|
||||
/* every case starts from the same state */
|
||||
v4_dstack_reset(&h->n->ds);
|
||||
how = h->line(h->self, state_line, (unsigned)sizeof state_line - 1u, out, 0u, &len);
|
||||
if (how < 0) lost = 1;
|
||||
if (how != V4_TEXT_COMPLETED) came_back = 0;
|
||||
v4_dstack_reset(&h->n->ds);
|
||||
|
||||
for (k = 0; came_back && k < c->line_count; k++) {
|
||||
len = 0;
|
||||
how = h->line(h->self, c->lines[k], length(c->lines[k]), out + kept, V4_POST_OUT - kept, &len);
|
||||
if (how < 0) { came_back = 0; break; }
|
||||
if (how < 0) { came_back = 0; lost = 1; break; }
|
||||
if (how == V4_TEXT_ERROR) errored = 1;
|
||||
total += len;
|
||||
kept = total < V4_POST_OUT ? total : V4_POST_OUT;
|
||||
@@ -95,6 +96,15 @@ int v4_post_run(const v4_post_host *h, const v4_post_case *cases, unsigned count
|
||||
say(h, "> stack<");
|
||||
for (k = depth < SHOWN_STACK ? depth : SHOWN_STACK; k-- > 0; ) { say_number(h, (long long)left[k]); say(h, " "); }
|
||||
say(h, ">\n");
|
||||
|
||||
/* The node did not come back from a line: it is stopped, or will
|
||||
* run for ever. Nothing more can be asked of it, so POST ends
|
||||
* here and says which case it was. */
|
||||
if (lost) {
|
||||
say(h, "POST: the node did not come back from "); say(h, c->name);
|
||||
say(h, "; "); say_number(h, (long long)(count - i - 1u)); say(h, " not run\n");
|
||||
break;
|
||||
}
|
||||
}
|
||||
say(h, "PARITY:V4_POST tests="); say_number(h, (long long)tally->tests);
|
||||
say(h, " pass="); say_number(h, (long long)tally->pass);
|
||||
|
||||
Reference in New Issue
Block a user