internal static void AllThreadRelease(int currentThreadIndex) { for (int i = 0; i < Thread.threadTable.Length; i++) { #if SINGULARITY_KERNEL if (Scheduler.IsIdleThread(i)) { continue; } #endif if (i == currentThreadIndex) { if (Transitions.HasGCRequest(i)) { Transitions.ClearGCRequest(i); } } else if (Transitions.UnderGCControl(i)) { Transitions.ReleaseGCControl(i); } // Signal all threads to ensure that the GC process didn't // accidentally "gobble" an event signal that was meant for // something else. if (Thread.threadTable[i] != null) { Thread.SignalGCEvent(i); } } }
private static void VerifyAllThreadsGCControlled(Thread thread) { int limit = Thread.threadTable.Length; for (int i = 0; i < limit; i++) { Thread t = Thread.threadTable[i]; if (t != null && t != thread) { #if !SINGULARITY VTable.Assert(Transitions.UnderGCControl(t.threadIndex)); #endif } } }
internal static void AllThreadRendezvous(int currentThreadIndex) { Transitions.MakeGCRequests(currentThreadIndex); for (int i = 0; i < Thread.threadTable.Length; i++) { if (Thread.threadTable[i] == null || i == currentThreadIndex) { continue; } CollectorStatistics.Event(GCEvent.StopThread, i); while (!Transitions.TakeGCControl(i) && !Transitions.UnderGCControl(i) && Transitions.HasGCRequest(i) && Thread.threadTable[i] != null) { // NOTE: there is no code in this loop that could // cause a signal on an event to be consumed. Thread.WaitForGCEvent(currentThreadIndex); } } }
internal static void EnsureAllocationAllowed() { // Verify that we're not in an interrupt or non-preemptible region where allocations are prohibited Microsoft.Singularity.Processor currentProcessor = Microsoft.Singularity.Processor.CurrentProcessor; if (currentProcessor != null) // The Processor object itself may still need to be allocated { if (currentProcessor.InInterruptContext) { Tracing.Log(Tracing.Fatal, "Attempt to allocate memory from interrupt context!"); VTable.DebugPrint("Attempt to allocate memory from interrupt context!\n"); VTable.DebugBreak(); } #if false // Currently too many allocations with preemption disabled to debug right now if (currentProcessor.PreemptionDisabled) { VTable.DebugPrint("Attempt to allocate memory with preemption disabled!\n"); VTable.DebugBreak(); } #endif } VTable.Deny(Thread.CurrentThread != null && Transitions.fInitializedRuntime && Transitions.UnderGCControl(Thread.GetCurrentThreadIndex())); }