{ stuff mutex_lock(); critical section mutex_unlock(); end }
byte t0_incrit = 0; byte t1_incrit = 0; inline mutex_lock() { skip; } inline mutex_unlock() { skip; } proctype A() { t0_incrit = 0; /* Some stuff */ mutex_lock(); t0_incrit = 1; /* Hi! */ t0_incrit = 0; /* Ok, done */ mutex_unlock(); } | proctype B() { t1_incrit = 0; /* Some stuff */ mutex_lock(); t1_incrit = 1; /* Hi! */ t1_incrit = 0; /* Ok, done */ mutex_unlock(); } init { run A(); run B(); } |
$ spin -a saddest.promela $ gcc -o pan pan.c $ ./pan (Spin Version 4.3.0 -- 22 June 2007) + Partial Order Reduction [...] $
proctype monitor() { assert(!(t0_incrit && t1_incrit)); } init { run A(); run B(); run monitor(); }
$ spin -a saddest.promela $ gcc -o pan pan.c $ ./pan pan: assertion violated !((t0_incrit&&t1_incrit)) (at depth 9) pan: wrote saddest.promela.trail [...]
$ ./pan -C 1: :init:(0):[(run A())] 2: :init:(0):[(run B())] 3: :init:(0):[(run monitor())] 4: B(2):[t1_incrit = 0] 5: B(2):[(1)] 6: B(2):[t1_incrit = 1] 7: A(1):[t0_incrit = 0] 8: A(1):[(1)] 9: A(1):[t0_incrit = 1] pan: assertion violated !((t0_incrit&&t1_incrit)) (at depth 10) spin: trail ends after 10 steps
byte locked = 0; inline mutex_lock() { do :: 1 -> atomic { if :: locked == 0 -> locked = 1; break; :: else -> skip; fi } od }
inline mutex_unlock() { assert (locked == 1); locked = 0; }
$ spin -a happier.promela $ gcc -o pan pan.c $ ./pan [...] State-vector 28 byte, depth reached 27, errors: 0 [...]
proctype fairness() { do :: 1 -> t0_incrit -> skip; t1_incrit -> skip; progress: skip od } [...] run fairness(); [...]
$ spin -a happier-progress.promela $ gcc -o pan pan.c -DNP $ ./pan -l pan: non-progress cycle (at depth 20) pan: wrote happier-progress.promela.trail [...] State-vector 36 byte, depth reached 35, errors: 1 [...]
$ ./pan -l -C [...] <<<<<START OF CYCLE>>>>> 22: B(3):[((locked==0))] 24: B(3):[break] 26: B(3):[t1_incrit = 1] 28: B(3):[t1_incrit = 0] 30: B(3):[assert((locked==1))] 32: B(3):[locked = 0] 34: B(3):[(1)] 36: B(3):[(1)]
proctype A() { f0 = 1; do :: f1 -> if :: turn != 0 -> f0 = 0; turn == 0 -> skip; f0 = 1; :: else -> skip; fi :: else -> break; od; t0_incrit = 1; t0_incrit = 0; turn = 1; f0 = 0; } | proctype B() { f1 = 1; do :: f0 -> if :: turn != 1 -> f1 = 0; turn == 1 -> skip; f1 = 1; :: else -> skip; fi :: else -> break; od; t1_incrit = 1; t1_incrit = 0; turn = 0; f1 = 0; } |
$ spin -a dekker.promela $ gcc -o pan pan.c $ ./pan [...] State-vector 32 byte, depth reached 29, errors: 0 [...]
proctype fairness0() { f0 -> t0_incrit; } proctype fairness1() { f1 -> t1_incrit; }
$ spin -a dekker-waiting.promela $ gcc -o pan pan.c $ ./pan [...] State-vector 40 byte, depth reached 106, errors: 0 [...]