public void TakeDestroyReleaseWorkAsRemove() { SimpleElementsContainer <int> testInst = new SimpleElementsContainer <int>(); try { for (int i = 0; i < 10; i++) { testInst.Add(i, new PoolOperations(), true); } for (int i = 0; i < 10; i++) { var item = testInst.Take(); item.MarkElementDestroyed(); testInst.Release(item); Assert.IsTrue(item.IsRemoved); Assert.IsTrue(item.IsRemoved); Assert.AreEqual(10 - i - 1, testInst.AvailableCount); Assert.AreEqual(10 - i - 1, testInst.Count); } } finally { testInst.ProcessAllElements(o => o.MarkElementDestroyed()); } }
public void ComplexTest() { SimpleElementsContainer <int> testInst = new SimpleElementsContainer <int>(); try { for (int i = 0; i < 1; i++) { testInst.Add(i, new PoolOperations(), true); } TestContext.WriteLine("ComplexTest started"); RunComplexTest(testInst, Environment.ProcessorCount, 100000, 10); TestContext.WriteLine("ComplexTest phase 1 finished"); for (int i = testInst.Count; i < Environment.ProcessorCount; i++) { testInst.Add(i, new PoolOperations(), true); } RunComplexTest(testInst, Environment.ProcessorCount, 1000000, 10); TestContext.WriteLine("ComplexTest phase 2 finished"); for (int i = testInst.Count; i < 2 * Environment.ProcessorCount; i++) { testInst.Add(i, new PoolOperations(), true); } RunComplexTest(testInst, Environment.ProcessorCount, 1000000, 10); TestContext.WriteLine("ComplexTest phase 3 finished"); } finally { testInst.ProcessAllElements(o => o.MarkElementDestroyed()); } }
/// <summary> /// Attempts to create a new element and registers it in pool. /// Returns 'null' in case of failure. /// </summary> /// <param name="timeout">Creation timeout in milliseconds</param> /// <param name="token">Cancellation token</param> /// <returns>Created element in case of success, otherwise null</returns> private PoolElementWrapper <TElem> TryCreateNewElement(int timeout, CancellationToken token) { if (_disposeCancellation.IsCancellationRequested || token.IsCancellationRequested) { return(null); } if (Volatile.Read(ref _reservedCount) >= _maxElementCount) { return(null); } _usedElementTracker.Reset(); PoolElementWrapper <TElem> result = null; try { if (Interlocked.Increment(ref _reservedCount) > _maxElementCount) { return(null); } TElem element = default(TElem); if (CreateElement(out element, timeout, token)) { result = _elementsContainer.Add(element, this, false); result.SetPoolName(this.Name); } else { Profiling.Profiler.ObjectPoolElementFaulted(this.Name, this.ElementCount); } } finally { if (result == null) { Interlocked.Decrement(ref _reservedCount); } } if (result != null) { Profiling.Profiler.ObjectPoolElementCreated(this.Name, this.ElementCount); } return(result); }
/// <summary> /// Adds new element to the ObjectPool /// </summary> /// <param name="elem">New element</param> /// <exception cref="ObjectDisposedException">ObjectPool is in disposed state</exception> /// <exception cref="InvalidOperationException">Too many elements inside ObjectPool</exception> public void AddElement(TElem elem) { if (_disposeCancellation.IsCancellationRequested) { throw new ObjectDisposedException(this.GetType().Name); } if (this.ElementCount >= (1 << 16) - 2) { throw new InvalidOperationException("Max supported ElementCount is 65534"); } var addedElem = _elementsContainer.Add(elem, this, true); addedElem.SetPoolName(this.Name); Profiling.Profiler.ObjectPoolElementCreated(this.Name, this.ElementCount); }
private static void RunTestObjectPoolWithLListSimple(int threadCount, int elemCount, int opCount, int pauseSpin) { SimpleElementsContainer <PoolElem> pool = new SimpleElementsContainer <PoolElem>(); for (int i = 0; i < elemCount; i++) { pool.Add(new PoolElem(), new PoolElemOpSup(), true); } TestObjectPoolWithLListSimple(pool, threadCount, opCount, pauseSpin); PoolElementWrapper <PoolElem> tmp; while (pool.TryTake(out tmp, 0, new CancellationToken())) { tmp.MarkElementDestroyed(); pool.Release(tmp); } }
public void TestAddElementAndNotMakeAvailable() { SimpleElementsContainer <int> testInst = new SimpleElementsContainer <int>(); try { Assert.AreEqual(0, testInst.Count); Assert.AreEqual(0, testInst.AvailableCount); var wrapper = testInst.Add(100, new PoolOperations(), false); Assert.IsNotNull(wrapper); Assert.IsTrue(wrapper.IsBusy); Assert.AreEqual(100, wrapper.Element); Assert.AreEqual(1, testInst.Count); Assert.AreEqual(0, testInst.AvailableCount); } finally { testInst.ProcessAllElements(o => o.MarkElementDestroyed()); } }
public void TestRescanWorks() { SimpleElementsContainer <int> testInst = new SimpleElementsContainer <int>(); try { for (int i = 0; i < 10; i++) { testInst.Add(i, new PoolOperations(), true); } testInst.ProcessAllElements(o => o.MarkElementDestroyed()); testInst.RescanContainer(); Assert.AreEqual(0, testInst.Count); Assert.AreEqual(0, testInst.AvailableCount); } finally { testInst.ProcessAllElements(o => o.MarkElementDestroyed()); } }
public void TestTakeUntilEmpty() { SimpleElementsContainer <int> testInst = new SimpleElementsContainer <int>(); try { for (int i = 0; i < 10; i++) { testInst.Add(i, new PoolOperations(), true); } List <PoolElementWrapper <int> > takenElems = new List <PoolElementWrapper <int> >(); PoolElementWrapper <int> item; for (int i = 0; i < 10; i++) { bool takeRes = testInst.TryTake(out item, 0, new CancellationToken()); takenElems.Add(item); Assert.IsTrue(takeRes); Assert.IsNotNull(item); Assert.IsTrue(item.IsBusy); } Assert.AreEqual(0, testInst.AvailableCount); bool takeResO = testInst.TryTake(out item, 0, new CancellationToken()); Assert.IsFalse(takeResO); for (int i = 0; i < takenElems.Count; i++) { testInst.Release(takenElems[i]); } } finally { testInst.ProcessAllElements(o => o.MarkElementDestroyed()); } }
public void TestSimpleTakeRelease() { SimpleElementsContainer <int> testInst = new SimpleElementsContainer <int>(); try { for (int i = 0; i < 10; i++) { testInst.Add(i, new PoolOperations(), true); } Assert.AreEqual(10, testInst.Count); Assert.AreEqual(10, testInst.AvailableCount); var item = testInst.Take(); Assert.IsNotNull(item); Assert.IsTrue(item.Element >= 0 && item.Element < 10); Assert.IsTrue(item.IsBusy); Assert.IsFalse(item.IsElementDestroyed); Assert.AreEqual(10, testInst.Count); Assert.AreEqual(9, testInst.AvailableCount); testInst.Release(item); Assert.IsFalse(item.IsBusy); Assert.AreEqual(10, testInst.Count); Assert.AreEqual(10, testInst.AvailableCount); } finally { testInst.ProcessAllElements(o => o.MarkElementDestroyed()); } }
public void TestRemoveOnTake() { SimpleElementsContainer <int> testInst = new SimpleElementsContainer <int>(); try { for (int i = 0; i < 10; i++) { testInst.Add(i, new PoolOperations(), true); } testInst.ProcessAllElements(o => o.MarkElementDestroyed()); PoolElementWrapper <int> item; bool takeResult = testInst.TryTake(out item, 0, new CancellationToken()); Assert.IsFalse(takeResult); Assert.AreEqual(0, testInst.Count); } finally { testInst.ProcessAllElements(o => o.MarkElementDestroyed()); } }