diff options
author | vnugent <public@vaughnnugent.com> | 2023-01-18 22:43:14 -0500 |
---|---|---|
committer | vnugent <public@vaughnnugent.com> | 2023-01-18 22:43:14 -0500 |
commit | 46caaac9debdaad496c07af9d3806e67a447066c (patch) | |
tree | 750bebaa5f3b59f06792b99de8a6fae995452bca /lib/Utils/src | |
parent | 52b8e30437e235817ed534dec860e781bb0468c0 (diff) |
Heap diag and plugin log file names
Diffstat (limited to 'lib/Utils/src')
-rw-r--r-- | lib/Utils/src/Extensions/TimerExtensions.cs | 4 | ||||
-rw-r--r-- | lib/Utils/src/Extensions/TimerResumeHandle.cs (renamed from lib/Utils/src/Extensions/TimerResetHandle.cs) | 16 | ||||
-rw-r--r-- | lib/Utils/src/Memory/Diagnostics/HeapDiagnosticException.cs | 43 | ||||
-rw-r--r-- | lib/Utils/src/Memory/Diagnostics/HeapStatistics.cs | 76 | ||||
-rw-r--r-- | lib/Utils/src/Memory/Diagnostics/IllegalHeapOperationException.cs | 43 | ||||
-rw-r--r-- | lib/Utils/src/Memory/Diagnostics/TrackedHeapWrapper.cs | 178 | ||||
-rw-r--r-- | lib/Utils/src/Memory/MemoryUtil.cs | 125 | ||||
-rw-r--r-- | lib/Utils/src/Memory/RpMallocPrivateHeap.cs | 2 | ||||
-rw-r--r-- | lib/Utils/src/Memory/Win32PrivateHeap.cs | 4 |
9 files changed, 440 insertions, 51 deletions
diff --git a/lib/Utils/src/Extensions/TimerExtensions.cs b/lib/Utils/src/Extensions/TimerExtensions.cs index 37929bf..328f4da 100644 --- a/lib/Utils/src/Extensions/TimerExtensions.cs +++ b/lib/Utils/src/Extensions/TimerExtensions.cs @@ -47,9 +47,9 @@ namespace VNLib.Utils.Extensions /// <param name="timer"></param> /// <param name="resumeTime"><see cref="TimeSpan"/> representing the amount of time the timer should wait before invoking the callback function</param> /// <returns>A new <see cref="OpenHandle"/> if the timer was stopped successfully that will resume the timer when closed, null otherwise</returns> - public static TimerResetHandle? Stop(this Timer timer, TimeSpan resumeTime) + public static TimerResumeHandle? Stop(this Timer timer, TimeSpan resumeTime) { - return timer.Change(Timeout.Infinite, Timeout.Infinite) ? new TimerResetHandle(timer, resumeTime) : null; + return timer.Change(Timeout.Infinite, Timeout.Infinite) ? new TimerResumeHandle(timer, resumeTime) : null; } /// <summary> diff --git a/lib/Utils/src/Extensions/TimerResetHandle.cs b/lib/Utils/src/Extensions/TimerResumeHandle.cs index 57a71e8..f386974 100644 --- a/lib/Utils/src/Extensions/TimerResetHandle.cs +++ b/lib/Utils/src/Extensions/TimerResumeHandle.cs @@ -3,9 +3,9 @@ * * Library: VNLib * Package: VNLib.Utils -* File: TimerExtensions.cs +* File: TimerResetHandle.cs * -* TimerExtensions.cs is part of VNLib.Utils which is part of the larger +* TimerResetHandle.cs is part of VNLib.Utils which is part of the larger * VNLib collection of libraries and utilities. * * VNLib.Utils is free software: you can redistribute it and/or modify @@ -31,12 +31,12 @@ namespace VNLib.Utils.Extensions /// A handle that represents a paused timer that may be resumed when the handle is disposed /// or the Resume() method is called /// </summary> - public readonly struct TimerResetHandle: IEquatable<TimerResetHandle>, IDisposable + public readonly struct TimerResumeHandle: IEquatable<TimerResumeHandle>, IDisposable { private readonly Timer _timer; private readonly TimeSpan _resumeTime; - internal TimerResetHandle(Timer timer, TimeSpan resumeTime) + internal TimerResumeHandle(Timer timer, TimeSpan resumeTime) { _timer = timer; _resumeTime = resumeTime; @@ -53,14 +53,14 @@ namespace VNLib.Utils.Extensions public void Dispose() => Resume(); ///<inheritdoc/> - public bool Equals(TimerResetHandle other) => _timer.Equals(other) && _resumeTime == other._resumeTime; + public bool Equals(TimerResumeHandle other) => _timer.Equals(other) && _resumeTime == other._resumeTime; ///<inheritdoc/> - public override bool Equals(object? obj) => obj is TimerResetHandle trh && Equals(trh); + public override bool Equals(object? obj) => obj is TimerResumeHandle trh && Equals(trh); ///<inheritdoc/> public override int GetHashCode() => _timer.GetHashCode() + _resumeTime.GetHashCode(); ///<inheritdoc/> - public static bool operator ==(TimerResetHandle left, TimerResetHandle right) => left.Equals(right); + public static bool operator ==(TimerResumeHandle left, TimerResumeHandle right) => left.Equals(right); ///<inheritdoc/> - public static bool operator !=(TimerResetHandle left, TimerResetHandle right) => !(left == right); + public static bool operator !=(TimerResumeHandle left, TimerResumeHandle right) => !(left == right); } }
\ No newline at end of file diff --git a/lib/Utils/src/Memory/Diagnostics/HeapDiagnosticException.cs b/lib/Utils/src/Memory/Diagnostics/HeapDiagnosticException.cs new file mode 100644 index 0000000..af76f6e --- /dev/null +++ b/lib/Utils/src/Memory/Diagnostics/HeapDiagnosticException.cs @@ -0,0 +1,43 @@ +/* +* Copyright (c) 2022 Vaughn Nugent +* +* Library: VNLib +* Package: VNLib.Utils +* File: HeapDiagnosticException.cs +* +* HeapDiagnosticException.cs is part of VNLib.Utils which is part of the larger +* VNLib collection of libraries and utilities. +* +* VNLib.Utils is free software: you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published +* by the Free Software Foundation, either version 2 of the License, +* or (at your option) any later version. +* +* VNLib.Utils is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +* General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with VNLib.Utils. If not, see http://www.gnu.org/licenses/. +*/ + +using System; + +namespace VNLib.Utils.Memory.Diagnostics +{ + /// <summary> + /// A base class for heap memory diagnostics exceptions + /// </summary> + public class HeapDiagnosticException : NativeMemoryException + { + public HeapDiagnosticException(string message) : base(message) + {} + + public HeapDiagnosticException() + {} + + public HeapDiagnosticException(string message, Exception innerException) : base(message, innerException) + {} + } +} diff --git a/lib/Utils/src/Memory/Diagnostics/HeapStatistics.cs b/lib/Utils/src/Memory/Diagnostics/HeapStatistics.cs new file mode 100644 index 0000000..ec9fe0c --- /dev/null +++ b/lib/Utils/src/Memory/Diagnostics/HeapStatistics.cs @@ -0,0 +1,76 @@ +/* +* Copyright (c) 2022 Vaughn Nugent +* +* Library: VNLib +* Package: VNLib.Utils +* File: HeapStatistics.cs +* +* HeapStatistics.cs is part of VNLib.Utils which is part of the larger +* VNLib collection of libraries and utilities. +* +* VNLib.Utils is free software: you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published +* by the Free Software Foundation, either version 2 of the License, +* or (at your option) any later version. +* +* VNLib.Utils is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +* General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with VNLib.Utils. If not, see http://www.gnu.org/licenses/. +*/ + +using System; + +namespace VNLib.Utils.Memory.Diagnostics +{ + /// <summary> + /// A structures that represents the current/last captures + /// statistics of the monitored heap + /// </summary> + public readonly struct HeapStatistics : IEquatable<HeapStatistics> + { + /// <summary> + /// The current size (in bytes) of the heap + /// </summary> + public readonly ulong AllocatedBytes { get; init; } + /// <summary> + /// The largest block size seen + /// </summary> + public readonly ulong MaxBlockSize { get; init; } + /// <summary> + /// The largest size of the heap, in bytes. + /// </summary> + public readonly ulong MaxHeapSize { get; init; } + /// <summary> + /// The smallest block size seen allocated + /// </summary> + public readonly ulong MinBlockSize { get; init; } + /// <summary> + /// The number of allocated handles/blocks + /// </summary> + public readonly ulong AllocatedBlocks { get; init; } + + ///<inheritdoc/> + public override bool Equals(object? obj) => obj is HeapStatistics s && Equals(s); + + ///<inheritdoc/> + public override int GetHashCode() => (int)((AllocatedBytes ^ MaxBlockSize) & int.MaxValue); + + ///<inheritdoc/> + public static bool operator ==(HeapStatistics left, HeapStatistics right) => left.Equals(right); + ///<inheritdoc/> + public static bool operator !=(HeapStatistics left, HeapStatistics right) => !(left == right); + + ///<inheritdoc/> + public bool Equals(HeapStatistics other) + { + return MinBlockSize == other.MinBlockSize + && MaxBlockSize == other.MaxBlockSize + && MaxHeapSize == other.MaxHeapSize + && AllocatedBytes == other.AllocatedBytes; + } + } +} diff --git a/lib/Utils/src/Memory/Diagnostics/IllegalHeapOperationException.cs b/lib/Utils/src/Memory/Diagnostics/IllegalHeapOperationException.cs new file mode 100644 index 0000000..6b608f2 --- /dev/null +++ b/lib/Utils/src/Memory/Diagnostics/IllegalHeapOperationException.cs @@ -0,0 +1,43 @@ +/* +* Copyright (c) 2022 Vaughn Nugent +* +* Library: VNLib +* Package: VNLib.Utils +* File: IllegalHeapOperationException.cs +* +* IllegalHeapOperationException.cs is part of VNLib.Utils which is part of the larger +* VNLib collection of libraries and utilities. +* +* VNLib.Utils is free software: you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published +* by the Free Software Foundation, either version 2 of the License, +* or (at your option) any later version. +* +* VNLib.Utils is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +* General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with VNLib.Utils. If not, see http://www.gnu.org/licenses/. +*/ + +using System; + +namespace VNLib.Utils.Memory.Diagnostics +{ + /// <summary> + /// An exception that represents an illegal memory operation during heap monitoring + /// </summary> + public class IllegalHeapOperationException : HeapDiagnosticException + { + public IllegalHeapOperationException(string message) : base(message) + {} + + public IllegalHeapOperationException(string message, Exception innerException) : base(message, innerException) + {} + + public IllegalHeapOperationException() + {} + } +} diff --git a/lib/Utils/src/Memory/Diagnostics/TrackedHeapWrapper.cs b/lib/Utils/src/Memory/Diagnostics/TrackedHeapWrapper.cs new file mode 100644 index 0000000..2069d08 --- /dev/null +++ b/lib/Utils/src/Memory/Diagnostics/TrackedHeapWrapper.cs @@ -0,0 +1,178 @@ +/* +* Copyright (c) 2022 Vaughn Nugent +* +* Library: VNLib +* Package: VNLib.Utils +* File: TrackedHeapWrapper.cs +* +* TrackedHeapWrapper.cs is part of VNLib.Utils which is part of the larger +* VNLib collection of libraries and utilities. +* +* VNLib.Utils is free software: you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published +* by the Free Software Foundation, either version 2 of the License, +* or (at your option) any later version. +* +* VNLib.Utils is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +* General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with VNLib.Utils. If not, see http://www.gnu.org/licenses/. +*/ + +using System; +using System.Collections; +using System.Collections.Concurrent; + + +namespace VNLib.Utils.Memory.Diagnostics +{ + /// <summary> + /// A wrapper for <see cref="IUnmangedHeap"/> that tracks + /// statistics for memory allocations. + /// </summary> + public class TrackedHeapWrapper : VnDisposeable, IUnmangedHeap + { + private readonly IUnmangedHeap _heap; + private readonly object _statsLock; + private readonly ConcurrentDictionary<IntPtr, ulong> _table; + + /// <summary> + /// Gets the underlying heap + /// </summary> + protected IUnmangedHeap Heap => _heap; + + /// <summary> + /// Gets the internal lock held when updating statistics + /// during allocations or frees + /// </summary> + protected object StatsLock => _statsLock; + + /* Stats block */ + private ulong _alloctedBytes; + private ulong _maxBlockSize; + private ulong _maxHeapSize; + private ulong _minBlockSize; + + + /// <summary> + /// Creates a new diagnostics wrapper for the heap + /// </summary> + /// <param name="heap">The heap to gather statistics on</param> + public TrackedHeapWrapper(IUnmangedHeap heap) + { + _statsLock = new(); + _table = new(); + _heap = heap; + //Default min block size to 0 + _minBlockSize = ulong.MaxValue; + } + + /// <summary> + /// Captures the current state of the heap. + /// </summary> + /// <returns>A new <see cref="HeapStatistics"/> captured from the current heap</returns> + public HeapStatistics GetCurrentStats() + { + //Aquire stats lock + lock (_statsLock) + { + return new() + { + AllocatedBytes = _alloctedBytes, + MaxBlockSize = _maxBlockSize, + MaxHeapSize = _maxHeapSize, + MinBlockSize = _minBlockSize, + //The number of elements in the table is the number of tacked blocks + AllocatedBlocks = (ulong)_table.Count + }; + } + } + + ///<inheritdoc/> + public IntPtr Alloc(nuint elements, nuint size, bool zero) + { + //Calc the number of bytes allocated + ulong bytes = checked((ulong)elements * (ulong)size); + + //Alloc the block + IntPtr block = Heap.Alloc(elements, size, zero); + + //Store number of bytes allocated + _table[block] = bytes; + + lock (_statsLock) + { + UpdateStats(bytes); + } + + return block; + } + + private void UpdateStats(ulong bytes) + { + //Update stats + _alloctedBytes += bytes; + _maxBlockSize = Math.Max(_maxBlockSize, bytes); + _maxHeapSize = Math.Max(_maxHeapSize, _alloctedBytes); + _minBlockSize = Math.Min(_minBlockSize, bytes); + } + + ///<inheritdoc/> + protected override void Free() + { + Heap.Dispose(); + } + + ///<inheritdoc/> + public bool Free(ref IntPtr block) + { + //Remvoe the block from the table, if it has already been freed, raise exception + if(!_table.TryRemove(block, out ulong bytes)) + { + throw new IllegalHeapOperationException($"Double free detected. The block {block:x} has already been freed."); + } + + //Free the block + bool result = Heap.Free(ref block); + + //Update stats + lock (_statsLock) + { + _alloctedBytes -= bytes; + } + + return result; + } + + ///<inheritdoc/> + public void Resize(ref IntPtr block, nuint elements, nuint size, bool zero) + { + //Store old block pointer + IntPtr oldBlock = block; + + //Cacl new size + ulong newSize = checked((ulong)size * (ulong)elements); + + //resize the block + Heap.Resize(ref block, elements, size, zero); + + //Remove old size + _ = _table.TryRemove(oldBlock, out ulong oldSize); + + //Update new size + _table[block] = newSize; + + lock (_statsLock) + { + //Remove old ref + _alloctedBytes -= oldSize; + + //Update stats + UpdateStats(newSize); + } + } + } +} diff --git a/lib/Utils/src/Memory/MemoryUtil.cs b/lib/Utils/src/Memory/MemoryUtil.cs index 410db6b..c20d956 100644 --- a/lib/Utils/src/Memory/MemoryUtil.cs +++ b/lib/Utils/src/Memory/MemoryUtil.cs @@ -3,9 +3,9 @@ * * Library: VNLib * Package: VNLib.Utils -* File: Memory.cs +* File: MemoryUtil.cs * -* Memory.cs is part of VNLib.Utils which is part of the larger +* MemoryUtil.cs is part of VNLib.Utils which is part of the larger * VNLib collection of libraries and utilities. * * VNLib.Utils is free software: you can redistribute it and/or modify @@ -26,10 +26,12 @@ using System; using System.Buffers; using System.Security; using System.Threading; +using System.Diagnostics; using System.Runtime.InteropServices; using System.Runtime.CompilerServices; using VNLib.Utils.Extensions; +using VNLib.Utils.Memory.Diagnostics; namespace VNLib.Utils.Memory { @@ -40,8 +42,20 @@ namespace VNLib.Utils.Memory [ComVisible(false)] public unsafe static class MemoryUtil { + /// <summary> + /// The environment variable name used to specify the shared heap type + /// to create + /// </summary> public const string SHARED_HEAP_TYPE_ENV= "VNLIB_SHARED_HEAP_TYPE"; + /// <summary> + /// When creating a heap that accepts an initial size, this value is passed + /// to it, otherwise no initial heap size is set. + /// </summary> public const string SHARED_HEAP_INTIAL_SIZE_ENV = "VNLIB_SHARED_HEAP_SIZE"; + /// <summary> + /// The environment variable name used to enable share heap diagnostics + /// </summary> + public const string SHARED_HEAP_ENABLE_DIAGNOISTICS_ENV = "VNLIB_SHARED_HEAP_DIAGNOSTICS"; /// <summary> /// Initial shared heap size (bytes) @@ -70,15 +84,21 @@ namespace VNLib.Utils.Memory private static readonly Lazy<IUnmangedHeap> _sharedHeap = InitHeapInternal(); - //Avoiding statit initializer + //Avoiding static initializer private static Lazy<IUnmangedHeap> InitHeapInternal() { - Lazy<IUnmangedHeap> heap = new (() => InitHeapInternal(true), LazyThreadSafetyMode.PublicationOnly); + //Get env for heap diag + bool enableDiag = Environment.GetEnvironmentVariable(SHARED_HEAP_ENABLE_DIAGNOISTICS_ENV) == "1"; + + Trace.WriteIf(enableDiag, "Shared heap diagnostics enabled"); + + Lazy<IUnmangedHeap> heap = new (() => InitHeapInternal(true, enableDiag), LazyThreadSafetyMode.PublicationOnly); + //Cleanup the heap on process exit AppDomain.CurrentDomain.DomainUnload += DomainUnloaded; + return heap; } - private static void DomainUnloaded(object? sender, EventArgs e) { @@ -90,47 +110,68 @@ namespace VNLib.Utils.Memory } /// <summary> + /// Gets the shared heap statistics if stats are enabled + /// </summary> + /// <returns> + /// The <see cref="HeapStatistics"/> of the shared heap, or an empty + /// <see cref="HeapStatistics"/> if diagnostics are not enabled. + /// </returns> + public static HeapStatistics GetSharedHeapStats() + { + /* + * If heap is allocated and the heap type is a tracked heap, + * get the heap's stats, otherwise return an empty handle + */ + return _sharedHeap.IsValueCreated && _sharedHeap.Value is TrackedHeapWrapper h + ? h.GetCurrentStats() : new HeapStatistics(); + } + + /// <summary> /// Initializes a new <see cref="IUnmangedHeap"/> determined by compilation/runtime flags /// and operating system type for the current proccess. /// </summary> /// <returns>An <see cref="IUnmangedHeap"/> for the current process</returns> /// <exception cref="SystemException"></exception> /// <exception cref="DllNotFoundException"></exception> - public static IUnmangedHeap InitializeNewHeapForProcess() => InitHeapInternal(false); + public static IUnmangedHeap InitializeNewHeapForProcess() => InitHeapInternal(false, false); - private static IUnmangedHeap InitHeapInternal(bool isShared) + private static IUnmangedHeap InitHeapInternal(bool isShared, bool enableStats) { bool IsWindows = OperatingSystem.IsWindows(); + //Get environment varable string? heapType = Environment.GetEnvironmentVariable(SHARED_HEAP_TYPE_ENV); + //Get inital size string? sharedSize = Environment.GetEnvironmentVariable(SHARED_HEAP_INTIAL_SIZE_ENV); + //Try to parse the shared size from the env if (!nuint.TryParse(sharedSize, out nuint defaultSize)) { defaultSize = SHARED_HEAP_INIT_SIZE; } - //Gen the private heap from its type or default - switch (heapType) + + //convert to upper + heapType = heapType?.ToUpperInvariant(); + + //Create the heap + IUnmangedHeap heap = heapType switch { - case "win32": - if (!IsWindows) - { - throw new PlatformNotSupportedException("Win32 private heaps are not supported on non-windows platforms"); - } - return Win32PrivateHeap.Create(defaultSize); - case "rpmalloc": - //If the shared heap is being allocated, then return a lock free global heap - return isShared ? RpMallocPrivateHeap.GlobalHeap : new RpMallocPrivateHeap(false); - default: - return IsWindows ? Win32PrivateHeap.Create(defaultSize) : new ProcessHeap(); - } + "WIN32" => IsWindows ? Win32PrivateHeap.Create(defaultSize) : throw new PlatformNotSupportedException("Win32 private heaps are not supported on non-windows platforms"), + //If the shared heap is being allocated, then return a lock free global heap + "RPMALLOC" => isShared ? RpMallocPrivateHeap.GlobalHeap : new RpMallocPrivateHeap(false), + //Get the process heap if the heap is shared, otherwise create a new win32 private heap + _ => IsWindows && !isShared ? Win32PrivateHeap.Create(defaultSize) : new ProcessHeap(), + }; + + //If diagnosticts is enabled, wrap the heap in a stats heap + return enableStats ? new TrackedHeapWrapper(heap) : heap; } /// <summary> /// Gets a value that indicates if the Rpmalloc native library is loaded /// </summary> - public static bool IsRpMallocLoaded { get; } = Environment.GetEnvironmentVariable(SHARED_HEAP_TYPE_ENV) == "rpmalloc"; + public static bool IsRpMallocLoaded { get; } = Environment.GetEnvironmentVariable(SHARED_HEAP_TYPE_ENV)?.ToUpperInvariant() == "RPMALLOC"; #region Zero @@ -142,19 +183,23 @@ namespace VNLib.Utils.Memory [MethodImpl(MethodImplOptions.NoInlining | MethodImplOptions.NoOptimization)] public static void UnsafeZeroMemory<T>(ReadOnlySpan<T> block) where T : unmanaged { - if (!block.IsEmpty) + if (block.IsEmpty) + { + return; + } + + uint byteSize = ByteCount<T>((uint)block.Length); + + checked { - checked + fixed (void* ptr = &MemoryMarshal.GetReference(block)) { - fixed (void* ptr = &MemoryMarshal.GetReference(block)) - { - //Calls memset - Unsafe.InitBlock(ptr, 0, (uint)(block.Length * sizeof(T))); - } + //Calls memset + Unsafe.InitBlock(ptr, 0, byteSize); } } } - + /// <summary> /// Zeros a block of memory of umanged type. If Windows is detected at runtime, calls RtlSecureZeroMemory Win32 function /// </summary> @@ -163,15 +208,19 @@ namespace VNLib.Utils.Memory [MethodImpl(MethodImplOptions.NoInlining | MethodImplOptions.NoOptimization)] public static void UnsafeZeroMemory<T>(ReadOnlyMemory<T> block) where T : unmanaged { - if (!block.IsEmpty) + if (block.IsEmpty) { - checked - { - //Pin memory and get pointer - using MemoryHandle handle = block.Pin(); - //Calls memset - Unsafe.InitBlock(handle.Pointer, 0, (uint)(block.Length * sizeof(T))); - } + return; + } + + uint byteSize = ByteCount<T>((uint)block.Length); + + checked + { + //Pin memory and get pointer + using MemoryHandle handle = block.Pin(); + //Calls memset + Unsafe.InitBlock(handle.Pointer, 0, byteSize); } } diff --git a/lib/Utils/src/Memory/RpMallocPrivateHeap.cs b/lib/Utils/src/Memory/RpMallocPrivateHeap.cs index f9b7db6..0af91a0 100644 --- a/lib/Utils/src/Memory/RpMallocPrivateHeap.cs +++ b/lib/Utils/src/Memory/RpMallocPrivateHeap.cs @@ -226,7 +226,7 @@ namespace VNLib.Utils.Memory /// Initializes a new RpMalloc first class heap to allocate memory blocks from /// </summary> /// <param name="zeroAll">A global flag to zero all blocks of memory allocated</param> - /// <exception cref="NativeMemoryOutOfMemoryException"></exception> + /// <exception cref="NativeMemoryException"></exception> public RpMallocPrivateHeap(bool zeroAll):base(zeroAll, true) { //Alloc the heap diff --git a/lib/Utils/src/Memory/Win32PrivateHeap.cs b/lib/Utils/src/Memory/Win32PrivateHeap.cs index fe214f4..bdf22f9 100644 --- a/lib/Utils/src/Memory/Win32PrivateHeap.cs +++ b/lib/Utils/src/Memory/Win32PrivateHeap.cs @@ -3,9 +3,9 @@ * * Library: VNLib * Package: VNLib.Utils -* File: PrivateHeap.cs +* File: Win32PrivateHeap.cs * -* PrivateHeap.cs is part of VNLib.Utils which is part of the larger +* Win32PrivateHeap.cs is part of VNLib.Utils which is part of the larger * VNLib collection of libraries and utilities. * * VNLib.Utils is free software: you can redistribute it and/or modify |