| 1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253 |
- 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;
- }
- }
- }
- }
- }
- }
|