2

I would like to know how System.Threading.Thread works in the CLR. I guess threads in the CLR are "lightweight", meaning they are mapped many-to-one to kernel threads... but who schedules these threads? When I create a thread, does it always create a corresponding "kernel" thread unless number of threads is larger than the number of physical cores? Does it try to schedule these threads on the available cores? Any info/sources are greatly appreciated.

Dervin Thunk
  • 19,515
  • 28
  • 127
  • 217

3 Answers3

3

You could check SSCLI. It is CLR 2.0 publicly available sources in C++ aka ROTOR project. It is the only place that will reveal the truth :)

UPD: in comments there're clues where to find actual thing in the ROTOR if someone is interested ;)

Ivan Danilov
  • 14,287
  • 6
  • 48
  • 66
  • @Dervin: it's not that daunting as you could think. It is very well-written code. I had a chance to dive into it. You could read about my experience [here](http://sparethought.wordpress.com/2011/06/16/clr-internals-implementation-of-net-timers/). It's not that hard, really ;) – Ivan Danilov Aug 06 '11 at 02:06
  • @Dervin: there're many attributes like `MethodImplAttribute(MethodImplOptions.InternalCall)` on methods. It means that actual implementation you should search in native code (try just find in files by name - it would be simpler than to describe each step here). – Ivan Danilov Aug 06 '11 at 02:15
  • 1
    @Dervin: here, I found it. `Thread.cs` calls `StartInternal()`, that is mapped to `ThreadNative::Start` in `ecall.cpp` on line 888, which in turn is implemented in `comsynchronizable.cpp` on line 450. And see several lines before (on 450 there's private method that is actually called from `ThreadNative::Start`) – Ivan Danilov Aug 06 '11 at 02:21
  • @Dervin: Bottom of this iceberg is in comsyncronizable.cpp at line 512 :) – Ivan Danilov Aug 06 '11 at 02:32
  • 2
    @Dervin, I think this is not documented on purpose. Another implementation of CLR should be free implement threads in any way it pleases (assuming they work correctly). And you usually don't document implementation-specific details. – svick Aug 06 '11 at 02:33
  • @svick: absolutely agreed. But to see how the things are actually implemented in real-world system is exceptionally interesting :) – Ivan Danilov Aug 06 '11 at 02:35
2

MSDN:

An operating-system ThreadId has no fixed relationship to a managed thread, because an unmanaged host can control the relationship between managed and unmanaged threads. Specifically, a sophisticated host can use the Fiber API to schedule many managed threads against the same operating system thread, or to move a managed thread among different operating system threads.

svick
  • 236,525
  • 50
  • 385
  • 514
elevener
  • 1,097
  • 7
  • 20
  • Even in rotor it comes to if (!CLRTaskHosted()) { bRet = CreateNewOSThread(stackSize, start, args); } else { bRet = CreateNewHostTask(stackSize, start, args); } and it common that behaviour is I think intentionally undocumented so I don't think it's a good practice to rely on any thread beahviour. – elevener Aug 06 '11 at 02:03
  • @Dervin: Well, hosted CLR is separate thing. If I understand correctly it is for rare cases when CLR is hosted inside some other process. The most known example is CLR inside SQL Server instance that handles custom types there. – Ivan Danilov Aug 06 '11 at 02:26
  • @Dervin: And finally in `comsyncronizable.cpp` at line 512 you can see actual call to `::CreateThread()` from WinAPI. elevener just stopped one step from it when told about `CreateNewOSThread()`. – Ivan Danilov Aug 06 '11 at 02:30
  • @Ivan I posted the place that showed the difference in behaviour in different situations, it's clear even from name that CreateNewOSThread creates OS thread :) Btw, AFAIR CLR is hosted for example in situation then you use .NET component from COM application so it's not so rare. – elevener Aug 06 '11 at 02:37
0

there is no "ultimate answer/documentation" to that...

in such cases you usually need to resort to checking the source if available - alternatively use something like Reflector to get to the source... this can be overwhelming quantity-wise but will give you certainly the answers you seek...

Yahia
  • 69,653
  • 9
  • 115
  • 144
  • Why not though? Why isn't this thoroughly documented by Microsoft? I find this hard to believe that I have to go into the source to find out if they use a greedy or roundrobin algorithm to schedule the green threads... – Dervin Thunk Aug 06 '11 at 01:58
  • 1
    I think they don't want people relying on a specific implementation/detail... think for example of Mono which could implement this specific detail differently so "normal app code" should not rely on such details – Yahia Aug 06 '11 at 02:00
  • Have a look at the mono sources it's the best way. But you can't be sure that it wouldn't be changed later. – elevener Aug 06 '11 at 02:12