1*7e7eb5aeSPaul E. McKenneyC DCL-fixed 2*7e7eb5aeSPaul E. McKenney 3*7e7eb5aeSPaul E. McKenney(* 4*7e7eb5aeSPaul E. McKenney * Result: Never 5*7e7eb5aeSPaul E. McKenney * 6*7e7eb5aeSPaul E. McKenney * This litmus test demonstrates that double-checked locking can be 7*7e7eb5aeSPaul E. McKenney * reliable given proper use of smp_load_acquire() and smp_store_release() 8*7e7eb5aeSPaul E. McKenney * in addition to the locking. 9*7e7eb5aeSPaul E. McKenney *) 10*7e7eb5aeSPaul E. McKenney 11*7e7eb5aeSPaul E. McKenney{ 12*7e7eb5aeSPaul E. McKenney int flag; 13*7e7eb5aeSPaul E. McKenney int data; 14*7e7eb5aeSPaul E. McKenney} 15*7e7eb5aeSPaul E. McKenney 16*7e7eb5aeSPaul E. McKenneyP0(int *flag, int *data, spinlock_t *lck) 17*7e7eb5aeSPaul E. McKenney{ 18*7e7eb5aeSPaul E. McKenney int r0; 19*7e7eb5aeSPaul E. McKenney int r1; 20*7e7eb5aeSPaul E. McKenney int r2; 21*7e7eb5aeSPaul E. McKenney 22*7e7eb5aeSPaul E. McKenney r0 = smp_load_acquire(flag); 23*7e7eb5aeSPaul E. McKenney if (r0 == 0) { 24*7e7eb5aeSPaul E. McKenney spin_lock(lck); 25*7e7eb5aeSPaul E. McKenney r1 = READ_ONCE(*flag); 26*7e7eb5aeSPaul E. McKenney if (r1 == 0) { 27*7e7eb5aeSPaul E. McKenney WRITE_ONCE(*data, 1); 28*7e7eb5aeSPaul E. McKenney smp_store_release(flag, 1); 29*7e7eb5aeSPaul E. McKenney } 30*7e7eb5aeSPaul E. McKenney spin_unlock(lck); 31*7e7eb5aeSPaul E. McKenney } 32*7e7eb5aeSPaul E. McKenney r2 = READ_ONCE(*data); 33*7e7eb5aeSPaul E. McKenney} 34*7e7eb5aeSPaul E. McKenney 35*7e7eb5aeSPaul E. McKenneyP1(int *flag, int *data, spinlock_t *lck) 36*7e7eb5aeSPaul E. McKenney{ 37*7e7eb5aeSPaul E. McKenney int r0; 38*7e7eb5aeSPaul E. McKenney int r1; 39*7e7eb5aeSPaul E. McKenney int r2; 40*7e7eb5aeSPaul E. McKenney 41*7e7eb5aeSPaul E. McKenney r0 = smp_load_acquire(flag); 42*7e7eb5aeSPaul E. McKenney if (r0 == 0) { 43*7e7eb5aeSPaul E. McKenney spin_lock(lck); 44*7e7eb5aeSPaul E. McKenney r1 = READ_ONCE(*flag); 45*7e7eb5aeSPaul E. McKenney if (r1 == 0) { 46*7e7eb5aeSPaul E. McKenney WRITE_ONCE(*data, 1); 47*7e7eb5aeSPaul E. McKenney smp_store_release(flag, 1); 48*7e7eb5aeSPaul E. McKenney } 49*7e7eb5aeSPaul E. McKenney spin_unlock(lck); 50*7e7eb5aeSPaul E. McKenney } 51*7e7eb5aeSPaul E. McKenney r2 = READ_ONCE(*data); 52*7e7eb5aeSPaul E. McKenney} 53*7e7eb5aeSPaul E. McKenney 54*7e7eb5aeSPaul E. McKenneylocations [flag;data;0:r0;0:r1;1:r0;1:r1] 55*7e7eb5aeSPaul E. McKenneyexists (0:r2=0 \/ 1:r2=0) 56