Ejemplo n.º 1
0
 internal override void PostRootScanHook()
 {
     if (inFixUp)
     {
         timingAfterCopy = Environment.TickCount;
         CoCoBarrier.ChangePhase(CoCoBarrier.Phase.Idle, true, true);
     }
 }
Ejemplo n.º 2
0
        internal static void CoCoLoop()
        {
            if (fDebug)
            {
                VTable.DebugPrint("coco thread = ");
                VTable.DebugPrint((ulong)Win32Native.GetCurrentThreadId());
                VTable.DebugPrint("\n");
                VTable.DebugPrint("CoCo at ");
                VTable.DebugPrint((ulong)Magic.addressOf(Thread.CurrentThread));
                VTable.DebugPrint("\n");
            }
            for (;;)
            {
                lock (interlock) {
                    doingCoCo = false;
                    for (;;)
                    {
                        if (die)
                        {
                            return;
                        }
                        else if (didStartTrace)
                        {
                            didStartTrace = false;
                            Monitor.PulseAll(interlock);
                        }
                        else if (didEndTrace)
                        {
                            didEndTrace = false;
                            Monitor.PulseAll(interlock);
                            if (wantCoCo)
                            {
                                break;
                            }
                        }
                        Monitor.Wait(interlock);
                    }
                    wantCoCo = false;
                }

                // now further tracing is BLOCKED

                cyclesStarted++;
                timingBefore = Environment.TickCount;

                if (fDebug)
                {
                    VTable.DebugPrint("+++++ Start Concurrent Copying\n");
                }

                CoCoBarrier.EnablePinning();
                doingCoCo = true;
                ConcurrentMSCollector.stackMarkReferenceVisitor =
                    CoCoMSCollector.nopStackMarker;
                ConcurrentMSCollector.stackMarkPinnedReferenceVisitor =
                    CoCoMSCollector.pinStackMarker;
                // Perform a scan of all call stacks, including the call
                // stack of the CoCo thread.
                ConcurrentMSCollector.TrivialHandshake      = false;
                ConcurrentMSCollector.IncludeMUWInHandshake = false;
                ConcurrentMSCollector.CollectorHandshake(cocoThread);
                // In order to scan the call stack of the current thread,
                // we need a TransitionRecord for the thread.  At this
                // point we don't have one, so we have to go through
                // CollectBodyTransition to get one.
                Transitions.MakeGCRequest(cocoThread.threadIndex);
                GC.InvokeCollection(cocoThread);
                ConcurrentMSCollector.TrivialHandshake          = true;
                ConcurrentMSCollector.IncludeMUWInHandshake     = true;
                ConcurrentMSCollector.stackMarkReferenceVisitor =
                    CoCoMSCollector.normalStackMarker;
                ConcurrentMSCollector.stackMarkPinnedReferenceVisitor =
                    CoCoMSCollector.normalStackMarker;

                timingAfterPin = Environment.TickCount;

                if (fDebug)
                {
                    VTable.DebugPrint("+++++ Copying\n");
                }

                if (CoCoBarrier.instance.NeedsPrepPhase)
                {
                    CoCoBarrier.ChangePhase(CoCoBarrier.Phase.Prep, false, true);
                }

                timingAfterPrep = Environment.TickCount;

                CoCoBarrier.ChangePhase(CoCoBarrier.Phase.Copy, true, true);

                numCopied += CoCoBarrier.instance.Copy();

                CoCoBarrier.ChangePhase(CoCoBarrier.Phase.Fixup, true, true);

                AddCollectionRequest();

                // wait for a complete collector cycle.  This is for fixup.
                if (fDebug)
                {
                    VTable.DebugPrint("+++++ Fixup: Waiting to start tracing\n");
                }
                lock (interlock) {
                    while (!didStartTrace && !die)
                    {
                        Monitor.Wait(interlock);
                    }
                    if (die)
                    {
                        return;
                    }
                    didStartTrace = false;
                    inFixUp       = true;
                    Monitor.PulseAll(interlock);
                }

                if (fDebug)
                {
                    VTable.DebugPrint("+++++ Fixup: Waiting to end tracing\n");
                }
                lock (interlock) {
                    while (!didEndTrace && !die)
                    {
                        Monitor.Wait(interlock);
                    }
                    if (die)
                    {
                        return;
                    }
                    didEndTrace = false;
                    doingCoCo   = false;
                    inFixUp     = false;
                    Monitor.PulseAll(interlock);
                }

                timingAfter = Environment.TickCount;

                CoCoBarrier.ChangePhase(CoCoBarrier.Phase.Idle, false, false);

                if (fDebug)
                {
                    VTable.DebugPrint("+++++ Finish Concurrent Copying\n");
                }

                pinTime     += (timingAfterPin - timingBefore);
                prepTime    += (timingAfterPrep - timingAfterPin);
                copyTime    += (timingAfterCopy - timingAfterPrep);
                forwardTime += (timingAfter - timingAfterCopy);

                cycles++;
            }
        }