73 lines
		
	
	
		
			3.0 KiB
		
	
	
	
		
			C#
		
	
	
			
		
		
	
	
			73 lines
		
	
	
		
			3.0 KiB
		
	
	
	
		
			C#
		
	
	
using DotNetty.Common.Internal;
 | 
						|
using DotNetty.Common.Utilities;
 | 
						|
 | 
						|
namespace base_kcp
 | 
						|
{
 | 
						|
    public abstract class ConcurrentCircularArrayQueue<T> : ConcurrentCircularArrayQueueL0Pad<T>
 | 
						|
        where T : class
 | 
						|
    {
 | 
						|
        protected long Mask;
 | 
						|
        protected readonly T[] Buffer;
 | 
						|
 | 
						|
        protected ConcurrentCircularArrayQueue(int capacity)
 | 
						|
        {
 | 
						|
            int actualCapacity = IntegerExtensions.RoundUpToPowerOfTwo(capacity);
 | 
						|
            this.Mask = actualCapacity - 1;
 | 
						|
            // pad data on either end with some empty slots.
 | 
						|
            this.Buffer = new T[actualCapacity + RefArrayAccessUtil.RefBufferPad * 2];
 | 
						|
        }
 | 
						|
 | 
						|
        /// <summary>
 | 
						|
        /// Calculates an element offset based on a given array index.
 | 
						|
        /// </summary>
 | 
						|
        /// <param name="index">The desirable element index.</param>
 | 
						|
        /// <returns>The offset in bytes within the array for a given index.</returns>
 | 
						|
        protected long CalcElementOffset(long index) => RefArrayAccessUtil.CalcElementOffset(index, this.Mask);
 | 
						|
 | 
						|
        /// <summary>
 | 
						|
        /// A plain store (no ordering/fences) of an element to a given offset.
 | 
						|
        /// </summary>
 | 
						|
        /// <param name="offset">Computed via <see cref="CalcElementOffset"/>.</param>
 | 
						|
        /// <param name="e">A kitty.</param>
 | 
						|
        protected void SpElement(long offset, T e) => RefArrayAccessUtil.SpElement(this.Buffer, offset, e);
 | 
						|
 | 
						|
        /// <summary>
 | 
						|
        /// An ordered store(store + StoreStore barrier) of an element to a given offset.
 | 
						|
        /// </summary>
 | 
						|
        /// <param name="offset">Computed via <see cref="CalcElementOffset"/>.</param>
 | 
						|
        /// <param name="e">An orderly kitty.</param>
 | 
						|
        protected void SoElement(long offset, T e) => RefArrayAccessUtil.SoElement(this.Buffer, offset, e);
 | 
						|
 | 
						|
        /// <summary>
 | 
						|
        /// A plain load (no ordering/fences) of an element from a given offset.
 | 
						|
        /// </summary>
 | 
						|
        /// <param name="offset">Computed via <see cref="CalcElementOffset"/>.</param>
 | 
						|
        /// <returns>The element at the offset.</returns>
 | 
						|
        protected T LpElement(long offset) => RefArrayAccessUtil.LpElement(this.Buffer, offset);
 | 
						|
 | 
						|
        /// <summary>
 | 
						|
        /// A volatile load (load + LoadLoad barrier) of an element from a given offset.
 | 
						|
        /// </summary>
 | 
						|
        /// <param name="offset">Computed via <see cref="CalcElementOffset"/>.</param>
 | 
						|
        /// <returns>The element at the offset.</returns>
 | 
						|
        protected T LvElement(long offset) => RefArrayAccessUtil.LvElement(this.Buffer, offset);
 | 
						|
 | 
						|
        public override void Clear()
 | 
						|
        {
 | 
						|
            while (this.TryDequeue(out T _) || !this.IsEmpty)
 | 
						|
            {
 | 
						|
                // looping
 | 
						|
            }
 | 
						|
        }
 | 
						|
 | 
						|
        public int Capacity() => (int)(this.Mask + 1);
 | 
						|
    }
 | 
						|
 | 
						|
    public abstract class ConcurrentCircularArrayQueueL0Pad<T> : AbstractQueue<T>
 | 
						|
    {
 | 
						|
#pragma warning disable 169 // padded reference
 | 
						|
        long p00, p01, p02, p03, p04, p05, p06, p07;
 | 
						|
        long p30, p31, p32, p33, p34, p35, p36, p37;
 | 
						|
#pragma warning restore 169
 | 
						|
    }
 | 
						|
} |