11// Copyright (c) Microsoft. All rights reserved.
22// Licensed under the MIT license. See LICENSE file in the project root for full license information.
33
4- using System . Runtime . InteropServices ;
5-
64namespace System . Buffers
75{
86 /// <summary>
@@ -11,70 +9,34 @@ namespace System.Buffers
119 /// </summary>
1210 internal class MemoryPoolSlab : IDisposable
1311 {
14- /// <summary>
15- /// This handle pins the managed array in memory until the slab is disposed. This prevents it from being
16- /// relocated and enables any subsections of the array to be used as native memory pointers to P/Invoked API calls.
17- /// </summary>
18- private GCHandle _gcHandle ;
19- private bool _isDisposed ;
20-
21- public MemoryPoolSlab ( byte [ ] data )
12+ private MemoryPoolSlab ( byte [ ] pinnedData )
2213 {
23- Array = data ;
24- _gcHandle = GCHandle . Alloc ( data , GCHandleType . Pinned ) ;
25- NativePointer = _gcHandle . AddrOfPinnedObject ( ) ;
14+ PinnedArray = pinnedData ;
2615 }
2716
2817 /// <summary>
2918 /// True as long as the blocks from this slab are to be considered returnable to the pool. In order to shrink the
3019 /// memory pool size an entire slab must be removed. That is done by (1) setting IsActive to false and removing the
3120 /// slab from the pool's _slabs collection, (2) as each block currently in use is Return()ed to the pool it will
3221 /// be allowed to be garbage collected rather than re-pooled, and (3) when all block tracking objects are garbage
33- /// collected and the slab is no longer references the slab will be garbage collected and the memory unpinned will
34- /// be unpinned by the slab's Dispose.
22+ /// collected and the slab is no longer references the slab will be garbage collected
3523 /// </summary>
36- public bool IsActive => ! _isDisposed ;
24+ public bool IsActive => PinnedArray != null ;
3725
38- public IntPtr NativePointer { get ; private set ; }
39-
40- public byte [ ] Array { get ; private set ; }
26+ public byte [ ] PinnedArray { get ; private set ; }
4127
4228 public static MemoryPoolSlab Create ( int length )
4329 {
44- // allocate and pin requested memory length
45- var array = new byte [ length ] ;
30+ // allocate requested memory length from the pinned memory heap
31+ var pinnedArray = GC . AllocateUninitializedArray < byte > ( length , pinned : true ) ;
4632
4733 // allocate and return slab tracking object
48- return new MemoryPoolSlab ( array ) ;
49- }
50-
51- protected void Dispose ( bool disposing )
52- {
53- if ( _isDisposed )
54- {
55- return ;
56- }
57-
58- _isDisposed = true ;
59-
60- Array = null ;
61- NativePointer = IntPtr . Zero ;
62-
63- if ( _gcHandle . IsAllocated )
64- {
65- _gcHandle . Free ( ) ;
66- }
67- }
68-
69- ~ MemoryPoolSlab ( )
70- {
71- Dispose ( false ) ;
34+ return new MemoryPoolSlab ( pinnedArray ) ;
7235 }
7336
7437 public void Dispose ( )
7538 {
76- Dispose ( true ) ;
77- GC . SuppressFinalize ( this ) ;
39+ PinnedArray = null ;
7840 }
7941 }
8042}
0 commit comments