Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance. Project price only 1 $
You can buy this project and download/modify it how often you want.
/*
* Quasar: lightweight threads and actors for the JVM.
* Copyright (c) 2013-2015, Parallel Universe Software Co. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
* the Eclipse Foundation
*
* or (per the licensee's choosing)
*
* under the terms of the GNU Lesser General Public License version 3.0
* as published by the Free Software Foundation.
*/
package co.paralleluniverse.strands.queues;
import java.lang.invoke.MethodHandles;
import java.lang.invoke.VarHandle;
import java.util.NoSuchElementException;
/**
*
* @author pron
*/
public abstract class SingleConsumerLinkedArrayPrimitiveQueue extends SingleConsumerLinkedArrayQueue {
boolean enqRaw(long item) {
final Node node;
final int index;
final int blockSize = blockSize();
Node nn = null;
for (;;) {
final PrimitiveNode t = (PrimitiveNode) tail;
final int i = t.tailIndex;
if (i < blockSize) {
if (compareAndSetTailIndex(t, i, i + 1)) {
node = t;
index = i;
break;
}
// backoff();
} else {
if (nn == null)
nn = newNode();
nn.prev = t;
if (compareAndSetTail(t, nn)) {
t.next = nn;
nn = null;
} else
backoff();
}
}
enqRaw(node, index, item);
if (true) {
final PrimitiveNode n = (PrimitiveNode) node;
while (n.maxReadIndex != index)
;
n.maxReadIndex = index + 1;
} else {
while (!compareAndSetMaxReadIndex(node, index, index + 1))
;
}
return true;
}
long pollRaw() {
final long raw = peekRaw();
deqHead();
return raw;
}
private long peekRaw() {
if (!prePeek())
throw new NoSuchElementException();
return getRaw(head, headIndex);
}
abstract void enqRaw(Node n, int i, long item);
abstract long getRaw(Node n, int i);
@Override
boolean hasValue(Node n, int index) {
return index < ((PrimitiveNode) n).maxReadIndex;
}
@Override
boolean isDeleted(Node n, int index) {
return getBit(((PrimitiveNode) n).deleted, index);
}
@Override
void markDeleted(Node n1, int index) {
assert index <= blockSize();
final PrimitiveNode n = (PrimitiveNode) n1;
n.deleted = setBit(n.deleted, index);
}
static abstract class PrimitiveNode extends Node {
volatile int tailIndex;
volatile int maxReadIndex;
short deleted;
}
private static short setBit(short bits, int index) {
return (short) (bits | (1 << index));
}
private static boolean getBit(short bits, int index) {
return (bits >>> index & 1) != 0;
}
private static final VarHandle TAIL_INDEX;
private static final VarHandle MAX_READ_INDEX;
static {
try {
MethodHandles.Lookup l = MethodHandles.lookup();
TAIL_INDEX = l.findVarHandle(PrimitiveNode.class, "tailIndex", int.class);
MAX_READ_INDEX = l.findVarHandle(PrimitiveNode.class, "maxReadIndex", int.class);
} catch (ReflectiveOperationException e) {
throw new ExceptionInInitializerError(e);
}
}
private boolean compareAndSetTailIndex(Node n, int expect, int update) {
return TAIL_INDEX.compareAndSet((PrimitiveNode) n, expect, update);
}
private boolean compareAndSetMaxReadIndex(Node n, int expect, int update) {
return MAX_READ_INDEX.compareAndSet((PrimitiveNode) n, expect, update);
}
// private static final long tailIndexOffset;
// private static final long maxReadIndexOffset;
//
// static {
// try {
// tailIndexOffset = UNSAFE.objectFieldOffset(PrimitiveNode.class.getDeclaredField("tailIndex"));
// maxReadIndexOffset = UNSAFE.objectFieldOffset(PrimitiveNode.class.getDeclaredField("maxReadIndex"));
// } catch (Exception ex) {
// throw new Error(ex);
// }
// }
//
// private boolean compareAndSetTailIndex(Node n, int expect, int update) {
// return UNSAFE.compareAndSwapInt((PrimitiveNode) n, tailIndexOffset, expect, update);
// }
//
// private boolean compareAndSetMaxReadIndex(Node n, int expect, int update) {
// return UNSAFE.compareAndSwapInt((PrimitiveNode) n, maxReadIndexOffset, expect, update);
// }
}