From a32652197bfe3a9f2d5c22b34a34d532639b299a Mon Sep 17 00:00:00 2001 From: Norman Maurer Date: Mon, 18 Aug 2014 08:35:25 +0200 Subject: [PATCH] Avoid redundant reads of head in peakNode Motivation: There is not need todo redunant reads of head in peakNode as we can just spin on next() until it becomes visible. Modifications: Remove redundant reads of head in peakNode. This is based on @nitsanw's patch for akka. See https://github.com/akka/akka/pull/15596 Result: Less volatile access. --- .../netty/util/internal/MpscLinkedQueue.java | 25 ++++++++----------- 1 file changed, 11 insertions(+), 14 deletions(-) diff --git a/common/src/main/java/io/netty/util/internal/MpscLinkedQueue.java b/common/src/main/java/io/netty/util/internal/MpscLinkedQueue.java index 652bccbcf1..4baa5ac0fb 100644 --- a/common/src/main/java/io/netty/util/internal/MpscLinkedQueue.java +++ b/common/src/main/java/io/netty/util/internal/MpscLinkedQueue.java @@ -97,21 +97,18 @@ final class MpscLinkedQueue extends MpscLinkedQueueTailRef implements Queu * Returns the node right next to the head, which contains the first element of this queue. */ private MpscLinkedQueueNode peekNode() { - for (;;) { - final MpscLinkedQueueNode head = headRef(); - final MpscLinkedQueueNode next = head.next(); - if (next != null) { - return next; - } - if (head == tailRef()) { - return null; - } - - // If we are here, it means: - // * offer() is adding the first element, and - // * it's between replaceTail(newTail) and oldTail.setNext(newTail). - // (i.e. next == oldTail and oldTail.next == null and head == oldTail != newTail) + MpscLinkedQueueNode head = headRef(); + MpscLinkedQueueNode next = head.next(); + if (next == null && head != tailRef()) { + // if tail != head this is not going to change until consumer makes progress + // we can avoid reading the head and just spin on next until it shows up + // + // See https://github.com/akka/akka/pull/15596 + do { + next = head.next(); + } while (next == null); } + return next; } @Override