-
Notifications
You must be signed in to change notification settings - Fork 4.9k
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
[NativeAOT] Remove ThunkPool crst. #88778
Conversation
Tagging subscribers to this area: @agocke, @MichalStrehovsky, @jkotas Issue DetailsWe can use a regular lock in ThunkPool instead of pInvoking a Crst from the native runtime. The only thing that was stopping us was that ThunkPool is in the Base library and Test.CorLib did not have support for We can also assume that any CoreLib that supports threading will also have support for
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is nominally Runtime.Base code. Using a CoreLib-based lock seems like it violates layering.
Yup, we'd need a Monitor class in Runtime.Base for this to keep Runtime.Base buildable as a standalone library. We don't build it because Jan didn't want me to because Test.CoreLib kind of guards the layering. But it makes it non-obvious that this "poor man's lock" is going to be the implementation of locking in the shipping runtime if/once we restore the .NET Native layering. |
Now that I'm looking at it, we also added a no-op cast cache to Test.CoreLib that has also the same kind of problem: runtime/src/coreclr/nativeaot/Test.CoreLib/src/System/Runtime/CompilerServices/CastCache.cs Line 11 in a23c7a1
The code we write for inclusion in Test.CoreLib needs to be shippable. I think we should start building Runtime.Base to make it 100% clear this needs to be shippable code, it's not just test code. |
I do not think this could work for the complete Monitor implementation. Monitor must live in a Core Library, at least because it allocates things. |
As we discussed with Michal this needs more thought. I'll probably close this, if there is no simple enough solution. |
The .NET Native layering was not great. It was driven by:
If we were to do this again, we would want to look at the principled approach. For example, define the shared piece as GC and thread suspension only and everything else to be app-local. A litmus test for well-designed shared piece is whether it can be usable by both regular CoreCLR and native AOT running in the same process. With this in mind, I think it would ok to move the thunk allocator out of Runtime.Base. I do not think we would want to have the thunk allocator in the shared piece if we were to attempt to build it again. |
That could work too. From a quick look it doesn't have to live in Runtime.Base. It was probably just convenient to put it there because the native/assembly part of it has to live somewhere and we have Runtime.WorkstationGC/ServerGC. If we pull the managed part into CoreLib and the unmanaged part into a separate lib file, that would work. We had a System.Private.TypeLoader.Native lib file for "native stuff System.Private.TypeLoader needs to call into". We can have a similar System.Private.CoreLib.Native lib file with "native stuff CoreLib needs to call into" (it doesn't feel right to stash it into libSystem.Native, the main reason being that we don't build it on Windows). |
That makes sense. I just wonder where that puts Test.CoreLib? |
Test.CoreLib is minimum viable CoreLib for test purposes. It should be correct, but it does not need to be complete or high performance. For example, if it needed locks, I think it would be ok to implement them as simple spin locks. |
Iirc the thunk pools are only needed for delegate marshaling. Test.corelib already doesn't have that. |
yes, it would make it technically ok to have a lock that just throws NotImplementedException, but that feels like defeating the intent of having Test.CoreLib |
The idea is to have the thunkpool in the full System.Private.CoreLib only, and omit them in runtime base and Test.CoreLib. There is no throwing implementation of the lock in this plan. We do not need thunkpool in Test.CoreLib. It is not required for testing core runtime. |
I have moved the thunkpool to the full System.Private.CoreLib. It did make things simpler. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks
Thanks!! |
We don't need to move the C++/assembly pieces (RhAllocateThunksMapping, etc.) into a separate library that is "owned" by CoreLib instead of the runtime? |
We can start "native stuff CoreLib needs to call into" library. Ideally, it would be shared by all runtimes, or at least by regular CoreCLR and NAOT. ThunkPools are not the only CoreLib supporting part that lives in runtime just because it was convenient to put it there. |
Would that result in every compilation unit having a separate thunk pool? |
Every compilation unit has its own thunk pool after this PR. It is just like any other CoreLib code, every compilation unit gets its own copy. Every compilation would get its own copy of the thunk pool helpers with the proposed change. It is just a drop in the bucket. |
We can use a regular lock in ThunkPool instead of pInvoking a Crst from the native runtime. The only thing that was stopping us was that ThunkPool is in the Base library and Test.CorLib did not have support for
lock
statement.But, since Base and Test.CorLib themselves do not use ThunkPool, we can move the thunkpool to the full Corelib where we can use regular locks.