kernel+tests: M4 shared-fate — nine group-death test cases, per-space arena cursors

Eight new QEMU cases (thread-fault-group, kill-threaded-group,
kill-via-worker-tid, racing-triggers, exit-group, leader-thread-exit,
thread-exit-solo, shm-mapping-ref) driving seven new thread-test modes; a
shared checkGroupDead asserts the contract everywhere: one notification,
badged with the leader, reason on the leader's record, no member listed,
claims released first.

The shm-mapping-ref case flushed out the per-task DMA/shared-memory arena
cursor bug directly (a sibling's regions mapped over the worker's), so both
cursors moved to the AddressSpaceRef like the mmap/MMIO cursors before them
(threading M7 pattern). Runtime gains Thread.tryExitCurrent for the leader
-EPERM refusal path. Docs updated: threading.md's shared-fate gap is closed,
process-management.md and process-lifecycle.md describe the leader re-key,
plan status = implemented. Full suite: 100/100.
This commit is contained in:
Daniel Samson
2026-07-22 10:49:46 +01:00
parent 1882161cb4
commit 2bc2a0d70d
10 changed files with 565 additions and 43 deletions
+65
View File
@@ -327,6 +327,71 @@ CASES = [
"expect": r"DANOS-TEST-RESULT: PASS",
"fail": r"DANOS-TEST-RESULT: FAIL"},
# docs/shared-fate-plan.md M4: a worker's CPU fault kills the whole group —
# one notification (badged with the leader), the leader's reason is the fault
# class, and every counter returns to base.
{"name": "thread-fault-group",
"smp": 4,
"timeout": 60,
"expect": r"thread-test: worker faulting[\s\S]*DANOS-TEST-RESULT: PASS",
"fail": r"DANOS-TEST-RESULT: FAIL"},
# docs/shared-fate-plan.md M4: process_kill on a threaded group — the
# spinning worker dies by the deferred (condemned) path, both members'
# device claims are free before the single leader-badged notification.
{"name": "kill-threaded-group",
"smp": 4,
"timeout": 60,
"expect": r"DANOS-TEST-RESULT: PASS",
"fail": r"DANOS-TEST-RESULT: FAIL"},
# docs/shared-fate-plan.md M4: process_kill aimed at a WORKER tid kills the
# whole group (the capability is per-process), still badged with the leader.
{"name": "kill-via-worker-tid",
"smp": 4,
"timeout": 60,
"expect": r"DANOS-TEST-RESULT: PASS",
"fail": r"DANOS-TEST-RESULT: FAIL"},
# docs/shared-fate-plan.md M4: two members fault near-simultaneously on
# different cores; the dying latch makes them one group death
# (fault_kill_count == 1) with a deterministic leader reason.
{"name": "racing-triggers",
"smp": 4,
"timeout": 60,
"expect": r"DANOS-TEST-RESULT: PASS",
"fail": r"DANOS-TEST-RESULT: FAIL"},
# docs/shared-fate-plan.md M4: exit(3) from a WORKER is group death with the
# leader's reason reading .aborted (the exit_group lesson).
{"name": "exit-group",
"smp": 4,
"timeout": 60,
"expect": r"thread-test: worker exiting the process[\s\S]*DANOS-TEST-RESULT: PASS",
"fail": r"DANOS-TEST-RESULT: FAIL"},
# docs/shared-fate-plan.md M4: the LEADER's thread_exit is refused (-EPERM);
# the worker is unaffected and the process then exits clean.
{"name": "leader-thread-exit",
"timeout": 60,
"expect": r"thread-test: leader thread_exit refused ok[\s\S]*DANOS-TEST-RESULT: PASS",
"fail": r"DANOS-TEST-RESULT: FAIL"},
# docs/shared-fate-plan.md M4: regression — a WORKER's thread_exit stays
# per-thread; the sibling survives it.
{"name": "thread-exit-solo",
"timeout": 60,
"expect": r"thread-test: solo sibling survived ok[\s\S]*DANOS-TEST-RESULT: PASS",
"fail": r"DANOS-TEST-RESULT: FAIL"},
# docs/shared-fate-plan.md M3/M4: a shared-memory region whose only HANDLE
# died with its creator thread survives on the MAPPING reference — the
# sibling's view stays intact through allocator churn.
{"name": "shm-mapping-ref",
"timeout": 60,
"expect": r"thread-shm: mapping survives creator ok[\s\S]*DANOS-TEST-RESULT: PASS",
"fail": r"thread-shm: FAIL|DANOS-TEST-RESULT: FAIL"},
# docs/threading-plan.md M4: futex — a thread parks in futex_wait and is woken by
# futex_wake (serial order waiting/waking/woke), and timedWait reports a timeout.
{"name": "thread-futex",