-
Notifications
You must be signed in to change notification settings - Fork 1.5k
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
Cleanup _Execute_once()
#4087
Merged
Merged
Cleanup _Execute_once()
#4087
Conversation
This file contains 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
…g GH 1194's change to directly call InitOnceExecuteOnce().
After GH 3861, they're both declared by xcall_once.h, so we don't need to use the internal _Execute_once() (with a worse interface) anymore. Drop the "TRANSITION, ABI" comment which referred to _Execute_once(). Qualify std::call_once() like std::once_flag above. (_Execute_once() lives in namespace std and was being found through ADL!) Since call_once() handles stateful lambdas, we can directly capture `this` and use it. Finally, call_once() doesn't care about the return value, so we don't need to `return 1;`.
We're `using namespace std;` so we don't need qualification. Because call_once() supports stateful lambdas, we can simply capture `_Storage` by reference. We're in stl/src so we don't really need to worry about True Placement New being hijacked, but let's `static_cast<void*>` to preserve the original code and make it clear that we are indeed invoking True Placement New.
They were guarded by `_CRTBLD` after GH 3935, so this doesn't affect users. The definition of `_Execute_once()` exactly repeated the declaration, except for `extern "C++"` which is fine to drop because stl/src is always built classically.
Also drop pointless "_Execute_once function" comment.
What is XFG and why is it removed? |
According to my limited understanding, it was a variant of the control flow guard feature, but was abandoned because it proved to be unworkable in practice. |
AlexGuteniev
approved these changes
Oct 13, 2023
CaseyCarter
approved these changes
Oct 18, 2023
🔥🔥🔥 Yes, YES! 🔥🔥🔥 |
This comment was marked as outdated.
This comment was marked as outdated.
This comment was marked as resolved.
This comment was marked as resolved.
In `AsyncCausalityTracer`, `m_causalityAPIs` and `m_isSupported` are private data members, initialized to `nullptr` and `false`. Let's pretend that `GetActivationFactory()` fails. In that case, the data members remain `nullptr` and `false` forever. Accordingly, we can hardcode the return values of `get()` and `isCausalitySupported()`. Also, `release()` becomes a no-op.
Now that `asyncCausalityTracer.release()` is a no-op, `__crtCleanupCausalityStaticFactories()` does nothing. Note that it wasn't exported - it was used only for cross-TU interaction between ppltasks.cpp and dllmain.cpp in stl/src, so we can remove this function outright. Then, dllmain.cpp becomes a stub.
…e` now. Accordingly, we can drop all of these branches. Note that this drops `_M_scheduled = true;`.
In `<ppltasks.h>`, `_TaskEventLogger`'s constructor assigned `_M_scheduled = false;`, and we previously removed the only way for it to be set to `true`. Accordingly, we can drop this branch.
From bottom to top: `const GUID PPLTaskCausalityPlatformID` wasn't exported. It had internal linkage, so we can definitely drop it. Nothing mentions the `AsyncCausalityTracer` type or the `asyncCausalityTracer` global variable anymore. Finally, we don't need the using-directives here.
The app implementation of `_TaskEventLogger` is now identical to the desktop implementation (after we drop the `_IsContinuation` parameter name). Unify them.
…pt`. Also drop the commented-out parameter names to avoid wrapping; they aren't useful when the function does nothing.
CaseyCarter
approved these changes
Oct 24, 2023
I'm mirroring this to the MSVC-internal repo - please notify me if any further changes are pushed. |
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.
xonce.cpp
only) while preserving Remove XP (and Server 2003) support from STL #1194's change to directly callInitOnceExecuteOnce()
._Execute_once()
usage inppltasks.cpp
, and as an associated change, simplifydllmain.cpp
.call_once()
instead of_Execute_once()
inexcptptr.cpp
.thread::id
,stacktrace_entry
, andbasic_stacktrace
#3861, they're both declared byxcall_once.h
, so we don't need to use the internal_Execute_once()
(with a worse interface) anymore.using namespace std;
so we don't need qualification.call_once()
supports stateful lambdas, we can simply capture_Storage
by reference.stl/src
so we don't really need to worry about True Placement New being hijacked, but let'sstatic_cast<void*>
to preserve the original code and make it clear that we are indeed invoking True Placement New.xcall_once.h
._CRTBLD
after Various cleanups #3935, so this doesn't affect users._Execute_once()
exactly repeated the declaration, except forextern "C++"
which is fine to drop becausestl/src
is always built classically._Execute_once()
is unused._Execute_once
function" comment.The code removal in
ppltasks.cpp
looks like I'm just thoughtlessly annihilating a bunch of weird logic, but I actually performed it carefully step-by-step. This code was_CRT_APP
-only, for "async causality tracing". As far as I can tell (looking up TFS changesets 923210 on 2013-04-02 and 1175213 on 2014-02-07, as this code was introduced and moved around), this was implemented in the hopes of improving debugging, back when ppltasks was envisioned as a top-level feature and the new major model for concurrency, instead of the minor implementation detail of<future>
that it eventually ended up as. The async causality logging mechanism never existed for Desktop, and was conditionally available for App (it depended on OS version). That is, it's not necessary for any of<future>
's work, and this was so undocumented, I strongly doubt that anyone aside from the original developer in 2013-2014 ever used it (I certainly haven't).Attempting to use real
std::call_once()
here ran into problems, because App didn't have access to the necessary Windows API functions that power it instead of_Execute_once()
. In theory that could have been solvable with enough MSBuild effort, but I think that we can simply remove this code, and I'm willing to take the risk and bear any potential servicing burden if I'm wrong.This doesn't affect bincompat because it's internal to
stl/src
and There's Only One STL (stl/src
is always consistent with itself). I also verified that the exports ofbinaries\x86chk\bin\i386\app\msvcp140d_app.dll
are unchanged.The steps that I followed started by considering what would happen if the causality APIs weren't detected as present, and then performing logical transformations after that.
AsyncCausalityTracer
,m_causalityAPIs
andm_isSupported
are private data members, initialized tonullptr
andfalse
. Let's pretend thatGetActivationFactory()
fails. In that case, the data members remainnullptr
andfalse
forever. Accordingly, we can hardcode the return values ofget()
andisCausalitySupported()
. Also,release()
becomes a no-op.asyncCausalityTracer.release()
is a no-op,__crtCleanupCausalityStaticFactories()
does nothing. Note that it wasn't exported - it was used only for cross-TU interaction betweenppltasks.cpp
anddllmain.cpp
instl/src
, so we can remove this function outright. Then,dllmain.cpp
becomes a stub.asyncCausalityTracer.isCausalitySupported()
is alwaysfalse
now._M_scheduled = true;
._M_scheduled
is alwaysfalse
now.<ppltasks.h>
,_TaskEventLogger
's constructor assigned_M_scheduled = false;
, and we previously removed the only way for it to be set totrue
. Accordingly, we can drop this branch.const GUID PPLTaskCausalityPlatformID
wasn't exported. It had internal linkage, so we can definitely drop it.AsyncCausalityTracer
type or theasyncCausalityTracer
global variable anymore._TaskEventLogger
is now identical to the desktop implementation (after we drop the_IsContinuation
parameter name). Unify them.extern "C"
functions explicitlynoexcept
#4106 by markingextern "C"
DllMain()
asnoexcept
.