public Span <byte> Rent(int numberOfElements, bool clearBuffer = false) { if (_disposed) { throw new ObjectDisposedException("NativeBufferPool"); } Span <byte> buffer; if (numberOfElements > _maxElements) { #if DEBUG System.Diagnostics.Debugger.Break(); #endif buffer = new Span <byte>(Marshal.AllocHGlobal(numberOfElements * Marshal.SizeOf(typeof(byte))).ToPointer(), numberOfElements); } else { int index = BufferUtilities.SelectBucketIndex(numberOfElements); NativeBufferBucket bucket = Volatile.Read(ref _buckets[index]); if (bucket == null) { NativeBufferBucket newBucket = new NativeBufferBucket(BufferUtilities.GetMaxSizeForBucket(index), NUMBER_OF_BUFFERS_IN_BUCKET); if (Interlocked.CompareExchange(ref _buckets[index], newBucket, null) != null) { newBucket.Dispose(); } bucket = _buckets[index]; } var rented = bucket.Rent(); buffer = new Span <byte>(rented._memory, rented._length); } if (clearBuffer) { BufferUtilities.ClearSpan(buffer); } return(buffer); }
public void Return(Span <byte> buffer, bool clearBuffer = false) { if (_disposed) { throw new ObjectDisposedException("NativeBufferPool"); } if (clearBuffer) { BufferUtilities.ClearSpan(buffer); } if (buffer.Length > _maxElements) { Marshal.FreeHGlobal(new IntPtr(buffer.UnsafePointer)); } else { _buckets[BufferUtilities.SelectBucketIndex(buffer.Length)].Return(new NativeBuffer(buffer.UnsafePointer, 0)); } }