diff --git a/akka-actor/src/main/java/akka/dispatch/affinity/OnSpinWait.java b/akka-actor/src/main/java/akka/dispatch/affinity/OnSpinWait.java new file mode 100644 index 0000000000..dd6d44b050 --- /dev/null +++ b/akka-actor/src/main/java/akka/dispatch/affinity/OnSpinWait.java @@ -0,0 +1,36 @@ +/* + * Copyright (C) 2009-2020 Lightbend Inc. + */ + +package akka.dispatch.affinity; + +import akka.util.Unsafe; +import java.lang.invoke.MethodHandle; +import java.lang.invoke.MethodHandles; +import akka.annotation.InternalApi; +import static java.lang.invoke.MethodType.methodType; + +/** + * INTERNAL API + */ +@InternalApi +final class OnSpinWait { + private final static MethodHandle handle; + + public final static void spinWait() throws Throwable { + handle.invoke(); // Will be inlined as an invokeExact since the callsite matches the MH definition of () -> void + } + + static { + final MethodHandle noop = MethodHandles.constant(Object.class, null).asType(methodType(Void.TYPE)); + MethodHandle impl; + try { + impl = MethodHandles.lookup().findStatic(Thread.class, "onSpinWait", methodType(Void.TYPE)); + } catch (NoSuchMethodException nsme) { + impl = noop; + } catch (IllegalAccessException iae) { + impl = noop; + } + handle = impl; + }; +} \ No newline at end of file diff --git a/akka-actor/src/main/scala/akka/dispatch/affinity/AffinityPool.scala b/akka-actor/src/main/scala/akka/dispatch/affinity/AffinityPool.scala index 918bbd8eac..66e32f8591 100644 --- a/akka-actor/src/main/scala/akka/dispatch/affinity/AffinityPool.scala +++ b/akka-actor/src/main/scala/akka/dispatch/affinity/AffinityPool.scala @@ -5,8 +5,6 @@ package akka.dispatch.affinity import java.lang.Integer.reverseBytes -import java.lang.invoke.MethodHandles -import java.lang.invoke.MethodType.methodType import java.util.Collections import java.util.concurrent._ import java.util.concurrent.TimeUnit.MICROSECONDS @@ -15,16 +13,18 @@ import java.util.concurrent.locks.LockSupport import scala.annotation.{ switch, tailrec } import scala.collection.{ immutable, mutable } -import scala.util.control.NonFatal import com.typesafe.config.Config import akka.annotation.{ ApiMayChange, InternalApi } import akka.dispatch._ import akka.event.Logging -import akka.util.{ ImmutableIntMap, OptionVal, ReentrantGuard } +import akka.util.{ ImmutableIntMap, ReentrantGuard } import akka.util.Helpers.Requiring +import scala.annotation.{ switch, tailrec } +import scala.collection.{ immutable, mutable } + @InternalApi @ApiMayChange private[affinity] object AffinityPool { @@ -42,13 +42,6 @@ private[affinity] object AffinityPool { // PoolState: all threads have been stopped, does not process tasks and does not accept new ones final val Terminated = 5 - // Method handle to JDK9+ onSpinWait method - private val onSpinWaitMethodHandle = - try OptionVal.Some(MethodHandles.lookup.findStatic(classOf[Thread], "onSpinWait", methodType(classOf[Void]))) - catch { - case NonFatal(_) => OptionVal.None - } - type IdleState = Int // IdleState: Initial state final val Initial = 0 @@ -85,10 +78,7 @@ private[affinity] object AffinityPool { idling = true transitionTo(Spinning) case Spinning => - onSpinWaitMethodHandle match { - case OptionVal.Some(m) => m.invokeExact() - case OptionVal.None => - } + OnSpinWait.spinWait() turns += 1 if (turns > maxSpins) transitionTo(Yielding)