/** Creates a special chunk that is not pooled. */

        internal PoolChunk(PoolArena <T> arena, T memory, int size, bool huge)
        {
            this.Origin              = huge ? PoolChunkOrigin.UnpooledHuge : PoolChunkOrigin.UnpooledNormal;
            this.Arena               = arena;
            this.Memory              = memory;
            this.memoryMap           = null;
            this.depthMap            = null;
            this.subpages            = null;
            this.subpageOverflowMask = 0;
            this.pageSize            = 0;
            this.pageShifts          = 0;
            this.maxOrder            = 0;
            this.unusable            = (sbyte)(this.maxOrder + 1);
            this.chunkSize           = size;
            this.log2ChunkSize       = IntegerExtensions.Log2(this.chunkSize);
            this.maxSubpageAllocs    = 0;
        }
        // TODO: Test if adding padding helps under contention
        //private long pad0, pad1, pad2, pad3, pad4, pad5, pad6, pad7;

        internal PoolChunk(PoolArena <T> arena, T memory, int pageSize, int maxOrder, int pageShifts, int chunkSize)
        {
            Contract.Requires(maxOrder < 30, "maxOrder should be < 30, but is: " + maxOrder);

            this.Origin              = PoolChunkOrigin.Pooled;
            this.Arena               = arena;
            this.Memory              = memory;
            this.pageSize            = pageSize;
            this.pageShifts          = pageShifts;
            this.maxOrder            = maxOrder;
            this.chunkSize           = chunkSize;
            this.unusable            = (sbyte)(maxOrder + 1);
            this.log2ChunkSize       = IntegerExtensions.Log2(chunkSize);
            this.subpageOverflowMask = ~(pageSize - 1);
            this.freeBytes           = chunkSize;

            Contract.Assert(maxOrder < 30, "maxOrder should be < 30, but is: " + maxOrder);
            this.maxSubpageAllocs = 1 << maxOrder;

            // Generate the memory map.
            this.memoryMap = new sbyte[this.maxSubpageAllocs << 1];
            this.depthMap  = new sbyte[this.memoryMap.Length];
            int memoryMapIndex = 1;

            for (int d = 0; d <= maxOrder; ++d)
            {
                // move down the tree one level at a time
                int depth = 1 << d;
                for (int p = 0; p < depth; ++p)
                {
                    // in each level traverse left to right and set value to the depth of subtree
                    this.memoryMap[memoryMapIndex] = (sbyte)d;
                    this.depthMap[memoryMapIndex]  = (sbyte)d;
                    memoryMapIndex++;
                }
            }

            this.subpages = this.NewSubpageArray(this.maxSubpageAllocs);
        }