fix(runtime): interleave executors due at one instant move by move - #850
devin-ai-integration[bot] wants to merge 8 commits into
Conversation
Co-Authored-By: jason.han <hanhuijun@gmail.com>
|
I'll fix CI failures and address comments from users with write access. I'll skip comments containing "(aside)".
|
…nd a move that may end a run Co-Authored-By: jason.han <hanhuijun@gmail.com>
…or-turns Co-Authored-By: jason.han <hanhuijun@gmail.com> # Conflicts: # cmd/sysml/check_engine_test.go # internal/exec/runtime/advance.go # internal/exec/runtime/model.go
…erleave Co-Authored-By: jason.han <hanhuijun@gmail.com>
|
This branch now conflicts with
To resolve: merge current Planned merge order for the execution PRs: #844 → #850 → #838 → (#851 → #853 → #857) → #830 → #833 → #842 → #837 → #834 → #816. Re-run the full gate ( |
…or-turns Co-Authored-By: jason.han <hanhuijun@gmail.com> # Conflicts: # docs/project/spec-compliance.md # internal/exec/runtime/model.go # internal/exec/runtime/scheduler.go # internal/exec/runtime/testdata/check/reduction_expected.txt # internal/ir/lower/footprint.go
|
Hold on pushes: please don't push to this branch, including |
What and why
Executors due at one instant (two actions, an action and a state machine, two machines) are unordered, but under
explore,check,replayandseed:<n>the executor drawn from the due order ran all its work at the instant before any other could move. Two actions that each read a shared counter and then write it never reached the lost update: both reads before either write.The executor drawn now makes one move, then keeps its turn only while its next move is independent of everything each other due executor may still do at the instant; otherwise the due order is drawn again.
future_footprint.go: an executor's future at the instant is everything it may still do, stopped only at a wait on a literal delay that resolves past the instant.gate()gathers every send any executor may make at the instant; a machine's future then leaves out a transition whose signal no queued message carries and no gathered send can meet (cannotFire), unless some executor may send anything.message_dependence.goContext.relation+lower.Footprint.DependentBy(g, rel): two executors on two objects commute on direct accesses to features each object holds itself (Relation.Held); a send naming no target (Channel.Own) meets no consumer run for another object. A send and an accept, or two accepts, are separated only where both signal types resolve statically and do not conform; an unresolved type, aviaroute, an unresolved receiver or port, and a dispatch that may drop the message all stay dependent.advance.goContext.endContended: a move that may end the driver's performance (an action token past no unguarded succession, out of a nested frame, or reaching beyond its node; a machine that can complete or terminate) yields to any rival still able to move, since the run's outcome is read at that end.-engine checkholds the same turn:invocationRun.turnlimits the enabled moves to the held executor, is part of the canonical state (turn:line) and is saved and restored with each frame. The persistent-set reduction uses the sameDependentBywith the same relation, andpersistentClosure.includenow follows future dependence from every unit it adds, enabled or not; a do behavior stepping a stated flow contributes that flow's token footprints.StateExecutor.runMovereports whether the machine ran a unit at all, not only whether it bumped the event or do-step counters, so resuming a held entry or completing the machine counts as its move and a turn goes on through the rest of the instant's work.declaredandreversekeep their order: the executor drawn runs its work at the instant through (scheduler.interleavesTurns).Specification basis
Kernel Semantic Library
Clocks.kerml/Occurrences.kerml: two performances waiting on the sameTimeInstantValueareHappensBefore-linked by nothing, so their steps interleave. Thespec-compliance.mdrows for executors due at one instant and for the model checker's moves now describe move-by-move turns; both stay Faithful.How it was verified
cmd/sysml/explore_turns_test.go:TestExploreRunsAHeldEntryAsAMove: a held entry cascade with aGoqueued behind it and an action reading what the cascade writes. Every explored and seeded run dispatchesGoat the instant (inner+b), and explore reaches the read between the cascade and the dispatch (order = 12; seen = 1).cmd/sysml/explore_turns_test.go:TestExploreInterleavesExecutorsMoveByMove: the read-then-write pair reaches 3 outcomes under explore (complete) and check (witness replayed), seeds 1..12 reach all three, anddeclared/reversekeepseen = 0, seen = 1/seen = 1, seen = 0. It fails ondevelop(2 outcomes, no seed reaches the lost update).TestCheckReductionIsSoundpasses (reduced finals equal unreduced). Final outcome sets over the reduction corpus againstdevelop: unchanged in 17 models, strictly larger in 2 (por_state_send_accept+1,por_state_join_exit+6), none lost.TestExploredRunsAreGivenOneObjectPerInstantiateandTestExploredPathsAreCheckedAgainstTheDeclarationsreach theirdevelopoutcomes at their unchanged budgets.go build ./...,go vet ./...,gofmt -l .,go test ./...(pilot library XMI downloaded),go test -race ./internal/exec/runtime/...,make lint,python3 scripts/changelog.py checkpass.make docs-checkfails only ondocs/project/third-party-notices.mdlinkingdocs/assets/landing/libavoid-js.LICENSE.txt, whichdevelopdoes not carry either.Expectations that moved
developreduction_expected.txtpor_state_effect_write,por_state_guard_readpor_state_do_writepor_state_send_acceptpor_state_join_exitpor_state_join_guardpor_constructorreplexploreComms::Craft::ackseen = 1; sent = 2:lookreadssentbeforetx'scountat t=3, which then runs beforeackendscmd/sysmlnested linked pair (explore, machine alone and siblings)received = 1×3,received = 2×1received = 1×4,received = 2×1received = 2witness draws the due order at t=3 twicerepllinked pairRunForexplore -advance(run_test,repl)-engine checkpeek+glowsawfalse or true); the witness names the turn's redrawChecklist
make testandmake lintpass locallychanges/unreleased/<slug>.<section>.md, not as an edit toCHANGELOG.mdmake docs-countsrun if a gate count moved (compliance rows need nothing: the census is counted at docs build)F4,K5) in the body, docs, or changelogLink to Devin session: https://nasa-jpl-demo.devinenterprise.com/sessions/5344039f62464badb7a0a648e6384b08
Open in Devin Desktop: https://nasa-jpl-demo.devinenterprise.com/desktop/session/5344039f62464badb7a0a648e6384b08?variant=devin
Requested by: @HuiJun