Example #1
0
        public void RegisterCreateMachine(MachineId source, MachineId target)
        {
            this.LogCreate(source, target);
            this.CreateCount++;

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

            this.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 is null)
            {
                var newState = new InstrMachineState(target.Value, this.Log, this.Config.EnableRaceDetectorLogging);
                this.MachineState[target.Value] = newState;
                return;
            }

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

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

            targetState.JoinEpochAndVC(sourceMachineState.VC);
            this.MachineState[target.Value] = targetState;
            sourceMachineState.IncrementEpochAndVC();
        }
Example #2
0
        private InstrMachineState GetCurrentState(MachineId machineId)
        {
            if (this.MachineState.ContainsKey(machineId.Value))
            {
                return(this.MachineState[machineId.Value]);
            }

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

            this.MachineState[machineId.Value] = newState;
            return(newState);
        }
Example #3
0
        public void RegisterWrite(ulong source, string sourceLocation,
                                  UIntPtr location, UIntPtr objHandle, UIntPtr offset, bool isVolatile)
        {
            this.LogWrite(sourceLocation, source, objHandle, offset);
            this.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 MachineState is not guaranteed.
            if (!this.MachineState.ContainsKey(source))
            {
                // WriteToLog("Saw a write in an action without a corresponding deq");
                var newState = new InstrMachineState(source, this.Log, this.Config.EnableRaceDetectorLogging);
                this.MachineState[source] = newState;
            }

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

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

            if (this.VarState.ContainsKey(key))
            {
                var varState   = this.VarState[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))
                {
                    this.ReportRace(RaceDiagnostic.WriteWrite, varState.LastWriteLocation, writeMId, sourceLocation, currentMId, objHandle, offset);
                }

                varState.InMonitorWrite = this.InMonitor;
                if (this.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 = this.Config.EnableReadWriteTracing ? varState.LastReadLocation[readMId] : string.Empty;
                        this.ReportRace(RaceDiagnostic.ReadWrite, firstLocation, readMId, sourceLocation, currentMId, objHandle, offset);
                    }
                }
                else
                {
                    if (varState.VC.AnyGt(currentVC))
                    {
                        // SharedRead-write Race.
                        this.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
            {
                this.VarState[key] = new VarState(true, currentEpoch, this.Config.EnableReadWriteTracing, this.InMonitor);
                if (this.Config.EnableReadWriteTracing)
                {
                    this.VarState[key].LastWriteLocation = sourceLocation;
                }
            }
        }