public                       DirectBuffer this[int index]
 {
     [MethodImpl(MethodImplOptions.AggressiveInlining)]
     get
     {
         if ((uint)index >= BufferCount)
         {
             BuffersThrowHelper.ThrowIndexOutOfRange();
         }
         // ReSharper disable once ImpureMethodCallOnReadonlyValueField
         return(DirectBuffer.Slice(index * BufferSize, BufferSize));
     }
 }
Esempio n. 2
0
        internal unsafe SharedMemoryPool(string path, uint maxLogSizeMb,
                                         LMDBEnvironmentFlags envFlags,
                                         Wpid ownerId,
                                         int rmMaxBufferLength     = RmDefaultMaxBufferLength,
                                         int rmMaxBuffersPerBucket = RmDefaultMaxBuffersPerBucket, bool rentAlwaysClean = false)
            : base(
                (pool, bucketSize) =>
        {
            if (bucketSize > pool.MaxBufferSize)
            {
                BuffersThrowHelper.ThrowBadLength();
            }
            var smbp = (SharedMemoryPool)pool;

#pragma warning disable 618
            var sm = smbp.RentNative(bucketSize);

            Debug.Assert(!sm.IsDisposed);
            Debug.Assert(sm.ReferenceCount == 0);
            Debug.Assert(Unsafe.ReadUnaligned <uint>(sm.HeaderPointer) == HeaderFlags.IsOwned);
#pragma warning restore 618

            // TODO review if Releasing -> IsOwned should keep disposed state?
            // RMP calls CreateNew outside lock, so if we call RentNative only here
            // then it could return IsOwned without IsDisposed. But we a technically
            // inside the pool until this factory returns. Buffers from RentNative
            // should be unusable without explicit un-dispose action.

            // Set counter to zero
            sm.CounterRef &= ~AtomicCounter.CountMask;

            return(sm);
        },
                RmMinPoolBufferLength,
                Math.Max(RmDefaultMaxBufferLength, Math.Min(RmMaxPoolBufferLength, BitUtil.FindNextPositivePowerOfTwo(rmMaxBufferLength))),
                // from ProcCount to DefaultMaxNumberOfBuffersPerBucket x 2
                Math.Max(Environment.ProcessorCount, Math.Min(RmDefaultMaxBuffersPerBucket * 2, rmMaxBuffersPerBucket)),
                MaxBucketsToTry, rentAlwaysClean: rentAlwaysClean)
        {
            if (ownerId <= 0)
            {
                ThrowHelper.ThrowArgumentOutOfRangeException("ownerId <= 0");
            }

            Directory.CreateDirectory(path);

            _bra     = new BufferRefAllocator(path, envFlags, ownerId, PageSize, maxLogSizeMb * 1024 * 1024L);
            _buckets = new SharedMemoryBuckets(Path.Combine(path, "buckets"), pageSize: PageSize, maxBucketIndex: BufferRef.MaxBucketIdx);

            StartMonitoringTask();
        }
Esempio n. 3
0
        public T Rent()
        {
            if (_disposed)
            {
                BuffersThrowHelper.ThrowDisposed <LockedObjectPool <T> >();
            }

            var objects = _objects;
            T   obj     = null;

            var allocate = false;

#if !NETCOREAPP
            try
#endif
            {
                var spinner = new SpinWait();
                while (0 != Interlocked.CompareExchange(ref _locker, 1, 0))
                {
                    spinner.SpinOnce();
                }

                if (_index < objects.Length)
                {
                    obj = objects[_index];
                    objects[_index++] = null;
                    allocate          = obj == null;
                }
            }
#if !NETCOREAPP
            finally
#endif
            {
                Volatile.Write(ref _locker, 0);
            }

            if (allocate || (obj == null && AllocateOnEmpty))
            {
                if (TraceLowCapacityAllocation && !allocate)
                {
                    DoTrace();
                }
                obj = CreateNewObject();
            }

            return(obj);
        }
Esempio n. 4
0
        public static int IndexToOffset(int index, int head, int len)
        {
            if (AdditionalCorrectnessChecks.Enabled && (head < 0 || len < 0))
            {
                BuffersThrowHelper.ThrowIndexOutOfRange();
            }
            // return (head + index) % len;
            // len is not guaranteed to be power of 2, cannot use bit mask
            // but we could avoid branch: we do not need modulo
            // instead we only need to subtract len if we wrap over it
            var offset    = head + index;
            var isWrapped = (len - (offset + 1)) >> 31; // 0 or -1
            var result    = offset + isWrapped * len;

            if (AdditionalCorrectnessChecks.Enabled)
            {
                ThrowHelper.Assert(result >= 0);
                ThrowHelper.Assert(result < len);
            }

            return(result);
        }
Esempio n. 5
0
        internal T?Rent(int cpuId)
        {
            if (_disposed)
            {
                BuffersThrowHelper.ThrowDisposed <LockedObjectPool <T> >();
            }

            T?obj;

            for (int i = 0; i <= Cpu.CoreCount; i++)
            {
                if ((obj = _perCorePools[cpuId].Rent()) != null)
                {
                    return(obj);
                }

                if (++cpuId == Cpu.CoreCount)
                {
                    cpuId = 0;
                }
            }

            return(RentSlow());
        }