Ejemplo n.º 1
0
        public void RegisterCreateMachine(MachineId source, MachineId target)
        {
            LogCreate(source, target);
            CreateCount++;

            // The id of the created machine should not conflict with an id seen earlier
            Runtime.Assert(MS.ContainsKey(target.Value) == false, $"New ID {target} conflicts with an already existing id");

            DescriptiveName[target.Value] = target.ToString();

            // In case the runtime creates a machine, simply create a machine state for it,
            // with a fresh VC where the appropriate component is incremented.
            // no hb rule needs to be triggered
            if (source == null)
            {
                var newState = new InstrMachineState(target.Value, this.Log, Config.EnableRaceDetectorLogging);
                MS[target.Value] = newState;
                return;
            }

            DescriptiveName[source.Value] = source.ToString();

            var sourceMachineState = GetCurrentState(source);
            var targetState        = new InstrMachineState(target.Value, this.Log, Config.EnableRaceDetectorLogging);

            targetState.JoinEpochAndVC(sourceMachineState.VC);
            MS[target.Value] = targetState;
            sourceMachineState.IncrementEpochAndVC();
        }
Ejemplo n.º 2
0
        private InstrMachineState GetCurrentState(MachineId machineId)
        {
            if (MS.ContainsKey(machineId.Value))
            {
                return(MS[machineId.Value]);
            }

            // WriteToLog("Saw first operation for " + machineId);
            var newState = new InstrMachineState(machineId.Value, this.Log, Config.EnableRaceDetectorLogging);

            MS[machineId.Value] = newState;
            return(newState);
        }
Ejemplo n.º 3
0
        public void RegisterWrite(ulong source, string sourceLocation,
                                  UIntPtr location, UIntPtr objHandle, UIntPtr offset, bool isVolatile)
        {
            LogWrite(sourceLocation, source, objHandle, offset);
            WriteCount++;

            var key = new Tuple <UIntPtr, UIntPtr>(objHandle, offset);

            // For Raise actions and init actions, we might not have seen a dequeue
            // of the action yet, so source \in MS is not guaranteed
            if (!MS.ContainsKey(source))
            {
                // WriteToLog("Saw a write in an action without a corresponding deq");
                var newState = new InstrMachineState(source, this.Log, Config.EnableRaceDetectorLogging);
                MS[source] = newState;
            }

            // Implementation of the FastTrack rules for write operations
            var machineState = MS[source];
            var currentEpoch = machineState.Epoch;
            var currentMId   = Epoch.MId(machineState.Epoch);
            var currentVC    = machineState.VC;

            Runtime.Assert(currentMId == (long)source, "Inconsistent Epoch");

            if (VS.ContainsKey(key))
            {
                var varState   = VS[key];
                var writeEpoch = varState.WriteEpoch;
                var readEpoch  = varState.ReadEpoch;
                var writeMId   = Epoch.MId(writeEpoch);

                if (writeEpoch == currentEpoch)
                {
                    // Same-epoch write
                    return;
                }

                if (writeMId != currentMId && !Epoch.Leq(writeEpoch, currentVC.GetComponent(writeMId)) &&
                    !InSameMonitor(varState.InMonitorWrite, this.InMonitor))
                {
                    ReportRace(RaceDiagnostic.WriteWrite, varState.lastWriteLocation, writeMId, sourceLocation, currentMId, objHandle, offset);
                }

                varState.InMonitorWrite = this.InMonitor;
                if (Config.EnableReadWriteTracing)
                {
                    varState.lastWriteLocation = sourceLocation;
                }

                if (readEpoch != Epoch.ReadShared)
                {
                    var readMId = Epoch.MId(readEpoch);
                    if (readMId != currentMId && !Epoch.Leq(readEpoch, currentVC.GetComponent(readMId)) &&
                        !InSameMonitor(varState.InMonitorRead[readMId], this.InMonitor))
                    {
                        // Read-Write Race
                        string firstLocation = Config.EnableReadWriteTracing ? varState.LastReadLocation[readMId] : "";
                        ReportRace(RaceDiagnostic.ReadWrite, firstLocation, readMId, sourceLocation, currentMId, objHandle, offset);
                    }
                }
                else
                {
                    if (varState.VC.AnyGt(currentVC))
                    {
                        // SharedRead-Write Race
                        ReportReadSharedWriteRace(sourceLocation, currentMId, currentVC, varState, objHandle, offset);
                    }
                    else
                    {
                        // Note: the FastTrack implementation seems not to do this
                        varState.ReadEpoch = Epoch.Zero;
                    }
                }

                varState.WriteEpoch = currentEpoch;
            }
            else
            {
                VS[key] = new VarState(true, currentEpoch, Config.EnableReadWriteTracing, this.InMonitor);
                if (Config.EnableReadWriteTracing)
                {
                    VS[key].lastWriteLocation = sourceLocation;
                }
            }
        }
Ejemplo n.º 4
0
        public void RegisterRead(ulong source, string sourceLocation, UIntPtr location, UIntPtr objHandle, UIntPtr offset, bool isVolatile)
        {
            LogRead(sourceLocation, source, objHandle, offset);
            ReadCount++;

            var key = new Tuple <UIntPtr, UIntPtr>(objHandle, offset);

            // For Raise actions and init actions, we might not have seen a dequeue
            // of the action yet, so source \in MS is not guaranteed
            if (!MS.ContainsKey(source))
            {
                // WriteToLog("Saw a read in an action without a corresponding deq");
                MS[source] = new InstrMachineState(source, this.Log, Config.EnableRaceDetectorLogging);
            }

            // Implementation of the FastTrack rules for read operations
            var machineState = MS[source];
            var currentEpoch = machineState.Epoch;

            if (VS.ContainsKey(key))
            {
                var varState = VS[key];
                varState.InMonitorRead[(long)source] = this.InMonitor;
                if (Config.EnableReadWriteTracing)
                {
                    varState.LastReadLocation[(long)source] = sourceLocation;
                }

                if (varState.ReadEpoch == currentEpoch)
                {
                    // Same-epoch read
                    return;
                }

                VectorClock mVC        = machineState.VC;
                long        readEpoch  = varState.ReadEpoch;
                long        writeEpoch = varState.WriteEpoch;
                long        writeMId   = Epoch.MId(writeEpoch);
                long        currentMId = (long)source;

                // The lastest write was from a diff machine, and no HB
                if (writeMId != currentMId && !Epoch.Leq(writeEpoch, mVC.GetComponent(writeMId)) &&
                    !InSameMonitor(varState.InMonitorWrite, this.InMonitor))
                {
                    // Write/Read race
                    ReportRace(RaceDiagnostic.WriteRead, varState.lastWriteLocation, writeMId, sourceLocation, currentMId, objHandle, offset);
                    return;
                }

                if (readEpoch == Epoch.ReadShared)
                {
                    Runtime.Assert((long)currentMId == Epoch.MId(currentEpoch), "Inconsistent Epoch");
                    varState.VC.SetComponent(currentMId, currentEpoch);
                }
                else
                {
                    long rMId = Epoch.MId(readEpoch);
                    if (currentMId == rMId || Epoch.Leq(readEpoch, mVC.GetComponent(rMId)))
                    {
                        varState.ReadEpoch = currentEpoch;
                    }
                    else
                    {
                        if (varState.VC == null)
                        {
                            varState.VC = new VectorClock(Math.Max(rMId, currentMId));
                        }
                        varState.VC.SetComponent(rMId, readEpoch);
                        varState.VC.SetComponent(currentMId, currentEpoch);
                        varState.ReadEpoch = Epoch.ReadShared;
                    }
                }
            }
            else // The first read from this variable
            {
                var currentState = new VarState(false, currentEpoch, Config.EnableReadWriteTracing, this.InMonitor);
                currentState.InMonitorRead[(long)source] = this.InMonitor;
                if (Config.EnableReadWriteTracing)
                {
                    currentState.LastReadLocation[(long)source] = sourceLocation;
                }
                VS[key] = currentState;
            }
        }