1
1
// Copyright (c) Microsoft. All rights reserved.
2
2
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
3
3
4
- using System . Runtime . InteropServices ;
5
-
6
4
namespace System . Buffers
7
5
{
8
6
/// <summary>
@@ -11,70 +9,34 @@ namespace System.Buffers
11
9
/// </summary>
12
10
internal class MemoryPoolSlab : IDisposable
13
11
{
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 )
22
13
{
23
- Array = data ;
24
- _gcHandle = GCHandle . Alloc ( data , GCHandleType . Pinned ) ;
25
- NativePointer = _gcHandle . AddrOfPinnedObject ( ) ;
14
+ PinnedArray = pinnedData ;
26
15
}
27
16
28
17
/// <summary>
29
18
/// True as long as the blocks from this slab are to be considered returnable to the pool. In order to shrink the
30
19
/// memory pool size an entire slab must be removed. That is done by (1) setting IsActive to false and removing the
31
20
/// slab from the pool's _slabs collection, (2) as each block currently in use is Return()ed to the pool it will
32
21
/// 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
35
23
/// </summary>
36
- public bool IsActive => ! _isDisposed ;
24
+ public bool IsActive => PinnedArray != null ;
37
25
38
- public IntPtr NativePointer { get ; private set ; }
39
-
40
- public byte [ ] Array { get ; private set ; }
26
+ public byte [ ] PinnedArray { get ; private set ; }
41
27
42
28
public static MemoryPoolSlab Create ( int length )
43
29
{
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 ) ;
46
32
47
33
// 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 ) ;
72
35
}
73
36
74
37
public void Dispose ( )
75
38
{
76
- Dispose ( true ) ;
77
- GC . SuppressFinalize ( this ) ;
39
+ PinnedArray = null ;
78
40
}
79
41
}
80
42
}
0 commit comments