Unexplained ForkJoinTask behavior

classic Classic list List threaded Threaded
2 messages Options
Reply | Threaded
Open this post in threaded view
|

Unexplained ForkJoinTask behavior

Kirk Pepperdine
Hi,

I’ve been instrumenting ForkJoinPool along with ForkJoinTask. I have two different workloads that are being run sequentially. Lets call them W1 and W2.

If I run in the order W1,W2 what I’ve noticed is that the call to private int setCompletion(int completion) is being made twice by two different ForkJoinWorkerThread for W1 and once for W2. When I say two calls, what I really mean is the status word is reset to the same NORMAL completion value.

The casual stack for both W1 and W2 is;
setCompletion():284, ForkJoinTask, returns success of the call
quietlyComplete():999, ForkJoinTalk, returns void
tryComplete():579, CountedCompleter, returns void
compute():317, AbstractTask, returns void
exec():731, CountedCompleter, always returns false
doExec():309, ForkJoinTask, return status word
runTask():902, ForkJoinTask$WorkQueue,
scan():1690, ForkJoinPool
runWorker():1645, ForkJoinPool
run():157 ForkJoinWorkerThread

The second call always originates from doExec() as follows

setCompletion():284
doExec():314, ForkJoinTask, return status word
runTask():902, ForkJoinTask$WorkQueue,
scan():1690, ForkJoinPool
runWorker():1645, ForkJoinPool
run():157 ForkJoinWorkerThread

So I ran a few experiments.

1) run order -> W1,W1,W2. The first call to W1 resulted in the two calls to setCompletion whereas the second call resulted in only a single call. W2 results in a single call.

2) run order ->W2,W1. W2 makes two calls to setCompletion sometimes.

So, I can’t say that I fully understand what is happening but the whole things smells a bit racy. I would have expected the second thread to see the status word and abort it’s call to setCompletion. That it does set the status word doesn’t appear to be harmful in any meaningful makes me wonder if this race (assuming it is a race) is known and intentional. Maybe someone with a better understanding can comment?

Output from the first run.

setCompletion(11110000000000000000000000000000)
called by: java.util.concurrent.ForkJoinWorkerThread::ForkJoinPool.commonPool-worker-7
Status word    : 10000000000000000
setCompletion(11110000000000000000000000000000)
Called by: java.util.concurrent.ForkJoinWorkerThread::ForkJoinPool.commonPool-worker-1
Status word    : 10000000000000000
Results…..
Concurrent Stats             : DoubleSummaryStatistics{count=6836890, sum=25379822.900800, min=0.000020, average=3.712188, max=48.941529}
Submitted Tasks             : 1
number of tasks retired   : 2
Run time (server)            : 12508.4665035 ms
Concurrent Time (client) : 12555.359548 ms
----------------------------------------------------------------

setCompletion(11110000000000000000000000000000)
called by: java.util.concurrent.ForkJoinWorkerThread::ForkJoinPool.commonPool-worker-7
Status word    : 10000000000000000
Results…..
Stopped Stats                : DoubleSummaryStatistics{count=6834790, sum=50802.064404, min=0.000048, average=0.007433, max=17.487807}
Tasks                             : 1
number of tasks retired : 1
Run time (server)          : 7410.314671 ms
Stopped Time (client)    : 7412.75453 ms
————————————————————————————————

Regards,
Kirk

_______________________________________________
Concurrency-interest mailing list
[hidden email]
http://cs.oswego.edu/mailman/listinfo/concurrency-interest

signature.asc (507 bytes) Download Attachment
Reply | Threaded
Open this post in threaded view
|

Re: Unexplained ForkJoinTask behavior

Doug Lea
On 01/13/2015 03:28 AM, Kirk Pepperdine wrote:

> Hi,
>
> I’ve been instrumenting ForkJoinPool along with ForkJoinTask. I have two
> different workloads that are being run sequentially. Lets call them W1 and
> W2.
>
> If I run in the order W1,W2 what I’ve noticed is that the call to private int
> setCompletion(int completion) is being made twice by two different
> ForkJoinWorkerThread for W1 and once for W2. When I say two calls, what I
> really mean is the status word is reset to the same NORMAL completion value.

Yes, multiple attempts to normally complete are allowed to write.
(It avoids a needless CAS.) Thanks for pointing out that this
doesn't seem to be stated currently in internal documentation,
that will be improved. (I think that a mention of this was
inadvertently omitted during an update.)

-Doug


_______________________________________________
Concurrency-interest mailing list
[hidden email]
http://cs.oswego.edu/mailman/listinfo/concurrency-interest