ReservedRegion.cs
1 using System; 2 3 namespace ARMeilleure.Memory 4 { 5 public class ReservedRegion 6 { 7 public const int DefaultGranularity = 65536; // Mapping granularity in Windows. 8 9 public IJitMemoryBlock Block { get; } 10 11 public IntPtr Pointer => Block.Pointer; 12 13 private readonly ulong _maxSize; 14 private readonly ulong _sizeGranularity; 15 private ulong _currentSize; 16 17 public ReservedRegion(IJitMemoryAllocator allocator, ulong maxSize, ulong granularity = 0) 18 { 19 if (granularity == 0) 20 { 21 granularity = DefaultGranularity; 22 } 23 24 Block = allocator.Reserve(maxSize); 25 _maxSize = maxSize; 26 _sizeGranularity = granularity; 27 _currentSize = 0; 28 } 29 30 public void ExpandIfNeeded(ulong desiredSize) 31 { 32 if (desiredSize > _maxSize) 33 { 34 throw new OutOfMemoryException(); 35 } 36 37 if (desiredSize > _currentSize) 38 { 39 // Lock, and then check again. We only want to commit once. 40 lock (this) 41 { 42 if (desiredSize >= _currentSize) 43 { 44 ulong overflowBytes = desiredSize - _currentSize; 45 ulong moreToCommit = (((_sizeGranularity - 1) + overflowBytes) / _sizeGranularity) * _sizeGranularity; // Round up. 46 Block.Commit(_currentSize, moreToCommit); 47 _currentSize += moreToCommit; 48 } 49 } 50 } 51 } 52 53 public void Dispose() 54 { 55 Block.Dispose(); 56 } 57 } 58 }