##// END OF EJS Templates
Закрыть ветку diagnostics
Закрыть ветку diagnostics

File last commit:

r24:ee04e1fa78da default
r38:1cedc4e58acc diagnostics
Show More
MTQueue.cs
75 lines | 2.5 KiB | text/x-csharp | CSharpLexer
cin
Implemented interllocked queue...
r14 using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
namespace Implab.Parallels {
public class MTQueue<T> {
class Node {
public Node(T value) {
this.value = value;
}
public readonly T value;
public Node next;
}
Node m_first;
Node m_last;
public void Enqueue(T value) {
var last = m_last;
var next = new Node(value);
while (last != Interlocked.CompareExchange(ref m_last, next, last))
last = m_last;
if (last != null)
last.next = next;
else
m_first = next;
}
public bool TryDequeue(out T value) {
Node first;
Node next = null;
value = default(T);
do {
first = m_first;
if (first == null)
return false;
next = first.next;
if (next == null) {
// this is the last element,
cin
Promise is rewritten to use interlocked operations instead of locks
r19 // then try to update the tail
cin
Implemented interllocked queue...
r14 if (first != Interlocked.CompareExchange(ref m_last, null, first)) {
cin
fixed dispatch pool race condition
r24 // this is a race condition
cin
Implemented interllocked queue...
r14 if (m_last == null)
cin
Promise is rewritten to use interlocked operations instead of locks
r19 // the queue is empty
cin
Implemented interllocked queue...
r14 return false;
cin
Promise is rewritten to use interlocked operations instead of locks
r19 // tail has been changed, than we need to restart
cin
Implemented interllocked queue...
r14 continue;
}
// tail succesfully updated and first.next will never be changed
// other readers will fail due to inconsistency m_last != m_fist, but m_first.next == null
// but the writer may update the m_first since the m_last is null
// so we need to fix inconsistency by setting m_first to null, but if it already has been
// updated by a writer then we should just give up
Interlocked.CompareExchange(ref m_first, null, first);
break;
} else {
if (first == Interlocked.CompareExchange(ref m_first, next, first))
// head succesfully updated
break;
}
} while (true);
value = first.value;
return true;
}
}
}