Example #1
0
        /// <summary>
        /// 添加缓冲区
        /// </summary>
        /// <param name="buffer">缓冲区</param>
        internal void Push(ref PoolBuffer buffer)
        {
            if (buffer.Pool == this)
            {
START:
                while (System.Threading.Interlocked.CompareExchange(ref freeBufferLock, 1, 0) != 0)
                {
                    AutoCSer.Threading.ThreadYield.Yield(AutoCSer.Threading.ThreadYield.Type.SubBufferPoolPush);
                }
                if (freeCurrent == freeEnd)
                {
                    if (backFree == null)
                    {
                        System.Threading.Interlocked.Exchange(ref freeBufferLock, 0);
                        Monitor.Enter(createFreeLock);
                        if (backFree != null)
                        {
                            Monitor.Exit(createFreeLock);
                            goto START;
                        }
                        byte *newBackFree;
                        try
                        {
                            newBackFree = UnmanagedPool.Default.Get();
                        }
                        finally { Monitor.Exit(createFreeLock); }
                        while (System.Threading.Interlocked.CompareExchange(ref freeBufferLock, 1, 0) != 0)
                        {
                            AutoCSer.Threading.ThreadYield.Yield(AutoCSer.Threading.ThreadYield.Type.SubBufferPoolSetBackFree);
                        }
                        backFree = newBackFree;
                        if (freeCurrent != freeEnd)
                        {
                            goto PUSH;
                        }
                    }
                    *(byte **)backFree = freeStart;
                    freeEnd            = backFree + UnmanagedPool.DefaultSize;
                    freeCurrent        = (uint *)(freeStart = backFree + sizeof(byte **));
                    backFree           = null;
                }
PUSH:
                *freeCurrent++ = buffer.Index;
                System.Threading.Interlocked.Exchange(ref freeBufferLock, 0);
                buffer.Pool = null;
            }
        }
Example #2
0
        /// <summary>
        /// 添加缓冲区
        /// </summary>
        /// <param name="buffer">缓冲区</param>
        internal void Push(ref PoolBuffer buffer)
        {
            if (buffer.Pool == this)
            {
START:
                freeBufferLock.EnterYield();
                if (freeCurrent == freeEnd)
                {
                    if (backFree == null)
                    {
                        freeBufferLock.Exit();
                        Monitor.Enter(createFreeLock);
                        if (backFree != null)
                        {
                            Monitor.Exit(createFreeLock);
                            goto START;
                        }
                        byte *newBackFree;
                        try
                        {
                            newBackFree = UnmanagedPool.Default.GetPointer().Byte;
                        }
                        finally { Monitor.Exit(createFreeLock); }
                        freeBufferLock.EnterYield();
                        backFree = newBackFree;
                        if (freeCurrent != freeEnd)
                        {
                            goto PUSH;
                        }
                    }
                    *(byte **)backFree = freeStart;
                    freeEnd            = backFree + UnmanagedPool.DefaultSize;
                    freeCurrent        = (uint *)(freeStart = backFree + sizeof(byte **));
                    backFree           = null;
                }
PUSH:
                *freeCurrent++ = buffer.Index;
                freeBufferLock.Exit();
                buffer.Pool = null;
            }
        }
Example #3
0
        /// <summary>
        /// 获取缓冲区
        /// </summary>
        /// <returns>缓冲区</returns>
        internal void Get(ref PoolBuffer buffer)
        {
            freeBufferLock.EnterYield();
            if (freeStart != freeCurrent)
            {
                uint freeIndex = *--freeCurrent;
                if (freeStart == freeCurrent)
                {
                    byte *free = freeStart - sizeof(byte **);
                    if (*(byte **)free == null)
                    {
                        freeBufferLock.Exit();
                    }
                    else
                    {
                        freeStart   = *(byte **)free;
                        freeEnd     = freeStart + (UnmanagedPool.DefaultSize - sizeof(byte **));
                        freeCurrent = (uint *)freeEnd;
                        if (backFree == null)
                        {
                            freeBufferLock.Exit();
                            Monitor.Enter(createFreeLock);
                            freeBufferLock.EnterYield();
                            if (backFree == null)
                            {
                                backFree = free;
                                freeBufferLock.Exit();
                                Monitor.Exit(createFreeLock);
                            }
                            else
                            {
                                freeBufferLock.Exit();
                                Monitor.Exit(createFreeLock);
                                UnmanagedPool.Default.Push(free);
                            }
                        }
                        else
                        {
                            freeBufferLock.Exit();
                            UnmanagedPool.Default.Push(free);
                        }
                    }
                }
                else
                {
                    freeBufferLock.Exit();
                }
                buffer.Set(this, freeIndex);
                return;
            }
            freeBufferLock.Exit();
            uint index = (uint)System.Threading.Interlocked.Increment(ref bufferIndex) - 1;

            if (index >= bufferCount)
            {
                Monitor.Enter(bufferLock);
                try
                {
                    while (index >= bufferCount)
                    {
                        int arrayIndex = (int)(bufferCount >> arrayBits);
                        if (arrayIndex == Buffers.Length)
                        {
                            Buffers = Buffers.copyNew(arrayIndex << 1);
                        }
                        Buffers[arrayIndex] = new byte[bufferSize];
                        bufferCount        += arrayBufferCount;
                    }
                }
                finally { Monitor.Exit(bufferLock); }
            }
            buffer.Set(this, index);
        }
Example #4
0
 internal void CopyToClear(ref PoolBuffer targetBuffer)
 {
     targetBuffer.Pool  = Pool;
     targetBuffer.Index = Index;
     Pool = null;
 }