@@ -43,9 +43,7 @@ public sealed partial class Pipe
43
43
private readonly PipeScheduler _writerScheduler ;
44
44
45
45
private int _pooledSegmentCount ;
46
- private readonly BufferSegment [ ] _bufferSegmentPool ;
47
- // Temporary list to hold Segments return while being reset
48
- private readonly BufferSegment [ ] _bufferSegmentsToReturn ;
46
+ private readonly SegmentAsValue [ ] _bufferSegmentPool ;
49
47
50
48
private readonly DefaultPipeReader _reader ;
51
49
private readonly DefaultPipeWriter _writer ;
@@ -97,8 +95,7 @@ public Pipe(PipeOptions options)
97
95
ThrowHelper . ThrowArgumentNullException ( ExceptionArgument . options ) ;
98
96
}
99
97
100
- _bufferSegmentPool = new BufferSegment [ SegmentPoolSize ] ;
101
- _bufferSegmentsToReturn = new BufferSegment [ SegmentPoolSize ] ;
98
+ _bufferSegmentPool = new SegmentAsValue [ SegmentPoolSize ] ;
102
99
103
100
_operationState = default ;
104
101
_readerCompletion = default ;
@@ -297,66 +294,6 @@ private int GetSegmentSize(int sizeHint, int maxBufferSize = int.MaxValue)
297
294
return adjustedToMaximumSize ;
298
295
}
299
296
300
- private BufferSegment CreateSegmentSynchronized ( )
301
- {
302
- BufferSegment [ ] segmentPool = _bufferSegmentPool ;
303
- lock ( segmentPool )
304
- {
305
- int index = _pooledSegmentCount - 1 ;
306
- if ( ( uint ) index < ( uint ) segmentPool . Length )
307
- {
308
- _pooledSegmentCount = index ;
309
- return segmentPool [ index ] ;
310
- }
311
- }
312
-
313
- return new BufferSegment ( ) ;
314
- }
315
-
316
- private void ReturnSegments ( BufferSegment from , BufferSegment toExclusive )
317
- {
318
- Debug . Assert ( from != null ) ;
319
- Debug . Assert ( from != toExclusive ) ;
320
-
321
- // Reset the Segments and return their data out of lock
322
- BufferSegment [ ] segmentToReturn = _bufferSegmentsToReturn ;
323
- int count = 0 ;
324
- do
325
- {
326
- BufferSegment next = from . NextSegment ;
327
- Debug . Assert ( next != null || toExclusive == null ) ;
328
-
329
- from . ResetMemory ( ) ;
330
-
331
- if ( ( uint ) count < ( uint ) segmentToReturn . Length )
332
- {
333
- // Store in temporary list while preforming expensive resets
334
- segmentToReturn [ count ] = from ;
335
- count ++ ;
336
- }
337
-
338
- from = next ;
339
- } while ( from != toExclusive ) ;
340
-
341
- // Add the Segments back to pool from the temporary list under lock
342
- BufferSegment [ ] segmentPool = _bufferSegmentPool ;
343
- lock ( segmentPool )
344
- {
345
- int index = _pooledSegmentCount ;
346
- for ( int i = 0 ; i < count ; i ++ )
347
- {
348
- if ( ( uint ) index < ( uint ) segmentPool . Length )
349
- {
350
- segmentPool [ index ] = segmentToReturn [ i ] ;
351
- index ++ ;
352
- }
353
- segmentToReturn [ i ] = null ;
354
- }
355
-
356
- _pooledSegmentCount = index ;
357
- }
358
- }
359
-
360
297
internal bool CommitUnsynchronized ( )
361
298
{
362
299
_operationState . EndWrite ( ) ;
@@ -1115,5 +1052,97 @@ public void Reset()
1115
1052
ResetState ( ) ;
1116
1053
}
1117
1054
}
1055
+
1056
+ private BufferSegment CreateSegmentSynchronized ( )
1057
+ {
1058
+ SegmentAsValue [ ] segmentPool = _bufferSegmentPool ;
1059
+ lock ( segmentPool )
1060
+ {
1061
+ int index = _pooledSegmentCount - 1 ;
1062
+ if ( ( uint ) index < ( uint ) segmentPool . Length )
1063
+ {
1064
+ _pooledSegmentCount = index ;
1065
+ return segmentPool [ index ] ;
1066
+ }
1067
+ }
1068
+
1069
+ return new BufferSegment ( ) ;
1070
+ }
1071
+
1072
+ private void ReturnSegments ( BufferSegment from , BufferSegment toExclusive )
1073
+ {
1074
+ Debug . Assert ( from != null ) ;
1075
+ Debug . Assert ( from != toExclusive ) ;
1076
+
1077
+ // Reset the Segments and return their data out of lock
1078
+ ValueSegmentList segmentsToReturn = default ;
1079
+ ref var startSegment = ref segmentsToReturn . Segment00 ;
1080
+ int count = 0 ;
1081
+ do
1082
+ {
1083
+ BufferSegment next = from . NextSegment ;
1084
+ Debug . Assert ( next != null || toExclusive == null ) ;
1085
+
1086
+ from . ResetMemory ( ) ;
1087
+
1088
+ if ( ( uint ) count < ( uint ) SegmentPoolSize )
1089
+ {
1090
+ // Store in temporary list while preforming expensive resets
1091
+ Unsafe . Add ( ref startSegment , count ) = from ;
1092
+ count ++ ;
1093
+ }
1094
+
1095
+ from = next ;
1096
+ } while ( from != toExclusive ) ;
1097
+
1098
+ // Add the Segments back to pool from the temporary list under lock
1099
+ SegmentAsValue [ ] segmentPool = _bufferSegmentPool ;
1100
+ lock ( segmentPool )
1101
+ {
1102
+ int index = _pooledSegmentCount ;
1103
+ for ( int i = 0 ; i < count ; i ++ )
1104
+ {
1105
+ if ( ( uint ) index < ( uint ) segmentPool . Length )
1106
+ {
1107
+ segmentPool [ index ] = Unsafe . Add ( ref startSegment , i ) ;
1108
+ index ++ ;
1109
+ }
1110
+ }
1111
+
1112
+ _pooledSegmentCount = index ;
1113
+ }
1114
+ }
1115
+
1116
+ // Used to avoid covariant checks on the array
1117
+ private readonly struct SegmentAsValue
1118
+ {
1119
+ private readonly BufferSegment _bufferSegment ;
1120
+ public SegmentAsValue ( BufferSegment bufferSegment ) => _bufferSegment = bufferSegment ;
1121
+ public static implicit operator SegmentAsValue ( BufferSegment b ) => new SegmentAsValue ( b ) ;
1122
+ public static implicit operator BufferSegment ( SegmentAsValue s ) => s . _bufferSegment ;
1123
+ }
1124
+
1125
+ // Temporary list to hold Segments return while being reset
1126
+ #pragma warning disable CS0649
1127
+ private ref struct ValueSegmentList
1128
+ {
1129
+ public BufferSegment Segment00 ;
1130
+ public BufferSegment Segment01 ;
1131
+ public BufferSegment Segment02 ;
1132
+ public BufferSegment Segment03 ;
1133
+ public BufferSegment Segment04 ;
1134
+ public BufferSegment Segment05 ;
1135
+ public BufferSegment Segment06 ;
1136
+ public BufferSegment Segment07 ;
1137
+ public BufferSegment Segment08 ;
1138
+ public BufferSegment Segment09 ;
1139
+ public BufferSegment Segment10 ;
1140
+ public BufferSegment Segment11 ;
1141
+ public BufferSegment Segment12 ;
1142
+ public BufferSegment Segment13 ;
1143
+ public BufferSegment Segment14 ;
1144
+ public BufferSegment Segment15 ;
1145
+ }
1146
+ #pragma warning enable CS0649
1118
1147
}
1119
1148
}
0 commit comments