예제 #1
0
        public void ShouldExecuteDelayedActionAddedLaterInNearestSyncedState()
        {
            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 == 10)
                        {
                            timeSlave.ExecuteInNearestSyncedState(ts =>
                            {
                                time = ts.TimeElapsed;
                            });
                        }
                        return(true);
                    });

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

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

                    Assert.AreEqual(100, time.Ticks);
                }
        }
예제 #2
0
        public void ShouldSleep()
        {
            const int slavesCount = 5;
            const int roundsCount = 3;

            using (var timeSource = new MasterTimeSource()
            {
                Quantum = TimeInterval.FromMilliseconds(1000), AdvanceImmediately = false
            })
            {
                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);
            }
        }
예제 #3
0
        public void ShouldHandleMultipleSinks()
        {
            const int slavesCount = 5;
            const int roundsCount = 3;

            using (var masterTimeSource = new MasterTimeSource())
            {
                var timeSinks = new SimpleTimeSink[slavesCount];
                for (int i = 0; i < slavesCount; i++)
                {
                    timeSinks[i] = new SimpleTimeSink(double.MaxValue);
                    masterTimeSource.RegisterSink(timeSinks[i]);
                }

                // the first round does not increment the time - it just triggers a sync point
                masterTimeSource.Run(roundsCount + 1);
                Assert.AreEqual(roundsCount + 1, masterTimeSource.NumberOfSyncPoints);

                for (int i = 0; i < slavesCount; i++)
                {
                    Assert.AreEqual(roundsCount * masterTimeSource.Quantum.Ticks, timeSinks[i].ElapsedVirtualTime.Ticks);
                    Assert.AreEqual(roundsCount, timeSinks[i].NumberOfRounds);
                }
            }
        }
예제 #4
0
        public void ShouldHandleSlaveTimeSourceWithDifferentQuantum()
        {
            const int roundsCount = 3;

            using (var timeSource = new MasterTimeSource {
                Quantum = TimeInterval.FromTicks(100), AdvanceImmediately = true
            })
                using (var timeSlave = new SlaveTimeSource(null)
                {
                    Quantum = TimeInterval.FromTicks(10), 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(roundsCount + 1);

                    Assert.AreEqual(roundsCount + 1, timeSource.NumberOfSyncPoints);
                    Assert.AreEqual(10 * roundsCount + 1, timeSlave.NumberOfSyncPoints);
                    Assert.AreEqual(10 * roundsCount, timeSink.NumberOfRounds);

                    Assert.AreEqual(roundsCount * timeSource.Quantum.Ticks, timeSource.ElapsedVirtualTime.Ticks);
                    Assert.AreEqual(roundsCount * timeSource.Quantum.Ticks, timeSlave.ElapsedVirtualTime.Ticks);
                    Assert.AreEqual(roundsCount * timeSource.Quantum.Ticks, timeSink.ElapsedVirtualTime.Ticks);
                }
        }
예제 #5
0
        public void ShouldHandleSlaveTimeSourceWithNotAlignedQuantum()
        {
            using (var timeSource = new MasterTimeSource {
                Quantum = TimeInterval.FromTicks(10), AdvanceImmediately = true
            })
                using (var timeSlave = new SlaveTimeSource(null)
                {
                    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);
                }
        }
예제 #6
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);
                }
        }
예제 #7
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);
            }
        }
예제 #8
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);
            }
        }
예제 #9
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);
                }
        }
예제 #10
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);
                }
        }
예제 #11
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);
                }
        }