private IEnumerable <Event> OtherJobs(Simulation env, PreemptiveResource repairman) { // The repairman's other (unimportant) job. while (true) { // Start a new job var doneIn = JobDuration; while (doneIn > TimeSpan.Zero) { // Retry the job until it is done. // It's priority is lower than that of machine repairs. using (var req = repairman.Request(priority: 2)) { yield return(req); var start = env.Now; yield return(env.Timeout(doneIn)); if (env.ActiveProcess.HandleFault()) { doneIn -= env.Now - start; } else { doneIn = TimeSpan.Zero; } } } } }
public void Simulate(int rseed = RandomSeed) { // Setup and start the simulation // Create an environment and start the setup process var start = new DateTime(2014, 2, 1); var env = new Simulation(start, rseed); env.Log("== Machine shop =="); var repairman = new PreemptiveResource(env, 1); var machines = Enumerable.Range(0, NumMachines).Select(x => new Machine(env, "Machine " + x, repairman)).ToArray(); env.Process(OtherJobs(env, repairman)); var startPerf = DateTime.UtcNow; // Execute! env.Run(SimTime); var perf = DateTime.UtcNow - startPerf; // Analyis/results env.Log("Machine shop results after {0} days.", (env.Now - start).TotalDays); foreach (var machine in machines) { env.Log("{0} made {1} parts.", machine.Name, machine.PartsMade); } env.Log(string.Empty); env.Log("Processed {0} events in {1} seconds ({2} events/s).", env.ProcessedEvents, perf.TotalSeconds, (env.ProcessedEvents / perf.TotalSeconds)); }
public void Start(int rseed = 42) { YakNames = YakNames.ToList().Shuffle().ToArray(); // Setup and start the simulation // Create an environment and start the setup process var start = DateTime.Now; var env = new Simulation(start, rseed); env.Log("== Dairy Production Plant =="); var milker = new PreemptiveResource(env, 1); var shaver = new PreemptiveResource(env, 1); var yaks = Enumerable.Range(0, 20).Select(x => new ActiveObjects.Cow(env, YakNames[x], milker, shaver)).ToArray(); //env.Process(ShavingJobs(env, shaver)); var startPerf = DateTime.UtcNow; // Execute! env.Run(TimeSpan.FromDays(365)); var perf = DateTime.UtcNow - startPerf; // Analyis/results env.Log("Dairy Production Plant results after {0} days.", (env.Now - start).TotalDays); env.Log(string.Empty); env.Log("Processed {0} events in {1} seconds ({2} events/s).", env.ProcessedEvents, perf.TotalSeconds, (env.ProcessedEvents / perf.TotalSeconds)); env.Log($"Milked: { ActiveObjects.Cow.Milked} animals."); env.Log($"Total Milking Timed: { ActiveObjects.Cow.TotalMilkingTime}."); }
private IEnumerable <Event> ShavingJob(Simulation env, PreemptiveResource shaver) { while (true) { // Start a new job var doneIn = Environment.RandNormal(PtMeanShaving, PtSigmaShaving); while (doneIn > TimeSpan.Zero) { // Retry the job until it is done. // It's priority is lower than that of milking using (var req = shaver.Request(priority: 2)) { yield return(req); var start = env.Now; yield return(env.Timeout(doneIn)); if (env.ActiveProcess.HandleFault()) { doneIn -= env.Now - start; } else { doneIn = TimeSpan.Zero; } } } } }
private IEnumerable <Event> TestPreemptiveResourceTimeoutB(Environment env, PreemptiveResource res, int prio) { using (var req = res.Request(priority: prio, preempt: true)) { yield return(req); } }
SimEvents ResourceOccupier(PreemptiveResource resource, double timeout) { using (var req = resource.Request()) { yield return(req); yield return(Env.Timeout(timeout)); } }
SimEvents WithTimeout_PEM_A(PreemptiveResource resource, double priority) { using (var req = resource.Request(priority)) { yield return(req); Assert.True(Env.ActiveProcess.Preempted()); yield return(Env.Event()); } }
SimEvents ResourceRequester(PreemptiveResource resource, ILinkedQueue <SimProcess> completed) { using (var req = resource.Request()) { yield return(req); completed.Enqueue(Env.ActiveProcess); yield return(Env.Timeout(10)); } }
public void TestPreemptiveResourceTimeout0() { var env = new Environment(); var res = new PreemptiveResource(env, capacity: 1); env.Process(TestPreemptiveResourceTimeoutA(env, res, 1)); env.Process(TestPreemptiveResourceTimeoutB(env, res, 0)); env.Run(); }
SimEvents ResourceRequester_WithCount(PreemptiveResource resource, int expectedCount) { using (var req = resource.Request()) { yield return(req); Assert.AreEqual(expectedCount, resource.Count); yield return(Env.Timeout(10)); } }
SimEvents ResourceRequester_Occupied_WithTimeout(PreemptiveResource resource, double timeout) { var req = resource.Request(); var cond = req.Or(Env.Timeout(timeout)); yield return(cond); // Resource is occupied Assert.False(cond.Ev1.Succeeded); Assert.True(cond.Ev2.Succeeded); }
SimEvents ResourceRequester_WithPriority(PreemptiveResource resource, ILinkedQueue <SimProcess> completed, double priority) { using (var req = resource.Request(priority, false)) { yield return(req); completed.Enqueue(Env.ActiveProcess); yield return(Env.Timeout(10)); } }
public Machine(Simulation env, string name, PreemptiveResource repairman) : base(env) { Name = name; PartsMade = 0; Broken = false; // Start "working" and "break_machine" processes for this machine. Process = env.Process(Working(repairman)); env.Process(BreakMachine()); }
private IEnumerable <Event> TestPreemptiveResourceTimeoutA(Environment env, PreemptiveResource res, int prio) { using (var req = res.Request(priority: prio, preempt: true)) { yield return(req); Assert.IsTrue(env.ActiveProcess.HandleFault()); yield return(env.Timeout(TimeSpan.FromSeconds(1))); Assert.IsFalse(env.ActiveProcess.HandleFault()); } }
SimEvents Simple_PEM(int id, PreemptiveResource res, double priority, ICollection <Tuple <double, int, PreemptionInfo> > log) { using (var req = res.Request(priority)) { yield return(req); yield return(Env.Timeout(5)); PreemptionInfo info; log.Add(Env.ActiveProcess.Preempted(out info) ? Tuple.Create(Env.Now, id, info) : Tuple.Create(Env.Now, id, (PreemptionInfo)null)); } }
private IEnumerable <Event> TestMixedPreemtion(int id, Environment env, PreemptiveResource res, int delay, int prio, bool preempt, List <Tuple <int, int> > log) { yield return(env.Timeout(TimeSpan.FromSeconds(delay))); using (var req = res.Request(priority: prio, preempt: preempt)) { yield return(req); yield return(env.Timeout(TimeSpan.FromSeconds(5))); if (!env.ActiveProcess.HandleFault()) { log.Add(Tuple.Create(env.Now.Second, id)); } } }
private IEnumerable <Event> TestPreemtiveResource(int id, Environment env, PreemptiveResource res, int delay, int prio, Dictionary <DateTime, int> log) { yield return(env.Timeout(TimeSpan.FromSeconds(delay))); using (var req = res.Request(priority: prio, preempt: true)) { yield return(req); yield return(env.Timeout(TimeSpan.FromSeconds(5))); if (!env.ActiveProcess.HandleFault()) { log.Add(env.Now, id); } } }
/// <summary> /// A daily event that indicates the yak can be milked. /// </summary> /// <returns>Scheduled Event</returns> private IEnumerable <Event> LifeCycle(PreemptiveResource milker) { while (true) { yield return(Environment.Timeout(TimeSpan.FromDays(1))); // Ready to milk the Cow // Request a milker. The Cow will be milked as soon as the milker is available. var timeToMilk = Environment.RandNormal(PtMeanMilking, PtSigmaMilking); using (var req = milker.Request(priority: 1, preempt: false)) { yield return(req); // Milker available, start milking the yak. var time = Environment.RandNormal(PtMeanMilking, PtSigmaMilking); TotalMilkingTime += time; yield return(Environment.Timeout(time)); // The yak is milked. ProductionData.Add(new Milk() { Animal = new Animal() { Code = "", Name = Name }, Composition = new MilkComposition() { Fats = Math.Round(Environment.RandUniform(0.055, 0.072), precision), Lactose = Math.Round(Environment.RandUniform(0.045, 0.05), precision), Minerals = Math.Round(Environment.RandUniform(0.08, 0.09), precision), Protein = Math.Round(Environment.RandUniform(0.049, 0.053), precision), Solids = Math.Round(Environment.RandUniform(0.169, 0.177), precision), }, Kg = Math.Round(Environment.RandUniform(0.3, 2.9), 2), ProductionInfo = new ProductionInfo() { DateOfProduction = Environment.Now, ProductionTime = time, Costs = hourlySalary / 60 * time.Minutes } });; Milked++; } } }
public void TestPreemtiveResource() { var start = new DateTime(2014, 4, 1); var env = new Environment(start); var res = new PreemptiveResource(env, capacity: 2); var log = new Dictionary <DateTime, int>(); // id d p env.Process(TestPreemtiveResource(0, env, res, 0, 1, log)); env.Process(TestPreemtiveResource(1, env, res, 0, 1, log)); env.Process(TestPreemtiveResource(2, env, res, 1, 0, log)); env.Process(TestPreemtiveResource(3, env, res, 2, 2, log)); env.Run(); var expected = new Dictionary <int, int> { { 5, 0 }, { 6, 2 }, { 10, 3 } }.ToDictionary(x => start + TimeSpan.FromSeconds(x.Key), x => x.Value); CollectionAssert.AreEqual(expected, log); }
private IEnumerable <Event> Working(PreemptiveResource repairman) { /* * Produce parts as long as the simulation runs. * * While making a part, the machine may break multiple times. * Request a repairman when this happens. */ while (true) { // Start making a new part var doneIn = Environment.RandNormal(PtMean, PtSigma); while (doneIn > TimeSpan.Zero) { // Working on the part var start = Environment.Now; yield return(Environment.Timeout(doneIn)); if (Environment.ActiveProcess.HandleFault()) { Broken = true; doneIn -= Environment.Now - start; // How much time left? // Request a repairman. This will preempt its "other_job". using (var req = repairman.Request(priority: 1, preempt: true)) { yield return(req); yield return(Environment.Timeout(RepairTime)); } Broken = false; } else { doneIn = TimeSpan.Zero; // Set to 0 to exit while loop. } } // Part is done. PartsMade++; } }
public void TestMixedPreemtion() { var start = new DateTime(2014, 4, 2); var env = new Environment(start); var res = new PreemptiveResource(env, capacity: 2); var log = new List <Tuple <int, int> >(); env.Process(TestMixedPreemtion(0, env, res, 0, 1, true, log)); env.Process(TestMixedPreemtion(1, env, res, 0, 1, true, log)); env.Process(TestMixedPreemtion(2, env, res, 1, 0, false, log)); env.Process(TestMixedPreemtion(3, env, res, 1, 0, true, log)); env.Process(TestMixedPreemtion(4, env, res, 2, 2, true, log)); env.Run(); var expected = new List <Tuple <int, int> > { Tuple.Create(5, 0), Tuple.Create(6, 3), Tuple.Create(10, 2), Tuple.Create(11, 4) }; CollectionAssert.AreEqual(expected, log); }
public void TestMixedPreemtion() { var start = new DateTime(2014, 4, 2); var env = new Environment(start); var res = new PreemptiveResource(env, capacity: 2); var log = new List<Tuple<int, int>>(); env.Process(TestMixedPreemtion(0, env, res, 0, 1, true, log)); env.Process(TestMixedPreemtion(1, env, res, 0, 1, true, log)); env.Process(TestMixedPreemtion(2, env, res, 1, 0, false, log)); env.Process(TestMixedPreemtion(3, env, res, 1, 0, true, log)); env.Process(TestMixedPreemtion(4, env, res, 2, 2, true, log)); env.Run(); var expected = new List<Tuple<int, int>> { Tuple.Create(5, 0), Tuple.Create(6, 3), Tuple.Create(10, 2), Tuple.Create(11, 4) }; CollectionAssert.AreEqual(expected, log); }
public void TestPreemtiveResource() { var start = new DateTime(2014, 4, 1); var env = new Environment(start); var res = new PreemptiveResource(env, capacity: 2); var log = new Dictionary<DateTime, int>(); // id d p env.Process(TestPreemtiveResource(0, env, res, 0, 1, log)); env.Process(TestPreemtiveResource(1, env, res, 0, 1, log)); env.Process(TestPreemtiveResource(2, env, res, 1, 0, log)); env.Process(TestPreemtiveResource(3, env, res, 2, 2, log)); env.Run(); var expected = new Dictionary<int, int> { {5, 0}, {6, 2}, {10, 3} }.ToDictionary(x => start + TimeSpan.FromSeconds(x.Key), x => x.Value); CollectionAssert.AreEqual(expected, log); }
private IEnumerable<Event> TestMixedPreemtion(int id, Environment env, PreemptiveResource res, int delay, int prio, bool preempt, List<Tuple<int, int>> log) { yield return env.Timeout(TimeSpan.FromSeconds(delay)); using (var req = res.Request(priority: prio, preempt: preempt)) { yield return req; yield return env.Timeout(TimeSpan.FromSeconds(5)); if (!env.ActiveProcess.HandleFault()) log.Add(Tuple.Create(env.Now.Second, id)); } }
private IEnumerable<Event> TestPreemptiveResourceTimeoutA(Environment env, PreemptiveResource res, int prio) { using (var req = res.Request(priority: prio, preempt: true)) { yield return req; Assert.IsTrue(env.ActiveProcess.HandleFault()); yield return env.Timeout(TimeSpan.FromSeconds(1)); Assert.IsFalse(env.ActiveProcess.HandleFault()); } }
private IEnumerable<Event> TestPreemptiveResourceTimeoutB(Environment env, PreemptiveResource res, int prio) { using (var req = res.Request(priority: prio, preempt: true)) { yield return req; } }
private IEnumerable<Event> TestPreemtiveResource(int id, Environment env, PreemptiveResource res, int delay, int prio, Dictionary<DateTime, int> log) { yield return env.Timeout(TimeSpan.FromSeconds(delay)); using (var req = res.Request(priority: prio, preempt: true)) { yield return req; yield return env.Timeout(TimeSpan.FromSeconds(5)); if (!env.ActiveProcess.HandleFault()) log.Add(env.Now, id); } }
/// <summary> /// Initializes a yak in its simulation environment. /// </summary> /// <param name="environment"></param> /// <param name="milker"></param> public Cow(Simulation environment, string name, PreemptiveResource milker, PreemptiveResource shaver) : base(environment) { Process = environment.Process(LifeCycle(milker)); Name = name; }
SimEvents WithTimeout_PEM_B(PreemptiveResource resource, double priority) { using (var req = resource.Request(priority)) { yield return(req); } }