On 03/03/2017 10:51 AM, Grzegorz Gierlach wrote:
> It passes on x86 however for some reason I'm not 100% sure it is a correct
> implementation. Is there a better way of doing it?
The discussion about "correct", "way of doing it" is irrelevant if you don't
describe what is your intent with this test.
But mechanically, this is a Dekker test in disguise:
http://hg.openjdk.java.net/code-tools/jcstress/file/tip/tests-custom/src/main/java/org/openjdk/jcstress/tests/volatiles/DekkerTest.java
The only forbidden state is (0, 0) in plain old Dekker. It stands to reason that
gating the 0->1 transition with CAS makes (1, 1) forbidden too. So your test
should pass, modulo runtime and hardware bugs.
> @JCStressTest
>
> @State
> @Outcome(id ="1, 0",expect =ACCEPTABLE,desc ="first executed")
> @Outcome(id ="0, 1",expect =ACCEPTABLE,desc ="second executed")
> @Outcome(id ="1, 1",expect =FORBIDDEN,desc ="both executed!")
> @Outcome(id ="0, 0",expect =FORBIDDEN,desc ="none executed!")
> publicclassVolatileConcurrencyTest{
>
> volatileObjectreceiver;
>
> volatileObjectresolution;
>
> AtomicBooleanapplied =newAtomicBoolean();
>
> @Actor
> voidactor1(IntResult2r){
> receiver =newObject();
> if(resolution !=null&&applied.compareAndSet(false,true)){
> r.r1 =1;
> }else{
> r.r1 =0;
> }
> }
>
> @Actor
> voidactor2(IntResult2r){
> resolution =newObject();
> if(receiver !=null&&applied.compareAndSet(false,true)){
> r.r2 =1;
> }else{
> r.r2 =0;
> }
> }
> }
-Aleksey