From 9a02ca8e0c978a92fb40e41a815493a7e731da49 Mon Sep 17 00:00:00 2001 From: InauguralPhysicist Date: Sat, 5 Sep 2026 22:13:04 -0500 Subject: [PATCH] test: embed-concurrent's planted-race control runs until it OBSERVES the race MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The #885 control asserted that a deliberately shared global cross-talks between two threads within a fixed 200 rounds each. That is a bet on the scheduler, and it lost on CI for PR #1106 @ 07a0ac3 (2026-09-06): `control cross-talk: A=0 B=0 over 200 rounds each`, with the file identical on main and the lane green on the previous push. PR #1034 hit the same shape before the start barrier was added. Now each worker runs at least ROUNDS rounds and keeps racing until BOTH sides have observed at least one mismatch or PLANT_BUDGET (200000) rounds elapse; the check requires both sides to have seen it. The property is unchanged — a harness that never interleaves exhausts the budget and FAILS — only the sample size adapts to the scheduler. Measured on the dev box: 3/3 runs stop at the 200-round minimum (A=198/200 B=199/200; 199/198; 188/189). Plant: making the shared global `__thread` (race impossible) gives `A=0/200000 B=0/200000` and EMBED_CONCURRENT_FAIL in 0.37 s, so the budget costs nothing on a failing control either. Co-Authored-By: Claude Fable 5.1 Claude-Session: https://claude.ai/code/session_01Kpzyjv1SaLaqBf45FSFDhB --- src/embed_concurrent.c | 35 ++++++++++++++++++++++++++++------- 1 file changed, 28 insertions(+), 7 deletions(-) diff --git a/src/embed_concurrent.c b/src/embed_concurrent.c index 0d119cf7..a82fa6f7 100644 --- a/src/embed_concurrent.c +++ b/src/embed_concurrent.c @@ -25,6 +25,7 @@ */ #include "eigs_embed.h" #include +#include #include #include #include @@ -237,12 +238,27 @@ static volatile double planted_shared_threshold; /* the mistake, deliberately * is the interleaving premise the comment below already claims. */ static pthread_barrier_t planted_start; -typedef struct { double want; int mismatches; } PlantArg; +typedef struct { double want; int mismatches; int rounds_run; } PlantArg; + +/* The control must OBSERVE the race, not merely give it 200 chances. A fixed + * round count is a bet on the scheduler: on a runner slot where one thread's + * write-yield-read triple stays adjacent, 200 rounds can pass with zero + * cross-talk (CI on 07a0ac3, 2026-09-06: `A=0 B=0 over 200 rounds each`, the + * file identical on main; PR #1034 hit the same shape before the barrier was + * added). So each worker runs at least ROUNDS rounds and then keeps racing + * until BOTH sides have seen at least one mismatch or PLANT_BUDGET rounds have + * elapsed. A harness that truly never interleaves still exhausts the budget + * and FAILS the control — the property being checked is unchanged; only the + * sample size adapts to the scheduler. */ +#define PLANT_BUDGET 200000 +static _Atomic int planted_seen; /* number of workers that observed a mismatch */ static void *planted_worker(void *p) { PlantArg *a = (PlantArg *)p; + int counted = 0; pthread_barrier_wait(&planted_start); - for (int i = 0; i < ROUNDS; i++) { + for (int i = 0; i < PLANT_BUDGET; i++) { + if (i >= ROUNDS && atomic_load(&planted_seen) >= 2) break; planted_shared_threshold = a->want; /* Give the other thread a window between write and read. Without one * the compiler and the scheduler can keep the pair adjacent and the @@ -251,13 +267,18 @@ static void *planted_worker(void *p) { * value being kept in a register; the yield supplies the interleaving. */ sched_yield(); double got = planted_shared_threshold; - if (got < a->want - 1e-9 || got > a->want + 1e-9) a->mismatches++; + a->rounds_run++; + if (got < a->want - 1e-9 || got > a->want + 1e-9) { + a->mismatches++; + if (!counted) { counted = 1; atomic_fetch_add(&planted_seen, 1); } + } } return NULL; } static void test_planted_fault_is_detectable(void) { - PlantArg a = { 0.001, 0 }, b = { 0.002, 0 }; + PlantArg a = { 0.001, 0, 0 }, b = { 0.002, 0, 0 }; + atomic_store(&planted_seen, 0); pthread_t ta, tb; pthread_barrier_init(&planted_start, NULL, 2); pthread_create(&ta, NULL, planted_worker, &a); @@ -268,10 +289,10 @@ static void test_planted_fault_is_detectable(void) { /* The shared global MUST produce cross-talk. If it does not, the harness is * not interleaving and every green row above is uninformative. */ - check(a.mismatches + b.mismatches > 0, + check(a.mismatches > 0 && b.mismatches > 0, "control: a shared global DOES cross-talk under this harness"); - printf(" control cross-talk: A=%d B=%d over %d rounds each\n", - a.mismatches, b.mismatches, ROUNDS); + printf(" control cross-talk: A=%d/%d B=%d/%d rounds (min %d, budget %d)\n", + a.mismatches, a.rounds_run, b.mismatches, b.rounds_run, ROUNDS, PLANT_BUDGET); } int main(void) {