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 ca7a5907ab..959160e4f5 100644 --- a/common/src/main/java/io/netty/util/internal/MpscLinkedQueue.java +++ b/common/src/main/java/io/netty/util/internal/MpscLinkedQueue.java @@ -18,63 +18,15 @@ */ package io.netty.util.internal; -import static java.util.concurrent.atomic.AtomicReferenceFieldUpdater.newUpdater; - import java.io.IOException; import java.io.ObjectInputStream; import java.io.ObjectOutputStream; -import java.io.Serializable; import java.lang.reflect.Array; import java.util.Arrays; import java.util.Collection; import java.util.Iterator; import java.util.NoSuchElementException; import java.util.Queue; -import java.util.concurrent.atomic.AtomicReferenceFieldUpdater; - -abstract class MpscLinkedQueuePad0 { - long p00, p01, p02, p03, p04, p05, p06, p07; - long p30, p31, p32, p33, p34, p35, p36, p37; -} - -abstract class MpscLinkedQueueHeadRef extends MpscLinkedQueuePad0 { - @SuppressWarnings("rawtypes") - private static final AtomicReferenceFieldUpdater UPDATER = - newUpdater(MpscLinkedQueueHeadRef.class, MpscLinkedQueueNode.class, "headRef"); - private volatile MpscLinkedQueueNode headRef; - - protected final MpscLinkedQueueNode headRef() { - return headRef; - } - protected final void headRef(MpscLinkedQueueNode val) { - headRef = val; - } - protected final void lazySetHeadRef(MpscLinkedQueueNode newVal) { - UPDATER.lazySet(this, newVal); - } -} - -abstract class MpscLinkedQueuePad1 extends MpscLinkedQueueHeadRef { - long p00, p01, p02, p03, p04, p05, p06, p07; - long p30, p31, p32, p33, p34, p35, p36, p37; -} - -abstract class MpscLinkedQueueTailRef extends MpscLinkedQueuePad1 { - @SuppressWarnings("rawtypes") - private static final AtomicReferenceFieldUpdater UPDATER = - newUpdater(MpscLinkedQueueTailRef.class, MpscLinkedQueueNode.class, "tailRef"); - private volatile MpscLinkedQueueNode tailRef; - protected final MpscLinkedQueueNode tailRef() { - return tailRef; - } - protected final void tailRef(MpscLinkedQueueNode val) { - tailRef = val; - } - @SuppressWarnings("unchecked") - protected final MpscLinkedQueueNode getAndSetTailRef(MpscLinkedQueueNode newVal) { - return (MpscLinkedQueueNode) UPDATER.getAndSet(this, newVal); - } -} /** * A lock-free concurrent single-consumer multi-producer {@link Queue}. @@ -113,7 +65,10 @@ abstract class MpscLinkedQueueTailRef extends MpscLinkedQueuePad1 { * data structure modified to avoid false sharing between head and tail Ref as per implementation of MpscLinkedQueue * on JCTools project. */ -public final class MpscLinkedQueue extends MpscLinkedQueueTailRef implements Queue { +final class MpscLinkedQueue extends MpscLinkedQueueTailRef implements Queue { + + private static final long serialVersionUID = -1878402552271506449L; + // offer() occurs at the tail of the linked list. // poll() occurs at the head of the linked list. // @@ -131,8 +86,8 @@ public final class MpscLinkedQueue extends MpscLinkedQueueTailRef implemen // since Unsafe does not expose XCHG operation intrinsically. MpscLinkedQueue() { MpscLinkedQueueNode tombstone = new DefaultNode(null); - headRef(tombstone); - tailRef(tombstone); + setHeadRef(tombstone); + setTailRef(tombstone); } /** @@ -403,8 +358,8 @@ public final class MpscLinkedQueue extends MpscLinkedQueueTailRef implemen in.defaultReadObject(); final MpscLinkedQueueNode tombstone = new DefaultNode(null); - headRef(tombstone); - tailRef(tombstone); + setHeadRef(tombstone); + setTailRef(tombstone); for (;;) { @SuppressWarnings("unchecked") @@ -416,9 +371,7 @@ public final class MpscLinkedQueue extends MpscLinkedQueueTailRef implemen } } - private static final class DefaultNode extends MpscLinkedQueueNode implements Serializable { - - private static final long serialVersionUID = 1006745279405945948L; + private static final class DefaultNode extends MpscLinkedQueueNode { private T value; diff --git a/common/src/main/java/io/netty/util/internal/MpscLinkedQueueHeadRef.java b/common/src/main/java/io/netty/util/internal/MpscLinkedQueueHeadRef.java new file mode 100644 index 0000000000..cf8d4a91b2 --- /dev/null +++ b/common/src/main/java/io/netty/util/internal/MpscLinkedQueueHeadRef.java @@ -0,0 +1,54 @@ +/* + * Copyright 2014 The Netty Project + * + * The Netty Project licenses this file to you under the Apache License, + * version 2.0 (the "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + */ + +package io.netty.util.internal; + +import java.io.Serializable; +import java.util.concurrent.atomic.AtomicReferenceFieldUpdater; + + +abstract class MpscLinkedQueueHeadRef extends MpscLinkedQueuePad0 implements Serializable { + + private static final long serialVersionUID = 8467054865577874285L; + + @SuppressWarnings("rawtypes") + private static final AtomicReferenceFieldUpdater UPDATER; + + static { + @SuppressWarnings("rawtypes") + AtomicReferenceFieldUpdater updater; + updater = PlatformDependent.newAtomicReferenceFieldUpdater(MpscLinkedQueueHeadRef.class, "headRef"); + if (updater == null) { + updater = AtomicReferenceFieldUpdater.newUpdater( + MpscLinkedQueueHeadRef.class, MpscLinkedQueueNode.class, "headRef"); + } + UPDATER = updater; + } + + private transient volatile MpscLinkedQueueNode headRef; + + protected final MpscLinkedQueueNode headRef() { + return headRef; + } + + protected final void setHeadRef(MpscLinkedQueueNode headRef) { + this.headRef = headRef; + } + + protected final void lazySetHeadRef(MpscLinkedQueueNode headRef) { + UPDATER.lazySet(this, headRef); + } +} diff --git a/common/src/main/java/io/netty/util/internal/MpscLinkedQueuePad0.java b/common/src/main/java/io/netty/util/internal/MpscLinkedQueuePad0.java new file mode 100644 index 0000000000..04631e78e4 --- /dev/null +++ b/common/src/main/java/io/netty/util/internal/MpscLinkedQueuePad0.java @@ -0,0 +1,22 @@ +/* + * Copyright 2014 The Netty Project + * + * The Netty Project licenses this file to you under the Apache License, + * version 2.0 (the "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + */ + +package io.netty.util.internal; + +abstract class MpscLinkedQueuePad0 { + long p00, p01, p02, p03, p04, p05, p06, p07; + long p30, p31, p32, p33, p34, p35, p36, p37; +} diff --git a/common/src/main/java/io/netty/util/internal/MpscLinkedQueuePad1.java b/common/src/main/java/io/netty/util/internal/MpscLinkedQueuePad1.java new file mode 100644 index 0000000000..66b486b5cf --- /dev/null +++ b/common/src/main/java/io/netty/util/internal/MpscLinkedQueuePad1.java @@ -0,0 +1,25 @@ +/* + * Copyright 2014 The Netty Project + * + * The Netty Project licenses this file to you under the Apache License, + * version 2.0 (the "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + */ + +package io.netty.util.internal; + +abstract class MpscLinkedQueuePad1 extends MpscLinkedQueueHeadRef { + + private static final long serialVersionUID = 2886694927079691637L; + + long p00, p01, p02, p03, p04, p05, p06, p07; + long p30, p31, p32, p33, p34, p35, p36, p37; +} diff --git a/common/src/main/java/io/netty/util/internal/MpscLinkedQueueTailRef.java b/common/src/main/java/io/netty/util/internal/MpscLinkedQueueTailRef.java new file mode 100644 index 0000000000..38679acf93 --- /dev/null +++ b/common/src/main/java/io/netty/util/internal/MpscLinkedQueueTailRef.java @@ -0,0 +1,53 @@ +/* + * Copyright 2014 The Netty Project + * + * The Netty Project licenses this file to you under the Apache License, + * version 2.0 (the "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + */ + +package io.netty.util.internal; + +import java.util.concurrent.atomic.AtomicReferenceFieldUpdater; + +abstract class MpscLinkedQueueTailRef extends MpscLinkedQueuePad1 { + + private static final long serialVersionUID = 8717072462993327429L; + + @SuppressWarnings("rawtypes") + private static final AtomicReferenceFieldUpdater UPDATER; + + static { + @SuppressWarnings("rawtypes") + AtomicReferenceFieldUpdater updater; + updater = PlatformDependent.newAtomicReferenceFieldUpdater(MpscLinkedQueueTailRef.class, "tailRef"); + if (updater == null) { + updater = AtomicReferenceFieldUpdater.newUpdater( + MpscLinkedQueueTailRef.class, MpscLinkedQueueNode.class, "tailRef"); + } + UPDATER = updater; + } + + private transient volatile MpscLinkedQueueNode tailRef; + + protected final MpscLinkedQueueNode tailRef() { + return tailRef; + } + + protected final void setTailRef(MpscLinkedQueueNode tailRef) { + this.tailRef = tailRef; + } + + @SuppressWarnings("unchecked") + protected final MpscLinkedQueueNode getAndSetTailRef(MpscLinkedQueueNode tailRef) { + return (MpscLinkedQueueNode) UPDATER.getAndSet(this, tailRef); + } +}