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(); }
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); }
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; } } }