Ejemplo n.º 1
0
        public void TestProducerConsumer()
        {
            const int      NumIters = 500;
            SemaphoreLight inst     = new SemaphoreLight(0);

            var task1 = Task.Factory.StartNew(() =>
            {
                for (int i = 0; i < NumIters; i++)
                {
                    Assert.IsTrue(inst.Wait(30000));
                }
                Assert.IsFalse(inst.Wait(0));
            }, TaskCreationOptions.LongRunning);

            var task2 = Task.Factory.StartNew(() =>
            {
                for (int i = 0; i < NumIters; i++)
                {
                    inst.Release();
                }
            }, TaskCreationOptions.LongRunning);


            Task.WaitAll(task1, task2);
        }
Ejemplo n.º 2
0
        public void TestCancellation()
        {
            SemaphoreLight          inst     = new SemaphoreLight(0);
            CancellationTokenSource tokenSrc = new CancellationTokenSource();
            bool cancelled = false;

            Task.Run(() =>
            {
                try
                {
                    inst.Wait(tokenSrc.Token);
                }
                catch (OperationCanceledException)
                {
                    Volatile.Write(ref cancelled, true);
                    Thread.MemoryBarrier();
                }
            });

            TimingAssert.IsTrue(5000, () => inst.WaiterCount > 0);
            Assert.IsFalse(Volatile.Read(ref cancelled));

            tokenSrc.Cancel();
            TimingAssert.IsTrue(5000, () => Volatile.Read(ref cancelled));

            Assert.AreEqual(0, inst.CurrentCount);
            Assert.AreEqual(0, inst.WaiterCount);
        }
Ejemplo n.º 3
0
        private void Arrange()
        {
            var random = new Random();

            _localChannelNumber           = (uint)random.Next(0, int.MaxValue);
            _localWindowSize              = (uint)random.Next(0, int.MaxValue);
            _localPacketSize              = (uint)random.Next(0, int.MaxValue);
            _remoteChannelNumber          = (uint)random.Next(0, int.MaxValue);
            _remoteWindowSize             = (uint)random.Next(0, int.MaxValue);
            _remotePacketSize             = (uint)random.Next(0, int.MaxValue);
            _channelClosedRegister        = new List <ChannelEventArgs>();
            _channelExceptionRegister     = new List <ExceptionEventArgs>();
            _initialSessionSemaphoreCount = random.Next(10, 20);
            _sessionSemaphore             = new SemaphoreLight(_initialSessionSemaphoreCount);

            _sessionMock        = new Mock <ISession>(MockBehavior.Strict);
            _connectionInfoMock = new Mock <IConnectionInfo>(MockBehavior.Strict);

            _sequence = new MockSequence();
            _sessionMock.InSequence(_sequence).Setup(p => p.ConnectionInfo).Returns(_connectionInfoMock.Object);
            _connectionInfoMock.InSequence(_sequence).Setup(p => p.RetryAttempts).Returns(1);
            _sessionMock.Setup(p => p.SessionSemaphore).Returns(_sessionSemaphore);
            _sessionMock.InSequence(_sequence)
            .Setup(
                p =>
                p.SendMessage(
                    It.Is <ChannelOpenMessage>(
                        m =>
                        m.LocalChannelNumber == _localChannelNumber &&
                        m.InitialWindowSize == _localWindowSize && m.MaximumPacketSize == _localPacketSize &&
                        m.Info is SessionChannelOpenInfo)));
            _sessionMock.InSequence(_sequence)
            .Setup(p => p.WaitOnHandle(It.IsNotNull <WaitHandle>()))
            .Callback <WaitHandle>(
                w =>
            {
                _sessionMock.Raise(
                    s => s.ChannelOpenConfirmationReceived += null,
                    new MessageEventArgs <ChannelOpenConfirmationMessage>(
                        new ChannelOpenConfirmationMessage(
                            _localChannelNumber,
                            _remoteWindowSize,
                            _remotePacketSize,
                            _remoteChannelNumber)));
                w.WaitOne();
            });
            _sessionMock.InSequence(_sequence).Setup(p => p.IsConnected).Returns(true);
            _sessionMock.InSequence(_sequence)
            .Setup(
                p => p.TrySendMessage(It.Is <ChannelCloseMessage>(c => c.LocalChannelNumber == _remoteChannelNumber)))
            .Returns(true);
            _sessionMock.InSequence(_sequence)
            .Setup(s => s.WaitOnHandle(It.IsNotNull <EventWaitHandle>()))
            .Callback <WaitHandle>(w => w.WaitOne());

            _channel            = new ChannelSession(_sessionMock.Object, _localChannelNumber, _localWindowSize, _localPacketSize);
            _channel.Closed    += (sender, args) => _channelClosedRegister.Add(args);
            _channel.Exception += (sender, args) => _channelExceptionRegister.Add(args);
            _channel.Open();
        }
Ejemplo n.º 4
0
        public void SemaphoreLightConstructorTest()
        {
            int            initialCount = 0; // TODO: Initialize to an appropriate value
            SemaphoreLight target       = new SemaphoreLight(initialCount);

            Assert.Inconclusive("TODO: Implement code to verify target");
        }
Ejemplo n.º 5
0
        public void TestTimeoutWork()
        {
            SemaphoreLight inst = new SemaphoreLight(0);

            Assert.IsFalse(inst.Wait(1000));
            Assert.AreEqual(0, inst.CurrentCount);
        }
        public void CurrentCountTest()
        {
            var initialCount = new Random().Next(1, 20);
            var target       = new SemaphoreLight(initialCount);

            Assert.AreEqual(initialCount, target.CurrentCount);
        }
        public void WaitTest()
        {
            const int sleepTime    = 200;
            const int initialCount = 2;
            var       target       = new SemaphoreLight(initialCount);

            var start = DateTime.Now;

            target.Wait();
            target.Wait();

            Assert.IsTrue((DateTime.Now - start).TotalMilliseconds < 50);

            var releaseThread = new Thread(
                () =>
            {
                Thread.Sleep(sleepTime);
                target.Release();
            });

            releaseThread.Start();

            target.Wait();

            var end     = DateTime.Now;
            var elapsed = end - start;

            Assert.IsTrue(elapsed.TotalMilliseconds > 200);
            Assert.IsTrue(elapsed.TotalMilliseconds < 250);
        }
Ejemplo n.º 8
0
        public void WaitTest()
        {
            int            initialCount = 0;                                // TODO: Initialize to an appropriate value
            SemaphoreLight target       = new SemaphoreLight(initialCount); // TODO: Initialize to an appropriate value

            target.Wait();
            Assert.Inconclusive("A method that does not return a value cannot be verified.");
        }
        /// <summary>
        /// Конструктор PrioritizedElementsContainer
        /// </summary>
        /// <param name="comparer">Объект для сравнения элементов</param>
        public PrioritizedElementsContainer(PoolElementComparer <T> comparer)
        {
            Contract.Requires <ArgumentNullException>(comparer != null);

            _allElements      = new SparceArrayStorage <PoolElementWrapper <T> >(true);
            _comparer         = comparer;
            _occupiedElements = new SemaphoreLight(0);
            _syncObject       = new object();
        }
Ejemplo n.º 10
0
        public void CurrentCountTest()
        {
            int            initialCount = 0;                                // TODO: Initialize to an appropriate value
            SemaphoreLight target       = new SemaphoreLight(initialCount); // TODO: Initialize to an appropriate value
            int            actual;

            actual = target.CurrentCount;
            Assert.Inconclusive("Verify the correctness of this test method.");
        }
        private void Arrange()
        {
            var random = new Random();

            _localChannelNumber           = (uint)random.Next(0, int.MaxValue);
            _localWindowSize              = (uint)random.Next(2000, 3000);
            _localPacketSize              = (uint)random.Next(1000, 2000);
            _initialSessionSemaphoreCount = random.Next(10, 20);
            _sessionSemaphore             = new SemaphoreLight(_initialSessionSemaphoreCount);
            _channelClosedRegister        = new List <ChannelEventArgs>();
            _channelExceptionRegister     = new List <ExceptionEventArgs>();
            _actualException              = null;

            _failureReasonCode  = (uint)random.Next(0, int.MaxValue);
            _failureDescription = random.Next().ToString(CultureInfo.InvariantCulture);
            _failureLanguage    = random.Next().ToString(CultureInfo.InvariantCulture);

            _sessionMock        = new Mock <ISession>(MockBehavior.Strict);
            _connectionInfoMock = new Mock <IConnectionInfo>(MockBehavior.Strict);

            var sequence = new MockSequence();

            _sessionMock.InSequence(sequence).Setup(p => p.ConnectionInfo).Returns(_connectionInfoMock.Object);
            _connectionInfoMock.InSequence(sequence).Setup(p => p.RetryAttempts).Returns(1);
            _sessionMock.Setup(p => p.SessionSemaphore).Returns(_sessionSemaphore);
            _sessionMock.InSequence(sequence)
            .Setup(
                p =>
                p.SendMessage(
                    It.Is <ChannelOpenMessage>(
                        m =>
                        m.LocalChannelNumber == _localChannelNumber &&
                        m.InitialWindowSize == _localWindowSize && m.MaximumPacketSize == _localPacketSize &&
                        m.Info is SessionChannelOpenInfo)));
            _sessionMock.InSequence(sequence)
            .Setup(p => p.WaitOnHandle(It.IsNotNull <WaitHandle>()))
            .Callback <WaitHandle>(
                w =>
            {
                _sessionMock.Raise(
                    s => s.ChannelOpenFailureReceived += null,
                    new MessageEventArgs <ChannelOpenFailureMessage>(
                        new ChannelOpenFailureMessage(
                            _localChannelNumber,
                            _failureDescription,
                            _failureReasonCode,
                            _failureLanguage
                            )));
                w.WaitOne();
            });
            _sessionMock.InSequence(sequence).Setup(p => p.ConnectionInfo).Returns(_connectionInfoMock.Object);
            _connectionInfoMock.InSequence(sequence).Setup(p => p.RetryAttempts).Returns(1);

            _channel            = new ChannelSession(_sessionMock.Object, _localChannelNumber, _localWindowSize, _localPacketSize);
            _channel.Closed    += (sender, args) => _channelClosedRegister.Add(args);
            _channel.Exception += (sender, args) => _channelExceptionRegister.Add(args);
        }
        public void Release()
        {
            var initialCount = new Random().Next(1, 10);
            var target       = new SemaphoreLight(initialCount);

            Assert.AreEqual(initialCount, target.Release());
            Assert.AreEqual(initialCount + 1, target.CurrentCount);

            Assert.AreEqual(initialCount + 1, target.Release());
            Assert.AreEqual(initialCount + 2, target.CurrentCount);
        }
Ejemplo n.º 13
0
        public void ComplexTest()
        {
            SemaphoreLight sem = new SemaphoreLight(0);

            for (int i = 0; i < 5; i++)
            {
                RunComplexTest(sem, 5000000, Math.Max(1, Environment.ProcessorCount / 2));
                Assert.AreEqual(0, sem.CurrentCount);
                TestContext.WriteLine("=========== One pass ===========");
            }
        }
Ejemplo n.º 14
0
        public void ReleaseTest()
        {
            int            initialCount = 0;                                // TODO: Initialize to an appropriate value
            SemaphoreLight target       = new SemaphoreLight(initialCount); // TODO: Initialize to an appropriate value
            int            expected     = 0;                                // TODO: Initialize to an appropriate value
            int            actual;

            actual = target.Release();
            Assert.AreEqual(expected, actual);
            Assert.Inconclusive("Verify the correctness of this test method.");
        }
Ejemplo n.º 15
0
        public void TestReleaseWait()
        {
            SemaphoreLight inst = new SemaphoreLight(0);

            Assert.AreEqual(0, inst.CurrentCount);

            inst.Release();
            Assert.AreEqual(1, inst.CurrentCount);

            Assert.IsTrue(inst.Wait(0));
            Assert.AreEqual(0, inst.CurrentCount);
        }
        /// <summary>
        /// Конструктор PrioritizedElementsContainer
        /// </summary>
        /// <param name="comparer">Объект для сравнения элементов</param>
        public PrioritizedElementsContainer(PoolElementComparer <T> comparer)
        {
            if (comparer == null)
            {
                throw new ArgumentNullException(nameof(comparer));
            }

            _allElements      = new SparceArrayStorage <PoolElementWrapper <T> >(true);
            _comparer         = comparer;
            _occupiedElements = new SemaphoreLight(0);
            _syncObject       = new object();
        }
        protected override void SetupData()
        {
            var random = new Random();

            _localChannelNumber           = (uint)random.Next(0, int.MaxValue);
            _localWindowSize              = (uint)random.Next(2000, 3000);
            _localPacketSize              = (uint)random.Next(1000, 2000);
            _initialSessionSemaphoreCount = random.Next(10, 20);
            _sessionSemaphore             = new SemaphoreLight(_initialSessionSemaphoreCount);
            _channelClosedRegister        = new List <ChannelEventArgs>();
            _channelExceptionRegister     = new List <ExceptionEventArgs>();
            _waitOnConfirmationException  = new SystemException();
        }
Ejemplo n.º 18
0
        /// <summary>
        /// Конструктор ThreadPoolQueue
        /// </summary>
        /// <param name="boundedCapacity">Ограничение размера</param>
        public ThreadPoolGlobalQueue(int boundedCapacity)
        {
            _boundedCapacity         = boundedCapacity > 0 ? boundedCapacity : -1;
            _extendedCapacityRequest = 0;
            _mainQueue       = new ThreadPoolConcurrentQueue();
            _safeDisposeLock = new object();

            _freeNodes = null;
            if (boundedCapacity > 0)
            {
                _freeNodes = new SemaphoreLight(boundedCapacity);
            }
            _occupiedNodes = new SemaphoreLight(0);
        }
        protected override void SetupData()
        {
            var random = new Random();

            _localChannelNumber       = (uint)random.Next(0, int.MaxValue);
            _localWindowSize          = (uint)random.Next(2000, 3000);
            _localPacketSize          = (uint)random.Next(1000, 2000);
            _remoteChannelNumber      = (uint)random.Next(0, int.MaxValue);
            _remoteWindowSize         = (uint)random.Next(0, int.MaxValue);
            _remotePacketSize         = (uint)random.Next(100, 200);
            _channelCloseTimeout      = TimeSpan.FromSeconds(random.Next(10, 20));
            _sessionSemaphore         = new SemaphoreLight(1);
            _channelClosedRegister    = new List <ChannelEventArgs>();
            _channelExceptionRegister = new List <ExceptionEventArgs>();
        }
        public void Release_ReleaseCount()
        {
            var initialCount = new Random().Next(1, 10);
            var target       = new SemaphoreLight(initialCount);

            var releaseCount1 = new Random().Next(1, 10);

            Assert.AreEqual(initialCount, target.Release(releaseCount1));
            Assert.AreEqual(initialCount + releaseCount1, target.CurrentCount);

            var releaseCount2 = new Random().Next(1, 10);

            Assert.AreEqual(initialCount + releaseCount1, target.Release(releaseCount2));
            Assert.AreEqual(initialCount + releaseCount1 + releaseCount2, target.CurrentCount);
        }
Ejemplo n.º 21
0
        /// <summary>
        /// Initializes a new <see cref="SftpFileReader"/> instance with the specified handle,
        /// <see cref="ISftpSession"/> and the maximum number of pending reads.
        /// </summary>
        /// <param name="handle"></param>
        /// <param name="sftpSession"></param>
        /// <param name="chunkSize">The size of a individual read-ahead chunk.</param>
        /// <param name="maxPendingReads">The maximum number of pending reads.</param>
        /// <param name="fileSize">The size of the file, if known; otherwise, <c>null</c>.</param>
        public SftpFileReader(byte[] handle, ISftpSession sftpSession, uint chunkSize, int maxPendingReads, long?fileSize)
        {
            _handle              = handle;
            _sftpSession         = sftpSession;
            _chunkSize           = chunkSize;
            _fileSize            = fileSize;
            _semaphore           = new SemaphoreLight(maxPendingReads);
            _queue               = new Dictionary <int, BufferedRead>(maxPendingReads);
            _readLock            = new object();
            _readAheadCompleted  = new ManualResetEvent(false);
            _disposingWaitHandle = new ManualResetEvent(false);
            _waitHandles         = _sftpSession.CreateWaitHandleArray(_disposingWaitHandle, _semaphore.AvailableWaitHandle);

            StartReadAhead();
        }
        protected override void SetupData()
        {
            var random = new Random();

            _localChannelNumber           = (uint)random.Next(0, int.MaxValue);
            _localWindowSize              = (uint)random.Next(2000, 3000);
            _localPacketSize              = (uint)random.Next(1000, 2000);
            _initialSessionSemaphoreCount = random.Next(10, 20);
            _sessionSemaphore             = new SemaphoreLight(_initialSessionSemaphoreCount);
            _channelClosedRegister        = new List <ChannelEventArgs>();
            _channelExceptionRegister     = new List <ExceptionEventArgs>();
            _actualException              = null;

            _failureReasonCode  = (uint)random.Next(0, int.MaxValue);
            _failureDescription = random.Next().ToString(CultureInfo.InvariantCulture);
            _failureLanguage    = random.Next().ToString(CultureInfo.InvariantCulture);
        }
Ejemplo n.º 23
0
        public void TestManyReleaseWait()
        {
            SemaphoreLight inst = new SemaphoreLight(0);

            for (int i = 0; i < 100; i++)
            {
                Assert.AreEqual(i, inst.CurrentCount);
                inst.Release();
            }

            for (int i = 100; i > 0; i--)
            {
                Assert.AreEqual(i, inst.CurrentCount);
                Assert.IsTrue(inst.Wait(10));
            }

            Assert.AreEqual(0, inst.CurrentCount);
        }
Ejemplo n.º 24
0
        public void TestWakeUpOnRelease()
        {
            SemaphoreLight inst   = new SemaphoreLight(0);
            bool           wakeUp = false;

            Task.Run(() =>
            {
                inst.Wait();
                wakeUp = true;
            });

            TimingAssert.IsTrue(5000, () => inst.WaiterCount > 0);
            Assert.IsFalse(wakeUp);

            inst.Release();
            TimingAssert.IsTrue(5000, () => Volatile.Read(ref wakeUp));

            Assert.AreEqual(0, inst.CurrentCount);
            Assert.AreEqual(0, inst.WaiterCount);
        }
Ejemplo n.º 25
0
        /// <summary>
        /// <see cref="BlockingBatchingQueue{T}"/> constructor
        /// </summary>
        /// <param name="batchSize">Size of the batch</param>
        /// <param name="boundedCapacityInBatches">Maximum number of batches in queue (if less or equal to 0 then no limitation)</param>
        public BlockingBatchingQueue(int batchSize, int boundedCapacityInBatches)
        {
            if (batchSize <= 0)
            {
                throw new ArgumentOutOfRangeException(nameof(batchSize), $"'{nameof(batchSize)}' should be positive");
            }
            if (boundedCapacityInBatches > 0 && ((long)boundedCapacityInBatches * batchSize) > int.MaxValue)
            {
                throw new ArgumentOutOfRangeException(nameof(boundedCapacityInBatches), $"Max capacity value is depends on '{nameof(batchSize)}' value and equal to {int.MaxValue / batchSize}");
            }

            _innerQueue = new ConcurrentBatchingQueue <T>(batchSize);
            _boundedCapacityInBatches = boundedCapacityInBatches >= 0 ? boundedCapacityInBatches : -1;

            if (boundedCapacityInBatches > 0)
            {
                _freeNodes = new SemaphoreLight(boundedCapacityInBatches * batchSize);
            }
            _occupiedBatches = new SemaphoreLight(0);

            _isDisposed = false;
        }
Ejemplo n.º 26
0
        private void Arrange()
        {
            var random = new Random();

            _localChannelNumber           = (uint)random.Next(0, int.MaxValue);
            _localWindowSize              = (uint)random.Next(2000, 3000);
            _localPacketSize              = (uint)random.Next(1000, 2000);
            _initialSessionSemaphoreCount = random.Next(10, 20);
            _sessionSemaphore             = new SemaphoreLight(_initialSessionSemaphoreCount);
            _channelClosedRegister        = new List <ChannelEventArgs>();
            _channelExceptionRegister     = new List <ExceptionEventArgs>();
            _waitOnConfirmationException  = new SystemException();

            _sessionMock        = new Mock <ISession>(MockBehavior.Strict);
            _connectionInfoMock = new Mock <IConnectionInfo>(MockBehavior.Strict);

            var sequence = new MockSequence();

            _sessionMock.InSequence(sequence).Setup(p => p.ConnectionInfo).Returns(_connectionInfoMock.Object);
            _connectionInfoMock.InSequence(sequence).Setup(p => p.RetryAttempts).Returns(2);
            _sessionMock.Setup(p => p.SessionSemaphore).Returns(_sessionSemaphore);
            _sessionMock.InSequence(sequence)
            .Setup(
                p =>
                p.SendMessage(
                    It.Is <ChannelOpenMessage>(
                        m =>
                        m.LocalChannelNumber == _localChannelNumber &&
                        m.InitialWindowSize == _localWindowSize && m.MaximumPacketSize == _localPacketSize &&
                        m.Info is SessionChannelOpenInfo)));
            _sessionMock.InSequence(sequence)
            .Setup(p => p.WaitOnHandle(It.IsNotNull <WaitHandle>()))
            .Throws(_waitOnConfirmationException);

            _channel            = new ChannelSession(_sessionMock.Object, _localChannelNumber, _localWindowSize, _localPacketSize);
            _channel.Closed    += (sender, args) => _channelClosedRegister.Add(args);
            _channel.Exception += (sender, args) => _channelExceptionRegister.Add(args);
        }
Ejemplo n.º 27
0
        public void OverflowTest()
        {
            SemaphoreLight inst = new SemaphoreLight(0);

            inst.Release(int.MaxValue - 100);
            Assert.AreEqual(int.MaxValue - 100, inst.CurrentCount);

            inst.Release(100);
            Assert.AreEqual(int.MaxValue, inst.CurrentCount);

            try
            {
                inst.Release();
                Assert.Fail("SemaphoreFullException expected");
            }
            catch (SemaphoreFullException)
            {
            }

            bool waitResult = inst.Wait(0);

            Assert.IsTrue(waitResult);
        }
Ejemplo n.º 28
0
 /// <summary>
 /// Конструктор SimpleElementsContainer
 /// </summary>
 public SimpleElementsContainer()
 {
     _allElements        = new SparceArrayStorage <PoolElementWrapper <T> >(false);
     _globalFreeElements = new BunchElementStorage <T>(_allElements);
     _occupiedElements   = new SemaphoreLight(0);
 }
Ejemplo n.º 29
0
        private static TimeSpan TestSemaphoreLight(string name, int elemCount, int addThCount, int takeThCount, int addSpin, int takeSpin)
        {
            SemaphoreLight sem = new SemaphoreLight(0, int.MaxValue);

            CancellationTokenSource srcCancel = new CancellationTokenSource();

            Thread[] addThreads  = new Thread[addThCount];
            Thread[] takeThreads = new Thread[takeThCount];

            int addedElemCount = 0;

            Barrier barierStart  = new Barrier(1 + addThreads.Length + takeThreads.Length);
            Barrier barierAdders = new Barrier(1 + addThreads.Length);
            Barrier barierTakers = new Barrier(1 + takeThreads.Length);

            Action addAction = () =>
            {
                barierStart.SignalAndWait();

                int index = 0;
                while ((index = Interlocked.Increment(ref addedElemCount)) <= elemCount)
                {
                    sem.Release();
                    SpinWaitHelper.SpinWait(addSpin);
                }

                barierAdders.SignalAndWait();
            };


            Action takeAction = () =>
            {
                CancellationToken myToken = srcCancel.Token;

                barierStart.SignalAndWait();

                try
                {
                    while (!srcCancel.IsCancellationRequested)
                    {
                        sem.Wait(myToken);
                        SpinWaitHelper.SpinWait(takeSpin);
                    }
                }
                catch (OperationCanceledException)
                {
                }

                while (sem.Wait(0))
                {
                }

                barierTakers.SignalAndWait();
            };

            for (int i = 0; i < addThreads.Length; i++)
            {
                addThreads[i] = new Thread(new ThreadStart(addAction));
            }
            for (int i = 0; i < takeThreads.Length; i++)
            {
                takeThreads[i] = new Thread(new ThreadStart(takeAction));
            }


            for (int i = 0; i < takeThreads.Length; i++)
            {
                takeThreads[i].Start();
            }
            for (int i = 0; i < addThreads.Length; i++)
            {
                addThreads[i].Start();
            }

            barierStart.SignalAndWait();

            Stopwatch sw = Stopwatch.StartNew();

            barierAdders.SignalAndWait();
            srcCancel.Cancel();
            barierTakers.SignalAndWait();
            sw.Stop();

            for (int i = 0; i < addThreads.Length; i++)
            {
                addThreads[i].Join();
            }
            for (int i = 0; i < takeThreads.Length; i++)
            {
                takeThreads[i].Join();
            }

            Console.WriteLine(name + ". SemaphoreLight. Time = " + sw.ElapsedMilliseconds.ToString() + "ms");
            return(sw.Elapsed);
        }
Ejemplo n.º 30
0
        private void RunComplexTest(SemaphoreLight sem, int elemCount, int thCount)
        {
            int atomicRandom = 0;

            int trackElemCount   = elemCount;
            int waitedTimesCount = 0;
            int addFinished      = 0;

            Thread[] threadsTake = new Thread[thCount];
            Thread[] threadsAdd  = new Thread[thCount];

            CancellationTokenSource tokSrc = new CancellationTokenSource();

            Action addAction = () =>
            {
                Random rnd = new Random(Environment.TickCount + Interlocked.Increment(ref atomicRandom) * thCount * 2);

                while (true)
                {
                    int item = Interlocked.Decrement(ref trackElemCount);
                    if (item < 0)
                    {
                        break;
                    }

                    sem.Release();

                    int sleepTime = rnd.Next(100);
                    if (sleepTime > 0)
                    {
                        Thread.SpinWait(sleepTime);
                    }
                }

                Interlocked.Increment(ref addFinished);
            };


            Action takeAction = () =>
            {
                Random rnd = new Random(Environment.TickCount + Interlocked.Increment(ref atomicRandom) * thCount * 2);

                try
                {
                    while (Volatile.Read(ref addFinished) < thCount)
                    {
                        sem.Wait(tokSrc.Token);
                        Interlocked.Increment(ref waitedTimesCount);

                        int sleepTime = rnd.Next(100);
                        if (sleepTime > 0)
                        {
                            Thread.SpinWait(sleepTime);
                        }
                    }
                }
                catch (OperationCanceledException) { }

                TestContext.WriteLine("One take thread exit main cycle");

                while (sem.Wait(0))
                {
                    Interlocked.Increment(ref waitedTimesCount);
                }
            };


            for (int i = 0; i < threadsTake.Length; i++)
            {
                threadsTake[i] = new Thread(new ThreadStart(takeAction));
            }
            for (int i = 0; i < threadsAdd.Length; i++)
            {
                threadsAdd[i] = new Thread(new ThreadStart(addAction));
            }


            for (int i = 0; i < threadsTake.Length; i++)
            {
                threadsTake[i].Start();
            }
            for (int i = 0; i < threadsAdd.Length; i++)
            {
                threadsAdd[i].Start();
            }

            TestContext.WriteLine("All threads started");

            for (int i = 0; i < threadsAdd.Length; i++)
            {
                threadsAdd[i].Join();
            }

            TestContext.WriteLine("All add threads stopped");

            tokSrc.Cancel();

            TestContext.WriteLine("Cancell called");

            for (int i = 0; i < threadsTake.Length; i++)
            {
                threadsTake[i].Join();
            }

            TestContext.WriteLine("All take threads stopped");


            Assert.AreEqual(elemCount, waitedTimesCount);
        }