Lock-free buffer pool implementation, it is more simple solution than classic memory manager algorithms (e.g. buddy memory manager). But it should use less extra calculation for allocation and freeing buffers. It like "smart" buffer pool, it slices desired sizes, and do not free slices but put it in pool for further using. So big buffer should be sliced for concrete application.
コード例 #1
0
        public ArraySegment <byte> Allocate(int size)
        {
            if (size > 262144)
            {
                throw new ArgumentOutOfRangeException("Too large size");
            }
            size = 1024 << this.GetBitOffset(size);
            int num;
            int num2;

            if (!this.GetAllocated(size, out num, out num2))
            {
                while (true)
                {
                    long num3 = Interlocked.Read(ref this.indexOffset);
                    num2 = (int)num3;
                    num  = (int)(num3 >> 32);
                    while (this.buffers[num] == null)
                    {
                        Thread.Sleep(0);
                    }
                    if (this.buffers[num].Length - num2 < size)
                    {
                        if (num + 1 >= this.buffers.Length)
                        {
                            break;
                        }
                        if (Interlocked.CompareExchange(ref this.indexOffset, (long)(num + 1) << 32, num3) == num3)
                        {
                            this.buffers[num + 1] = SmartBufferPool.NewBuffer(this.ExtraMemoryUsage);
                        }
                    }
                    if (Interlocked.CompareExchange(ref this.indexOffset, num3 + (long)size, num3) == num3)
                    {
                        goto IL_C4;
                    }
                }
                throw new OutOfMemoryException("Source: BufferManager");
            }
IL_C4:
            return(new ArraySegment <byte>(this.buffers[num], num2, size));
        }
コード例 #2
0
        public SmartBufferPool(int maxMemoryUsageMb, int initialSizeMb, int extraBufferSizeMb)
        {
            this.InitialMemoryUsage = (long)initialSizeMb * 1048576L;
            this.ExtraMemoryUsage   = (long)extraBufferSizeMb * 1048576L;
            this.MaxBuffersCount    = ((long)maxMemoryUsageMb * 1048576L - this.InitialMemoryUsage) / this.ExtraMemoryUsage;
            this.MaxMemoryUsage     = this.InitialMemoryUsage + this.ExtraMemoryUsage * this.MaxBuffersCount;
            this.array = new LockFreeItem <long> [this.MaxMemoryUsage / 1024L];
            this.empty = new LockFreeStack <long>(this.array, 0, this.array.Length);
            int num = 0;

            while (262144 >> num >= 1024)
            {
                num++;
            }
            this.ready = new LockFreeStack <long> [num];
            for (int i = 0; i < this.ready.Length; i++)
            {
                this.ready[i] = new LockFreeStack <long>(this.array, -1, -1);
            }
            this.buffers    = new byte[this.MaxBuffersCount][];
            this.buffers[0] = SmartBufferPool.NewBuffer(this.InitialMemoryUsage);
        }
コード例 #3
0
 public static void Initialize(int maxMemoryUsageMb)
 {
     BufferManager.pool = new SmartBufferPool(maxMemoryUsageMb, maxMemoryUsageMb / 8, maxMemoryUsageMb / 16);
 }
コード例 #4
0
 public static void Initialize(int maxMemoryUsageMb, int initialSizeMb, int extraBufferSizeMb)
 {
     BufferManager.pool = new SmartBufferPool(maxMemoryUsageMb, initialSizeMb, extraBufferSizeMb);
 }