Skip to content
This repository has been archived by the owner on Jan 23, 2023. It is now read-only.
/ corefx Public archive

Commit

Permalink
Reduce lock time
Browse files Browse the repository at this point in the history
  • Loading branch information
benaadams committed Feb 12, 2019
1 parent ea5199c commit c175b05
Showing 1 changed file with 32 additions and 13 deletions.
45 changes: 32 additions & 13 deletions src/System.IO.Pipelines/src/System/IO/Pipelines/Pipe.cs
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,9 @@ public sealed partial class Pipe
private readonly PipeScheduler _readerScheduler;
private readonly PipeScheduler _writerScheduler;

private int _pooledSegmentCount;
private readonly BufferSegment[] _bufferSegmentPool;
private readonly BufferSegment[] _bufferSegmentsToReturn;

private readonly DefaultPipeReader _reader;
private readonly DefaultPipeWriter _writer;
Expand All @@ -52,7 +54,6 @@ public sealed partial class Pipe
private long _length;
private long _currentWriteLength;

private int _pooledSegmentCount;

private PipeAwaitable _readerAwaitable;
private PipeAwaitable _writerAwaitable;
Expand Down Expand Up @@ -97,6 +98,7 @@ public Pipe(PipeOptions options)
}

_bufferSegmentPool = new BufferSegment[SegmentPoolSize];
_bufferSegmentsToReturn = new BufferSegment[SegmentPoolSize];

_operationState = default;
_readerCompletion = default;
Expand Down Expand Up @@ -257,25 +259,39 @@ private void ReturnSegments(BufferSegment from, BufferSegment toExclusive)
Debug.Assert(from != null);
Debug.Assert(from != toExclusive);

// Reset the Segments and return their data out of lock
BufferSegment[] segmentToReturn = _bufferSegmentsToReturn;
int count = 0;
do
{
BufferSegment next = from.NextSegment;
Debug.Assert(next != null || toExclusive == null);

from.ResetMemory();

if ((uint)count < (uint)segmentToReturn.Length)
{
segmentToReturn[count] = from;
count++;
}

from = next;
} while (from != toExclusive);

// Add the Segments back to pool under lock
BufferSegment[] segmentPool = _bufferSegmentPool;
lock (segmentPool)
{
int index = _pooledSegmentCount;
do
for (int i = 0; i < count; i++)
{
BufferSegment next = from.NextSegment;
Debug.Assert(next != null || toExclusive == null);

from.ResetMemory();

if ((uint)index < (uint)segmentPool.Length)
{
segmentPool[index] = from;
segmentPool[index] = segmentToReturn[i];
index++;
}

from = next;
} while (from != toExclusive);
segmentToReturn[i] = null;
}

_pooledSegmentCount = index;
}
Expand Down Expand Up @@ -786,9 +802,12 @@ private void CompletePipe()
_readTail = null;
}

if (segment != null)
while (segment != null)
{
ReturnSegments(segment, toExclusive: null);
BufferSegment returnSegment = segment;
segment = segment.NextSegment;

returnSegment.ResetMemory();
}
}

Expand Down

0 comments on commit c175b05

Please sign in to comment.