Skip to content

Commit

Permalink
Remove more pointer chasing in tight loops
Browse files Browse the repository at this point in the history
  • Loading branch information
dmlloyd committed Sep 26, 2024
1 parent 7099668 commit 4ab166b
Showing 1 changed file with 9 additions and 7 deletions.
16 changes: 9 additions & 7 deletions src/main/java/org/jboss/threads/EnhancedQueueExecutor.java
Original file line number Diff line number Diff line change
Expand Up @@ -916,18 +916,19 @@ public void shutdown() {
public List<Runnable> shutdownNow() {
shutdown(true);
final ArrayList<Runnable> list = new ArrayList<>();
TaskNode head = getHead();
TaskNode[] unsharedTaskNodes = this.unsharedTaskNodes;
TaskNode head = getHead(unsharedTaskNodes);
QNode headNext;
for (;;) {
headNext = head.getNext();
if (headNext == head) {
// a racing consumer has already consumed it (and moved head)
head = getHead();
head = getHead(unsharedTaskNodes);
continue;
}
if (headNext instanceof TaskNode) {
TaskNode taskNode = (TaskNode) headNext;
if (compareAndSetHead(head, taskNode)) {
if (compareAndSetHead(unsharedTaskNodes, head, taskNode)) {
// save from GC nepotism
head.setNextOrdered(head);
if (getQueueLimited()) decreaseQueueSize();
Expand Down Expand Up @@ -1596,14 +1597,15 @@ public void run() {

private void runThreadBody() {
final LongAdder spinMisses = this.spinMisses;
TaskNode[] unsharedTaskNodes = this.unsharedTaskNodes;
// Eagerly allocate a PoolThreadNode for the next time it's needed
PoolThreadNode nextPoolThreadNode = new PoolThreadNode(currentThread());
// main loop
processingQueue: for (;;) {
TaskNode head;
QNode headNext;
for (;;) {
head = getHead();
head = getHead(unsharedTaskNodes);
headNext = head.getNext();
// headNext == head can happen if another consumer has already consumed head:
// retry with a fresh head
Expand Down Expand Up @@ -1686,7 +1688,7 @@ private void runThreadBody() {
nextPoolThreadNode.setNextRelaxed(null);
}
} else if (headNext instanceof TaskNode taskNode) {
if (compareAndSetHead(head, taskNode)) {
if (compareAndSetHead(unsharedTaskNodes, head, taskNode)) {
// save from GC Nepotism: generational GCs don't like
// cross-generational references, so better to "clean-up" head::next
// to save dragging head::next into the old generation.
Expand Down Expand Up @@ -2020,7 +2022,7 @@ boolean compareAndSetTail(final EnhancedQueueExecutor.TaskNode expect, final Enh
return getTail() == expect && unsafe.compareAndSwapObject(unsharedTaskNodes, RuntimeFields.tailOffset, expect, update);
}

TaskNode getHead() {
TaskNode getHead(final TaskNode[] unsharedTaskNodes) {
return (TaskNode) unsafe.getObjectVolatile(unsharedTaskNodes, RuntimeFields.headOffset);
}

Expand All @@ -2029,7 +2031,7 @@ TaskNode setHeadPlain(TaskNode head) {
return head;
}

boolean compareAndSetHead(final EnhancedQueueExecutor.TaskNode expect, final EnhancedQueueExecutor.TaskNode update) {
boolean compareAndSetHead(final TaskNode[] unsharedTaskNodes, final TaskNode expect, final TaskNode update) {
return unsafe.compareAndSwapObject(unsharedTaskNodes, RuntimeFields.headOffset, expect, update);
}

Expand Down

0 comments on commit 4ab166b

Please sign in to comment.