From d652155ae013f36a1ee17653a8e458baad2d9c2c Mon Sep 17 00:00:00 2001 From: Checkmate50 Date: Mon, 6 Jun 2016 23:14:18 -0600 Subject: Merging complete. Everything looks good *crosses fingers* --- Test/civl/lock-introduced.bpl | 110 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 110 insertions(+) create mode 100644 Test/civl/lock-introduced.bpl (limited to 'Test/civl/lock-introduced.bpl') diff --git a/Test/civl/lock-introduced.bpl b/Test/civl/lock-introduced.bpl new file mode 100644 index 00000000..5403e5d4 --- /dev/null +++ b/Test/civl/lock-introduced.bpl @@ -0,0 +1,110 @@ +// RUN: %boogie -noinfer -typeEncoding:m -useArrayTheory "%s" > "%t" +// RUN: %diff "%s.expect" "%t" +function {:builtin "MapConst"} MapConstBool(bool) : [X]bool; +function {:inline} {:linear "tid"} TidCollector(x: X) : [X]bool +{ + MapConstBool(false)[x := true] +} + +type X; +const nil: X; +var {:layer 0,2} b: bool; +var {:layer 1,3} lock: X; + +procedure {:yields} {:layer 3} Customer({:linear "tid"} tid: X) +requires {:layer 2} tid != nil; +requires {:layer 2} InvLock(lock, b); +ensures {:layer 2} InvLock(lock, b); +{ + yield; + assert {:layer 2} InvLock(lock, b); + while (*) + invariant {:layer 2} InvLock(lock, b); + { + call Enter(tid); + call Leave(tid); + yield; + assert {:layer 2} InvLock(lock, b); + } + yield; + assert {:layer 2} InvLock(lock, b); +} + +function {:inline} InvLock(lock: X, b: bool) : bool +{ + lock != nil <==> b +} + +procedure {:yields} {:layer 2,3} Enter({:linear "tid"} tid: X) +requires {:layer 2} tid != nil; +requires {:layer 2} InvLock(lock, b); +ensures {:layer 2} InvLock(lock, b); +ensures {:right} |{ A: assume lock == nil && tid != nil; lock := tid; return true; }|; +{ + yield; + assert {:layer 2} InvLock(lock, b); + call LowerEnter(tid); + yield; + assert {:layer 2} InvLock(lock, b); +} + +procedure {:yields} {:layer 2,3} Leave({:linear "tid"} tid:X) +requires {:layer 2} InvLock(lock, b); +ensures {:layer 2} InvLock(lock, b); +ensures {:atomic} |{ A: assert lock == tid && tid != nil; lock := nil; return true; }|; +{ + yield; + assert {:layer 2} InvLock(lock, b); + call LowerLeave(); + yield; + assert {:layer 2} InvLock(lock, b); +} + +procedure {:yields} {:layer 1,2} LowerEnter({:linear "tid"} tid: X) +ensures {:atomic} |{ A: assume !b; b := true; lock := tid; return true; }|; +{ + var status: bool; + yield; + L: + call status := CAS(false, true); + if (status) { + call SetLock(tid); + } + yield; + goto A, B; + + A: + assume status; + yield; + return; + + B: + assume !status; + goto L; +} + +procedure {:yields} {:layer 1,2} LowerLeave() +ensures {:atomic} |{ A: b := false; lock := nil; return true; }|; +{ + yield; + call SET(false); + call SetLock(nil); + yield; +} + +procedure {:layer 1} {:inline 1} SetLock(v: X) +modifies lock; +{ + lock := v; +} + +procedure {:yields} {:layer 0,1} CAS(prev: bool, next: bool) returns (status: bool); +ensures {:atomic} |{ +A: goto B, C; +B: assume b == prev; b := next; status := true; return true; +C: status := false; return true; +}|; + +procedure {:yields} {:layer 0,1} SET(next: bool); +ensures {:atomic} |{ A: b := next; return true; }|; + -- cgit v1.2.3