Elides the need to allocate an AkkaForkJoinTask for Mailbox-submission to...

... registerForExecution

by having Mailbox extend ForkJoinTask and using the fact that `ForkJoinTask.exec` when returning
`false` does not set completion on the task, so it is free to be resubmitted to the `ForkJoinPool`
without reinitialization.

Also adds the ability to use `fork()` when the currentThread is a worker thread of the pool that we want to execute on.

Adds a JMH benchmark for both the ping-pong performance and pipelined throughput.

TL;DR: Don't be lazy, read the results.

Results:

Code version:  Benchmark (threads) (tpt) Mode  Samples Result
Original code: pingPong          1     1 thrpt      20 2187447.027 ops/s
Original code: pingPong          1     5 thrpt      20 2204127.207 ops/s
Original code: pingPong          4     1 thrpt      20 1542096.697 ops/s
Original code: pingPong          4     5 thrpt      20 1603430.459 ops/s

ReuseFJT only: pingPong          1     1 thrpt      20 2308577.697 ops/s
ReuseFJT only: pingPong          1     5 thrpt      20 2328201.214 ops/s
ReuseFJT only: pingPong          4     1 thrpt      20 1643865.269 ops/s
ReuseFJT only: pingPong          4     5 thrpt      20 1543223.138 ops/s

ReuseFJT&fork: pingPong          1     1 thrpt      20 2545330.600 ops/s
ReuseFJT&fork: pingPong          1     5 thrpt      20 2548132.768 ops/s
ReuseFJT&fork: pingPong          4     1 thrpt      20 2224621.733 ops/s
ReuseFJT&fork: pingPong          4     5 thrpt      20 2107459.115 ops/s



Original code: floodPipe         1     1 thrpt      20 3813536.918 ops/s
Original code: floodPipe         1     5 thrpt      20 6281274.681 ops/s
Original code: floodPipe         4     1 thrpt      20 1872842.900 ops/s
Original code: floodPipe         4     5 thrpt      20 4010431.485 ops/s

ReuseFJT only: floodPipe         1     1 thrpt      20 4055351.297 ops/s
ReuseFJT only: floodPipe         1     5 thrpt      20 6443241.874 ops/s
ReuseFJT only: floodPipe         4     1 thrpt      20 1955466.592 ops/s
ReuseFJT only: floodPipe         4     5 thrpt      20 3909202.021 ops/s

ReuseFJT&fork: floodPipe         1     1 thrpt      20 5430810.893 ops/s
ReuseFJT&fork: floodPipe         1     5 thrpt      20 7172043.309 ops/s
ReuseFJT&fork: floodPipe         4     1 thrpt      20 4801234.598 ops/s
ReuseFJT&fork: floodPipe         4     5 thrpt      20 5433858.207 ops/s



So in short:

between 14% and 156% improvements(!) to throughput
I think that's a great point, Andriy.
Nobody will be referring to the FJT anyway.
On Nov 1, 2014 5:26 PM, "Andriy Plokhotnyuk" <notifications@github.com>
wrote:

> In akka-actor/src/main/scala/akka/dispatch/AbstractDispatcher.scala:
>
> > @@ -391,6 +392,9 @@ object ForkJoinExecutorConfigurator {
> >      override def getRawResult(): Unit = ()
> >      override def setRawResult(unit: Unit): Unit = ()
> >      final override def exec(): Boolean = try { runnable.run(); true } catch {
> > +      case ie: InterruptedException ⇒
> > +        Thread.currentThread.interrupt()
> > +        false
>
> Why don't return false always? It will save from redundant signalling of
> normal completion of the internal task.
>
> —
> Reply to this email directly or view it on GitHub
> <https://github.com/akka/akka/pull/16152/files#r19705216>.
>