fix: preserve FP control state across SysV context switch, expand tests - #3
Merged
Conversation
The SysV switch saved only the six callee-saved general-purpose registers, while MXCSR control bits and the x87 control word are also callee-saved under the SysV ABI. Mirror the Windows path: save and restore both in the switch and seed defaults in initStack, so rounding mode and FP exception masks no longer leak between fibers. Replace the Windows-only mxcsr test with a cross-platform FP control-state test that now guards this on both platforms.
After one resume each, every fiber's counter must be exactly 1. Serial run-to-completion would drive the first fiber to 3 before the second started, so this positively confirms cooperative interleaving rather than only checking the final per-fiber totals.
The new asm-based tests only compiled on Windows. x86_64-linux and x86_64-windows accept different inline-asm idioms, and these tests had no comptime target guard (unlike the Windows-only xmm6 test), so they first compiled on the Linux CI target and failed: - The FP-control test's helpers used the register-address-dereference form (stmxcsr (%[o]) with an "r" operand), a Zig 0.16 x86_64-windows workaround that the Linux assembler rejects as an invalid memory operand. Split the helpers by target at comptime: Windows keeps the workaround, other targets use the standard "m"/"=m" memory constraint. - The GP-register test used movabsq, an invalid mnemonic on the Linux assembler. Remove that test: it was already flagged as relying on compiler register scheduling, and callee-saved register preservation is covered by the behavioral tests (nested, deep-stack, local-integrity, interleaved).
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Fix a latent SysV bug where the context switch leaked FP control state between fibers, and expand the test suite to cover the core preservation and scheduling guarantees on both platforms.
Changes
src/arch/x86_64_sysv.zig): The SysV switch saved only the six callee-saved general-purpose registers, but the MXCSR control bits and the x87 control word are also callee-saved under the SysV ABI. A fiber that changed the rounding mode or FP exception masks could leak that state into whatever ran next. The switch now saves/restores both in a 16-byte slot andinitStackseeds the defaults, mirroring the Windows path (MXCSR at slot+0, x87 CW at slot+8).src/fiber.zig): eight new inline tests — cross-platform FP control-state preservation (the regression test for the fix), callee-saved GP registers, nested fibers, deep-stack yields, many yields, local-variable integrity, interleaved independent fibers (with a per-round assertion that positively confirms interleaving), and allocation-failure cleanup. The xmm6 test stays Windows-only by design (xmm6–15 are callee-saved only under Win64).### Fixedfor the SysV fix,### Addedfor the coverage.No public API changes.
Notes
The SysV fix's runtime behavior is proven by the
ubuntu-latestCI job, not locally: only the Windows target runs on the dev machine, and the Windows switch already preserved FP state, so the cross-platform FP test passes locally both before and after the asm change. On Linux, that test exercises the SysV switch and would fail without this fix.Test Plan
zig buildcompiles cleanlyzig build testpasses (11 tests, Windows)zig build examplesruns both exampleszig fmt --check .passesubuntu-latest(the real proof of the SysV fix) andwindows-latest