Uh oh!
There was an error while loading. Please reload this page.
[NativeAOT] Remove ThunkPool crst. - #88778
Conversation
ghost
commented
Jul 12, 2023
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
|
SingleAccretion
left a comment
There was a problem hiding this comment.
This is nominally Runtime.Base code. Using a CoreLib-based lock seems like it violates layering.
MichalStrehovsky
commented
Jul 12, 2023
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. |
MichalStrehovsky
commented
Jul 12, 2023
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: 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. |
VSadov
commented
Jul 12, 2023
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. |
VSadov
commented
Jul 13, 2023
As we discussed with Michal this needs more thought. I'll probably close this, if there is no simple enough solution. |
jkotas
commented
Jul 13, 2023
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. |
MichalStrehovsky
commented
Jul 13, 2023
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). |
VSadov
commented
Jul 14, 2023
That makes sense. I just wonder where that puts Test.CoreLib? |
jkotas
commented
Jul 16, 2023
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. |
MichalStrehovsky
commented
Jul 16, 2023
Iirc the thunk pools are only needed for delegate marshaling. Test.corelib already doesn't have that. |
VSadov
commented
Jul 18, 2023
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 |
jkotas
commented
Jul 18, 2023
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. |
VSadov
commented
Aug 26, 2023
I have moved the thunkpool to the full System.Private.CoreLib. It did make things simpler. |
VSadov
commented
Aug 27, 2023
Thanks!! |
MichalStrehovsky
commented
Aug 29, 2023
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? |
jkotas
commented
Aug 29, 2023
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. |
VSadov
commented
Aug 29, 2023
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
lockstatement.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.