fix(v4.0.0): step 6e review round 1 -- a take that does not take does nothing; output and answers wait at a middle node; no queue on the kernel's port; a printing wait is not interrupted
- The result of every take is looked at: a wire cut between the look and the take leaves nothing acted on (the text before run again, a refusal counted, a wait ended by an old answer, a way forgotten). - A node with no room to pass on what another printed, or its word of how text ended, leaves it on the wire it came by and moves it when there is room; what is behind it for the same port waits too. Sleep for room (9) is woken by room on any of the node's wires (engine; MESH.md 7d.3). - The lone node's host keeps no queue for the kernel's port: a message to it is error 18. The step limit is counted while the node waits for room. - A text waiting for room to print is not interrupted by console text; AWAIT is, as before. (BREAK?) is gone. - A GONE is believed only by the centre's port; unawaited answers let go are counted; nothing past a message's last character goes on a wire; AWAIT sets (AWAIT-FROM) only once the stack has been tried. - test_host_depth.c: ten paths, each run works or ends in one named stack error; it fails with (ROOM) or (ROOM-SERVE) taken out. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 5.5
parent
b1d09af043
commit
6a7d0aa27f
+148
-39
@@ -7,11 +7,19 @@
|
||||
* attempt at step 6d was tested on a shallow stack with every node there,
|
||||
* and hung on a deep one. Here node 11 does each thing a node does with a
|
||||
* message -- print, SEND, SEND with no way, AWAIT answered, AWAIT ended by a
|
||||
* GONE, pass a message on while its own text waits for room -- with its data
|
||||
* stack holding 20 to 32 values, and from 20 to 32 calls deep. After each,
|
||||
* every node must answer, and node 11's stack must be as deep as the text
|
||||
* made it, or its text must have ended in an error it reported. It may
|
||||
* refuse; it may not hang, and it may not swallow a line.
|
||||
* GONE, pass a message on while its own text waits for room, AWAIT broken
|
||||
* by a line from the console, refuse a message while its own text waits for
|
||||
* room, send a GONE -- with its data stack holding 20 to 32 values, and from
|
||||
* 20 to 33 calls deep.
|
||||
*
|
||||
* EVERY RUN ENDS ONE OF TWO WAYS, and which is checked: the path WORKS, all
|
||||
* of it, as it does on a shallow stack; or node 11's text ends in "Stack
|
||||
* overflow" or "Return stack overflow" and nothing else -- with nothing
|
||||
* half done: no message lost that was owed, no line swallowed. Where the
|
||||
* stack is shallow enough it must work. And after each, every node must
|
||||
* answer. "It came back" is not enough: with the nucleus's tries of the
|
||||
* stack taken out -- (ROOM-SERVE), (ROOM) -- this test fails (it was
|
||||
* mutated to see).
|
||||
*/
|
||||
#include "v4/image.h"
|
||||
#include "v4/fabric.h"
|
||||
@@ -173,16 +181,32 @@ static int row(void)
|
||||
}
|
||||
|
||||
/* ---- the sweep ---- */
|
||||
static unsigned runs, bad;
|
||||
static unsigned runs, bad, worked, refused_clean;
|
||||
|
||||
/* what the last path watches for: node 11 asleep for room, and, while it is, a message it has passed on to
|
||||
* the wire to node 12 */
|
||||
/* what the paths that wait for room watch for: node 11 asleep for room, and, while it is, a message it has
|
||||
* passed on to the wire to node 12 */
|
||||
static unsigned saw_room_wait, saw_passed;
|
||||
static void watch_mid(void)
|
||||
{
|
||||
if (pool[mid].n.doing && pool[mid].n.do_op == 9) { saw_room_wait++; if (places[mid].wire[3].tx && places[mid].wire[3].tx->used > 0) saw_passed++; }
|
||||
}
|
||||
|
||||
/* A MESSAGE THAT HAS BEEN PASSED ON AS OFTEN AS IT MAY BE comes to node 11 from node 12, for a node 99: its
|
||||
* fourth word is 1. No row of three can make one -- it takes sixteen nodes, or a ring -- so it is put on the
|
||||
* wire here, once, the first time node 11 is asleep for room. Node 11 refuses it without looking for its way:
|
||||
* the one refusal in which a message is dropped before the node's deepest use of its stacks. */
|
||||
static int spent_put;
|
||||
static void put_spent(void)
|
||||
{
|
||||
static const v4_cell hd[V4_WIRE_HEADER] = { 99, 12, V4_MSG_TEXT, 1, 0, 0, 4 }, text[1] = { 0x31 };
|
||||
if (!spent_put && places[mid].wire[3].rx) spent_put = v4_wire_put(places[mid].wire[3].rx, hd, text) == V4_WIRE_DONE;
|
||||
}
|
||||
static void watch_mid_spent(void)
|
||||
{
|
||||
watch_mid();
|
||||
if (saw_room_wait) put_spent();
|
||||
}
|
||||
|
||||
/* words that push 1, 2, 4, 8 and 16 values and call nothing while they do */
|
||||
static void fill(char *text, size_t cap, unsigned count)
|
||||
{
|
||||
@@ -193,17 +217,27 @@ static void fill(char *text, size_t cap, unsigned count)
|
||||
for (bit = 8; bit; bit >>= 1) if (count >= bit) { at += (size_t)snprintf(text + at, cap - at, "P%u ", bit); count -= bit; }
|
||||
}
|
||||
|
||||
#define PATHS 10u
|
||||
static const char *const path_name[PATHS] = { "a text that prints", "SEND", "SEND with no way", "AWAIT answered", "AWAIT ended by a GONE", "passing on while its text waits for room",
|
||||
"AWAIT broken by a line from the console", "a refusal while its text waits for room", "GONE",
|
||||
"a spent message refused while its text waits" };
|
||||
static char numbers[8192]; /* what 1200 0 DO I . LOOP prints */
|
||||
|
||||
/* A row made afresh for one path; node 11 is given the word ACT that takes it, and the words that fill the
|
||||
* stack and that call each other. */
|
||||
static int made(unsigned path)
|
||||
{
|
||||
static const char *const act[] = {
|
||||
static const char *const act[PATHS] = {
|
||||
": ACT 600 0 DO 65 EMIT LOOP ;",
|
||||
": ACT S\" 1 DROP\" 12 SEND ;",
|
||||
": ACT S\" 1 DROP\" 99 SEND ;",
|
||||
": ACT S\" 1 DROP\" 12 SEND 12 AWAIT DROP ;",
|
||||
": ACT 12 AWAIT DROP ;",
|
||||
": ACT 1200 0 DO I . LOOP ;",
|
||||
": ACT 12 AWAIT DROP ;",
|
||||
": ACT 1200 0 DO I . LOOP ;",
|
||||
": ACT 44 12 GONE ;",
|
||||
": ACT 1200 0 DO I . LOOP ;",
|
||||
};
|
||||
char line[64];
|
||||
unsigned k;
|
||||
@@ -216,30 +250,60 @@ static int made(unsigned path)
|
||||
if (path == 2 && !told(11, "NO-ROUTES 1 2 ROUTE 10 2 ROUTE 12 3 ROUTE")) return 0; /* no way for any node it has not been told of */
|
||||
if (path == 4 && !told(12, ": LL 400000 0 DO LOOP ;")) return 0;
|
||||
if (path == 5 && !told(10, ": SLOW 500000 0 DO LOOP ; : BUSY SLOW S\" 1 DROP\" 12 SEND SLOW ;")) return 0;
|
||||
if (path == 9 && !told(10, ": SLOW 500000 0 DO LOOP ; : BUSY SLOW SLOW ;")) return 0;
|
||||
/* 320 characters: more than fits beside what node 11 itself is waiting to print */
|
||||
if (path == 7 && !(told(10, ": SLOW 500000 0 DO LOOP ; : BUSY SLOW SLOW ;") && told(12, ": LATE 250000 0 DO LOOP PAD 320 BLANK PAD 320 99 SEND ;"))) return 0;
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* Node 11 takes the path with `text`; `values` is how many values the text leaves on its stack if it completes. */
|
||||
static int one(unsigned path, const char *what, unsigned depth, const char *text, unsigned values)
|
||||
/* 1 if `s` is `lead`, then some of `body` from its start, then exactly `end`. */
|
||||
static int is_cut_short(const char *s, const char *body, const char *end)
|
||||
{
|
||||
static const char *const name[] = { "a text that prints", "SEND", "SEND with no way", "AWAIT answered", "AWAIT ended by a GONE", "passing on while its text waits for room" };
|
||||
const char *why = 0;
|
||||
int how11;
|
||||
size_t n = strlen(s), e = strlen(end);
|
||||
return n >= e && strcmp(s + n - e, end) == 0 && strncmp(s, body, n - e) == 0 && n - e <= strlen(body);
|
||||
}
|
||||
|
||||
/* Node 11 takes the path with `text`; `values` is how many values the text leaves on its stack if it completes;
|
||||
* `must` says the stack is shallow enough that it must work. Returns 1 if it worked, 0 if it ended in a clean
|
||||
* stack error, and counts a failure if it did neither. */
|
||||
static int one(unsigned path, const char *what, unsigned depth, const char *text, unsigned values, int must)
|
||||
{
|
||||
static char sixhundred[601];
|
||||
const char *why = 0, *over = 0;
|
||||
v4_cell lost11 = pool[mid].n.mem[LOST], refused12 = pool[far].n.mem[REFUSED], ways12;
|
||||
int how11, works = 0, clean_error = 0;
|
||||
unsigned left;
|
||||
|
||||
if (!sixhundred[0]) memset(sixhundred, 'A', 600);
|
||||
runs++;
|
||||
forget();
|
||||
step_cap = 60000000;
|
||||
if (path == 4) { /* node 12 is busy for a long while and sends no answer; node 11 waits; its centre says 12 is gone */
|
||||
if (path == 8 && !told(12, "44 2 ROUTE")) why = "node 12 did not take a way";
|
||||
ways12 = pool[far].n.mem[ROUTE_COUNT];
|
||||
forget();
|
||||
saw_room_wait = 0; saw_passed = 0;
|
||||
if (why) { }
|
||||
else if (path == 4) { /* node 12 is busy for a long while and sends no answer; node 11 waits; its centre says 12 is gone */
|
||||
stuck = 1u << far;
|
||||
if (!put_text(12, "LL") || !put_text(11, text) || !run()) why = "it did not come to wait";
|
||||
else if (!put_text(10, "12 11 GONE") || !run()) why = "the GONE was not done";
|
||||
stuck = 0;
|
||||
if (!why && !run()) why = "the nodes did not come to rest";
|
||||
} else if (path == 5) { /* node 10, by which node 11 prints, is busy, and sends node 12 a message by node 11 meanwhile */
|
||||
saw_room_wait = 0; saw_passed = 0; watch = watch_mid;
|
||||
watch = watch_mid;
|
||||
if (!put_text(11, text) || !put_text(10, "BUSY") || !run()) why = "the nodes did not come to rest";
|
||||
watch = 0;
|
||||
} else if (path == 6) { /* node 12 sends no answer; node 11 waits, and is typed to */
|
||||
if (!put_text(11, text) || !run()) why = "it did not come to wait";
|
||||
else if (!put_text(11, "77 .") || !run()) why = "the nodes did not come to rest";
|
||||
} else if (path == 7) { /* node 10 is busy; node 12 sends a message for 99 by node 11, whose way for it is the full wire */
|
||||
watch = watch_mid;
|
||||
if (!put_text(11, text) || !put_text(10, "BUSY") || !put_text(12, "LATE") || !run()) why = "the nodes did not come to rest";
|
||||
watch = 0;
|
||||
} else if (path == 9) { /* node 10 is busy; a spent message comes while node 11 waits for room -- or, if it never does, afterwards */
|
||||
spent_put = 0; watch = watch_mid_spent;
|
||||
if (!put_text(11, text) || !put_text(10, "BUSY") || !run()) why = "the nodes did not come to rest";
|
||||
watch = 0;
|
||||
if (!why && !spent_put) { put_spent(); if (!run()) why = "the nodes did not come to rest"; }
|
||||
} else {
|
||||
if (!put_text(11, text) || !run()) why = "the nodes did not come to rest";
|
||||
}
|
||||
@@ -247,15 +311,43 @@ static int one(unsigned path, const char *what, unsigned depth, const char *text
|
||||
left = (unsigned)pool[mid].n.ds.depth;
|
||||
if (!why && !(asleep(hera) && asleep(mid) && asleep(far))) why = "a node is not asleep";
|
||||
if (!why && ended < 1) why = "node 11's text was not answered";
|
||||
if (!why && how11 == V4_TEXT_COMPLETED && left != values) why = "its stack is not as deep as the text made it";
|
||||
if (!why && how11 == V4_TEXT_ERROR && !(strstr(printed, "overflow") || strstr(printed, "Argument out of range") || strstr(printed, "Node gone") || strstr(printed, "Message refused")))
|
||||
why = "its text ended in an error it did not report";
|
||||
if (!why && how11 != V4_TEXT_COMPLETED && how11 != V4_TEXT_ERROR) why = "its text ended neither way";
|
||||
if (!why && path == 0 && how11 == V4_TEXT_COMPLETED && printed_len != 600) why = "not all it printed arrived";
|
||||
if (!why && path == 5 && how11 == V4_TEXT_COMPLETED && !strstr(printed, " 1199 ")) why = "not all it printed arrived";
|
||||
if (!why && path == 5 && how11 == V4_TEXT_COMPLETED && !(saw_room_wait > 0 && saw_passed > 0)) why = "it did not wait for room, or passed nothing on while it did";
|
||||
|
||||
/* which of the two ways did it end? */
|
||||
if (!why) {
|
||||
if (strstr(printed, "Return stack overflow\n")) over = "Return stack overflow\n";
|
||||
else if (strstr(printed, "Stack overflow\n")) over = "Stack overflow\n";
|
||||
switch (path) {
|
||||
case 0: works = how11 == V4_TEXT_COMPLETED && strcmp(printed, sixhundred) == 0 && left == values;
|
||||
clean_error = over && is_cut_short(printed, sixhundred, over); break;
|
||||
case 1: works = how11 == V4_TEXT_COMPLETED && printed_len == 0 && left == values && pool[mid].n.mem[LOST] == lost11 + 1; /* node 12's answer, which it did not wait for */
|
||||
clean_error = over && strcmp(printed, over) == 0 && pool[mid].n.mem[LOST] == lost11; break;
|
||||
case 2: works = how11 == V4_TEXT_ERROR && strcmp(printed, "Argument out of range\n") == 0 && left == values;
|
||||
clean_error = over && strcmp(printed, over) == 0; break;
|
||||
case 3: works = how11 == V4_TEXT_COMPLETED && printed_len == 0 && left == values && pool[mid].n.mem[LOST] == lost11;
|
||||
clean_error = over && strcmp(printed, over) == 0; break;
|
||||
case 4: works = how11 == V4_TEXT_ERROR && strcmp(printed, "Node gone\n") == 0 && left == values;
|
||||
clean_error = over && strcmp(printed, over) == 0; break;
|
||||
case 5: works = how11 == V4_TEXT_COMPLETED && strcmp(printed, numbers) == 0 && left == values && saw_room_wait > 0 && saw_passed > 0;
|
||||
clean_error = over && is_cut_short(printed, numbers, over); break;
|
||||
case 6: works = strcmp(printed, "Interrupted\n77 ") == 0 && ended == 2;
|
||||
if (over) { char want[64]; snprintf(want, sizeof want, "%s77 ", over); clean_error = strcmp(printed, want) == 0 && ended == 2; }
|
||||
break;
|
||||
case 7: works = how11 == V4_TEXT_COMPLETED && strcmp(printed, numbers) == 0 && left == values && saw_room_wait > 0
|
||||
&& pool[mid].n.mem[LOST] == lost11 + 1 && pool[far].n.mem[REFUSED] == refused12 + 1;
|
||||
clean_error = over && is_cut_short(printed, numbers, over) && pool[far].n.mem[REFUSED] == refused12 + 1; break; /* whoever refused it, node 12 was told */
|
||||
case 8: works = how11 == V4_TEXT_COMPLETED && printed_len == 0 && left == values && pool[far].n.mem[ROUTE_COUNT] == ways12 - 1;
|
||||
clean_error = over && strcmp(printed, over) == 0; break;
|
||||
case 9: works = how11 == V4_TEXT_COMPLETED && strcmp(printed, numbers) == 0 && left == values && saw_room_wait > 0
|
||||
&& pool[mid].n.mem[LOST] == lost11 + 1 && pool[far].n.mem[REFUSED] == refused12 + 1;
|
||||
clean_error = over && is_cut_short(printed, numbers, over) && pool[mid].n.mem[LOST] == lost11 + 1 && pool[far].n.mem[REFUSED] == refused12 + 1; break; /* it was dropped: its sender was told */
|
||||
}
|
||||
if (clean_error && !(path == 6 || (how11 == V4_TEXT_ERROR && left == 0))) clean_error = 0; /* a stack fault empties the stack */
|
||||
if (works && over) works = 0;
|
||||
if (!works && !clean_error) why = "it neither worked nor ended in a stack error and nothing else";
|
||||
else if (!works && must) why = "it ended in a stack error where the stack is shallow enough for it to work";
|
||||
}
|
||||
/* every node comes back */
|
||||
if (!why && !(strcmp(tell(11, "ABORT"), "") == 0 && ended == 1 && pool[mid].n.ds.depth == 0)) why = "node 11 did not answer ABORT";
|
||||
if (!why && !(strcmp(tell(11, "ABORT"), "") == 0 && ended == 1 && pool[mid].n.ds.depth == 0 && pool[mid].n.mem[AWAIT_FROM] == 0)) why = "node 11 did not answer ABORT";
|
||||
if (!why && path == 4 && !told(11, "12 3 ROUTE")) why = "node 11 did not take the way to 12 again";
|
||||
if (!why && strcmp(tell(11, "1 2 + ."), "3 ") != 0) why = "node 11 did not answer";
|
||||
if (!why && strcmp(tell(10, "1 2 + ."), "3 ") != 0) why = "node 10 did not answer";
|
||||
@@ -264,11 +356,14 @@ static int one(unsigned path, const char *what, unsigned depth, const char *text
|
||||
checks++;
|
||||
if (why) {
|
||||
failures++; bad++;
|
||||
printf("FAIL %s, %s %u: %s: \"%.60s\"\n", name[path], what, depth, why, printed);
|
||||
printf("FAIL %s, %s %u: %s: how %d, %u left, lost %+ld, refused %+ld, waits %u/%u: \"%.50s\"\n", path_name[path], what, depth, why, how11, left,
|
||||
(long)(pool[mid].n.mem[LOST] - lost11), (long)(pool[far].n.mem[REFUSED] - refused12), saw_room_wait, saw_passed, printed);
|
||||
show_stuck(text);
|
||||
(void)made(path); /* the next begins on a row that is whole */
|
||||
return -1;
|
||||
}
|
||||
return how11;
|
||||
if (works) worked++; else refused_clean++;
|
||||
return works;
|
||||
}
|
||||
|
||||
int main(void)
|
||||
@@ -299,30 +394,39 @@ int main(void)
|
||||
nucleus.mem[SRC] = TIB;
|
||||
nucleus.mem[LINE_STATUS] = 1;
|
||||
HOST_MESSAGES_EMPTY(&nucleus);
|
||||
{ size_t at = 0; for (k = 0; k < 1200; k++) at += (size_t)snprintf(numbers + at, sizeof numbers - at, "%u ", k); }
|
||||
|
||||
for (path = 0; path < 6; path++) {
|
||||
unsigned before = bad, done = 0, errors = 0;
|
||||
for (path = 0; path < PATHS; path++) {
|
||||
unsigned before = bad, w0 = worked, e0 = refused_clean, first_error = 0;
|
||||
int r;
|
||||
CHECK(made(path), "a row for path %u", path);
|
||||
if (failures > (int)bad) break;
|
||||
/* the data stack at every depth from 20 to full */
|
||||
/* the data stack at every depth from 20 to full: with 24 or fewer every path must work */
|
||||
for (k = V4_DATA_DEPTH - 12u; k <= V4_DATA_DEPTH; k++) {
|
||||
size_t at;
|
||||
fill(text, sizeof text, k);
|
||||
at = strlen(text);
|
||||
snprintf(text + at, sizeof text - at, "ACT");
|
||||
if (one(path, "values on the stack", k, text, k) == V4_TEXT_COMPLETED) done++; else errors++;
|
||||
r = one(path, "values on the stack", k, text, k, k + 8u <= V4_DATA_DEPTH);
|
||||
if (r == 0 && !first_error) first_error = k;
|
||||
}
|
||||
/* and from every depth of calls from 20 to past the end of the return stack */
|
||||
for (k = V4_RET_DEPTH - 12u; k <= V4_RET_DEPTH + 1u; k++) {
|
||||
printf(" %-42s %2u..%u values: works to %u, then a stack error and nothing else;", path_name[path], (unsigned)(V4_DATA_DEPTH - 12u), (unsigned)V4_DATA_DEPTH, first_error ? first_error - 1u : (unsigned)V4_DATA_DEPTH);
|
||||
/* and from every depth of calls from 14 to past the end of the return stack: 21 deep or less every path
|
||||
* must work -- 16 or less for the two that print and are woken while they wait for room, which go
|
||||
* deepest: the loop, the word that prints, EMIT, the wait, and (SERVE) under it */
|
||||
first_error = 0;
|
||||
for (k = V4_RET_DEPTH - 18u; k <= V4_RET_DEPTH + 1u; k++) {
|
||||
snprintf(text, sizeof text, "N%u", k);
|
||||
(void)one(path, "calls deep", k, text, 0);
|
||||
r = one(path, "calls deep", k, text, 0, k + ((path == 5 || path == 7 || path == 9) ? 16u : 11u) <= V4_RET_DEPTH);
|
||||
if (r == 0 && !first_error) first_error = k;
|
||||
}
|
||||
printf(" path %u: with %u to %u values on the stack, %u completed and %u ended in an error reported; %u failures\n", path, (unsigned)(V4_DATA_DEPTH - 12u), (unsigned)V4_DATA_DEPTH, done, errors, bad - before);
|
||||
printf(" calls: works to %u deep; %u worked, %u clean errors, %u failures\n", first_error ? first_error - 1u : (unsigned)(V4_RET_DEPTH + 1u), worked - w0, refused_clean - e0, bad - before);
|
||||
}
|
||||
/* ---- between texts: node 11 passes on, and refuses, with as many values waiting on its stack as a text
|
||||
* may leave (MESH.md 7d.4: the rule of 28). Not one fault. ---- */
|
||||
|
||||
/* ---- between texts: node 11 passes on, refuses, and holds what it has no room to pass on, with as many
|
||||
* values waiting on its stack as a text may leave (MESH.md 7d.4: the rule of 28). Not one fault. ---- */
|
||||
CHECK(row() && told(11, ": P1 7 ; : P2 7 7 ; : P4 7 7 7 7 ; : P8 7 7 7 7 7 7 7 7 ;") && told(11, ": P16 P8 P8 ;") && told(11, "77 5 ROUTE")
|
||||
&& told(12, ": S77 S\" 1 DROP\" 77 SEND ;"), "a row; node 11's way to 77 is a port with no one on it");
|
||||
&& told(12, ": S77 S\" 1 DROP\" 77 SEND ; : PR 1200 0 DO I . LOOP ;") && told(10, ": SLOW 500000 0 DO LOOP ; : BUSY SLOW SLOW ;"), "a row; node 11's way to 77 is a port with no one on it");
|
||||
for (k = V4_DATA_DEPTH - 12u; k + 4u <= V4_DATA_DEPTH; k++) {
|
||||
unsigned faults;
|
||||
v4_cell lost = pool[mid].n.mem[LOST], refused = pool[far].n.mem[REFUSED];
|
||||
@@ -331,11 +435,16 @@ int main(void)
|
||||
faults = pool[mid].n.faults;
|
||||
CHECK(strcmp(tell(12, "1 2 + ."), "3 ") == 0 && ended == 1, "with %u values waiting it passes text on to node 12, and what comes back", k);
|
||||
CHECK(told(12, "S77") && pool[mid].n.mem[LOST] == lost + 1 && pool[far].n.mem[REFUSED] == refused + 1, "and refuses a message it has no way for, and tells node 12");
|
||||
forget();
|
||||
saw_room_wait = 0; watch = watch_mid;
|
||||
CHECK(put_text(12, "PR") && put_text(10, "BUSY") && run() && strcmp(printed, numbers) == 0 && saw_room_wait > 0,
|
||||
"and holds what node 12 prints while node 10 is busy, asleep for room, and passes all of it on: %u characters", printed_len);
|
||||
watch = 0;
|
||||
CHECK(pool[mid].n.faults == faults && pool[mid].n.ds.depth == k && asleep(mid), "without a fault, its stack as it was: %u values", (unsigned)pool[mid].n.ds.depth);
|
||||
CHECK(strcmp(tell(11, "ABORT"), "") == 0 && strcmp(tell(11, "1 2 + ."), "3 ") == 0, "and it goes on");
|
||||
}
|
||||
|
||||
printf(" %u runs; %u in which a node did not come back\n", runs, bad);
|
||||
printf(" %u runs: %u worked, %u ended in a stack error and nothing else, %u did neither\n", runs, worked, refused_clean, bad);
|
||||
printf(" %d checks, %d failures\n", checks, failures);
|
||||
return failures != 0;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user