c# версия lock-free очереди от remark'а
От: vf  
Дата: 25.10.10 14:57
Оценка: 2 (1)
c# версия lock-free очереди от remark'а
Автор: remark
Дата: 10.03.10
, но с моими
Автор: vf
Дата: 23.10.10
изменениями, если есть желание их убрать следует убить queuedCount переменную и все что с ней связано:

using System;
using System.Threading;

namespace SocketServers
{
    struct LockFreeQueueItem<T>
    {
        public volatile Int32 Sequence;
        public T Value;

        public string ToString()
        {
            return string.Format("0x{0:X8}     {1}", Sequence, Value == null ? "EMPTY" : "FULL");
        }
    }

    class LockFreeQueue<T>
    {
        private volatile Int32 enqueueCount;
        private volatile Int32 dequeueCount;
        private volatile Int32 queuedCount;
        private LockFreeQueueItem<T>[] array;
        private readonly UInt32 size;

        public LockFreeQueue(UInt32 size1)
        {
            size = size1;

            array = new LockFreeQueueItem<T>[size];
            for (var i = 0; i < size; i++)
                array[i].Sequence = i;

            enqueueCount = 0;
            dequeueCount = 0;
        }

        public bool Enqueue(T value)
        {
            unchecked
            {
                for (; ; )
                {
                    UInt32 count = (UInt32)enqueueCount;
                    Int32 index = (Int32)(count % size);

                    var diff = (Int64)(UInt32)array[index].Sequence - (Int64)count;

                    if (diff == 0)
                    {
                        Int32 nextCount = (Int32)(count + 1);

                        if ((UInt32)Interlocked.CompareExchange(ref enqueueCount, nextCount, (Int32)count) == count)
                        {
                            array[index].Value = value;
                            Interlocked.Exchange(ref array[index].Sequence, nextCount);

                            Interlocked.Increment(ref queuedCount);

                            return true;
                        }
                    }
                    else if (diff < 0)
                    {
                        if (queuedCount < size)
                            continue;

                        return false;
                    }
                }
            }
        }

        public bool Dequeue(out T value)
        {
            unchecked
            {
                for (; ; )
                {
                    UInt32 count = (UInt32)dequeueCount;
                    Int32 nextCount = (Int32)(count + 1);
                    Int32 index = (Int32)(count % size);

                    var diff = (Int64)(UInt32)array[index].Sequence - (Int64)(UInt32)nextCount;

                    if (diff == 0)
                    {
                        if ((UInt32)Interlocked.CompareExchange(ref dequeueCount, nextCount, (Int32)count) == count)
                        {
                            value = array[index].Value;
                            array[index].Value = default(T);

                            Interlocked.Exchange(ref array[index].Sequence,
                                (Int32)(count + size));

                            Interlocked.Decrement(ref queuedCount);

                            return true;
                        }
                    }
                    else if (diff < 0)
                    {
                        if (queuedCount > 0)
                            continue;
                        
                        value = default(T);
                        return false;
                    }
                }
            }
        }

        public int Queued
        {
            get { return queuedCount; }
        }
    }
}



25.10.10 23:04: Перенесено из '.NET'
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.