55 lines
		
	
	
		
			811 B
		
	
	
	
		
			Plaintext
		
	
	
	
	
	
			
		
		
	
	
			55 lines
		
	
	
		
			811 B
		
	
	
	
		
			Plaintext
		
	
	
	
	
	
| C DCL-broken
 | |
| 
 | |
| (*
 | |
|  * Result: Sometimes
 | |
|  *
 | |
|  * This litmus test demonstrates more than just locking is required to
 | |
|  * correctly implement double-checked locking.
 | |
|  *)
 | |
| 
 | |
| {
 | |
| 	int flag;
 | |
| 	int data;
 | |
| }
 | |
| 
 | |
| P0(int *flag, int *data, spinlock_t *lck)
 | |
| {
 | |
| 	int r0;
 | |
| 	int r1;
 | |
| 	int r2;
 | |
| 
 | |
| 	r0 = READ_ONCE(*flag);
 | |
| 	if (r0 == 0) {
 | |
| 		spin_lock(lck);
 | |
| 		r1 = READ_ONCE(*flag);
 | |
| 		if (r1 == 0) {
 | |
| 			WRITE_ONCE(*data, 1);
 | |
| 			WRITE_ONCE(*flag, 1);
 | |
| 		}
 | |
| 		spin_unlock(lck);
 | |
| 	}
 | |
| 	r2 = READ_ONCE(*data);
 | |
| }
 | |
| 
 | |
| P1(int *flag, int *data, spinlock_t *lck)
 | |
| {
 | |
| 	int r0;
 | |
| 	int r1;
 | |
| 	int r2;
 | |
| 
 | |
| 	r0 = READ_ONCE(*flag);
 | |
| 	if (r0 == 0) {
 | |
| 		spin_lock(lck);
 | |
| 		r1 = READ_ONCE(*flag);
 | |
| 		if (r1 == 0) {
 | |
| 			WRITE_ONCE(*data, 1);
 | |
| 			WRITE_ONCE(*flag, 1);
 | |
| 		}
 | |
| 		spin_unlock(lck);
 | |
| 	}
 | |
| 	r2 = READ_ONCE(*data);
 | |
| }
 | |
| 
 | |
| locations [flag;data;0:r0;0:r1;1:r0;1:r1]
 | |
| exists (0:r2=0 \/ 1:r2=0)
 |