Skip to content

Commit

Permalink
Add VirtualArena.Reset(VirtualArenaResetKind resetKind) to allow to…
Browse files Browse the repository at this point in the history
… decommit partial committed memory
  • Loading branch information
xoofx committed Sep 17, 2022
1 parent 5028b82 commit d7dc8eb
Show file tree
Hide file tree
Showing 3 changed files with 80 additions and 3 deletions.
14 changes: 14 additions & 0 deletions src/Varena.Tests/TestVirtualArena.cs
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,20 @@ public void TestCreateBufferReset()
var span2 = buffer.AllocateRange(1024);
Assert.AreEqual((nuint)1024, buffer.AllocatedBytes);
Assert.AreEqual((nuint)1 << 16, buffer.CommittedBytes);
buffer.Reset(VirtualArenaResetKind.KeepMinimalCommitted);
Assert.AreEqual((nuint)1 << 16, buffer.CommittedBytes);
buffer.Reset(VirtualArenaResetKind.KeepAllCommitted);
Assert.AreEqual((nuint)1 << 16, buffer.CommittedBytes);

// Allocate a bit more than one commit block
buffer.AllocateRange(1024 + (1 << 16));
Assert.AreEqual((nuint)2 << 16, buffer.CommittedBytes);
buffer.Reset(VirtualArenaResetKind.KeepAllCommitted);
Assert.AreEqual((nuint)2 << 16, buffer.CommittedBytes);
buffer.Reset(VirtualArenaResetKind.KeepMinimalCommitted);
Assert.AreEqual((nuint)1 << 16, buffer.CommittedBytes);

Assert.Throws<ArgumentOutOfRangeException>(() => buffer.Reset((VirtualArenaResetKind)123));
}

[Test]
Expand Down
43 changes: 40 additions & 3 deletions src/Varena/VirtualArena.cs
Original file line number Diff line number Diff line change
Expand Up @@ -110,12 +110,49 @@ public void Dispose()
/// <exception cref="VirtualMemoryException">If this method fails to uncommit the memory used by this arena.</exception>
public void Reset()
{
if (CapacityInBytes > 0 && !_handler.TryUnCommit(_range))
Reset(VirtualArenaResetKind.Default);
}

/// <summary>
/// Resets the memory allocated by this arena with the specified reset options.
/// </summary>
/// <param name="resetKind">The kind of reset.</param>
/// <exception cref="VirtualMemoryException">If this method fails to uncommit the memory used by this arena.</exception>
public void Reset(VirtualArenaResetKind resetKind)
{
// We decommit only if we have something to decommit.
if (CommittedBytes > 0)
{
throw new VirtualMemoryException($"Unable to un-commit the memory range for the arena `{Name}`");
bool decommitSuccess = true;
switch (resetKind)
{
case VirtualArenaResetKind.Default:
// We decommit the entire committed bytes
decommitSuccess = _handler.TryUnCommit(new VirtualMemoryRange(this.BaseAddress, _committedBytes));
_committedBytes = 0;
break;
case VirtualArenaResetKind.KeepAllCommitted:
break;
case VirtualArenaResetKind.KeepMinimalCommitted:
// We decommit only entire committed bytes
var newCommittedBytes = this.CommitPageSizeMultiplier * this._handler.PageSize;
var bytesToDecommit = _committedBytes - newCommittedBytes;
if (bytesToDecommit > 0)
{
decommitSuccess = _handler.TryUnCommit(new VirtualMemoryRange((nint)this.BaseAddress + (nint)(newCommittedBytes), bytesToDecommit));
}
_committedBytes = newCommittedBytes;
break;
default:
throw new ArgumentOutOfRangeException(nameof(resetKind), resetKind, null);
}

if (!decommitSuccess)
{
throw new VirtualMemoryException($"Unable to un-commit the memory range for the arena `{Name}`");
}
}

_committedBytes = 0;
_allocatedBytes = 0;
ResetImpl();
}
Expand Down
26 changes: 26 additions & 0 deletions src/Varena/VirtualArenaResetKind.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
// Copyright (c) Alexandre Mutel. All rights reserved.
// Licensed under the BSD-Clause 2 license.
// See license.txt file in the project root for full license information.

namespace Varena;

/// <summary>
/// Type of reset for <see cref="VirtualArena.Reset(VirtualArenaResetKind)"/>.
/// </summary>
public enum VirtualArenaResetKind {

/// <summary>
/// All committed bytes are uncommitted.
/// </summary>
Default,

/// <summary>
/// Keep all committed bytes.
/// </summary>
KeepAllCommitted,

/// <summary>
/// Keep minimal committed bytes which is the committed memory page size multiplier.
/// </summary>
KeepMinimalCommitted,
}

0 comments on commit d7dc8eb

Please sign in to comment.