/** 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); }