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