Repository navigation
fix(libkernel): allocate the Windows thread-local slot on first use - #6956
oneandonlydean merged 1 commit into
Conversation
WindowsThreadLocal<T>::slot was a template static, so its dynamic initialization was unordered against the timer self-test in Time.cpp. With APS5_TRACE_TIMERS set, the self-test ran first, used slot 0 and aborted every title with "Cannot bind native thread state". The slot is now a function-local static. guest_nanosleep_timer_self_test runs guest_nanosleep_tests with APS5_TRACE_TIMERS=1 on Windows. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01KwsvKtVsZDLefysUM9m2QS
|
Some comparisons could not be completed because a pull request conflicts with the base branch. Review these shared files manually before concluding that there is no overlap.
|
|
Checked these by hand: none change the same lines. #6658 adds a test right after the same |
karimibrahim07
left a comment
There was a problem hiding this comment.
Windows check of head 75d29f5b3 merged onto main e3a8e4430 (clean merge). Windows 11 Pro (26300), Ryzen 5 3600, WinLibs GCC 15.2.0 r7, Ninja Release.
guest_nanosleepand the newguest_nanosleep_timer_self_testpass,--repeat until-fail:3(about 7 s each).- Negative control: with
main'sWindowsThreadLocal.hppand the new test kept,guest_nanosleep_timer_self_testfails withwhat(): Cannot bind native thread state(0xc0000409), the same error as in the description.
Code: a function-local static is the right fix. Dynamic initialization of a class template's inline static member is unordered, so any static initializer in libkernel that reaches Get() can see a zero slot. libc's HostThreadLocal.hpp already uses the same pattern (static const DWORD slot = FlsAlloc(...) inside the function), so the two thread-local helpers now match. The other WindowsThreadLocal users (TimedWait.cpp, twice, Tsd.cpp, Thread.cpp) only call Get(), so they all benefit and none depends on the old member. Destroy calling slotIndex() is safe: the slot is necessarily initialized by the time FLS calls it. I have no requests.
AI-assisted: yes. I ran the build, the tests and the negative control above.
|
Cross-validation on Windows 11 Pro 26220, NVIDIA RTX 4070 (596.21), MinGW GCC 15.2, PR head
Not checked: Linux/macOS (the change is Windows-only), a revert-and-rebuild of the fix, the other open PRs that touch Written with Claude Code assistance (validation by a subagent, reviewed in this session). |
What
Setting
APS5_TRACE_TIMERS=1crashed every title at startup on Windows withCannot bind native thread state.The timer self-test in
Time.cppruns during libkernel's static init.WindowsThreadLocal<T>::slotis a template static, so its init order isn't guaranteed, and here it hadn't run yet. The slot was still 0, soFlsSetValuefailed.The slot is now a function-local static, so it gets allocated on first use regardless of init order. Also added
guest_nanosleep_timer_self_test, which rerunsguest_nanosleep_testswithAPS5_TRACE_TIMERS=1(Windows only). #6658 adds a test right after the sameguest_nanosleepblock; no functional overlap.Tested
Windows 11, WinLibs GCC 15.2.0, Release.
alignasbuild error fixed in test(agc): align the indirect arguments block at run time #6452/fix(tests): allocate 64 KiB dispatch block dynamically #6829, and a symlink-permission failure inselect_testson my machine.Checklist
main; no other open PR implements the same functionsNotImplemented_nid_no_patch); silent stubs are listed under Silent stubs in their library's technical debt file.mdfiles or images added to the repository (attach them to this PR)🤖 Generated with Claude Code
https://claude.ai/code/session_01KwsvKtVsZDLefysUM9m2QS