Beispiel #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);
                }
        }
Beispiel #2
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);
                }
        }
Beispiel #3
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);
                }
        }
Beispiel #4
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);
                }
        }
Beispiel #5
0
        public Machine()
        {
            LocalTimeSource             = new SlaveTimeSource(this);
            LocalTimeSource.TimePassed += HandleTimeProgress;

            collectionSync        = new object();
            pausingSync           = new object();
            disposedSync          = new object();
            clockSource           = new BaseClockSource();
            localNames            = new Dictionary <IPeripheral, string>();
            PeripheralsGroups     = new PeripheralsGroupsManager(this);
            ownLifes              = new HashSet <IHasOwnLife>();
            pausedState           = new PausedState(this);
            SystemBus             = new SystemBus(this);
            registeredPeripherals = new MultiTree <IPeripheral, IRegistrationPoint>(SystemBus);
            userStateHook         = delegate
            {
            };
            userState = string.Empty;
            SetLocalName(SystemBus, SystemBusName);
        }
Beispiel #6
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);
                }
        }
Beispiel #7
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);
                }
        }
Beispiel #8
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);
                    }
        }
Beispiel #9
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();
                        }
        }
Beispiel #10
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);
                }
        }