From 5ae1c4ecb2cc0562a8490e3d2dcde10560960583 Mon Sep 17 00:00:00 2001 From: Ben Adams Date: Wed, 4 Nov 2015 08:07:34 +0000 Subject: [PATCH 1/2] MemoryPool2 Allocate returns newest Rather than a while loop on Allocate; return last memory block created rather than returning it to the pool and checking if one can be removed. --- .../Infrastructure/MemoryPool2.cs | 33 ++++++++++++------- 1 file changed, 21 insertions(+), 12 deletions(-) diff --git a/src/Microsoft.AspNet.Server.Kestrel/Infrastructure/MemoryPool2.cs b/src/Microsoft.AspNet.Server.Kestrel/Infrastructure/MemoryPool2.cs index 2ee01c0d10..cef7779dc4 100644 --- a/src/Microsoft.AspNet.Server.Kestrel/Infrastructure/MemoryPool2.cs +++ b/src/Microsoft.AspNet.Server.Kestrel/Infrastructure/MemoryPool2.cs @@ -74,24 +74,21 @@ namespace Microsoft.AspNet.Server.Kestrel.Infrastructure slab: null); } - while (true) + MemoryPoolBlock2 block; + if (_blocks.TryPop(out block)) { - MemoryPoolBlock2 block; - if (_blocks.TryPop(out block)) - { - // block successfully taken from the stack - return it - return block; - } - // no blocks available - grow the pool and try again - AllocateSlab(); + // block successfully taken from the stack - return it + return block; } + // no blocks available - grow the pool + return AllocateSlab(); } /// /// Internal method called when a block is requested and the pool is empty. It allocates one additional slab, creates all of the /// block tracking objects, and adds them all to the pool. /// - private void AllocateSlab() + private MemoryPoolBlock2 AllocateSlab() { var slab = MemoryPoolSlab2.Create(_slabLength); _slabs.Push(slab); @@ -99,8 +96,11 @@ namespace Microsoft.AspNet.Server.Kestrel.Infrastructure var basePtr = slab.ArrayPtr; var firstOffset = (int)((_blockStride - 1) - ((ulong)(basePtr + _blockStride - 1) % _blockStride)); - for (var offset = firstOffset; - offset + _blockLength <= _slabLength; + var poolAllocationLength = _slabLength - (_blockLength + _blockStride); + + var offset = firstOffset; + for (; + offset < poolAllocationLength; offset += _blockStride) { var block = MemoryPoolBlock2.Create( @@ -110,6 +110,15 @@ namespace Microsoft.AspNet.Server.Kestrel.Infrastructure slab); Return(block); } + + // return last block rather than adding to pool + var newBlock = MemoryPoolBlock2.Create( + new ArraySegment(slab.Array, offset, _blockLength), + basePtr, + this, + slab); + + return newBlock; } /// From 22dfd31261a16e4d873179b20f9b033f2af677c3 Mon Sep 17 00:00:00 2001 From: Ben Adams Date: Wed, 4 Nov 2015 22:04:19 +0000 Subject: [PATCH 2/2] More readable loop condition --- .../Infrastructure/MemoryPool2.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Microsoft.AspNet.Server.Kestrel/Infrastructure/MemoryPool2.cs b/src/Microsoft.AspNet.Server.Kestrel/Infrastructure/MemoryPool2.cs index cef7779dc4..86561516c6 100644 --- a/src/Microsoft.AspNet.Server.Kestrel/Infrastructure/MemoryPool2.cs +++ b/src/Microsoft.AspNet.Server.Kestrel/Infrastructure/MemoryPool2.cs @@ -96,11 +96,11 @@ namespace Microsoft.AspNet.Server.Kestrel.Infrastructure var basePtr = slab.ArrayPtr; var firstOffset = (int)((_blockStride - 1) - ((ulong)(basePtr + _blockStride - 1) % _blockStride)); - var poolAllocationLength = _slabLength - (_blockLength + _blockStride); + var poolAllocationLength = _slabLength - _blockStride; var offset = firstOffset; for (; - offset < poolAllocationLength; + offset + _blockLength < poolAllocationLength; offset += _blockStride) { var block = MemoryPoolBlock2.Create(