A caveat regarding comments in Rotor: sometimes there are comments left from the commercial CLR that do not fully apply. For example, the coordination mechanism in Rotor is considerably simpler than the commercial CLR, since it is not pre-emptive, yet this is not fully reflected in comments. (The commercial product *does* support pre-emption...)
Rotor always uses cooperative GC. Sometimes when unmanaged code is running, the thread is said to be in pre-emptive mode, but this has nothing to do with GC. (You are correct that this comes into play when unmanaged code is executed. It might hold locks or other resources, and should not be stopped, and so pre-emptive mode is used by Rotor in these situations.) Besides the confusing names for the modes, additional confusion may be resulting from the fact that JIT_PollGC uses the toggle between pre-emptive mode and cooperative mode to communicate with the garbage collector (to "pulse"). Once a GC has begun on one thread, the calls to JIT_PollGC on the other managed threads are equivalent to an assertion that it is safe to GC. The thread that will perform the GC waits until all threads currently in managed code have "checked in" using a two-step mechanism described below to proceed. (See SysSuspendForGC in threads.cpp for this logic. And, on quick inspection, not every comment in this code is applicable to Rotor...) Within the sync function, when Rotor calls the PAL's ::SuspendThread function to "capture" a thread for GC, it checks to see whether the thread is in cooperative mode or not. If it *is* in cooperative mode, the thread is suspended, the GCPending bit is set, and the thread is resumed so that the next JIT_PollGC() will cause the thread to cede control to the GC. If the thread is running native code in preemptive mode, the EE immediately resumes the thread, knowing that on its next transition from unmanaged to managed, it will poll and allow the GC to run. After this, the thread waits for all managed threads to raise events, after which GC can happen. Once GC has finished, the GCPending bit is cleared and away you go. (The m_SafeEvent field of Thread is the actual event that is used to signal.) FYI - the GC_PROTECT macros are for registering "roots" w/ the GC, as you surmise. No relationship with what we are talking about here. Hope that this is helpful. -- David Stutz Archana asked: well it all started after i saw a block of comments in vm/threads.cpp which mentions about sync and async suspension as i understand it, the compiler emits calls to JIT_PollGC at safe points (this calls CommonTripThread which is supposed to belong to the category of synchronous suspension functions). so i wanted a clear picture of the interaction happening between SysSuspendForGC and CommonTripThread. And also i would be extremely grateful if you could explain about- the Preemptive mode of the GC does this mode come into picture only when unmanaged code is executed ? most of the references in the code indicate that preemptive mode is enabled when there are calls to the OS / any exceptions occuring etc.. i am not able to understand this part of the functionality Is there any relation between this and the macros GCPROTECT_BEGIN and GCPROTECT_END ? (they seem to push objects onto a newly created frame which would be updated by the GC if it occurs etc..)