-
Notifications
You must be signed in to change notification settings - Fork 4.7k
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
API Proposal: Add ThreadPoolBoundHandle.AllocateUnsafeNativeOverlapped #42549
Comments
|
Ugh, nevermind, my mind is trained to see "Unsafe" at the beginning. You included it in the middle 😄 |
For the httpsys case, I'm curious, though: are you unable to use |
Maybe if we refactored some codez dotnet/aspnetcore#22022. I haven't looked deeply enough but I imagine it would be possible with the right amount of effort. |
@stephentoub Took a look, it's not doable as we need the closure for per call state. |
Ok. In general PreAllocatedOverlapped leads to much lower overheads than the other overload (and doesn't capture ExecutionContext each time you call AllocateNativeOverlapped, since it's not creating a new thing), so it might be what you want and more. |
Hmm. Ok. That's unfortunate. |
Yep, this one basically requires a per request allocation 😢 |
Humor me a second though, what if we wanted to make this support function pointers instead of delegates: namespace System.Threading
{
public sealed class ThreadPoolBoundHandle
{
+ public unsafe NativeOverlapped* AllocateUnsafeNativeOverlapped(delegate* managed<uint, uint, NativeOverlapped*, void> callback, object? state, object? pinData);
}
} This would bake the calling convention into the signature which might be limiting? Today we invoke the callback from managed code but I can imagine a future where we rewrite the IO thread pool to more directly call back into managed code from native code using the unmanaged calling convention and this signature would be unfortunate in that case. namespace System.Threading
{
public sealed class ThreadPoolBoundHandle
{
+ public unsafe NativeOverlapped* AllocateUnsafeNativeOverlapped(delegate* unmanaged<uint, uint, NativeOverlapped*, void> callback, object? state, object? pinData);
}
} We could do this or directly take an namespace System.Threading
{
public sealed class ThreadPoolBoundHandle
{
+ public unsafe NativeOverlapped* AllocateUnsafeNativeOverlapped(void* callback, object? state, object? pinData);
}
} Thoughts on how we might design something like this? |
I doubt it. Everything else being equal, we are able to managed the threadpool queues more efficiently on the managed side. What are you trying to optimize? The 3 extra instructions per work item invocation that you get with delegates compare to function pointers? |
I mean the IO thread pool that uses windows IO completion ports. Today a big chunk of that logic is written in native code (plus all of the native overlapped handling today that straddles native and managed). It seems there was some cost because we have this code https://source.dot.net/#System.Private.CoreLib/src/System/Threading/Overlapped.cs,53 that tries to stay in managed code for as long as possible while executing these callbacks (or maybe I'm reading that wrong). The question was purely hypothetical though, I don't know if it's worth it to ever have function pointers in any API but if we do at some point it seems like there could be interesting questions around calling convention and function signature. |
Re: |
namespace System.Threading
{
partial class ThreadPoolBoundHandle
{
[CLSCompliant(false)]
public unsafe NativeOverlapped* UnsafeAllocateNativeOverlapped(IOCompletionCallback callback, object? state, object? pinData);
}
}
namespace System.Threading
{
partial class PreAllocatedOverlapped : IDisposable
{
[CLSCompliant(false)]
public static PreAllocatedOverlapped UnsafeCreate(IOCompletionCallback callback, object? state, object? pinData);
}
} |
Background and Motivation
The Http.Sys server implementation in ASP.NET Core interacts with various native windows APIs using
ThreadPoolBoundHandle
. Most of these interactions don't require a capture of the execution context and in some cases it's detrimental (e.g. dotnet/aspnetcore#26128). There should be a way to avoid capturing the ExecutionContext when creating aNativeOverlapped*
from aThreadPoolBoundHandle
:Proposed API
The text was updated successfully, but these errors were encountered: