コード例 #1
0
ファイル: PoolThreadCache.cs プロジェクト: PlumpMath/NetUV
            void FreeEntry(Entry entry)
            {
                PoolChunk <T> chunk  = entry.Chunk;
                long          handle = entry.Handle;

                // recycle now so PoolChunk can be GC'ed.
                entry.Recycle();

                chunk.Arena.FreeChunk(chunk, handle, this.sizeClass);
            }
コード例 #2
0
        /**
         * Add {@link PoolChunk} and {@code handle} to the cache if there is enough room.
         * Returns {@code true} if it fit into the cache {@code false} otherwise.
         */
        internal bool Add(PoolArena <T> area, PoolChunk <T> chunk, long handle, int normCapacity, SizeClass sizeClass)
        {
            MemoryRegionCache cache = this.Cache(area, normCapacity, sizeClass);

            if (cache == null)
            {
                return(false);
            }
            return(cache.Add(chunk, handle));
        }
コード例 #3
0
 /// Moves the {@link PoolChunk} down the {@link PoolChunkList} linked-list so it will end up in the right
 /// {@link PoolChunkList} that has the correct minUsage / maxUsage in respect to {@link PoolChunk#usage()}.
 bool Move0(PoolChunk <T> chunk)
 {
     if (this.prevList == null)
     {
         // There is no previous PoolChunkList so return false which result in having the PoolChunk destroyed and
         // all memory associated with the PoolChunk will be released.
         Contract.Assert(chunk.Usage == 0);
         return(false);
     }
     return(this.prevList.Move(chunk));
 }
コード例 #4
0
        internal void Destroy(PoolArena <T> poolArena)
        {
            PoolChunk <T> chunk = this.head;

            while (chunk != null)
            {
                poolArena.DestroyChunk(chunk);
                chunk = chunk.Next;
            }
            this.head = null;
        }
コード例 #5
0
 internal bool Free(PoolChunk <T> chunk, long handle)
 {
     chunk.Free(handle);
     if (chunk.Usage < this.minUsage)
     {
         this.Remove(chunk);
         // Move the PoolChunk down the PoolChunkList linked-list.
         return(this.Move0(chunk));
     }
     return(true);
 }
コード例 #6
0
 protected internal sealed override void Deallocate()
 {
     if (this.Handle >= 0)
     {
         long handle = this.Handle;
         this.Handle = -1;
         this.Memory = default(T);
         this.Chunk.Arena.Free(this.Chunk, handle, this.MaxLength, this.Cache);
         this.Chunk = null;
         this.Recycle();
     }
 }
コード例 #7
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;
        }
コード例 #8
0
ファイル: PoolChunkList.cs プロジェクト: wazazhang/NetUV
        IEnumerator <IPoolChunkMetric> GetEnumeratorInternal()
        {
            lock (this.arena)
            {
                for (PoolChunk <T> cur = this.head; cur != null;)
                {
                    yield return(cur);

                    cur = cur.Next;
                }
            }
        }
コード例 #9
0
ファイル: PoolArena.cs プロジェクト: heng83/NetUV
        internal void Reallocate(PooledArrayBuffer <T> buf, int newCapacity, bool freeOldMemory)
        {
            Contract.Requires(newCapacity >= 0 && newCapacity <= buf.MaxCapacity);

            int oldCapacity = buf.Length;

            if (oldCapacity == newCapacity)
            {
                return;
            }

            PoolChunk <T> oldChunk  = buf.Chunk;
            long          oldHandle = buf.Handle;

            T[] oldMemory    = buf.Memory;
            int oldOffset    = buf.Offset;
            int oldMaxLength = buf.MaxLength;
            int readerIndex  = buf.ReaderIndex;
            int writerIndex  = buf.WriterIndex;

            this.Allocate(this.Parent.ThreadCache(), buf, newCapacity);
            if (newCapacity > oldCapacity)
            {
                MemoryCopy(
                    oldMemory, oldOffset,
                    buf.Memory, buf.Offset, oldCapacity);
            }
            else if (newCapacity < oldCapacity)
            {
                if (readerIndex < newCapacity)
                {
                    if (writerIndex > newCapacity)
                    {
                        writerIndex = newCapacity;
                    }
                    MemoryCopy(
                        oldMemory, oldOffset + readerIndex,
                        buf.Memory, buf.Offset + readerIndex, writerIndex - readerIndex);
                }
                else
                {
                    readerIndex = writerIndex = newCapacity;
                }
            }

            buf.SetIndex(readerIndex, writerIndex);

            if (freeOldMemory)
            {
                this.Free(oldChunk, oldHandle, oldMaxLength, buf.Cache);
            }
        }
コード例 #10
0
 protected internal override void DestroyChunk(PoolChunk <byte[]> chunk)
 {
     for (int i = 0; i < this.memoryChunks.Count; i++)
     {
         MemoryChunk memoryChunk = this.memoryChunks[i];
         if (ReferenceEquals(chunk.Memory, memoryChunk.Bytes))
         {
             this.memoryChunks.Remove(memoryChunk);
             memoryChunk.Dispose();
             break;
         }
     }
 }
コード例 #11
0
            public bool Add(PoolChunk <T> chunk, long handle)
            {
                Entry entry  = NewEntry(chunk, handle);
                bool  queued = this.queue.TryEnqueue(entry);

                if (!queued)
                {
                    // If it was not possible to cache the chunk, immediately recycle the entry
                    entry.Recycle();
                }

                return(queued);
            }
コード例 #12
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;
        }
コード例 #13
0
        bool Move(PoolChunk <T> chunk)
        {
            Contract.Assert(chunk.Usage < this.maxUsage);

            if (chunk.Usage < this.minUsage)
            {
                // Move the PoolChunk down the PoolChunkList linked-list.
                return(this.Move0(chunk));
            }

            // PoolChunk fits into this PoolChunkList, adding it here.
            this.Add0(chunk);
            return(true);
        }
コード例 #14
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;
        }
コード例 #15
0
        void AllocateNormal(PooledByteBuffer <T> buf, int reqCapacity, int normCapacity)
        {
            if (this.q050.Allocate(buf, reqCapacity, normCapacity) || this.q025.Allocate(buf, reqCapacity, normCapacity) ||
                this.q000.Allocate(buf, reqCapacity, normCapacity) || this.qInit.Allocate(buf, reqCapacity, normCapacity) ||
                this.q075.Allocate(buf, reqCapacity, normCapacity))
            {
                return;
            }

            // Add a new chunk.
            PoolChunk <T> c      = this.NewChunk(this.PageSize, this.maxOrder, this.PageShifts, this.ChunkSize);
            long          handle = c.Allocate(normCapacity);

            Debug.Assert(handle > 0);
            c.InitBuf(buf, handle, reqCapacity);
            this.qInit.Add(c);
        }
コード例 #16
0
 /// Adds the {@link PoolChunk} to this {@link PoolChunkList}.
 void Add0(PoolChunk <T> chunk)
 {
     chunk.Parent = this;
     if (this.head == null)
     {
         this.head  = chunk;
         chunk.Prev = null;
         chunk.Next = null;
     }
     else
     {
         chunk.Prev     = null;
         chunk.Next     = this.head;
         this.head.Prev = chunk;
         this.head      = chunk;
     }
 }
コード例 #17
0
 void Remove(PoolChunk <T> cur)
 {
     if (cur == this.head)
     {
         this.head = cur.Next;
         if (this.head != null)
         {
             this.head.Prev = null;
         }
     }
     else
     {
         PoolChunk <T> next = cur.Next;
         cur.Prev.Next = next;
         if (next != null)
         {
             next.Prev = cur.Prev;
         }
     }
 }
コード例 #18
0
ファイル: PoolArena.cs プロジェクト: PlumpMath/NetUV
        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);
            }
        }
コード例 #19
0
        public override string ToString()
        {
            if (this.head == null)
            {
                return("none");
            }

            var buf = new StringBuilder();

            for (PoolChunk <T> cur = this.head; ;)
            {
                buf.Append(cur);
                cur = cur.Next;
                if (cur == null)
                {
                    break;
                }
                buf.Append(Environment.NewLine);
            }

            return(buf.ToString());
        }
コード例 #20
0
ファイル: PoolArena.cs プロジェクト: PlumpMath/NetUV
        void AllocateNormal(PooledArrayBuffer <T> buf, int reqCapacity, int normCapacity)
        {
            lock (this)
            {
                if (this.q050.Allocate(buf, reqCapacity, normCapacity) ||
                    this.q025.Allocate(buf, reqCapacity, normCapacity) ||
                    this.q000.Allocate(buf, reqCapacity, normCapacity) ||
                    this.qInit.Allocate(buf, reqCapacity, normCapacity) ||
                    this.q075.Allocate(buf, reqCapacity, normCapacity))
                {
                    ++this.NumNormalAllocations;
                    return;
                }

                // Add a new chunk.
                PoolChunk <T> c      = this.NewChunk(this.PageSize, this.maxOrder, this.PageShifts, this.ChunkSize);
                long          handle = c.Allocate(normCapacity);
                ++this.NumNormalAllocations;
                Contract.Assert(handle > 0);
                c.InitBuf(buf, handle, reqCapacity);
                this.qInit.Add(c);
            }
        }
コード例 #21
0
ファイル: PoolArena.cs プロジェクト: PlumpMath/NetUV
        internal void Reallocate(PooledArrayBuffer <T> buf, int newCapacity, bool freeOldMemory)
        {
            Contract.Requires(newCapacity >= 0 && newCapacity <= buf.Capacity);

            int oldCapacity = buf.Capacity;

            if (oldCapacity == newCapacity)
            {
                return;
            }

            PoolChunk <T> oldChunk  = buf.Chunk;
            long          oldHandle = buf.Handle;

            T[] oldMemory    = buf.Array;
            int oldOffset    = buf.Offset;
            int oldMaxLength = buf.Length;

            this.Allocate(this.Parent.ThreadCache(), buf, newCapacity);
            if (newCapacity > oldCapacity)
            {
                this.MemoryCopy(
                    oldMemory, oldOffset,
                    buf.Array, buf.Offset, oldCapacity);
            }
            else if (newCapacity < oldCapacity)
            {
                this.MemoryCopy(
                    oldMemory, oldOffset,
                    buf.Array, buf.Offset, newCapacity);
            }

            if (freeOldMemory)
            {
                this.Free(oldChunk, oldHandle, oldMaxLength, buf.Cache);
            }
        }
コード例 #22
0
 internal override void InitUnpooled(PoolChunk <byte[]> chunk, int length)
 {
     base.InitUnpooled(chunk, length);
     this.InitMemoryAddress();
 }
コード例 #23
0
 internal virtual void InitUnpooled(PoolChunk <T> chunk, int length) => this.Init0(chunk, 0, 0, length, length, null);
コード例 #24
0
ファイル: PoolArena.cs プロジェクト: PlumpMath/NetUV
 protected internal void DestroyChunk(PoolChunk <T> chunk)
 {
     // Rely on GC.
 }
コード例 #25
0
 internal void Recycle()
 {
     this.Chunk  = null;
     this.Handle = -1;
     this.recyclerHandle.Release(this);
 }
コード例 #26
0
ファイル: PoolArena.cs プロジェクト: heng83/NetUV
 static void DestroyChunk(PoolChunk <T> chunk)
 {
     // Rely on GC.
 }
コード例 #27
0
 protected abstract void InitBuf(PoolChunk <T> chunk, long handle, PooledArrayBuffer <T> buf, int reqCapacity);
コード例 #28
0
 protected override void InitBuf(
     PoolChunk <T> chunk, long handle, PooledArrayBuffer <T> buf, int reqCapacity) => chunk.InitBuf(buf, handle, reqCapacity);
コード例 #29
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);
コード例 #30
0
ファイル: PoolThreadCache.cs プロジェクト: PlumpMath/NetUV
        ///
        // Add {@link PoolChunk} and {@code handle} to the cache if there is enough room.
        // Returns {@code true} if it fit into the cache {@code false} otherwise.
        //
        internal bool Add(PoolArena <T> area, PoolChunk <T> chunk, long handle, int normCapacity, SizeClass sizeClass)
        {
            MemoryRegionCache c = this.Cache(normCapacity, sizeClass);

            return(c != null && c.Add(chunk, handle));
        }