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'