public void ComplexTest() { using (BalancingStaticPoolManager <int> testInst = new BalancingStaticPoolManager <int>()) { for (int i = testInst.ElementCount; i < 1; i++) { testInst.AddElement(i); } RunComplexTest(testInst, 1, 100000, 10, false); for (int i = testInst.ElementCount; i < Environment.ProcessorCount; i++) { testInst.AddElement(i); } RunComplexTest(testInst, Environment.ProcessorCount, 1000000, 10, false); for (int i = testInst.ElementCount; i < 2 * Environment.ProcessorCount; i++) { testInst.AddElement(i); } RunComplexTest(testInst, Environment.ProcessorCount, 1000000, 10, false); RunComplexTest(testInst, 1, 100000, 10, true); RunComplexTest(testInst, Environment.ProcessorCount, 2000000, 10, true); RunComplexTest(testInst, Environment.ProcessorCount, 1000000, 100, true); } }
private void RunComplexTest(BalancingStaticPoolManager <int> testInst, int threadCount, int opCount, int pauseSpin, bool autoAddRemove) { Thread[] threads = new Thread[threadCount]; Barrier startBar = new Barrier(threadCount + 1); int opCountPerThread = opCount / threadCount; Action thAct = () => { Random localRand = new Random(Thread.CurrentThread.ManagedThreadId + Environment.TickCount); int pasueDiff = pauseSpin / 4; startBar.SignalAndWait(); int execOp = 0; while (execOp++ < opCountPerThread) { if (autoAddRemove && (testInst.ElementCount == 0 || localRand.Next(5) == 0)) { testInst.AddElement(execOp); } using (var el = testInst.Rent()) { if (autoAddRemove && testInst.ElementCount > 1 && localRand.Next(5) == 0) { testInst.RemoveElement(el); } int spinCount = localRand.Next(pauseSpin - pasueDiff, pauseSpin + pasueDiff); Thread.SpinWait(spinCount); } } if (autoAddRemove) { testInst.AddElement(execOp); } }; for (int i = 0; i < threads.Length; i++) { threads[i] = new Thread(new ThreadStart(thAct)); } for (int i = 0; i < threads.Length; i++) { threads[i].Start(); } startBar.SignalAndWait(); for (int i = 0; i < threads.Length; i++) { threads[i].Join(); } Assert.AreEqual(testInst.ElementCount, testInst.FreeElementCount); }
public void TestElementDestroyedAfterDispose() { RentedElementMonitor <int> elementMonitor = default(RentedElementMonitor <int>); Turbo.ObjectPools.Common.PoolElementWrapper <int> elemWrapper = null; try { using (BalancingStaticPoolManager <int> testInst = new BalancingStaticPoolManager <int>()) { testInst.AddElement(1); elementMonitor = testInst.Rent(); elemWrapper = elementMonitor.ElementWrapper; } Assert.IsTrue(elementMonitor.IsValid); Assert.IsFalse(elemWrapper.IsElementDestroyed); } finally { if (!object.ReferenceEquals(elementMonitor, null)) { elementMonitor.Dispose(); } } Assert.IsTrue(elemWrapper.IsElementDestroyed); }
public void TestSimpleRentRelease() { using (BalancingStaticPoolManager <int> testInst = new BalancingStaticPoolManager <int>()) { Assert.AreEqual(0, testInst.ElementCount); Assert.AreEqual(0, testInst.FreeElementCount); for (int i = 0; i < 10; i++) { testInst.AddElement(i); } Assert.AreEqual(10, testInst.ElementCount); Assert.AreEqual(10, testInst.FreeElementCount); for (int i = 0; i < 1000; i++) { using (var el = testInst.Rent()) { Assert.AreEqual(9, testInst.FreeElementCount); Assert.IsTrue(el.IsValid); } } Assert.AreEqual(10, testInst.FreeElementCount); } }
public void TestRemoveElement() { using (BalancingStaticPoolManager <int> testInst = new BalancingStaticPoolManager <int>()) { Assert.AreEqual(0, testInst.ElementCount); Assert.AreEqual(0, testInst.FreeElementCount); for (int i = 0; i < 10; i++) { testInst.AddElement(i); } Assert.AreEqual(10, testInst.ElementCount); Assert.AreEqual(10, testInst.FreeElementCount); for (int i = 0; i < 10; i++) { using (var el = testInst.Rent()) { Assert.IsTrue(el.IsValid); testInst.RemoveElement(el); Assert.IsFalse(el.IsValid); } Assert.AreEqual(10 - i - 1, testInst.ElementCount); Assert.AreEqual(10 - i - 1, testInst.FreeElementCount); } } }
public void TestRentInOrder() { using (BalancingStaticPoolManager <int> testInst = new BalancingStaticPoolManager <int>()) { Random rnd = new Random(); for (int i = 0; i < 1000; i++) { testInst.AddElement(rnd.Next()); } List <RentedElementMonitor <int> > rented = new List <RentedElementMonitor <int> >(); for (int i = 0; i < 1000; i++) { rented.Add(testInst.Rent()); } for (int i = 0; i < rented.Count - 1; i++) { Assert.IsTrue(rented[i].Element > rented[i + 1].Element); } for (int i = 0; i < rented.Count; i++) { rented[i].Dispose(); Assert.AreEqual(i + 1, testInst.FreeElementCount); } } }
private void RunFinalizerTest() { BalancingStaticPoolManager <int> testInst = new BalancingStaticPoolManager <int>(); testInst.AddElement(10); using (var item = testInst.Rent(false)) { Assert.IsTrue(item.IsValid); } }
public void TestNotAddToDisposed() { using (BalancingStaticPoolManager <int> testInst = new BalancingStaticPoolManager <int>()) { testInst.Dispose(); for (int i = 0; i < 10; i++) { testInst.AddElement(i); } } }
public void TestDoubleReleaseNotThrow() { using (BalancingStaticPoolManager <int> testInst = new BalancingStaticPoolManager <int>()) { testInst.AddElement(1); using (var item = testInst.Rent()) { item.Dispose(); item.Dispose(); } } }
public void WaitForElementReleaseNotBlockAfterStop() { using (BalancingStaticPoolManager <int> testInst = new BalancingStaticPoolManager <int>()) { testInst.AddElement(1); using (var item = testInst.Rent()) { Assert.IsTrue(item.IsValid); } testInst.Dispose(DisposeFlags.WaitForElementsRelease); } }
public void TestAddElements() { using (BalancingStaticPoolManager <int> testInst = new BalancingStaticPoolManager <int>()) { Assert.AreEqual(0, testInst.ElementCount); Assert.AreEqual(0, testInst.FreeElementCount); for (int i = 0; i < 10; i++) { testInst.AddElement(i); Assert.AreEqual(i + 1, testInst.ElementCount); Assert.AreEqual(i + 1, testInst.FreeElementCount); } } }
public void TestDestroyCalledOnDispose() { int destroyed = 0; Action <int> destroyAct = a => { Interlocked.Increment(ref destroyed); }; using (BalancingStaticPoolManager <int> testInst = new BalancingStaticPoolManager <int>(Comparer <int> .Default, "a", destroyAct)) { for (int i = 0; i < 10; i++) { testInst.AddElement(i); } } Assert.AreEqual(10, destroyed); }
public void TestRentWait() { using (BalancingStaticPoolManager <int> testInst = new BalancingStaticPoolManager <int>()) { for (int i = 0; i < 1; i++) { testInst.AddElement(i); } var item = testInst.Rent(); Task.Delay(500).ContinueWith(t => item.Dispose()); using (var item2 = testInst.Rent()) { Assert.IsTrue(item2.IsValid); } } }
public void WaitForElementReleaseWaits() { using (BalancingStaticPoolManager <int> testInst = new BalancingStaticPoolManager <int>()) { int elementRented = 0; int elementReleased = 0; testInst.AddElement(1); Task.Run(() => { using (var item = testInst.Rent()) { Interlocked.Increment(ref elementRented); Thread.Sleep(250); } Interlocked.Increment(ref elementReleased); }); SpinWait.SpinUntil(() => Volatile.Read(ref elementRented) == 1); testInst.Dispose(DisposeFlags.WaitForElementsRelease); TimingAssert.AreEqual(10000, 1, () => Volatile.Read(ref elementReleased)); } }
public void TestDestroyCalledOnRemove() { int destroyed = 0; Action <int> destroyAct = a => { Interlocked.Increment(ref destroyed); }; using (BalancingStaticPoolManager <int> testInst = new BalancingStaticPoolManager <int>(Comparer <int> .Default, "a", destroyAct)) { Assert.AreEqual(0, testInst.ElementCount); Assert.AreEqual(0, testInst.FreeElementCount); for (int i = 0; i < 10; i++) { testInst.AddElement(i); } Assert.AreEqual(10, testInst.ElementCount); Assert.AreEqual(10, testInst.FreeElementCount); for (int i = 0; i < 10; i++) { using (var el = testInst.Rent()) { Assert.IsTrue(el.IsValid); testInst.RemoveElement(el); Assert.IsFalse(el.IsValid); } Assert.AreEqual(i + 1, destroyed); } Assert.AreEqual(10, destroyed); Assert.AreEqual(0, testInst.ElementCount); } }
public void TestRentReleaseMany() { using (BalancingStaticPoolManager <int> testInst = new BalancingStaticPoolManager <int>()) { for (int i = 0; i < 10; i++) { testInst.AddElement(i); } List <RentedElementMonitor <int> > rented = new List <RentedElementMonitor <int> >(); for (int i = 0; i < 10; i++) { rented.Add(testInst.Rent()); Assert.AreEqual(10 - i - 1, testInst.FreeElementCount); } for (int i = 0; i < rented.Count; i++) { rented[i].Dispose(); Assert.AreEqual(i + 1, testInst.FreeElementCount); } } }
private void RunConcurrentUseWithDispose(int maxPoolElemCount, int threadCount, int opCount) { using (BalancingStaticPoolManager <int> testInst = new BalancingStaticPoolManager <int>()) { for (int i = 0; i < maxPoolElemCount; i++) { testInst.AddElement(i); } Thread[] threads = new Thread[threadCount]; Barrier startBar = new Barrier(threadCount + 1); int totalExecutedOpCount = 0; Action thAct = () => { Random localRand = new Random(Thread.CurrentThread.ManagedThreadId + Environment.TickCount); startBar.SignalAndWait(); try { while (true) { int curSpinTime = localRand.Next(0, 10000); Interlocked.Increment(ref totalExecutedOpCount); using (var el = testInst.Rent(60 * 1000, throwOnUnavail: true)) { if (curSpinTime > 5000) { Thread.Sleep(0); } else { Thread.SpinWait(curSpinTime); } } } } catch (ObjectDisposedException) { } catch (CantRetrieveElementException) { } }; for (int i = 0; i < threads.Length; i++) { threads[i] = new Thread(new ThreadStart(thAct)); } for (int i = 0; i < threads.Length; i++) { threads[i].Start(); } startBar.SignalAndWait(); while (Volatile.Read(ref totalExecutedOpCount) < opCount) { Thread.Sleep(1); } testInst.Dispose(); for (int i = 0; i < threads.Length; i++) { threads[i].Join(); } Assert.AreEqual(testInst.ElementCount, testInst.FreeElementCount, "testInst.ElementCount != testInst.FreeElementCount"); // Assert.AreEqual(testInst.ElementsCreated, testInst.ElementsDestroyed, "ElementsCreated != ElementsDestroyed"); } }