// Adds Houdini to the pipeline if the user has not done so public void AddHoudiniEngine() { foreach (Engine engine in Engines) { if (engine is VanillaHoudini) { houdiniEngine = (VanillaHoudini)engine; } } if (houdiniEngine == null) { houdiniEngine = new VanillaHoudini(GetNextSMTEngineID(), SMTEngine.GetSolverParameter().DefaultValue, SMTEngine.GetErrorLimitParameter().DefaultValue); Engines.Add(houdiniEngine); } }
private Houdini.HoudiniOutcome ScheduleEnginesInParallel(Pipeline pipeline) { Houdini.HoudiniOutcome outcome = null; CancellationTokenSource tokenSource = new CancellationTokenSource(); List <Task> underApproximatingTasks = new List <Task>(); List <Task> overApproximatingTasks = new List <Task>(); // Schedule the under-approximating engines first foreach (Engine engine in pipeline.GetEngines()) { if (!(engine is VanillaHoudini)) { if (engine is DynamicAnalysis) { DynamicAnalysis dynamicEngine = (DynamicAnalysis)engine; underApproximatingTasks.Add(Task.Factory.StartNew( () => { dynamicEngine.Start(getFreshProgram(true, false)); }, tokenSource.Token)); } else { SMTEngine smtEngine = (SMTEngine)engine; underApproximatingTasks.Add(Task.Factory.StartNew( () => { smtEngine.Start(getFreshProgram(true, true), ref outcome); }, tokenSource.Token)); } } } if (pipeline.runHoudini) { // We set a barrier on the under-approximating engines if a Houdini delay // is specified or no sliding is selected if (pipeline.GetHoudiniEngine().Delay > 0) { Print.VerboseMessage("Waiting at barrier until Houdini delay has elapsed or all under-approximating engines have finished"); Task.WaitAll(underApproximatingTasks.ToArray(), pipeline.GetHoudiniEngine().Delay * 1000); } else if (pipeline.GetHoudiniEngine().SlidingSeconds > 0) { Print.VerboseMessage("Waiting at barrier until all under-approximating engines have finished"); Task.WaitAll(underApproximatingTasks.ToArray()); } // Schedule the vanilla Houdini engine overApproximatingTasks.Add(Task.Factory.StartNew( () => { pipeline.GetHoudiniEngine().Start(getFreshProgram(true, true), ref outcome); }, tokenSource.Token)); // Schedule Houdinis every x seconds until the number of new Houdini instances exceeds the limit if (pipeline.GetHoudiniEngine().SlidingSeconds > 0) { int numOfRefuted = Houdini.ConcurrentHoudini.RefutedSharedAnnotations.Count; int newHoudinis = 0; bool runningHoudinis; do { // Wait before launching new Houdini instances Thread.Sleep(pipeline.GetHoudiniEngine().SlidingSeconds * 1000); // Only launch a fresh Houdini if the candidate invariant set has changed if (Houdini.ConcurrentHoudini.RefutedSharedAnnotations.Count > numOfRefuted) { numOfRefuted = Houdini.ConcurrentHoudini.RefutedSharedAnnotations.Count; VanillaHoudini newHoudiniEngine = new VanillaHoudini(pipeline.GetNextSMTEngineID(), pipeline.GetHoudiniEngine().Solver, pipeline.GetHoudiniEngine().ErrorLimit); pipeline.AddEngine(newHoudiniEngine); Print.VerboseMessage("Scheduling another Houdini instance"); overApproximatingTasks.Add(Task.Factory.StartNew( () => { newHoudiniEngine.Start(getFreshProgram(true, true), ref outcome); tokenSource.Cancel(false); }, tokenSource.Token)); ++newHoudinis; } // Are any Houdinis still running? runningHoudinis = false; foreach (Task task in overApproximatingTasks) { if (task.Status.Equals(TaskStatus.Running)) { runningHoudinis = true; } } } while (newHoudinis < pipeline.GetHoudiniEngine().SlidingLimit&& runningHoudinis); } try { Task.WaitAny(overApproximatingTasks.ToArray(), tokenSource.Token); tokenSource.Cancel(false); } catch (OperationCanceledException e) { Console.WriteLine("Unexpected exception: " + e); throw; } } else { Task.WaitAll(underApproximatingTasks.ToArray()); } return(outcome); }