1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72
|
package java.vm;
import java.util.concurrent.atomic.AtomicReference;
/**
A lock-free queue implementation
**/
@:native('haxe.java.vm.AtomicList')
@:nativeGen class AtomicList<T>
{
@:volatile @:private var head:AtomicNode<T>;
@:volatile @:private var tail:AtomicReference<AtomicNode<T>>;
public function new()
{
this.head = new AtomicNode(null);
this.head.set(new AtomicNode(null));
this.tail = new AtomicReference(head);
}
public function add(v:T)
{
var n = new AtomicNode(v), tail = this.tail;
var p = null;
while( !((p = tail.get()).compareAndSet(null, n)) )
{
tail.compareAndSet(p, p.get());
}
tail.compareAndSet(p, n);
}
public function pop():Null<T>
{
var p = null, pget = null, head = head;
do
{
p = head.get();
if ( (pget = p.get()) == null)
return null; //empty
} while(!head.compareAndSet(p, pget));
var ret = pget.value;
pget.value = null;
return ret;
}
public function peek()
{
var ret = head.get();
if (ret == null) return null; //empty
return ret.value;
}
public function peekLast()
{
return tail.get().value;
}
}
@:native('haxe.java.vm.AtomicNode')
@:nativeGen class AtomicNode<T> extends AtomicReference<AtomicNode<T>>
{
public var value:T;
public function new(value)
{
super();
this.value = value;
}
}
|