Skip to content

Instantly share code, notes, and snippets.

@Artur2
Created November 9, 2015 19:52
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save Artur2/f46ff732161dcd35c7b7 to your computer and use it in GitHub Desktop.
Save Artur2/f46ff732161dcd35c7b7 to your computer and use it in GitHub Desktop.
Lock Free List Sample
public class LockFreeList<T> : IEnumerable<T>
{
private volatile Node<T> _head;
private class Node<TItem>
{
public Node<TItem> Next { get; set; }
public TItem Value { get; set; }
}
public void Add(T item)
{
var spin = new SpinWait();
var node = new Node<T>() { Value = item };
var head = (Node<T>)null;
while (true)
{
head = _head;
node.Next = head;
if (Interlocked.CompareExchange(ref _head, node, head) == head)
break;
spin.SpinOnce();
}
}
public bool TryGet(out T item)
{
item = default(T);
var spin = new SpinWait();
var head = (Node<T>)null;
while (true)
{
head = _head;
if (head == null)
return false;
if (Interlocked.CompareExchange(ref _head, head.Next, head) == head)
{
item = head.Value;
return true;
}
spin.SpinOnce();
}
}
public IEnumerator<T> GetEnumerator()
{
return new LockFreeEnumerator(this);
}
IEnumerator IEnumerable.GetEnumerator()
{
return new LockFreeEnumerator(this);
}
private class LockFreeEnumerator : IEnumerator<T>
{
private LockFreeList<T> _lockFreeList;
private Node<T> _current;
private Node<T> _default;
public LockFreeEnumerator(LockFreeList<T> lockFreeList)
{
_lockFreeList = lockFreeList;
_default = _lockFreeList._head;
}
public T Current
{
get
{
return _current.Value;
}
}
object IEnumerator.Current
{
get
{
return _current;
}
}
public void Dispose()
{
}
public bool MoveNext()
{
if (_current == null)
{
Interlocked.Exchange(ref _current, _lockFreeList._head);
if (_current == null)
return false;
return true;
}
else
{
Interlocked.Exchange(ref _current, _current.Next);
if (_current == null)
return false;
return true;
}
}
public void Reset()
{
Interlocked.Exchange(ref _current, _default);
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment