mirror of
https://github.com/corda/corda.git
synced 2025-01-21 03:55:00 +00:00
add bare-bones ConcurrentLinkedQueue implementation
This commit is contained in:
parent
a8bb0d074b
commit
296cb74847
10
classpath/avian/Atomic.java
Normal file
10
classpath/avian/Atomic.java
Normal file
@ -0,0 +1,10 @@
|
||||
package avian;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
|
||||
public class Atomic {
|
||||
public static native long getOffset(Field field);
|
||||
|
||||
public static native boolean compareAndSwapObject
|
||||
(Object o, long offset, Object old, Object new_);
|
||||
}
|
88
classpath/java/util/concurrent/ConcurrentLinkedQueue.java
Normal file
88
classpath/java/util/concurrent/ConcurrentLinkedQueue.java
Normal file
@ -0,0 +1,88 @@
|
||||
package java.util.concurrent;
|
||||
|
||||
import avian.Atomic;
|
||||
|
||||
public class ConcurrentLinkedQueue<T> {
|
||||
private static final long QueueHead;
|
||||
private static final long QueueTail;
|
||||
private static final long NodeNext;
|
||||
|
||||
static {
|
||||
try {
|
||||
QueueHead = Atomic.getOffset
|
||||
(ConcurrentLinkedQueue.class.getField("head"));
|
||||
|
||||
QueueTail = Atomic.getOffset
|
||||
(ConcurrentLinkedQueue.class.getField("tail"));
|
||||
|
||||
NodeNext = Atomic.getOffset
|
||||
(Node.class.getField("next"));
|
||||
} catch (NoSuchFieldException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
private volatile Node<T> head = new Node(null, null);
|
||||
private volatile Node<T> tail = head;
|
||||
|
||||
public boolean add(T value) {
|
||||
Node<T> n = new Node(value, null);
|
||||
while (true) {
|
||||
Node<T> t = tail;
|
||||
Node<T> next = tail.next;
|
||||
if (t == tail) {
|
||||
if (next != null) {
|
||||
Atomic.compareAndSwapObject(this, QueueTail, t, next);
|
||||
} else if (Atomic.compareAndSwapObject(tail, NodeNext, null, n)) {
|
||||
Atomic.compareAndSwapObject(this, QueueTail, t, n);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public T peek() {
|
||||
return poll(false);
|
||||
}
|
||||
|
||||
public T poll() {
|
||||
return poll(true);
|
||||
}
|
||||
|
||||
public T poll(boolean remove) {
|
||||
while (true) {
|
||||
Node<T> h = head;
|
||||
Node<T> t = tail;
|
||||
Node<T> next = head.next;
|
||||
|
||||
if (h == head) {
|
||||
if (h == t) {
|
||||
if (next != null) {
|
||||
Atomic.compareAndSwapObject(this, QueueTail, t, next);
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
} else {
|
||||
T value = next.value;
|
||||
if ((! remove)
|
||||
|| Atomic.compareAndSwapObject(this, QueueHead, h, next))
|
||||
{
|
||||
return value;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static class Node<T> {
|
||||
public volatile T value;
|
||||
public volatile Node<T> next;
|
||||
|
||||
public Node(T value, Node<T> next) {
|
||||
this.value = value;
|
||||
this.next = next;
|
||||
}
|
||||
}
|
||||
}
|
@ -605,6 +605,33 @@ Avian_java_lang_Thread_yield
|
||||
t->m->system->yield();
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT int64_t JNICALL
|
||||
Avian_avian_Atomic_getOffset
|
||||
(Thread* t, object, uintptr_t* arguments)
|
||||
{
|
||||
return fieldOffset
|
||||
(t, jfieldVmField(t, reinterpret_cast<object>(arguments[0])));
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT int64_t JNICALL
|
||||
Avian_avian_Atomic_compareAndSwapObject
|
||||
(Thread* t, object, uintptr_t* arguments)
|
||||
{
|
||||
object target = reinterpret_cast<object>(arguments[0]);
|
||||
int64_t offset; memcpy(&offset, arguments + 1, 8);
|
||||
uintptr_t expect = arguments[3];
|
||||
uintptr_t update = arguments[4];
|
||||
|
||||
bool success = atomicCompareAndSwap
|
||||
(&cast<uintptr_t>(target, offset), expect, update);
|
||||
|
||||
if (success) {
|
||||
mark(t, target, offset);
|
||||
}
|
||||
|
||||
return success;
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT int64_t JNICALL
|
||||
Avian_avian_Classes_primitiveClass
|
||||
(Thread* t, object, uintptr_t* arguments)
|
||||
|
Loading…
Reference in New Issue
Block a user