ReservedRegion.cs 1.6 KB

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