/// <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; } }
/// <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; } }
/// <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); }
internal void CopyToClear(ref PoolBuffer targetBuffer) { targetBuffer.Pool = Pool; targetBuffer.Index = Index; Pool = null; }