예제 #1
0
 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!
 }
예제 #2
0
 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);
 }
예제 #3
0
            /// <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;
            }
예제 #4
0
 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;
 }
예제 #5
0
        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);
        }
예제 #6
0
        /// <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);
        }