/// <summary> /// Loads the known buggy InterceptionPoints. /// </summary> /// <param name="file">The file.</param> private void LoadKnownBuggyInterceptionPoints(string file) { using (TextReader tr = new StreamReader(file)) { try { string line; while ((line = tr.ReadLine()) != null) { line = line.Trim(); if (line.StartsWith("#") || string.IsNullOrWhiteSpace(line)) { continue; } string[] tokens = line.Split(' '); if (tokens.Length != 2) { continue; } this.blacklist.Add(this.GetPairID(tokens[0], tokens[1])); } } catch { ControllerHelper.Debug("ERROR when accessing the prebugfile"); } } }
/// <summary> /// Update trap delay mode. /// </summary> public void Initialize() { switch (this.TrapAlgorithm) { case TrapAlgorithm.Randomized: this.TrapController = this.RandomizedTrapController; break; case TrapAlgorithm.LearnedHB: this.TrapController = this.HBTrapController; break; default: this.TrapController = null; break; } if (this.TrapController == null) { ControllerHelper.Debug("Error: Trap controller is null!"); } else if (!this.TrapController.ParametersValid()) { ControllerHelper.Debug("Error: Trap controller parameters invalid!"); this.TrapController = null; } this.TrapController?.Initialize(this); }
/// <summary> /// Loads the plans from last run. /// </summary> /// <param name="file">The file.</param> private void LoadPlansFromLastRun(string file) { try { using (TextReader tr = new StreamReader(file)) { string line; Dictionary <string, int> planset = new Dictionary <string, int>(); while ((line = tr.ReadLine()) != null) { line = line.Trim(); if (line.StartsWith("#") || string.IsNullOrWhiteSpace(line)) { continue; } string[] tokens = line.Split(' '); if (tokens.Length != 3) { continue; } if (!planset.ContainsKey(tokens[0])) { planset[tokens[0]] = 0; } if (!planset.ContainsKey(tokens[2])) { planset[tokens[2]] = 0; } planset[tokens[0]]++; planset[tokens[2]]++; } foreach (string s in planset.Keys) { this.AddNewPlan(s, planset[s]); } } } catch { ControllerHelper.Debug("PrePlan file access error"); } }
/// <inheritdoc/> public void Initialize(TSVDRuntimeConfiguration configuration) { this.configuration = configuration; this.trapPoints = new Dictionary <string, Dictionary <Guid, Trap> >(); this.writeTrapPoints = new HashSet <string>(); if (this.configuration.BugLogPath != null) { this.bugLogger = new FileLogger(LogHelper.GetFilePathWithExecutionId(this.configuration.BugLogPath)); } this.isTrapActive = false; int seed = this.RandomSeed != 0 ? this.RandomSeed : Guid.NewGuid().GetHashCode(); this.random = new Random(seed); ControllerHelper.Debug(string.Format("RandomSeed: {0}", seed)); }
/// <summary> /// Finishes the trap. /// </summary> /// <param name="trapObjects">The trap objects.</param> /// <param name="trap">The trap.</param> /// <param name="interceptionPoint">The InterceptionPoint.</param> private void FinishTrap(Dictionary <string, HashSet <Trap> > trapObjects, Trap trap, InterceptionPoint interceptionPoint) { // execute the sleep if (trap != null) { try { } finally { Thread.BeginCriticalRegion(); trap.Semaphore.WaitOne(trap.Delay); ControllerHelper.Debug("Sleep : " + interceptionPoint.Tostring()); lock (trapObjects) { trapObjects.Remove(trap.ObjectId); } Thread.EndCriticalRegion(); } interceptionPoint.DelayCredit = this.InferSize; // figure out the which thread is blocked by this trap. { lock (this.perThreadLastTP) { foreach (var x in this.perThreadLastTP.Keys) { InterceptionPoint tp2 = this.perThreadLastTP[x]; if (interceptionPoint.Timestamp.AddMilliseconds(this.DelayPerDangerousInterceptionPoint * this.InferLimit) > tp2.Timestamp) { this.perThreadBlockedTP[x] = interceptionPoint; } } } } interceptionPoint.Trapped = true; this.isTrapActive = false; } }
/// <summary> /// Initialize the controller. /// </summary> /// <param name="configuration">The configuration.</param> /// <inheritdoc /> public void Initialize(TSVDRuntimeConfiguration configuration) { this.configuration = configuration; if (this.LogDirectory != null && Directory.Exists(this.LogDirectory)) { ControllerHelper.SetLoggingDirectory(this.LogDirectory); this.LastRunPlanFile = Path.Combine(this.LogDirectory, Path.GetFileName(this.LastRunPlanFile)); this.LastRunBugFile = Path.Combine(this.LogDirectory, Path.GetFileName(this.LastRunBugFile)); } if (this.configuration.BugLogPath != null) { this.bugLogger = new FileLogger(LogHelper.GetFilePathWithExecutionId(this.configuration.BugLogPath)); } this.isTrapActive = false; int seed = this.RandomSeed != 0 ? this.RandomSeed : Guid.NewGuid().GetHashCode(); this.random = new Random(seed); ControllerHelper.Debug(string.Format("RandomSeed: {0}", seed)); if (this.LastRunPlanFile != null) { if (File.Exists(this.LastRunPlanFile)) { this.LoadPlansFromLastRun(this.LastRunPlanFile); File.Delete(this.LastRunPlanFile); } this.lastRunPlanLogger = new FileLogger(this.LastRunPlanFile); } if (this.LastRunBugFile != null) { if (File.Exists(this.LastRunBugFile)) { this.LoadKnownBuggyInterceptionPoints(this.LastRunBugFile); } this.lastRunBugLogger = new FileLogger(this.LastRunBugFile); } }
/// <summary> /// Finds the racing tp. /// </summary> /// <param name="tp">The tp.</param> /// <returns>System.String.</returns> private string FindRacingTP(InterceptionPoint tp) { List <InterceptionPoint> list = new List <InterceptionPoint>(); // this block goes through the last-k tps that access the same object to find the dangerous list.co lock (this.lastInterceptionPointForOBJ) { if (this.lastInterceptionPointForOBJ.ContainsKey(tp.ObjID)) { Queue <InterceptionPoint> q = this.lastInterceptionPointForOBJ[tp.ObjID]; foreach (var tp2 in q) { // from different thread and at least one is write if ((tp2.ThreadId != tp.ThreadId) && (tp.IsWrite || tp2.IsWrite)) { // close enough from timing prespective if (tp2.Timestamp.AddMilliseconds(this.planDistance) > tp.Timestamp) { // the next condition is always true as we ignore the lock. Every LockState is false. if ((tp2.LockState == false) || (tp.LockState == false)) { if ((tp2.ActiveThdNum > 1) || (tp.ActiveThdNum > 1)) { list.Add(tp2); } } } } } // update the last access for this object q.Enqueue(tp); if (q.Count > this.LastTPWindow) { q.Dequeue(); } } else { this.lastInterceptionPointForOBJ[tp.ObjID] = new Queue <InterceptionPoint>(); this.lastInterceptionPointForOBJ[tp.ObjID].Enqueue(tp); } } // update the dangerous pair list string s = string.Empty; HashSet <string> temp = new HashSet <string>(); foreach (InterceptionPoint tp2 in list) { string st = tp.Tostring() + " ! " + tp2.Tostring(); string st2 = tp2.Tostring() + " ! " + tp.Tostring(); Tuple <string, string> tuple = new Tuple <string, string>(tp.Tostring(), tp2.Tostring()); string shortst = this.GetPairID(st, st2); string pairname = this.GetPairID(tp.Location, tp2.Location); if (this.blacklist.Contains(pairname)) { // the blacklist contains the bugs found in previous ROUNDS. DebugLog.Log("Skip blacked pair " + shortst); continue; } bool flag = false; lock (this.dangerousTPPairs) { if (this.hitTime.ContainsKey(tp.Location) && this.hitTime.ContainsKey(tp2.Location) && (this.hitTime[tp.Location] + this.hitTime[tp2.Location] >= 10) && this.dangerousTPPairs.Contains(shortst)) { continue; } // the hittime is how many time this dangerous pair has caused trap. It is used for decay. this.hitTime[tp.Location] = 0; this.hitTime[tp2.Location] = 0; this.dangerousTPPairs.Add(shortst); flag = true; } if (flag) { ControllerHelper.Debug("AddDangerList : " + st); this.LogPlanForNextRun(st); } } return(s); }