예제 #1
0
        public void ServiceCouldGrowBucketsWithResize()
        {
            // 2 counters per bucket
            Settings.AtomicCounterPoolBucketSize = 4;

            // 4 buckets initially
            var count = 100;

            var counters = new List <AtomicCounter>();

            for (int i = 0; i < count; i++)
            {
                counters.Add(AtomicCounterService.AcquireCounter());
            }

            foreach (var atomicCounter in counters)
            {
                atomicCounter.Dispose();
                AtomicCounterService.ReleaseCounter(atomicCounter);
            }

            Assert.AreEqual(64, AtomicCounterService.Buckets.Length);
            Assert.AreEqual(50, AtomicCounterService.Buckets.Where(x => x != null).Count());
            Assert.AreEqual(50 * 2, AtomicCounterService.Buckets.Where(x => x != null).Select(x => x.FreeCount).Sum());
        }
예제 #2
0
        // ReSharper disable once InconsistentNaming
        public void ServiceCouldCreateACPoolAndAcquireRelease()
        {
            Settings.AtomicCounterPoolBucketSize = 4;
            var ac  = AtomicCounterService.AcquireCounter();
            var ac1 = AtomicCounterService.AcquireCounter();

            Assert.IsTrue(ac.IsValid);

            Assert.AreEqual(1, ac.Increment());
            Assert.AreEqual(0, ac.Decrement());
            Assert.AreEqual(1, ac.Increment());

            Assert.Throws <InvalidOperationException>(() => ac.Dispose());

            Assert.AreEqual(0, ac.Decrement());

            Assert.Throws <InvalidOperationException>(() => AtomicCounterService.ReleaseCounter(ac));

            ac.Dispose();
            ac1.Dispose();

            Assert.Throws <ObjectDisposedException>(() => ac.Increment());
            Assert.Throws <ObjectDisposedException>(() => ac1.Increment());

            AtomicCounterService.ReleaseCounter(ac);
        }
예제 #3
0
        protected override void Dispose(bool disposing)
        {
            if (_externallyOwned)
            {
                ThrowHelper.ThrowNotSupportedException();
            }

            EnsureNotRetainedAndNotDisposed();

            // disposing == false when finalizing and detected that non pooled
            if (disposing)
            {
                TryReturnThisToPoolOrFinalize();
            }
            else
            {
                Debug.Assert(!_isPooled);
                _pool = null;

                // we still could add this to the pool of free pinned slices that are backed by an existing slab
                var pooledToFreeSlicesPool = _slicesPool.Return(this);
                if (pooledToFreeSlicesPool)
                {
                    return;
                }

                Counter.Dispose();
                AtomicCounterService.ReleaseCounter(Counter);
                ClearAfterDispose();

                // destroy the object and release resources
                var array = Interlocked.Exchange(ref _array, null);
                if (array != null)
                {
                    Debug.Assert(_handle.IsAllocated);
#pragma warning disable 618
                    _slab.Decrement();
                    _handle.Free();
#pragma warning restore 618
                }
                else
                {
                    ThrowDisposed <ArrayMemory <T> >();
                }

                Debug.Assert(!_handle.IsAllocated);
            }
        }
예제 #4
0
        public void ServiceBenchmark()
        {
            var count = 10000;

            Settings.AtomicCounterPoolBucketSize = count;

            var rounds   = 5000;
            var counters = new List <AtomicCounter>();

            using (Benchmark.Run("Service FullCycle", count * (long)rounds))
            {
                for (int r = 0; r < rounds; r++)
                {
                    for (int i = 0; i < count; i++)
                    {
                        counters.Add(AtomicCounterService.AcquireCounter());
                    }

                    for (int i = counters.Count - 1; i >= 0; i--)
                    {
                        var atomicCounter = counters[i];
                        atomicCounter.Dispose();
                        AtomicCounterService.ReleaseCounter(atomicCounter);
                    }

                    //foreach (var atomicCounter in counters)
                    //{
                    //    atomicCounter.Dispose();
                    //    AtomicCounterService.ReleaseCounter(atomicCounter);
                    //}

                    counters.Clear();
                }
            }

            Assert.AreEqual(4, AtomicCounterService.Buckets.Length);
            Assert.AreEqual(1, AtomicCounterService.Buckets.Where(x => x != null).Count());
        }
예제 #5
0
        protected override void Dispose(bool disposing)
        {
            EnsureNotRetainedAndNotDisposed();

            // disposing == false when finilizing and detected that non pooled
            if (disposing)
            {
                TryReturnThisToPoolOrFinalize();
            }
            else
            {
                Debug.Assert(!_isPooled);
                _pool = null;

                Counter.Dispose();
                AtomicCounterService.ReleaseCounter(Counter);
                ClearAfterDispose();

                // Dispose destructs this object and native buffer
                _offHeapBuffer.Dispose();
                // set all to default, increase chances to detect errors
                _offHeapBuffer = default;
            }
        }