{
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 [...]