Exemple #1
0
        internal static bool ExchangeReadyForCoCo(bool value)
        {
            CoCoThread t      = MixinThread(Thread.CurrentThread);
            bool       result = t.readyForCoCo;

            t.readyForCoCo = value;
            return(result);
        }
Exemple #2
0
 internal static void ThreadStart(Thread t_)
 {
     if (inited)
     {
         lock (interlock) {
             CoCoThread t = MixinThread(t_);
             t.readyForCoCo           = true;
             t.acknowledgedPhase      = (int)phase;
             t.acknowledgedForwarding = forwarding;
             t.acknowledgedPinning    = pinning;
         }
     }
 }
Exemple #3
0
 internal static void ClientHandshake()
 {
     if (inited)
     {
         if (fVerbose)
         {
             VTable.DebugPrint("         !! ClientHandshake: interlock at ");
             VTable.DebugPrint((ulong)Magic.addressOf(interlock));
             VTable.DebugPrint("\n");
         }
         if (fVerbose)
         {
             if (Magic.addressOf(interlock) != interlockAddr)
             {
                 VTable.DebugPrint("          !! ClientHandshake seeing interlock at new address: ");
                 VTable.DebugPrint((ulong)Magic.addressOf(interlock));
                 VTable.DebugPrint("\n");
             }
             if (ToSpaceAsPtr(interlock) != forwardedInterlockAddr)
             {
                 VTable.DebugPrint("          !! ClientHandshake seeing interlock at new FORWARDED address: ");
                 VTable.DebugPrint((ulong)ToSpaceAsPtr(interlock));
                 VTable.DebugPrint("\n");
             }
         }
         lock (interlock) {
             if (fVerbose)
             {
                 interlockAddr          = Magic.addressOf(interlock);
                 forwardedInterlockAddr = ToSpaceAsPtr(interlock);
             }
             CoCoThread t = MixinThread(Thread.CurrentThread);
             if (phase != (Phase)t.acknowledgedPhase ||
                 forwarding != t.acknowledgedForwarding ||
                 pinning != t.acknowledgedPinning)
             {
                 if (fDebug)
                 {
                     VTable.DebugPrint("          !! thread ");
                     VTable.DebugPrint((ulong)Magic.addressOf(t));
                     VTable.DebugPrint(" doing ack\n");
                 }
                 t.acknowledgedPhase      = (int)phase;
                 t.acknowledgedForwarding = forwarding;
                 t.acknowledgedPinning    = pinning;
                 t.phaseVersion++;
                 Monitor.PulseAll(interlock);
             }
         }
     }
 }
Exemple #4
0
        internal static UIntPtr PinDirect(UIntPtr baseAddr,
                                          UIntPtr address,
                                          Pinner pinner)
        {
            Object o = Magic.fromAddress(baseAddr);

            UIntPtr CoCoWord;

            bool waited = false;

            for (;;)
            {
                CoCoWord = MixinObject(o).preHeader.CoCoWord;
                if (IsSimple(CoCoWord) || IsForwarded(CoCoWord))
                {
                    break;
                }
                else if (IsCopying(CoCoWord))
                {
                    VTable.Assert(pinner == Pinner.Barrier);
                    if (fCount)
                    {
                        if (!waited)
                        {
                            waited = true;
                            numWaitPins++;
                        }
                        numPinWaits++;
                    }
                    // wait until it's copied
                    lock (interlock) {
                        CoCoThread t = MixinThread(Thread.CurrentThread);
                        t.pinnedOut = true;
                        Monitor.PulseAll(interlock);
                        while (t.pinnedOut)
                        {
                            Monitor.Wait(interlock);
                        }
                    }
                    // ok, now try again (by the time we get here the
                    // object could already be in the process of being
                    // copied agagin!)
                }
                else if (IsTagged(CoCoWord))
                {
                    CASCoCoWord(o, Simple(), CoCoWord);
                    NotifyPin(baseAddr);
                }
            }

            // what does it mean to get here?  the object cannot
            // be moved until the next pinning safepoint prior to
            // a transition out of Idle.

            VTable.Assert(IsSimple(CoCoWord) || IsForwarded(CoCoWord));

            // correct address
            if (IsForwarded(CoCoWord))
            {
                address -= baseAddr;
                address += ForwardPtr(CoCoWord);
            }

            return(address);
        }
Exemple #5
0
        internal static void ChangePhase(Phase phase_,
                                         bool forwarding_,
                                         bool pinning_)
        {
            if (fDebug)
            {
                VTable.DebugPrint("    --> CoCo going to ");
                switch (phase_)
                {
                case Phase.Idle: VTable.DebugPrint("Idle"); break;

                case Phase.Prep: VTable.DebugPrint("Prep"); break;

                case Phase.Copy: VTable.DebugPrint("Copy"); break;

                case Phase.Fixup: VTable.DebugPrint("Fixup"); break;

                default: VTable.NotReached(); break;
                }
                VTable.DebugPrint(" (with");
                if (!forwarding_)
                {
                    VTable.DebugPrint("out");
                }
                VTable.DebugPrint(" forwarding, with");
                if (!pinning_)
                {
                    VTable.DebugPrint("out");
                }
                VTable.DebugPrint(" pinning)\n");
            }
            lock (interlock) {
                phase      = phase_;
                forwarding = forwarding_ || forceForwarding;
                pinning    = pinning_ || forcePinning;
                SetAllowFastPath();
                isNotIdle = phase != Phase.Idle || forceNotIdle;
                CoCoThread t = MixinThread(Thread.CurrentThread);
                t.acknowledgedPhase      = (int)phase;
                t.acknowledgedForwarding = forwarding;
                t.acknowledgedPinning    = pinning;
                t.phaseVersion++;
                Monitor.PulseAll(interlock);
                for (;;)
                {
                    bool needToWait = false;
                    bool doPulseAll = false;
                    for (int i = 0; i < Thread.threadTable.Length; ++i)
                    {
                        Thread t_ = Thread.threadTable[i];
                        if (t_ == null)
                        {
                            continue;
                        }
                        t = MixinThread(t_);
                        if (Transitions.InDormantState(i) ||
                            !t.readyForCoCo ||
                            t.pinnedOut)
                        {
                            t.acknowledgedPhase      = (int)phase;
                            t.acknowledgedForwarding = forwarding;
                            t.acknowledgedPinning    = pinning;
                        }
                        if (t.pinnedOut && phase == Phase.Idle)
                        {
                            t.pinnedOut = false;
                            doPulseAll  = true;
                        }
                        if ((Phase)t.acknowledgedPhase != phase ||
                            t.acknowledgedForwarding != forwarding ||
                            t.acknowledgedPinning != pinning)
                        {
                            if (fDebug)
                            {
                                VTable.DebugPrint("         !! thread ");
                                VTable.DebugPrint((ulong)Magic.addressOf(t));
                                VTable.DebugPrint(" not ack\n");
                            }
                            needToWait = true;
                        }
                    }
                    if (doPulseAll)
                    {
                        Monitor.PulseAll(interlock);
                    }
                    if (!needToWait)
                    {
                        break;
                    }
                    // REVIEW: make the timeout less than 500 ms
                    Monitor.Wait(interlock, 500);
                }
            }
        }