threads(M4): futex_wait/futex_wake, the blocking primitive
New private syscalls futex_wait(addr, expected, timeout_ns)=40 and futex_wake(addr, count)=41. A waiter is a .blocked task tagged with Task.futex_addr (no queue linkage); futex_wait reads the user word under the big lock and parks only if it still equals expected, so a concurrent wake can't slip between the check and the block. futex_wake scans the task table and readies up to count waiters in the same address space. A timed wait also sets wake_at so the existing wakeExpired times it out; futex_addr staying non-zero (only futex_wake clears it) distinguishes timeout from a real wake. Waiters park in-kernel, so an idle core still halts (no busy-wait). runtime.Thread.Futex mirrors std.Thread.Futex (wait/timedWait/wake). thread-test gains a futex mode: a waiter parks, the main thread wakes it (serial order waiting/waking/woke, asserted by the case regex), and timedWait reports a timeout. Gate thread-futex PASS (3x); 18 guardrail cases green incl. sleep/event/ipc blocking paths; build + host tests clean.
This commit is contained in:
@@ -315,6 +315,14 @@ CASES = [
|
||||
"timeout": 60,
|
||||
"expect": r"DANOS-TEST-RESULT: PASS",
|
||||
"fail": r"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",
|
||||
"smp": 4,
|
||||
"timeout": 60,
|
||||
"expect": r"thread-futex: waiting[\s\S]*thread-futex: waking[\s\S]*thread-futex: woke[\s\S]*DANOS-TEST-RESULT: PASS",
|
||||
"fail": r"DANOS-TEST-RESULT: FAIL"},
|
||||
# Process arguments: argv arrives on the SysV entry stack (argv[0] = the spawned
|
||||
# name, argv[1..] = the system_spawn argument blob) and echoes back intact.
|
||||
{"name": "args",
|
||||
|
||||
Reference in New Issue
Block a user