Exemple #1
0
        internal void Free(PoolChunk <T> chunk, long handle, int normCapacity, PoolThreadCache <T> cache)
        {
            if (chunk.Unpooled)
            {
                int size = chunk.ChunkSize;
                DestroyChunk(chunk);
                switch (chunk.Origin)
                {
                case PoolChunk <T> .PoolChunkOrigin.UnpooledNormal:
                    Interlocked.Decrement(ref this.deallocationsNormal);
                    break;

                case PoolChunk <T> .PoolChunkOrigin.UnpooledHuge:
                    Interlocked.Add(ref this.activeBytesHuge, -size);
                    Interlocked.Decrement(ref this.deallocationsHuge);
                    break;

                default:
                    throw new InvalidOperationException("Unsupported PoolChunk.Origin: " + chunk.Origin);
                }
            }
            else
            {
                SizeClass sc = this.SizeClass(normCapacity);
                if (cache != null && cache.Add(this, chunk, handle, normCapacity, sc))
                {
                    // cached so not free it.
                    return;
                }

                this.FreeChunk(chunk, handle, sc);
            }
        }
Exemple #2
0
        internal PooledArrayBuffer <T> Allocate(PoolThreadCache <T> cache, int reqCapacity, int maxCapacity)
        {
            PooledArrayBuffer <T> buf = this.NewByteBuf(maxCapacity);

            this.Allocate(cache, buf, reqCapacity);
            return(buf);
        }
Exemple #3
0
        internal void InitUnpooled(PoolChunk <T> chunk, int length)
        {
            Contract.Assert(chunk != null);

            this.Chunk  = chunk;
            this.Handle = 0;
            // ReSharper disable once PossibleNullReferenceException
            this.Array  = chunk.Memory;
            this.Offset = chunk.Offset;
            this.Count  = length;
            this.Cache  = null;
        }
Exemple #4
0
        internal void Init(PoolChunk <T> chunk, long handle, int offset, int reqCapacity, int length, PoolThreadCache <T> cache)
        {
            Contract.Assert(handle >= 0);
            Contract.Assert(chunk != null);

            this.Chunk  = chunk;
            this.Handle = handle;
            // ReSharper disable once PossibleNullReferenceException
            this.Array  = chunk.Memory;
            this.Offset = offset;
            this.Count  = length;
            this.Cache  = cache;
        }
Exemple #5
0
        void Init0(PoolChunk <T> chunk, long handle, int offset, int length, int maxLength, PoolThreadCache <T> cache)
        {
            Debug.Assert(handle >= 0);
            Debug.Assert(chunk != null);

            this.Chunk     = chunk;
            this.Memory    = chunk.Memory;
            this.allocator = chunk.Arena.Parent;
            this.Cache     = cache;
            this.Handle    = handle;
            this.Offset    = offset;
            this.Length    = length;
            this.MaxLength = maxLength;
        }
        protected override IByteBuffer NewDirectBuffer(int initialCapacity, int maxCapacity)
        {
            PoolThreadCache <byte[]> cache       = this.threadCache.Value;
            PoolArena <byte[]>       directArena = cache.DirectArena;

            IByteBuffer buf;

            if (directArena != null)
            {
                buf = directArena.Allocate(cache, initialCapacity, maxCapacity);
            }
            else
            {
                buf = UnsafeByteBufferUtil.NewUnsafeDirectByteBuffer(this, initialCapacity, maxCapacity);
            }

            return(ToLeakAwareBuffer(buf));
        }
        protected override IByteBuffer NewHeapBuffer(int initialCapacity, int maxCapacity)
        {
            PoolThreadCache <byte[]> cache     = this.threadCache.Value;
            PoolArena <byte[]>       heapArena = cache.HeapArena;

            IByteBuffer buf;

            if (heapArena != null)
            {
                buf = heapArena.Allocate(cache, initialCapacity, maxCapacity);
            }
            else
            {
                buf = new UnpooledHeapByteBuffer(this, initialCapacity, maxCapacity);
            }

            return(ToLeakAwareBuffer(buf));
        }
        protected override IArrayBuffer <T> NewBuffer(int initialCapacity, int capacity)
        {
            PoolThreadCache <T> cache     = this.threadCache.Value;
            PoolArena <T>       heapArena = cache.HeapArena;

            ArrayBuffer <T> buffer;

            if (heapArena != null)
            {
                buffer = heapArena.Allocate(cache, initialCapacity, capacity);
            }
            else
            {
                buffer = new UnpooledArrayBuffer <T>(this, initialCapacity, capacity);
            }

            return(ToLeakAwareBuffer(buffer));
        }
Exemple #9
0
        internal void Free(PoolChunk <T> chunk, long handle, int normCapacity, PoolThreadCache <T> cache)
        {
            if (chunk.Unpooled)
            {
                int size = chunk.ChunkSize;
                this.DestroyChunk(chunk);
                Interlocked.Add(ref this.activeBytesHuge, -size);
                Interlocked.Decrement(ref this.deallocationsHuge);
            }
            else
            {
                SizeClass sc = this.SizeClass(normCapacity);
                if (cache != null && cache.Add(this, chunk, handle, normCapacity, sc))
                {
                    // cached so not free it.
                    return;
                }

                this.FreeChunk(chunk, handle, sc);
            }
        }
 protected override void OnRemoval(PoolThreadCache <byte[]> threadCache) => threadCache.Free();
Exemple #11
0
        void Allocate(PoolThreadCache <T> cache, PooledArrayBuffer <T> buf, int reqCapacity)
        {
            int normCapacity = this.NormalizeCapacity(reqCapacity);

            if (this.IsTinyOrSmall(normCapacity))
            {
                // capacity < pageSize
                int tableIdx;
                PoolSubpage <T>[] table;
                bool tiny = IsTiny(normCapacity);
                if (tiny)
                {
                    // < 512
                    if (cache.AllocateTiny(this, buf, reqCapacity, normCapacity))
                    {
                        // was able to allocate out of the cache so move on
                        return;
                    }
                    tableIdx = TinyIdx(normCapacity);
                    table    = this.tinySubpagePools;
                }
                else
                {
                    if (cache.AllocateSmall(this, buf, reqCapacity, normCapacity))
                    {
                        // was able to allocate out of the cache so move on
                        return;
                    }
                    tableIdx = SmallIdx(normCapacity);
                    table    = this.smallSubpagePools;
                }

                PoolSubpage <T> head = table[tableIdx];

                /**
                 * Synchronize on the head. This is needed as {@link PoolSubpage#allocate()} and
                 * {@link PoolSubpage#free(int)} may modify the doubly linked list as well.
                 */
                lock (head)
                {
                    PoolSubpage <T> s = head.Next;
                    if (s != head)
                    {
                        Contract.Assert(s.DoNotDestroy && s.ElemSize == normCapacity);
                        long handle = s.Allocate();
                        Contract.Assert(handle >= 0);
                        s.Chunk.InitBufWithSubpage(buf, handle, reqCapacity);

                        if (tiny)
                        {
                            ++this.NumTinyAllocations;
                        }
                        else
                        {
                            ++this.NumSmallAllocations;
                        }
                        return;
                    }
                }

                this.AllocateNormal(buf, reqCapacity, normCapacity);
                return;
            }

            if (normCapacity <= this.ChunkSize)
            {
                if (cache.AllocateNormal(this, buf, reqCapacity, normCapacity))
                {
                    // was able to allocate out of the cache so move on
                    return;
                }
                this.AllocateNormal(buf, reqCapacity, normCapacity);
            }
            else
            {
                // Huge allocations are never served via the cache so just call allocateHuge
                this.AllocateHuge(buf, reqCapacity);
            }
        }
Exemple #12
0
 internal virtual void Init(PoolChunk <T> chunk, long handle, int offset, int length, int maxLength, PoolThreadCache <T> cache) =>
 this.Init0(chunk, handle, offset, length, maxLength, cache);
 internal override void Init(PoolChunk <byte[]> chunk, long handle, int offset, int length, int maxLength,
                             PoolThreadCache <byte[]> cache)
 {
     base.Init(chunk, handle, offset, length, maxLength, cache);
     this.InitMemoryAddress();
 }
Exemple #14
0
 internal void Init(PoolChunk <T> chunk, long handle, int offset, int length, int maxLength,
                    PoolThreadCache <T> cache)
 {
     this.Init0(chunk, handle, offset, length, maxLength, cache);
     this.DiscardMarkers();
 }