1*4882a593SmuzhiyunC Z6.0+pooncerelease+poacquirerelease+fencembonceonce 2*4882a593Smuzhiyun 3*4882a593Smuzhiyun(* 4*4882a593Smuzhiyun * Result: Sometimes 5*4882a593Smuzhiyun * 6*4882a593Smuzhiyun * This litmus test shows that a release-acquire chain, while sufficient 7*4882a593Smuzhiyun * when there is but one non-reads-from (AKA non-rf) link, does not suffice 8*4882a593Smuzhiyun * if there is more than one. Of the three processes, only P1() reads from 9*4882a593Smuzhiyun * P0's write, which means that there are two non-rf links: P1() to P2() 10*4882a593Smuzhiyun * is a write-to-write link (AKA a "coherence" or just "co" link) and P2() 11*4882a593Smuzhiyun * to P0() is a read-to-write link (AKA a "from-reads" or just "fr" link). 12*4882a593Smuzhiyun * When there are two or more non-rf links, you typically will need one 13*4882a593Smuzhiyun * full barrier for each non-rf link. (Exceptions include some cases 14*4882a593Smuzhiyun * involving locking.) 15*4882a593Smuzhiyun *) 16*4882a593Smuzhiyun 17*4882a593Smuzhiyun{} 18*4882a593Smuzhiyun 19*4882a593SmuzhiyunP0(int *x, int *y) 20*4882a593Smuzhiyun{ 21*4882a593Smuzhiyun WRITE_ONCE(*x, 1); 22*4882a593Smuzhiyun smp_store_release(y, 1); 23*4882a593Smuzhiyun} 24*4882a593Smuzhiyun 25*4882a593SmuzhiyunP1(int *y, int *z) 26*4882a593Smuzhiyun{ 27*4882a593Smuzhiyun int r0; 28*4882a593Smuzhiyun 29*4882a593Smuzhiyun r0 = smp_load_acquire(y); 30*4882a593Smuzhiyun smp_store_release(z, 1); 31*4882a593Smuzhiyun} 32*4882a593Smuzhiyun 33*4882a593SmuzhiyunP2(int *x, int *z) 34*4882a593Smuzhiyun{ 35*4882a593Smuzhiyun int r1; 36*4882a593Smuzhiyun 37*4882a593Smuzhiyun WRITE_ONCE(*z, 2); 38*4882a593Smuzhiyun smp_mb(); 39*4882a593Smuzhiyun r1 = READ_ONCE(*x); 40*4882a593Smuzhiyun} 41*4882a593Smuzhiyun 42*4882a593Smuzhiyunexists (1:r0=1 /\ z=2 /\ 2:r1=0) 43