Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Abandon Windows-internal size optimizations for mutex and condition_variable #5030

Merged
merged 1 commit into from
Oct 30, 2024

Conversation

StephanTLavavej
Copy link
Member

For ages, we've had an "optimization" in the machinery for mutex and condition_variable, reducing their bloated sizes for Windows-internal builds. This is a relic of when we switched between different implementations for XP, Vista, and Win7; the largest size consumption was for the ConcRT-powered XP implementation. Windows could always assume it was the latest Windows, so it never needed that switching.

Unfortunately, the world is not as simple as we believed it to be. We thought that Windows was built consistently with a macro identifying it as Windows-internal, and that such object files were never mixed with ordinary object files (built with public VS). First, the macro scheme either changed or we didn't fully understand it in the first place (_CRT_WINDOWS vs. UNDOCKED_WINDOWS_UCRT), and second there's a lot of mixing between Windows-internal code and public-VS code via vcpkg and possibly other scenarios. See #4294 and #4301 for previous history here.

As @barcharcraz and @CaseyCarter noted to me, the fact that we can't properly ship a #pragma detect_mismatch to verify representation consistency is a severe problem. We keep getting reports from Windows devs who are encountering mismatch scenarios, and while they've been messing with their build settings to get around this, it's a strong indication that we should abandon the attempt.

This PR makes Windows-internal code behave exactly the same as public-VS code has always behaved, getting the unfortunately-bloated sizes. (Due to a long series of cleanups, made possible by dropping XP/Vista support, we now initialize only two pointers of this bloated space, and then we actually use only one, so it isn't as bad as it was before.)

There is no escape hatch for Windows-internal code - we're going to try to rip off the bandage with no escape hatch. (An escape hatch would just lead to more mismatch problems.) If the increased sizes cause performance regressions, that's an indication that they should be directly using Windows synchronization primitives. If there's mismatch caused by picking up this change in a non-simultaneous manner (e.g. updated Windows-internal "LKG" compiler, but using old public VS with the Windows-internal macros), the fix is to pick up the latest toolsets (possibly requiring backports on our side) to consistently get this change.

Note that this does not affect normal VS users.

Instead of mentioning the whole history in a comment (which is essentially irrelevant for understanding the state of the code after this change), or even mentioning that the constants could be reduced to 2 * sizeof(void*) if we could break ABI, I've gone further and noted the change that we actually need to make in vNext - ripping out this entire layer of machinery and using only one pointer. This was essentially implied by the existing TRANSITION comment about unused vptrs, but now we're clearly stating it.

@StephanTLavavej StephanTLavavej added the bug Something isn't working label Oct 21, 2024
@StephanTLavavej StephanTLavavej requested a review from a team as a code owner October 21, 2024 20:02
@StephanTLavavej StephanTLavavej added the blocked Something is preventing work on this label Oct 21, 2024
@StephanTLavavej
Copy link
Member Author

Marking as blocked until @barcharcraz can validate this with a Windows build.

@AlexGuteniev
Copy link
Contributor

Isn't there mix-and-match scenario by already shipped DLLs with new DLLs mixing?
Or there is a strict control that no STL things are on API boundaries?

@StephanTLavavej
Copy link
Member Author

Windows DLLs have C/COM/WinRT/etc. binary-stable interfaces, never involving STL types. (And if they had been exporting their internal mutex, then no public VS user could have consumed it.) I'm worrying about various mismatch scenarios, but not that one.

@StephanTLavavej StephanTLavavej removed the blocked Something is preventing work on this label Oct 29, 2024
@StephanTLavavej
Copy link
Member Author

Charlie reported her build results - x86 passed, x64 failed for unrelated reasons. That's good enough for me.

@StephanTLavavej StephanTLavavej self-assigned this Oct 29, 2024
@StephanTLavavej
Copy link
Member Author

I'm mirroring this to the MSVC-internal repo - please notify me if any further changes are pushed.

@StephanTLavavej StephanTLavavej merged commit d0a831d into microsoft:main Oct 30, 2024
39 checks passed
@StephanTLavavej StephanTLavavej deleted the no-more-mutex branch October 30, 2024 14:28
@CaseyCarter
Copy link
Contributor

Thanks for closing this window for ODR violations! 🪟

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
Archived in project
Development

Successfully merging this pull request may close these issues.

4 participants