diff options
Diffstat (limited to 'ARMeilleure/Memory/ReservedRegion.cs')
-rw-r--r-- | ARMeilleure/Memory/ReservedRegion.cs | 53 |
1 files changed, 53 insertions, 0 deletions
diff --git a/ARMeilleure/Memory/ReservedRegion.cs b/ARMeilleure/Memory/ReservedRegion.cs new file mode 100644 index 00000000..521019ad --- /dev/null +++ b/ARMeilleure/Memory/ReservedRegion.cs @@ -0,0 +1,53 @@ +using System; +using System.Collections.Generic; +using System.Text; + +namespace ARMeilleure.Memory +{ + class ReservedRegion + { + private const int DefaultGranularity = 65536; // Mapping granularity in Windows. + + public IntPtr Pointer { get; } + + private ulong _maxSize; + private ulong _sizeGranularity; + private ulong _currentSize; + + public ReservedRegion(ulong maxSize, ulong granularity = 0) + { + if (granularity == 0) + { + granularity = DefaultGranularity; + } + + Pointer = MemoryManagement.Reserve(maxSize); + _maxSize = maxSize; + _sizeGranularity = granularity; + _currentSize = 0; + } + + public void ExpandIfNeeded(ulong desiredSize) + { + if (desiredSize > _maxSize) + { + throw new OutOfMemoryException(); + } + + if (desiredSize > _currentSize) + { + // Lock, and then check again. We only want to commit once. + lock (this) + { + if (desiredSize >= _currentSize) + { + ulong overflowBytes = desiredSize - _currentSize; + ulong moreToCommit = (((_sizeGranularity - 1) + overflowBytes) / _sizeGranularity) * _sizeGranularity; // Round up. + MemoryManagement.Commit(new IntPtr((long)Pointer + (long)_currentSize), moreToCommit); + _currentSize += moreToCommit; + } + } + } + } + } +} |