writeonce/runtime/Makefile
shoney.arickathil f6a1da7eb4 feat: cross-shard actors — placement, envelopes, home-routed frees, WO-E222 (arc T6)
- spawn placement: round-robin across shards (same-shard when the
  engine is absent/single); the actor's mailbox and delivery belong to
  its HOME thread — a spawn to another shard travels as an ADOPT
  envelope, a send as a SEND envelope (mutex-guarded inbox + eventfd
  wake; the spec's lock-free rings stay a disclosed deviation until
  9e measures the mutex)
- workers: first envelope triggers lazy full-vm init UNDER the inbox
  mutex (TSan caught the memset racing a concurrent push, twice — the
  second was inbox_push reading wake_efd outside the lock; both fixed,
  gate x8 + battery clean); serve loop = adopt -> run to drained ->
  wait on the plane (the wake eventfd is watched by io_uring POLL_ADD
  oneshot / epoll level-triggered on BOTH backends)
- ownership across heaps: every allocation stamps rt->shard_id into
  the header (the field reserved since iteration 2); a drop on the
  wrong shard routes home as a FREE envelope — the owner's arena stays
  single-threaded by construction; at teardown routed frees become
  no-ops (arenas die wholesale) which is what un-danced the freed-mutex
  ASan SEGV the first ordering had
- WO-E222: an actor's state or message type that is (or transitively
  contains) an inferred-traced class refuses at the spawn/send — with
  round-robin every actor is potentially remote; corpus-pinned
  (compile-fail/traced-send, inference-aware: Box contains ?Node)
- determinism narrowed per spec: oop-e2e pins WO_SHARDS=1 (exact
  outputs); the fibers gate grows multi-shard SET assertions + a TSan
  run (wovm-tsan target; setarch -R fallback for kernel 6.5+ ASLR)
- NEXT_RUNNABLE honors engine shutdown for parked workers (deadlock
  hole closed); io_wait's adopt-wake (rc 1) no longer reads as fatal
- battery: oop-e2e 93/0, fibers 10/0 x8 (+WO_IO=epoll), log-watcher
  7/0, employee 8/0, web-app 21/0, deps 8/0, runtime tests 16/16

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-20 12:06:13 +02:00

83 lines
3 KiB
Makefile

CC ?= cc
CFLAGS ?= -O2 -Wall -Wextra -std=c11
LDFLAGS ?= -pthread
# toolchain version, single-sourced from the repo-root VERSION file; stamped
# into wovm's `--version`. `just dist` asserts woc and wovm agree with it.
WO_VERSION := $(shell cat ../VERSION 2>/dev/null || echo 0.0.0-dev)
VERFLAG := -DWO_VERSION='"$(WO_VERSION)"'
wo-rt: wo-rt.c
$(CC) $(CFLAGS) -o $@ $< $(LDFLAGS)
# ---- wovm VM core (src/) + unit tests (test/) ----
# Each test/test_*.c builds into its own ASan+UBSan binary linked against
# every src/*.c except main.c; `make test` runs them all.
# the database engine lives in its own top-level directory (iteration 9;
# user decision 2026-08-15) and is statically linked into every wovm and
# every test binary — one binary, unchanged
DBSRC := $(wildcard ../database/src/*.c)
DBHDR := $(wildcard ../database/src/*.h)
VMSRC := $(filter-out src/main.c,$(wildcard src/*.c)) $(DBSRC)
VMHDR := $(wildcard src/*.h) $(wildcard test/*.h) $(DBHDR)
TESTS := $(wildcard test/test_*.c)
TESTBIN := $(TESTS:test/%.c=build/%)
TCFLAGS := -std=c11 -Wall -Wextra -Werror -g -O1 \
-fsanitize=address,undefined -fno-omit-frame-pointer
build:
mkdir -p build
TESTHELP := $(wildcard test/wob_build.c)
build/%: test/%.c $(VMSRC) $(TESTHELP) $(VMHDR) | build
$(CC) $(TCFLAGS) -Isrc -Itest -I../database/src -o $@ $< $(TESTHELP) $(VMSRC)
test: $(TESTBIN)
@for t in $(TESTBIN); do echo "== $$t"; ./$$t || exit 1; done
# ISO dispatch flavor (switch instead of computed goto) — gated in every
# run so the fallback can never rot
ISOBIN := $(TESTS:test/%.c=build/iso_%)
build/iso_%: test/%.c $(VMSRC) $(TESTHELP) $(VMHDR) | build
$(CC) $(TCFLAGS) -DWO_ISO_C -Isrc -Itest -I../database/src -o $@ $< $(TESTHELP) $(VMSRC)
test-iso: $(ISOBIN)
@for t in $(ISOBIN); do echo "== $$t"; ./$$t || exit 1; done
# the wovm binary (plain optimized build; the test suite is the ASan gate)
wovm: src/main.c $(VMSRC) $(VMHDR)
$(CC) $(CFLAGS) $(VERFLAG) -Isrc -I../database/src -o $@ src/main.c $(VMSRC)
# ASan+UBSan wovm, same flags as the unit tests, for corpus fixtures that
# need a sanitizer to prove a free actually happened (gc/ cycle fixtures) —
# tasks 3/4 hand-built this each time because it didn't exist yet
build/wovm_asan: src/main.c $(VMSRC) $(VMHDR) | build
$(CC) $(TCFLAGS) -Isrc -I../database/src -o $@ src/main.c $(VMSRC)
wovm-asan: build/wovm_asan
# TSan flavor (arc stage 2): the cross-shard proofs run under this
build/wovm_tsan: src/main.c $(VMSRC) $(VMHDR) | build
$(CC) $(CFLAGS) -fsanitize=thread -g -Isrc -I../database/src -o $@ src/main.c $(VMSRC) $(LDFLAGS)
wovm-tsan: build/wovm_tsan
# fixture generator for the CLI smoke test
build/mkwob: test/mkwob.c test/wob_build.c $(VMHDR) | build
$(CC) $(CFLAGS) -Isrc -Itest -o $@ test/mkwob.c test/wob_build.c
bench/bench: bench/bench.c
$(CC) $(CFLAGS) -o $@ $< $(LDFLAGS)
bench: bench/bench
run: wo-rt
./wo-rt
clean:
rm -f wo-rt bench/bench wovm
rm -rf build
.PHONY: bench run clean test test-iso wovm-asan wovm-tsan