internal OffHeapMemory(RetainableMemoryPool <T> pool, int minLength) { _poolIdx = pool == null ? (byte)0 : pool.PoolIdx; // store counter inside the buffer as proof of concept. _isNativeWithHeader = true; Init(minLength); CounterRef = 0; // after init! }
internal OffHeapMemory(RetainableMemoryPool <T> pool, int minLength) : // NOTE: this object must release _counter when finalized or not pooled // Base class calls _counter.Dispose in it's dispose method and this is enough // for shared-memory backed counters. Base class doesn't know about ACS. base(AtomicCounterService.AcquireCounter()) { _pool = pool; Init(minLength); }
/// <summary> /// Creates the pool with numberOfBuffers buffers where each buffer is of bufferLength length. /// </summary> internal Bucket(RetainableMemoryPool <T> pool, Func <RetainableMemoryPool <T>, int, RetainableMemory <T> > factory, int bufferLength, int numberOfBuffers, int poolId) { // _lock = new SpinLock(Debugger.IsAttached); // only enable thread tracking if debugger is attached; it adds non-trivial overheads to Enter/Exit _buffers = new RetainableMemory <T> [numberOfBuffers]; _pool = pool; _factory = factory; _bufferLength = bufferLength; _poolId = poolId; }
public MemoryBucket(RetainableMemoryPool <T> pool, int bufferLength, int perCoreSize) : base(() => new PerCoreMemoryBucket(() => { var memory = pool.Factory(bufferLength); // AtomicCounter.Dispose(ref memory.CounterRef); // ThrowHelper.DebugAssert(memory.IsPooled); return(memory); }, perCoreSize), () => null, // RMP could look inside larger-size buckets and then allocates explicitly unbounded: false) { _pool = pool; BufferLength = bufferLength; }
internal static PrivateMemory <T> Create(int length, RetainableMemoryPool <T> pool) { var cpuId = Cpu.GetCurrentCoreId(); var alignedSize = (uint)BitUtil.FindNextPositivePowerOfTwo(Unsafe.SizeOf <T>()); if ((ulong)length * alignedSize > int.MaxValue) { ThrowHelper.ThrowArgumentOutOfRangeException(nameof(length)); } length = Math.Max(length, Settings.MIN_POOLED_BUFFER_LEN); var privateMemory = ObjectPool.Rent(cpuId); // Clear counter (with flags, PM does not have any flags). // We cannot tell if ObjectPool allocated a new one or took from pool // other then by checking if the counter is disposed, so we cannot require // that the counter is disposed. We only need that pooled object has the counter // in a disposed state so that no one accidentally uses the object while it is in the pool. privateMemory.CounterRef = 0; if (TypeHelper <T> .IsReferenceOrContainsReferences) { privateMemory._array = BufferPool <T> .Rent(length); privateMemory._offset = 0; ThrowHelper.DebugAssert(privateMemory._pointer == null); } else { privateMemory.AllocateBlittable((uint)(length * alignedSize), alignedSize, cpuId); ThrowHelper.DebugAssert(privateMemory._array == null); } privateMemory.PoolIndex = pool is null ? (byte)1 : pool.PoolIdx; privateMemory.Vec = privateMemory.GetVec().AsVec(); return(privateMemory); }
/// <summary> /// Create a <see cref="PrivateMemory{T}"/> from a <see cref="RetainableMemoryPool{T}"/>. /// </summary> internal static PrivateMemory <T> Create(int length, RetainableMemoryPool <T>?pool) { length = Math.Max(length, Settings.MIN_POOLED_BUFFER_LEN); var cpuId = Cpu.GetCurrentCoreId(); var privateMemory = ObjectPool.Rent(cpuId); ThrowHelper.DebugAssert(privateMemory.IsDisposed); // Clear counter (with flags, PM does not have any flags). // We cannot tell if ObjectPool allocated a new one or took from pool // other then by checking if the counter is disposed, so we cannot require // that the counter is disposed. We only need that pooled object has the counter // in a disposed state so that no one accidentally uses the object while it is in the pool. privateMemory.CounterRef = 0; if (TypeHelper <T> .IsReferenceOrContainsReferences) { var arr = BufferPool <T> .Rent(length); privateMemory._array = arr; privateMemory._length = arr.Length; privateMemory._offset = 0; ThrowHelper.DebugAssert(privateMemory._pointer == default); } else { privateMemory.AllocateBlittable(length, cpuId); ThrowHelper.DebugAssert(privateMemory._array == null); } privateMemory.PoolIndex = pool is null ? (byte)1 : pool.PoolIdx; privateMemory._memory = privateMemory.CreateMemory(); return(privateMemory); }