// TODO: Test if adding padding helps under contention //private long pad0, pad1, pad2, pad3, pad4, pad5, pad6, pad7; public PoolChunkList(PoolArena <T> arena, PoolChunkList <T> nextList, int minUsage, int maxUsage, int chunkSize) { Debug.Assert(minUsage <= maxUsage); _arena = arena; _nextList = nextList; _minUsage = minUsage; _maxUsage = maxUsage; _maxCapacity = CalculateMaxCapacity(minUsage, chunkSize); // the thresholds are aligned with PoolChunk.usage() logic: // 1) basic logic: usage() = 100 - freeBytes * 100L / chunkSize // so, for example: (usage() >= maxUsage) condition can be transformed in the following way: // 100 - freeBytes * 100L / chunkSize >= maxUsage // freeBytes <= chunkSize * (100 - maxUsage) / 100 // let freeMinThreshold = chunkSize * (100 - maxUsage) / 100, then freeBytes <= freeMinThreshold // // 2) usage() returns an int value and has a floor rounding during a calculation, // to be aligned absolute thresholds should be shifted for "the rounding step": // freeBytes * 100 / chunkSize < 1 // the condition can be converted to: freeBytes < 1 * chunkSize / 100 // this is why we have + 0.99999999 shifts. A example why just +1 shift cannot be used: // freeBytes = 16777216 == freeMaxThreshold: 16777216, usage = 0 < minUsage: 1, chunkSize: 16777216 // At the same time we want to have zero thresholds in case of (maxUsage == 100) and (minUsage == 100). // _freeMinThreshold = (maxUsage == 100) ? 0 : (int)(uint)(chunkSize * (100.0d - maxUsage + 0.99999999d) / 100L); _freeMaxThreshold = (minUsage == 100) ? 0 : (int)(uint)(chunkSize * (100.0d - minUsage + 0.99999999d) / 100L); }
// TODO: Test if adding padding helps under contention //private long pad0, pad1, pad2, pad3, pad4, pad5, pad6, pad7; public PoolChunkList(PoolArena <T> arena, PoolChunkList <T> nextList, int minUsage, int maxUsage, int chunkSize) { Contract.Assert(minUsage <= maxUsage); this.arena = arena; this.nextList = nextList; this.minUsage = minUsage; this.maxUsage = maxUsage; this.maxCapacity = CalculateMaxCapacity(minUsage, chunkSize); }
// TODO: Test if adding padding helps under contention //private long pad0, pad1, pad2, pad3, pad4, pad5, pad6, pad7; protected PoolArena( PooledByteBufferAllocator parent, int pageSize, int maxOrder, int pageShifts, int chunkSize) { Parent = parent; PageSize = pageSize; _maxOrder = maxOrder; PageShifts = pageShifts; ChunkSize = chunkSize; SubpageOverflowMask = ~(pageSize - 1); _tinySubpagePools = NewSubpagePoolArray(NumTinySubpagePools); for (int i = 0; i < _tinySubpagePools.Length; i++) { _tinySubpagePools[i] = NewSubpagePoolHead(pageSize); } NumSmallSubpagePools = pageShifts - 9; _smallSubpagePools = NewSubpagePoolArray(NumSmallSubpagePools); for (int i = 0; i < _smallSubpagePools.Length; i++) { _smallSubpagePools[i] = NewSubpagePoolHead(pageSize); } _q100 = new PoolChunkList <T>(this, null, 100, int.MaxValue, chunkSize); _q075 = new PoolChunkList <T>(this, _q100, 75, 100, chunkSize); _q050 = new PoolChunkList <T>(this, _q075, 50, 100, chunkSize); _q025 = new PoolChunkList <T>(this, _q050, 25, 75, chunkSize); _q000 = new PoolChunkList <T>(this, _q025, 1, 50, chunkSize); _qInit = new PoolChunkList <T>(this, _q000, int.MinValue, 25, chunkSize); _q100.PrevList(_q075); _q075.PrevList(_q050); _q050.PrevList(_q025); _q025.PrevList(_q000); _q000.PrevList(null); _qInit.PrevList(_qInit); var metrics = new List <IPoolChunkListMetric>(6); metrics.Add(_qInit); metrics.Add(_q000); metrics.Add(_q025); metrics.Add(_q050); metrics.Add(_q075); metrics.Add(_q100); _chunkListMetrics = metrics; }
// TODO: Test if adding padding helps under contention //private long pad0, pad1, pad2, pad3, pad4, pad5, pad6, pad7; protected PoolArena(PooledByteBufferAllocator parent, int pageSize, int maxOrder, int pageShifts, int chunkSize, int maxChunkCount) { this.Parent = parent; this.PageSize = pageSize; this.maxOrder = maxOrder; this.PageShifts = pageShifts; this.ChunkSize = chunkSize; this.maxChunkCount = maxChunkCount; this.SubpageOverflowMask = ~(pageSize - 1); this.tinySubpagePools = this.NewSubpagePoolArray(NumTinySubpagePools); for (int i = 0; i < this.tinySubpagePools.Length; i++) { this.tinySubpagePools[i] = this.NewSubpagePoolHead(pageSize); } this.NumSmallSubpagePools = pageShifts - 9; this.smallSubpagePools = this.NewSubpagePoolArray(this.NumSmallSubpagePools); for (int i = 0; i < this.smallSubpagePools.Length; i++) { this.smallSubpagePools[i] = this.NewSubpagePoolHead(pageSize); } this.q100 = new PoolChunkList <T>(null, 100, int.MaxValue, chunkSize); this.q075 = new PoolChunkList <T>(this.q100, 75, 100, chunkSize); this.q050 = new PoolChunkList <T>(this.q075, 50, 100, chunkSize); this.q025 = new PoolChunkList <T>(this.q050, 25, 75, chunkSize); this.q000 = new PoolChunkList <T>(this.q025, 1, 50, chunkSize); this.qInit = new PoolChunkList <T>(this.q000, int.MinValue, 25, chunkSize); this.q100.PrevList(this.q075); this.q075.PrevList(this.q050); this.q050.PrevList(this.q025); this.q025.PrevList(this.q000); this.q000.PrevList(null); this.qInit.PrevList(this.qInit); var metrics = new List <IPoolChunkListMetric>(6); metrics.Add(this.qInit); metrics.Add(this.q000); metrics.Add(this.q025); metrics.Add(this.q050); metrics.Add(this.q075); metrics.Add(this.q100); this.chunkListMetrics = metrics; }
internal void PrevList(PoolChunkList <T> list) { Debug.Assert(this.prevList == null); this.prevList = list; }
internal void PrevList(PoolChunkList <T> prevList) { Contract.Requires(this.prevList == null); this.prevList = prevList; }
internal void PrevList(PoolChunkList <T> list) { Debug.Assert(_prevList is null); _prevList = list; }