From b3ced6162cefa7dd71d394af65295644d1714748 Mon Sep 17 00:00:00 2001 From: Aleksandar Prokopec Date: Tue, 1 May 2012 19:07:16 +0200 Subject: [PATCH] Refactor Unsafe related stuff in scala.concurrent. --- .../concurrent/impl/AbstractPromise.java | 23 +++++++++++++++++-- .../scala/concurrent/impl/Promise.scala | 12 +--------- .../concurrent/{impl => util}/Unsafe.java | 17 ++++++++------ 3 files changed, 32 insertions(+), 20 deletions(-) rename src/library/scala/concurrent/{impl => util}/Unsafe.java (80%) diff --git a/src/library/scala/concurrent/impl/AbstractPromise.java b/src/library/scala/concurrent/impl/AbstractPromise.java index 8aac5de0426f..b1799c5fa9c7 100644 --- a/src/library/scala/concurrent/impl/AbstractPromise.java +++ b/src/library/scala/concurrent/impl/AbstractPromise.java @@ -9,13 +9,32 @@ package scala.concurrent.impl; - +import scala.concurrent.util.Unsafe; import java.util.concurrent.atomic.AtomicReferenceFieldUpdater; abstract class AbstractPromise { private volatile Object _ref; + + final static long _refoffset; + + static { + try { + _refoffset = Unsafe.instance.objectFieldOffset(AbstractPromise.class.getDeclaredField("_ref")); + } catch (Throwable t) { + throw new ExceptionInInitializerError(t); + } + } + + protected final boolean updateState(Object oldState, Object newState) { + return Unsafe.instance.compareAndSwapObject(this, _refoffset, oldState, newState); + } + + protected final Object getState() { + return _ref; + } + protected final static AtomicReferenceFieldUpdater updater = - AtomicReferenceFieldUpdater.newUpdater(AbstractPromise.class, Object.class, "_ref"); + AtomicReferenceFieldUpdater.newUpdater(AbstractPromise.class, Object.class, "_ref"); } \ No newline at end of file diff --git a/src/library/scala/concurrent/impl/Promise.scala b/src/library/scala/concurrent/impl/Promise.scala index e8d569fdba3e..b508c3b2e977 100644 --- a/src/library/scala/concurrent/impl/Promise.scala +++ b/src/library/scala/concurrent/impl/Promise.scala @@ -11,7 +11,6 @@ package scala.concurrent.impl import java.util.concurrent.TimeUnit.{ NANOSECONDS, MILLISECONDS } -import java.util.concurrent.atomic.AtomicReferenceFieldUpdater import scala.concurrent.{Awaitable, ExecutionContext, resolveEither, resolver, blocking, CanAwait, TimeoutException} //import scala.util.continuations._ import scala.concurrent.util.Duration @@ -77,7 +76,7 @@ object Promise { /** Default promise implementation. */ class DefaultPromise[T](implicit val executor: ExecutionContext) extends AbstractPromise with Promise[T] { self => - updater.set(this, Nil) // Start at "No callbacks" //FIXME switch to Unsafe instead of ARFU + updateState(null, Nil) // Start at "No callbacks" //FIXME switch to Unsafe instead of ARFU protected final def tryAwait(atMost: Duration): Boolean = { @tailrec @@ -124,15 +123,6 @@ object Promise { case _ => false } - @inline - private[this] final def updater = AbstractPromise.updater.asInstanceOf[AtomicReferenceFieldUpdater[AbstractPromise, AnyRef]] - - @inline - protected final def updateState(oldState: AnyRef, newState: AnyRef): Boolean = updater.compareAndSet(this, oldState, newState) - - @inline - protected final def getState: AnyRef = updater.get(this) - def tryComplete(value: Either[Throwable, T]): Boolean = { val callbacks: List[Either[Throwable, T] => Unit] = { try { diff --git a/src/library/scala/concurrent/impl/Unsafe.java b/src/library/scala/concurrent/util/Unsafe.java similarity index 80% rename from src/library/scala/concurrent/impl/Unsafe.java rename to src/library/scala/concurrent/util/Unsafe.java index 21f7e638e5e4..0cd48758d520 100644 --- a/src/library/scala/concurrent/impl/Unsafe.java +++ b/src/library/scala/concurrent/util/Unsafe.java @@ -6,22 +6,25 @@ ** |/ ** \* */ +package scala.concurrent.util; + -package scala.concurrent; import java.lang.reflect.Field; -final class Unsafe { + + +public final class Unsafe { public final static sun.misc.Unsafe instance; static { try { sun.misc.Unsafe found = null; for(Field field : sun.misc.Unsafe.class.getDeclaredFields()) { - if (field.getType() == sun.misc.Unsafe.class) { - field.setAccessible(true); - found = (sun.misc.Unsafe) field.get(null); - break; - } + if (field.getType() == sun.misc.Unsafe.class) { + field.setAccessible(true); + found = (sun.misc.Unsafe) field.get(null); + break; + } } if (found == null) throw new IllegalStateException("Can't find instance of sun.misc.Unsafe"); else instance = found;