Files
Brummel fbeeadeba5 iter embedding-abi-m2.1 (DONE 5-9): swarm-safe ctx ABI complete + sanitiser-verified
Completes Embedding ABI — M2.1 (Tasks 1-4 committed c9a84b3 as the
known-good subset; this commit lands Tasks 5-9 from the re-dispatch
against the Boss-corrected plan).

- T5: swarm.c per-thread-ctx scalar-swarm capability demo (no
  SHARED_CTX) + rc_accounting_shared_ctx_is_flagged_by_tsan added to
  the item-1 harness driver (de-globalisation negative-control teeth,
  where a shared ctx genuinely races on ctx->alloc_count).
- T6: M1 host.c migrated to the ctx ABI; embed_e2e green (s==25
  through the ctx-threaded forwarder).
- T7: DESIGN.md current-state update (provisional-until-M3 narrowed
  to the value/record layout; Decision-10 per-thread-ctx note);
  docs_honesty-pinned sentence + (con Int) snippet preserved verbatim.
- T8: regression gate — workspace green; null-ctx fallback
  byte-behaviour preserved.
- T9: bench-trio — compile_check/cross_lang clean; check.py
  tracked-P2 noise only, causally exonerated (zero codegen/runtime
  diff vs HEAD), NO baseline ratified.

Boss-verified directly (not on report trust): docs_honesty_pin 5/0,
design_schema_drift 8/0, embed_export_hash_stable 1/0,
embed_export_gate 6/0, embed_e2e 1/0, embed_staticlib_alloc_guard
2/0, print_no_leak_pin 1/0 + e2e rc_stats 4/0; the tsan coherent-stop
proven by hand — per-ctx clean (exit 0, 0 warnings), shared-ctx a
real ThreadSanitizer data race at rc.c:157/:208 (exit 66).

Known debt (journal + roadmap): DESIGN.md '## Embedding ABI (M1)'
header still says (M1) while the body mirrors M2 — out of Task 7's
scope-limited regions by design; post-audit doc-honesty tidy.

Milestone-close audit next.
2026-05-18 17:31:50 +02:00

50 lines
1.8 KiB
C

/* M2 item 2: scalar-kernel capability demo. N threads, each owning
* its own ailang_ctx_t, drive the headline scalar kernel; must be
* -fsanitize=thread-clean with every thread's result == the serial
* oracle. NO negative control here: a non-allocating scalar kernel
* writes no shared mutable state even under a shared ctx, so a
* shared-ctx variant cannot race (the de-globalisation negative
* control lives in the rc_accounting harness — Task 5 Step 3). */
#include <stdint.h>
#include <stdio.h>
#include <pthread.h>
typedef struct ailang_ctx ailang_ctx_t;
extern ailang_ctx_t *ailang_ctx_new(void);
extern void ailang_ctx_free(ailang_ctx_t *);
extern int64_t backtest_step(ailang_ctx_t *ctx, int64_t state, int64_t sample);
#define NTHREADS 8
#define NITERS 200000
static int64_t serial_oracle(void) {
/* mirrors examples/embed_backtest_step.ail: state += sample*sample,
* sample = (i & 7) over NITERS iterations. */
int64_t s = 0;
for (int i = 0; i < NITERS; i++) { int64_t x = i & 7; s = s + x * x; }
return s;
}
static void *worker(void *out) {
ailang_ctx_t *ctx = ailang_ctx_new();
int64_t s = 0;
for (int i = 0; i < NITERS; i++) s = backtest_step(ctx, s, (i & 7));
ailang_ctx_free(ctx);
*(int64_t *)out = s;
return NULL;
}
int main(void) {
pthread_t t[NTHREADS];
int64_t res[NTHREADS];
for (int i = 0; i < NTHREADS; i++) pthread_create(&t[i], NULL, worker, &res[i]);
for (int i = 0; i < NTHREADS; i++) pthread_join(t[i], NULL);
int64_t oracle = serial_oracle();
for (int i = 0; i < NTHREADS; i++) {
if (res[i] != oracle) { fprintf(stderr, "thread %d: %lld != %lld\n",
i, (long long)res[i], (long long)oracle); return 1; }
}
printf("swarm: ok (%lld)\n", (long long)oracle);
return 0;
}