/// <inheritdoc /> internal override MemoryGroup <T> AllocateGroup <T>( long totalLength, int bufferAlignment, AllocationOptions options = AllocationOptions.None) { long totalLengthInBytes = totalLength * Unsafe.SizeOf <T>(); if (totalLengthInBytes <= this.sharedArrayPoolThresholdInBytes) { var buffer = new SharedArrayPoolBuffer <T>((int)totalLength); return(MemoryGroup <T> .CreateContiguous(buffer, options.Has(AllocationOptions.Clean))); } if (totalLengthInBytes <= this.poolBufferSizeInBytes) { // Optimized path renting single array from the pool UnmanagedMemoryHandle mem = this.pool.Rent(); if (mem.IsValid) { UnmanagedBuffer <T> buffer = this.pool.CreateGuardedBuffer <T>(mem, (int)totalLength, options.Has(AllocationOptions.Clean)); return(MemoryGroup <T> .CreateContiguous(buffer, options.Has(AllocationOptions.Clean))); } } // Attempt to rent the whole group from the pool, allocate a group of unmanaged buffers if the attempt fails: if (MemoryGroup <T> .TryAllocate(this.pool, totalLength, bufferAlignment, options, out MemoryGroup <T> poolGroup)) { return(poolGroup); } return(MemoryGroup <T> .Allocate(this.nonPoolAllocator, totalLength, bufferAlignment, options)); }
/// <inheritdoc /> public override IMemoryOwner <T> Allocate <T>( int length, AllocationOptions options = AllocationOptions.None) { Guard.MustBeGreaterThanOrEqualTo(length, 0, nameof(length)); int lengthInBytes = length * Unsafe.SizeOf <T>(); if (lengthInBytes <= this.sharedArrayPoolThresholdInBytes) { var buffer = new SharedArrayPoolBuffer <T>(length); if (options.Has(AllocationOptions.Clean)) { buffer.GetSpan().Clear(); } return(buffer); } if (lengthInBytes <= this.poolBufferSizeInBytes) { UnmanagedMemoryHandle mem = this.pool.Rent(); if (mem.IsValid) { UnmanagedBuffer <T> buffer = this.pool.CreateGuardedBuffer <T>(mem, length, options.Has(AllocationOptions.Clean)); return(buffer); } } return(this.nonPoolAllocator.Allocate <T>(length, options)); }
public void Free_ClosesHandle() { var h = UnmanagedMemoryHandle.Allocate(128); h.Free(); Assert.True(h.IsInvalid); Assert.Equal(IntPtr.Zero, h.Handle); }
private protected UnmanagedMemoryManager(int length, bool zeroMem) { var size = UnmanagedMemoryHandle.SizeOf <T>(length); address = Marshal.AllocHGlobal(new IntPtr(size)); GC.AddMemoryPressure(size); Length = length; if (zeroMem) { Runtime.InteropServices.Memory.ClearBits(address, size); } owner = true; }
public UnmanagedBuffer <T> CreateGuardedBuffer <T>( UnmanagedMemoryHandle handle, int lengthInElements, bool clear) where T : struct { var buffer = new UnmanagedBuffer <T>(lengthInElements, new ReturnToPoolBufferLifetimeGuard(this, handle)); if (clear) { buffer.Clear(); } return(buffer); }
static void RunTest(string countStr) { int countInner = int.Parse(countStr); var l = new List <UnmanagedMemoryHandle>(); for (int i = 0; i < countInner; i++) { Assert.Equal(i, UnmanagedMemoryHandle.TotalOutstandingHandles); var h = UnmanagedMemoryHandle.Allocate(42); Assert.Equal(i + 1, UnmanagedMemoryHandle.TotalOutstandingHandles); l.Add(h); } for (int i = 0; i < countInner; i++) { Assert.Equal(countInner - i, UnmanagedMemoryHandle.TotalOutstandingHandles); l[i].Free(); Assert.Equal(countInner - i - 1, UnmanagedMemoryHandle.TotalOutstandingHandles); } }
public unsafe void Allocate_AllocatesReadWriteMemory() { var h = UnmanagedMemoryHandle.Allocate(128); Assert.False(h.IsInvalid); Assert.True(h.IsValid); byte *ptr = (byte *)h.Handle; for (int i = 0; i < 128; i++) { ptr[i] = (byte)i; } for (int i = 0; i < 128; i++) { Assert.Equal((byte)i, ptr[i]); } h.Free(); }
public ReturnToPoolBufferLifetimeGuard(UniformUnmanagedMemoryPool pool, UnmanagedMemoryHandle handle) : base(handle) => this.pool = pool;
public FreeHandle(UnmanagedMemoryHandle handle) : base(handle) { }
protected UnmanagedBufferLifetimeGuard(UnmanagedMemoryHandle handle) => this.handle = handle;