Ejemplo n.º 1
0
        public void ShouldHandleSlaveTimeSourceWithNotAlignedQuantum()
        {
            using (var timeSource = new MasterTimeSource {
                Quantum = TimeInterval.FromTicks(10), AdvanceImmediately = true
            })
                using (var timeSlave = new SlaveTimeSource()
                {
                    Quantum = TimeInterval.FromTicks(3), AdvanceImmediately = true
                })
                {
                    var timeSink = new SimpleTimeSink(1.0);

                    timeSource.RegisterSink(timeSlave);
                    timeSlave.RegisterSink(timeSink);

                    // the first round does not increment the time - it just triggers a sync point
                    timeSource.Run(1);

                    Assert.AreEqual(1, timeSource.NumberOfSyncPoints);
                    Assert.AreEqual(0, timeSlave.NumberOfSyncPoints);
                    Assert.AreEqual(0, timeSink.NumberOfRounds);

                    Assert.AreEqual(0, timeSource.ElapsedVirtualTime.Ticks);
                    Assert.AreEqual(0, timeSlave.ElapsedVirtualTime.Ticks);
                    Assert.AreEqual(0, timeSink.ElapsedVirtualTime.Ticks);

                    timeSource.Run(1);

                    Assert.AreEqual(2, timeSource.NumberOfSyncPoints);
                    Assert.AreEqual(4, timeSlave.NumberOfSyncPoints);
                    Assert.AreEqual(3, timeSink.NumberOfRounds);

                    Assert.AreEqual(10, timeSource.ElapsedVirtualTime.Ticks);
                    Assert.AreEqual(9, timeSlave.ElapsedVirtualTime.Ticks);
                    Assert.AreEqual(9, timeSink.ElapsedVirtualTime.Ticks);

                    timeSource.Run(1);

                    Assert.AreEqual(3, timeSource.NumberOfSyncPoints);
                    Assert.AreEqual(7, timeSlave.NumberOfSyncPoints);
                    Assert.AreEqual(6, timeSink.NumberOfRounds);

                    Assert.AreEqual(20, timeSource.ElapsedVirtualTime.Ticks);
                    Assert.AreEqual(18, timeSlave.ElapsedVirtualTime.Ticks);
                    Assert.AreEqual(18, timeSink.ElapsedVirtualTime.Ticks);

                    timeSource.Run(1);

                    Assert.AreEqual(4, timeSource.NumberOfSyncPoints);
                    Assert.AreEqual(11, timeSlave.NumberOfSyncPoints);
                    Assert.AreEqual(10, timeSink.NumberOfRounds);

                    Assert.AreEqual(30, timeSource.ElapsedVirtualTime.Ticks);
                    Assert.AreEqual(30, timeSlave.ElapsedVirtualTime.Ticks);
                    Assert.AreEqual(30, timeSink.ElapsedVirtualTime.Ticks);
                }
        }
Ejemplo n.º 2
0
 public void RunFor(TimeInterval period)
 {
     if (IsStarted)
     {
         throw new RecoverableException("This action is not available when emulation is already started");
     }
     InnerStartAll();
     MasterTimeSource.RunFor(period);
     InnerPauseAll();
 }
Ejemplo n.º 3
0
 public void PauseAll()
 {
     lock (machLock)
     {
         Array.ForEach(machs.Rights, x => x.Pause());
         ExternalsManager.Pause();
         MasterTimeSource.Stop();
         IsStarted = false;
     }
 }
Ejemplo n.º 4
0
        public void RunToNearestSyncPoint()
        {
            if (IsStarted)
            {
                throw new RecoverableException("This action is not available when emulation is already started");
            }

            InnerStartAll();
            MasterTimeSource.Run();
            InnerPauseAll();
        }
Ejemplo n.º 5
0
 public void Dispose()
 {
     FileFetcher.CancelDownload();
     lock (machLock)
     {
         PauseAll();
         Array.ForEach(machs.Rights, x => x.Dispose());
         machs.Clear();
         MasterTimeSource.Dispose();
         ExternalsManager.Clear();
         HostMachine.Dispose();
         CurrentLogger.Dispose();
         BackendManager.Dispose();
     }
 }
Ejemplo n.º 6
0
        public bool TryAddMachine(Machine machine, string name)
        {
            lock (machLock)
            {
                if (string.IsNullOrEmpty(name))
                {
                    name = GetNextMachineName(machine.Platform);
                }
                else if (machs.ExistsEither(name, machine))
                {
                    return(false);
                }

                machs.Add(name, machine);
                MasterTimeSource.RegisterSink(machine.LocalTimeSource);
                return(true);
            }
        }
Ejemplo n.º 7
0
 public void Dispose()
 {
     FileFetcher.CancelDownload();
     lock (machLock)
     {
         var toDispose = machs.Rights.ToArray();
         //Although a single machine does not have to be paused before its disposal,
         //disposing multiple entities has to ensure that all are stopped.
         ExternalsManager.Pause();
         Array.ForEach(toDispose, x => x.Pause());
         Array.ForEach(toDispose, x => x.Dispose());
         machs.Clear();
         MasterTimeSource.Dispose();
         ExternalsManager.Clear();
         HostMachine.Dispose();
         CurrentLogger.Dispose();
         BackendManager.Dispose();
     }
 }
Ejemplo n.º 8
0
        public Emulation()
        {
            MasterTimeSource = new MasterTimeSource();
            HostMachine      = new HostMachine();
            MACRepository    = new MACRepository();
            ExternalsManager = new ExternalsManager();
            ExternalsManager.AddExternal(HostMachine, HostMachine.HostMachineName);
            Connector                = new Connector();
            FileFetcher              = new CachingFileFetcher();
            CurrentLogger            = Logger.GetLogger();
            randomGenerator          = new Lazy <PseudorandomNumberGenerator>(() => new PseudorandomNumberGenerator());
            nameCache                = new LRUCache <object, Tuple <string, string> >(NameCacheSize);
            peripheralToMachineCache = new LRUCache <IPeripheral, Machine>(PeripheralToMachineCacheSize);

            machs            = new FastReadConcurrentTwoWayDictionary <string, Machine>();
            machs.ItemAdded += (name, machine) =>
            {
                machine.StateChanged       += OnMachineStateChanged;
                machine.PeripheralsChanged += (m, e) =>
                {
                    if (e.Operation != PeripheralsChangedEventArgs.PeripheralChangeType.Addition)
                    {
                        nameCache.Invalidate();
                        peripheralToMachineCache.Invalidate();
                    }
                };

                OnMachineAdded(machine);
            };

            machs.ItemRemoved += (name, machine) =>
            {
                machine.StateChanged -= OnMachineStateChanged;
                nameCache.Invalidate();
                peripheralToMachineCache.Invalidate();

                OnMachineRemoved(machine);
            };
            BackendManager = new BackendManager();
            BlobManager    = new BlobManager();
            theBag         = new Dictionary <string, object>();
        }
Ejemplo n.º 9
0
        public void ShouldExecuteDelayedActionInNearestSyncedStateExactlyOnce()
        {
            var time = TimeInterval.Empty;

            var alreadyDone = false;

            using (var master = new MasterTimeSource {
                Quantum = TimeInterval.FromTicks(10), AdvanceImmediately = true
            })
                using (var timeSlave = new SlaveTimeSource(null)
                {
                    Quantum = TimeInterval.FromTicks(10), AdvanceImmediately = true
                })
                {
                    var timeSink = new SimpleTimeSink(1.0, (sts, th, ti) =>
                    {
                        if (alreadyDone)
                        {
                            return(true);
                        }
                        timeSlave.ExecuteInNearestSyncedState(ts =>
                        {
                            time = ts.TimeElapsed;
                        });
                        alreadyDone = true;
                        return(true);
                    });

                    master.RegisterSink(timeSlave);
                    timeSlave.RegisterSink(timeSink);

                    master.Run(1);
                    Assert.AreEqual(0, time.Ticks);
                    Assert.AreEqual(false, alreadyDone);
                    // here we must run 2 rounds as delayed actions are executed at the beginning of each round
                    master.Run(1);
                    Assert.AreEqual(true, alreadyDone);
                    Assert.AreEqual(10, time.Ticks);
                    master.Run(1);
                    Assert.AreEqual(10, time.Ticks);
                }
        }
Ejemplo n.º 10
0
        public void ShouldCalculateCumulativeLoadForLowPerformance()
        {
            const int slavesCount = 5;
            const int roundsCount = 3;

            using (var timeSource = new MasterTimeSource()
            {
                Quantum = TimeInterval.FromTicks(1000000), AdvanceImmediately = false
            })
            {
                var timeSinks = new SimpleTimeSink[slavesCount];
                for (int i = 0; i < slavesCount; i++)
                {
                    timeSinks[i] = new SimpleTimeSink(0.1);
                    timeSource.RegisterSink(timeSinks[i]);
                }
                timeSource.Run(roundsCount);
                Assert.AreEqual(10.0, timeSource.CumulativeLoad, 0.05);
            }
        }
Ejemplo n.º 11
0
        public void ShouldCalculateCumulativeLoadForIndefinitePerformance()
        {
            const int slavesCount = 5;
            const int roundsCount = 3;

            using (var timeSource = new MasterTimeSource()
            {
                Quantum = TimeInterval.FromTicks(1000000), AdvanceImmediately = true
            })
            {
                var timeSinks = new SimpleTimeSink[slavesCount];
                for (int i = 0; i < slavesCount; i++)
                {
                    timeSinks[i] = new SimpleTimeSink(double.MaxValue);
                    timeSource.RegisterSink(timeSinks[i]);
                }
                timeSource.Run(roundsCount);
                Assert.IsTrue(timeSource.CumulativeLoad < 0.1);
            }
        }
Ejemplo n.º 12
0
        public void ShouldNotTickDisconnectedSlaveTimeSource()
        {
            using (var master = new MasterTimeSource {
                Quantum = TimeInterval.FromTicks(10), AdvanceImmediately = true
            })
                using (var timeSlave = new SlaveTimeSource(null)
                {
                    Quantum = TimeInterval.FromTicks(10), AdvanceImmediately = true
                })
                {
                    var timeSink = new SimpleTimeSink(1.0);

                    master.RegisterSink(timeSlave);
                    timeSlave.RegisterSink(timeSink);

                    // the first round does not increment the time - it just triggers a sync point
                    master.Run(1 + 1);

                    Assert.AreEqual(2, master.NumberOfSyncPoints);
                    Assert.AreEqual(2, timeSlave.NumberOfSyncPoints);
                    Assert.AreEqual(1, timeSink.NumberOfRounds);

                    Assert.AreEqual(10, master.ElapsedVirtualTime.Ticks);
                    Assert.AreEqual(10, timeSlave.ElapsedVirtualTime.Ticks);
                    Assert.AreEqual(10, timeSink.ElapsedVirtualTime.Ticks);

                    timeSlave.TimeHandle.Dispose();

                    master.Run(1);

                    Assert.AreEqual(3, master.NumberOfSyncPoints);
                    Assert.AreEqual(2, timeSlave.NumberOfSyncPoints);
                    Assert.AreEqual(1, timeSink.NumberOfRounds);

                    Assert.AreEqual(20, master.ElapsedVirtualTime.Ticks);
                    Assert.AreEqual(10, timeSlave.ElapsedVirtualTime.Ticks);
                    Assert.AreEqual(10, timeSink.ElapsedVirtualTime.Ticks);
                }
        }
Ejemplo n.º 13
0
        public void ShouldNotSleepOnAdvanceImmediately()
        {
            const int slavesCount = 5;
            const int roundsCount = 3;

            using (var timeSource = new MasterTimeSource {
                Quantum = TimeInterval.FromMilliseconds(1000), AdvanceImmediately = true
            })
            {
                var timeSinks = new SimpleTimeSink[slavesCount];
                for (int i = 0; i < slavesCount; i++)
                {
                    timeSinks[i] = new SimpleTimeSink(double.MaxValue);
                    timeSource.RegisterSink(timeSinks[i]);
                }
                var sw = Stopwatch.StartNew();

                // the first round does not increment the time - it just triggers a sync point
                timeSource.Run(roundsCount + 1);

                var after = sw.Elapsed;
                Assert.IsTrue(after.TotalSeconds < roundsCount);
            }
        }
Ejemplo n.º 14
0
        public void ShouldExecuteNonAlignedDelayedActionInSyncedStateExactlyOnce()
        {
            var time = TimeInterval.Empty;

            using (var master = new MasterTimeSource {
                Quantum = TimeInterval.FromTicks(10), AdvanceImmediately = true
            })
                using (var timeSlave = new SlaveTimeSource(null)
                {
                    Quantum = TimeInterval.FromTicks(10), AdvanceImmediately = true
                })
                {
                    var timeSink = new SimpleTimeSink(1.0, (sts, th, ti) =>
                    {
                        if (sts.NumberOfRounds != 1)
                        {
                            return(true);
                        }
                        timeSlave.ExecuteInSyncedState(ts =>
                        {
                            time = timeSlave.ElapsedVirtualTime;
                        }, new TimeStamp(TimeInterval.FromTicks(31), master.Domain));
                        return(true);
                    });

                    master.RegisterSink(timeSlave);
                    timeSlave.RegisterSink(timeSink);

                    master.Run(4);
                    Assert.AreEqual(0, time.Ticks);
                    master.Run(1);
                    Assert.AreEqual(40, time.Ticks);
                    master.Run(1);
                    Assert.AreEqual(40, time.Ticks);
                }
        }
Ejemplo n.º 15
0
        public void ShouldHandleBlockingAtTheEndOfGrantedInterval()
        {
            var indicator = false;

            using (var master = new MasterTimeSource {
                Quantum = TimeInterval.FromTicks(10), AdvanceImmediately = true
            })
                using (var timeSlave = new SlaveTimeSource(null)
                {
                    Quantum = TimeInterval.FromTicks(10), AdvanceImmediately = true
                })
                    using (var timeSink = new MoreComplicatedTimeSink("A"))
                    {
                        // tester thread
                        new Thread(() =>
                        {
                            this.Trace();
                            timeSink.ExecuteOnDispatcherThread((ts, ti) =>
                            {
                                this.Trace();
                                Assert.AreEqual(10, ti.Ticks);

                                ts.TimeHandle.ReportBackAndBreak(TimeInterval.Empty);
                            });

                            this.Trace();
                            // here we sleep to make sure that master won't go further
                            Thread.Sleep(5000);

                            this.Trace();
                            Assert.AreEqual(10, master.ElapsedVirtualTime.Ticks);
                            Assert.AreEqual(10, timeSlave.ElapsedVirtualTime.Ticks);
                            indicator = true;

                            this.Trace();
                            timeSink.ExecuteOnDispatcherThread((ts, ti) =>
                            {
                                this.Trace();
                                Assert.AreEqual(0, ti.Ticks);
                                ts.TimeHandle.ReportBackAndContinue(TimeInterval.Empty);
                            });

                            timeSink.ExecuteOnDispatcherThread((ts, ti) =>
                            {
                                this.Trace();
                                Assert.AreEqual(10, ti.Ticks);
                                ts.TimeHandle.ReportBackAndContinue(TimeInterval.Empty);
                            });
                        })
                        {
                            Name = "tester thread"
                        }.Start();

                        master.RegisterSink(timeSlave);
                        timeSlave.RegisterSink(timeSink);

                        // just to pass the first syncpoint
                        master.Run(1);

                        this.Trace();
                        master.Run(1);
                        this.Trace();
                        Assert.IsTrue(indicator);
                        Assert.AreEqual(10, master.ElapsedVirtualTime.Ticks);
                        Assert.AreEqual(10, timeSlave.ElapsedVirtualTime.Ticks);

                        master.Run(1);
                        Assert.AreEqual(20, master.ElapsedVirtualTime.Ticks);
                        Assert.AreEqual(20, timeSlave.ElapsedVirtualTime.Ticks);
                    }
        }
Ejemplo n.º 16
0
        public void ShouldHandleTwoBlockingSinks()
        {
            var indicator = false;

            using (var master = new MasterTimeSource {
                Quantum = TimeInterval.FromTicks(10), AdvanceImmediately = true
            })
                using (var timeSlave = new SlaveTimeSource(null)
                {
                    Quantum = TimeInterval.FromTicks(10), AdvanceImmediately = true
                })
                    using (var timeSinkA2 = new MoreComplicatedTimeSink("A"))
                        using (var timeSinkB2 = new MoreComplicatedTimeSink("B"))
                        {
                            var ttt = new Thread(() =>
                            {
                                Parallel(
                                    () =>
                                {
                                    timeSinkA2.ExecuteOnDispatcherThread((sts, ti) =>
                                    {
                                        this.Trace();
                                        Assert.AreEqual(10, ti.Ticks);
                                        var timeUsed = TimeInterval.FromTicks(4);
                                        var timeLeft = ti - timeUsed;
                                        sts.TimeHandle.ReportBackAndBreak(timeLeft);
                                    });
                                },

                                    () =>
                                {
                                    timeSinkB2.ExecuteOnDispatcherThread((sts, ti) =>
                                    {
                                        this.Trace();
                                        Assert.AreEqual(10, ti.Ticks);
                                        var timeUsed = TimeInterval.FromTicks(6);
                                        var timeLeft = ti - timeUsed;
                                        sts.TimeHandle.ReportBackAndBreak(timeLeft);
                                    });
                                }
                                    );

                                // here we sleep to make sure that master won't go further
                                this.Trace();
                                Thread.Sleep(5000);

                                this.Trace();
                                Assert.AreEqual(4, master.ElapsedVirtualTime.Ticks);
                                Assert.AreEqual(4, timeSlave.ElapsedVirtualTime.Ticks);

                                Parallel(
                                    () =>
                                {
                                    timeSinkA2.ExecuteOnDispatcherThread((sts, ti) =>
                                    {
                                        this.Trace();
                                        Assert.AreEqual(6, ti.Ticks);
                                        var timeUsed = TimeInterval.FromTicks(4);
                                        var timeLeft = ti - timeUsed;
                                        sts.TimeHandle.ReportBackAndBreak(timeLeft);
                                    });
                                },

                                    () =>
                                {
                                    timeSinkB2.ExecuteOnDispatcherThread((sts, ti) =>
                                    {
                                        this.Trace();
                                        Assert.AreEqual(4, ti.Ticks);
                                        sts.TimeHandle.ReportBackAndBreak(ti);
                                    });
                                }
                                    );

                                // here we sleep to make sure that master won't go further
                                this.Trace();
                                Thread.Sleep(5000);

                                this.Trace();
                                Assert.AreEqual(6, master.ElapsedVirtualTime.Ticks);
                                Assert.AreEqual(6, timeSlave.ElapsedVirtualTime.Ticks);

                                Parallel(
                                    () =>
                                {
                                    timeSinkA2.ExecuteOnDispatcherThread((sts, ti) =>
                                    {
                                        this.Trace();
                                        Assert.AreEqual(2, ti.Ticks);
                                        sts.TimeHandle.ReportBackAndBreak(ti);
                                    });
                                },

                                    () =>
                                {
                                    timeSinkB2.ExecuteOnDispatcherThread((sts, ti) =>
                                    {
                                        this.Trace();
                                        Assert.AreEqual(4, ti.Ticks);
                                        sts.TimeHandle.ReportBackAndContinue(TimeInterval.Empty);
                                    });
                                }
                                    );

                                // here we sleep to make sure that master won't go further
                                this.Trace();
                                Thread.Sleep(5000);

                                this.Trace();
                                Assert.AreEqual(8, master.ElapsedVirtualTime.Ticks);
                                Assert.AreEqual(8, timeSlave.ElapsedVirtualTime.Ticks);

                                Parallel(
                                    () =>
                                {
                                    timeSinkA2.ExecuteOnDispatcherThread((sts, ti) =>
                                    {
                                        this.Trace();
                                        Assert.AreEqual(2, ti.Ticks);
                                        indicator = true;
                                        sts.TimeHandle.ReportBackAndContinue(TimeInterval.Empty);
                                    });
                                },

                                    () =>
                                {
                                    timeSinkB2.ExecuteOnDispatcherThread((sts, ti) =>
                                    {
                                        this.Trace();
                                        Assert.Fail();
                                    }, false);           // do not wait for finish
                                    Thread.Sleep(10000); // wait for 10s and check if Fail() is called
                                }
                                    );
                            })
                            {
                                Name = "tester thread"
                            };
                            ttt.Start();

                            master.RegisterSink(timeSlave);
                            timeSlave.RegisterSink(timeSinkA2);
                            timeSlave.RegisterSink(timeSinkB2);

                            // just to pass the first syncpoint
                            master.Run(1);

                            master.Run(1);
                            Assert.IsTrue(indicator);

                            this.Trace();
                            Assert.AreEqual(10, master.ElapsedVirtualTime.Ticks);
                            Assert.AreEqual(10, timeSlave.ElapsedVirtualTime.Ticks);

                            ttt.Join();
                        }
        }
Ejemplo n.º 17
0
        public void ShouldUpdateExecutedTimeAfterBlocking()
        {
            var indicator        = false;
            var firstTime        = true;
            var threadToSinkSync = new ManualResetEvent(false);
            var sinkToThreadSync = new ManualResetEvent(false);

            using (var master = new MasterTimeSource {
                Quantum = TimeInterval.FromTicks(10), AdvanceImmediately = true
            })
                using (var timeSlave = new SlaveTimeSource(null)
                {
                    Quantum = TimeInterval.FromTicks(10), AdvanceImmediately = true
                })
                {
                    var timeSink = new SimpleTimeSink(1.0, (sts, th, ti) =>
                    {
                        if (firstTime)
                        {
                            Assert.AreEqual(10, ti.Ticks);
                            firstTime    = false;
                            var timeUsed = TimeInterval.FromTicks(ti.Ticks / 2);
                            var timeLeft = ti - timeUsed;

                            sts.ElapsedVirtualTime += timeUsed;

                            th.ReportBackAndBreak(timeLeft);
                            sinkToThreadSync.Set();
                            threadToSinkSync.WaitOne();
                        }
                        else
                        {
                            Assert.AreEqual(5, ti.Ticks);
                            sts.ElapsedVirtualTime += ti;
                            th.ReportBackAndContinue(TimeInterval.Empty);
                        }

                        return(false);
                    });

                    // tester thread
                    new Thread(() =>
                    {
                        // wait for the pause
                        sinkToThreadSync.WaitOne();

                        // here we sleep to make sure that master won't go further
                        Thread.Sleep(5000);

                        Assert.AreEqual(5, master.ElapsedVirtualTime.Ticks);
                        Assert.AreEqual(5, timeSlave.ElapsedVirtualTime.Ticks);
                        indicator = true;

                        threadToSinkSync.Set();
                    }).Start();

                    master.RegisterSink(timeSlave);
                    timeSlave.RegisterSink(timeSink);

                    // just to pass the first syncpoint
                    master.Run(1);

                    master.Run(1);
                    Assert.IsTrue(indicator);

                    Assert.AreEqual(10, master.ElapsedVirtualTime.Ticks);
                    Assert.AreEqual(10, timeSlave.ElapsedVirtualTime.Ticks);
                    Assert.AreEqual(10, timeSink.ElapsedVirtualTime.Ticks);
                }
        }
Ejemplo n.º 18
0
 public void PauseAll()
 {
     MasterTimeSource.Stop();
     InnerPauseAll();
     IsStarted = false;
 }
Ejemplo n.º 19
0
 public void StartAll()
 {
     IsStarted = true;
     InnerStartAll();
     MasterTimeSource.Start();
 }