JDK-8145808 : [PIT] test java/awt/Graphics2D/MTGraphicsAccessTest/MTGraphicsAccessTest.java hangs on Win. 8
Type:Bug
Component:client-libs
Sub-Component:2d
Affected Version:9
Priority:P3
Status:Resolved
Resolution:Fixed
OS:windows_8
Submitted:2015-12-18
Updated:2020-10-12
Resolved:2015-12-24
The Version table provides details related to the release that this issue/RFE will be addressed.
Unresolved : Release in which this issue/RFE will be addressed. Resolved: Release in which this issue/RFE has been resolved. Fixed : Release in which this issue/RFE has been fixed. The release containing this fix may be available for download as an Early Access Release or a General Availability Release.
the test hangs often (being run as a part of regression test suite or just separately, as a standalone application).
OS: Windows 8.1 x64
JDK9-client, b97
Comments
Fix Request (8u):
Backport to 8u requested because it is a part of 8u271-oracle. Patch applies cleanly. Testing: checked that test passes.
26-06-2020
The hang shows us waiting here :-
at java.lang.Thread.sleep(Native Method)
at MTGraphicsAccessTest.mysleep(MTGraphicsAccessTest.java:127)
at MTGraphicsAccessTest.<init>(MTGraphicsAccessTest.java:111)
at MTGraphicsAccessTest.main(MTGraphicsAccessTest.java:183)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:520)
at com.sun.javatest.regtest.agent.MainWrapper$MainThread.run(MainWrapper.java:110)
at java.lang.Thread.run(Thread.java:747)
The passing test prints this before it reaches the code shown above :
"Approximate test run time: 7 seconds"
I don't see any circumstances where it could get to that code *without* printing the message.
Perhaps the test harness threw it away in the timeout case ?
Next the loop we hang on is this :-
while (stillRunning > 0) { mysleep(500); }
stillRunning is incremented when we create and start threads and
is decremented when we join the thread.
And we do not reach the above line until the requested number of threads
have already been created and started.
Since they are not shown in the thread log, logic says they must already
have been joined.
And since we are still looping it then follows that we did not get
stillRunning properly decremented.
I think the problem is that although "stillRunning" is declared volatile
the updates to it are respectively
"stillRunning++;" - when creating
"stillRunning--" - when the thread exits.
But ++ and -- are not atomic and so two different threads
could correctly read "2" as the value, each then prepares the result of
the decrement as "1", and writes "1".
We should be down to zero and exit the loop but never do.
So volatile is not sufficient here.
The missing log output from the normal run of the program is the main
problem with this theory but I am going to blame the test harness for that.