/// <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> /// 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) { // DebugLog.Log("AddDangerList : " + st); this.LogPlanForNextRun(st); } } return(s); }