xref: /linux/Documentation/litmus-tests/locking/DCL-fixed.litmus (revision 1ac731c529cd4d6adbce134754b51ff7d822b145)
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