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); }
/// <summary> /// Форсировать добавление элемента в главную очередь (игнорирует ограничения по размеру) /// </summary> /// <param name="item">Элемент</param> public void ForceAdd(ThreadPoolWorkItem item) { Contract.Requires(item != null); _mainQueue.Add(item); if (_freeNodes != null) { UpdateExtendedCapacityRequestField(1); } _occupiedNodes.Release(); }
/// <summary> /// Основной код возвращения элемента в множество свободных /// </summary> /// <param name="element">Элемент</param> private void ReleaseCore(PoolElementWrapper <T> element) { Contract.Requires(element != null); try { } finally { element.MakeAvailableAtomic(); _occupiedElements.Release(); } }
/// <summary> /// Основной код возвращения элемента в множество свободных /// </summary> /// <param name="element">Элемент</param> private void ReleaseCore(PoolElementWrapper <T> element) { TurboContract.Requires(element != null, conditionString: "element != null"); try { } finally { element.MakeAvailableAtomic(); _occupiedElements.Release(); } }
/// <summary> /// Запросить временное расширение вместимости /// </summary> /// <param name="extensionVal">Величиная расширения</param> public void RequestCapacityExtension(int extensionVal) { Contract.Requires <ArgumentException>(extensionVal >= 0); if (_freeNodes == null || extensionVal == 0) { return; } _freeNodes.Release(extensionVal); UpdateExtendedCapacityRequestField(extensionVal); }
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); }
/// <summary> /// Запросить временное расширение вместимости /// </summary> /// <param name="extensionVal">Величиная расширения</param> public void RequestCapacityExtension(int extensionVal) { if (extensionVal < 0) { throw new ArgumentOutOfRangeException(nameof(extensionVal), "extensionVal should be greater or equal to 0"); } if (_freeNodes == null || extensionVal == 0) { return; } _freeNodes.Release(extensionVal); UpdateExtendedCapacityRequestField(extensionVal); }
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); }
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); }
public void PutObject(T item) { _objects.Push(item); _sem.Release(); //_objects.Enqueue(item); //_objects.Add(item); }
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."); }
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> /// Adds new item to the tail of the queue (inner core method) /// </summary> /// <param name="item">New item</param> /// <param name="timeout">Adding timeout</param> /// <param name="token">Cancellation token</param> /// <returns>Was added sucessufully</returns> /// <exception cref="OperationCanceledException">Cancellation was requested by token</exception> /// <exception cref="ObjectDisposedException">Queue was disposed</exception> private bool TryAddInner(T item, int timeout, CancellationToken token) { if (_isDisposed) { throw new ObjectDisposedException(this.GetType().Name); } if (token.IsCancellationRequested) { throw new OperationCanceledException(token); } bool elementAdded = false; int batchCountIncreased = 0; bool entered = false; try { if (_freeNodes == null || _freeNodes.Wait(timeout, token)) { entered = true; _innerQueue.Enqueue(item, out batchCountIncreased); elementAdded = true; } } finally { if (!elementAdded && entered && _freeNodes != null) { _freeNodes.Release(); } if (elementAdded && batchCountIncreased > 0) { _occupiedBatches.Release(batchCountIncreased); } } return(elementAdded); }
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); }
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); }
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); }
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); }
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); }