A Calculus of Atomic Actions Serdar Tasiran Koc University, Istanbul, Turkey Tayfun ElmasShaz Qadeer Koc University Microsoft Research.

Slides:



Advertisements
Similar presentations
Technologies for finding errors in object-oriented software K. Rustan M. Leino Microsoft Research, Redmond, WA Lecture 1 Summer school on Formal Models.
Advertisements

Automated Theorem Proving Lecture 1. Program verification is undecidable! Given program P and specification S, does P satisfy S?
Challenges in increasing tool support for programming K. Rustan M. Leino Microsoft Research, Redmond, WA, USA 23 Sep 2004 ICTAC Guiyang, Guizhou, PRC joint.
The many faces of TM Tim Harris. Granularity Distributed, large-scale atomic actions Composable shared memory data structures Leaf shared memory data.
QED: A Simplifier for Concurrent Programs Shaz Qadeer Microsoft Research Joint work with Tayfun ElmasAli SezginSerdar Tasiran.
A Program Transformation For Faster Goal-Directed Search Akash Lal, Shaz Qadeer Microsoft Research.
Verifying Executable Object-Oriented Specifications with Separation Logic Stephan van Staden, Cristiano Calcagno, Bertrand Meyer.
Reduction, abstraction, and atomicity: How much can we prove about concurrent programs using them? Serdar Tasiran Koç University Istanbul, Turkey Tayfun.
Goldilocks: Efficiently Computing the Happens-Before Relation Using Locksets Tayfun Elmas 1, Shaz Qadeer 2, Serdar Tasiran 1 1 Koç University, İstanbul,
Verification of Multithreaded Object- Oriented Programs with Invariants Bart Jacobs, K. Rustan M. Leino, Wolfram Schulte.
1 1 Regression Verification for Multi-Threaded Programs Sagar Chaki, SEI-Pittsburgh Arie Gurfinkel, SEI-Pittsburgh Ofer Strichman, Technion-Haifa Originally.
A Rely-Guarantee-Based Simulation for Verifying Concurrent Program Transformations Hongjin Liang, Xinyu Feng & Ming Fu Univ. of Science and Technology.
Hoare’s Correctness Triplets Dijkstra’s Predicate Transformers
A simple sequential reasoning approach for sound modular verification of mainstream multithreaded programs Wolfram Schulte & Bart Jacobs Microsoft Research.
Ch. 7 Process Synchronization (1/2) I Background F Producer - Consumer process :  Compiler, Assembler, Loader, · · · · · · F Bounded buffer.
Ashish Kundu CS590F Purdue 02/12/07 Language-Based Information Flow Security Andrei Sabelfield, Andrew C. Myers Presentation: Ashish Kundu
1 Beyond Reduction Busy Acquire atomic void busy_acquire() { while (true) { if (CAS(m,0,1)) break; } } if (m == 0) { m = 1; return true; } else.
Part IV: Exploiting Purity for Atomicity. Busy Acquire atomic void busy_acquire() { while (true) { if (CAS(m,0,1)) break; } } CAS(m,0,1) (fails) (succeeds)
/ PSWLAB Atomizer: A Dynamic Atomicity Checker For Multithreaded Programs By Cormac Flanagan, Stephen N. Freund 24 th April, 2008 Hong,Shin.
Verifying Concurrent Programs with Relaxed Conflict Detection Tayfun Elmas, Ismail Kuru, Serdar Taşıran, Omer Subasi Koç University Istanbul, Turkey.
Generalizing Reduction and Abstraction to Simplify Concurrent Programs: The QED Approach Shaz Qadeer Microsoft Research Redmond, WA Serdar Taşıran Serdar.
1 Operational Semantics Mooly Sagiv Tel Aviv University Textbook: Semantics with Applications.
Modular Verification of Multithreaded Software Shaz Qadeer Compaq Systems Research Center Shaz Qadeer Compaq Systems Research Center Joint work with Cormac.
Building a program verifier K. Rustan M. Leino Microsoft Research, Redmond, WA 10 May 2006 Guest lecture, Shaz Qadeer’s cse599f, Formal Verification of.
OOP #10: Correctness Fritz Henglein. Wrap-up: Types A type is a collection of objects with common behavior (operations and properties). (Abstract) types.
Copyright © 2006 The McGraw-Hill Companies, Inc. Programming Languages 2nd edition Tucker and Noonan Chapter 18 Program Correctness To treat programming.
ESC Java. Static Analysis Spectrum Power Cost Type checking Data-flow analysis Model checking Program verification AutomatedManual ESC.
1 A Modular Checker for Multithreaded Programs Cormac Flanagan HP Systems Research Center Joint work with Shaz Qadeer Sanjit A. Seshia.
Thread-Modular Verification Shaz Qadeer Joint work with Cormac Flanagan Stephen Freund Shaz Qadeer Joint work with Cormac Flanagan Stephen Freund.
Well-cooked Spaghetti: Weakest-Precondition of Unstructured Programs Mike Barnett and Rustan Leino Microsoft Research Redmond, WA, USA.
Operational Semantics Semantics with Applications Chapter 2 H. Nielson and F. Nielson
Formal Verification of SpecC Programs using Predicate Abstraction Himanshu Jain Daniel Kroening Edmund Clarke Carnegie Mellon University.
C. FlanaganType Systems for Multithreaded Software1 Cormac Flanagan UC Santa Cruz Stephen N. Freund Williams College Shaz Qadeer Microsoft Research.
Compositional Verification of Termination-Preserving Refinement of Concurrent Programs Hongjin Liang Univ. of Science and Technology of China (USTC) Joint.
Software Engineering Prof. Dr. Bertrand Meyer March 2007 – June 2007 Chair of Software Engineering Static program checking and verification Slides: Based.
Runtime Refinement Checking of Concurrent Data Structures (the VYRD project) Serdar Tasiran Koç University, Istanbul, Turkey Shaz Qadeer Microsoft Research,
Verifying Concurrent Programs with Relaxed Conflict Detection Tayfun Elmas, Ismail Kuru, Serdar Taşıran, Omer Subasi Koç University Istanbul, Turkey.
Aditya V. Nori, Sriram K. Rajamani Microsoft Research India.
11/18/20151 Operating Systems Design (CS 423) Elsa L Gunter 2112 SC, UIUC Based on slides by Roy Campbell, Sam.
Formal verification of skiplist algorithms Student: Trinh Cong Quy Supervisor: Bengt Jonsson Reviewer: Parosh Abdulla.
Concurrent Linked Lists and Linearizability Proofs Companion slides for The Art of Multiprocessor Programming by Maurice Herlihy & Nir Shavit Modified.
COP4020 Programming Languages Introduction to Axiomatic Semantics Prof. Robert van Engelen.
Automated and Modular Refinement Reasoning for Concurrent Programs Shaz Qadeer.
CIS 842: Specification and Verification of Reactive Systems Lecture INTRO-Examples: Simple BIR-Lite Examples Copyright 2004, Matt Dwyer, John Hatcliff,
Motivation  Parallel programming is difficult  Culprit: Non-determinism Interleaving of parallel threads But required to harness parallelism  Sequential.
Program Logic for Concurrency Refinement Verification Xinyu Feng University of Science and Technology of China Joint work with Hongjin Liang (USTC) and.
Compositionality Entails Sequentializability Pranav Garg, P. Madhusudan University of Illinois at Urbana-Champaign.
Understanding ADTs CSE 331 University of Washington.
Institute for Applied Information Processing and Communications (IAIK) – Secure & Correct Systems 1 Static Checking  note for.
Static Techniques for V&V. Hierarchy of V&V techniques Static Analysis V&V Dynamic Techniques Model Checking Simulation Symbolic Execution Testing Informal.
Operational Semantics Mooly Sagiv Tel Aviv University Textbook: Semantics with Applications Chapter.
/ PSWLAB Thread Modular Model Checking by Cormac Flanagan and Shaz Qadeer (published in Spin’03) Hong,Shin Thread Modular Model.
A Calculus of Atomic Actions Tayfun Elmas, Shaz Qadeer and Serdar Tasiran POPL ‘ – Seminar in Distributed Algorithms Cynthia Disenfeld 27/05/2013.
Program Analysis and Verification
Operational Semantics Mooly Sagiv Tel Aviv University Sunday Scrieber 8 Monday Schrieber.
Simplifying Linearizability Proofs Using Reduction and Abstraction Serdar Tasiran Koc University, Istanbul, Turkey Tayfun Elmas, Ali Sezgin, Omer Subasi.
Operational Semantics Mooly Sagiv Reference: Semantics with Applications Chapter 2 H. Nielson and F. Nielson
Operational Semantics Mooly Sagiv Reference: Semantics with Applications Chapter 2 H. Nielson and F. Nielson
Healing Data Races On-The-Fly
Chapter 3 of Programming Languages by Ravi Sethi
Graph-Based Operational Semantics
Joint work with Yong Li, Xinyu Feng, Zhong Shao and Yu Zhang
Verification of Concurrent Programs
Hongjin Liang, Xinyu Feng & Ming Fu
Programming Languages 2nd edition Tucker and Noonan
Over-Approximating Boolean Programs with Unbounded Thread Creation
A Refinement Calculus for Promela
Programming Languages 2nd edition Tucker and Noonan
Program Analysis and Verification
Presentation transcript:

A Calculus of Atomic Actions Serdar Tasiran Koc University, Istanbul, Turkey Tayfun ElmasShaz Qadeer Koc University Microsoft Research

Problem Verifying assertions in concurrent programs –Local conditions, program invariants, data integrity, absence of null pointer dereferences,... 2 static void transfer(Account from, Account to, int amount) { assert (from != null && to != null); assert (from.balance >= amount); old_total := from.balance + to.balance; tmp := from.balance; from.balance := tmp – amount; tmp := to.balance; to.balance := tmp + amount; assert (from.balance + to.balance == old_total); }

Our Approach: QED Proof method for verifying assertions Implementation: The QED tool Central idea: Atomicity Allows separation of concerns –Concurrency: Non-interference, synchronization mechanism –Data: Sequential reasoning within atomic blocks to prove assertions QED proof rules: Program transformation steps –Abstraction: To increase “non-interference” between actions –Reduction: Prove bigger blocks atomic –Grow atomic blocks Sequential reasoning within atomic blocks 3

Outline Motivating example Proof method Experience Full example: Multiset 4

Example – inc () 5 inc (): int t; acquire (lock); t = x; t = t + 1; x = t; release(lock); Main: assume (x == 0); inc() || inc() assert (x == 2)

Proof by Owicki-Gries A: x=0, L0: acquire(l); x=0, held(l,A)> L1: t := x; x=0, held(l,A), t=x> L2: t := t + 1; x=0, held(l,A), t=x+1> L3: x := t; x=1, held(l,A)> L4: release(l) x=1, B: x=0, L0: acquire(l); x=0, held(l,B)> L1: t := x; x=0, held(l,B), t=x> L2: t := t + 1; x=0, held(l,B), t=x+1> L3: x := t; x=1, held(l,B)> L4: release(l) x=1, 6 ||

Reduction α right mover (R) if for every execution ξ = ……. α β ……. ξ’ = ……. β α ……. is equivalent to ξ Static check for α being a right mover: –For all actions β in program, is α β always “simulated” by β α? –Easy case: β cannot follow α Example: α = β = lock.acquire() Reduction: Atomic patterns –RRRR N LLLLL –RRRRR –LLLLL –......

Proof by reduction inc (): int t; acquire (lock); t = x; t = t + 1 x = t; release(lock); R B B B L inc (): int t; acquire (lock); t = x; t = t + 1 x = t; release(lock); inc (): x = x + 1; REDUCE-SEQUENTIAL

Proof by reduction assume (x == 0); inc() || inc() assert (x == 2) assume (x == 0); x = x + 1 || x = x + 1 assert (x == 2) assume (x == 0); x = x + 1; assert (x == 2) B B INLINE-CALL REDUCE-PARALLEL

Non-blocking increment 10 inc (): int t; while(true) { t = x; if(CAS(x, t, t+1)) break; } CAS(x, t, t + 1): assume (x == t); x = t + 1; return true; assume (x != t); return false; □

Abstraction for reduction 11 inc (): int t; while(*) { t = x; assume x != t; } t = x; assume x == t; x = t + 1; inc (): int t; while(true) { t = x; if(CAS(x, t, t+1)) break; }

Abstraction for reduction 12 inc (): int t; while(*) { t = x; assume x != t; } t = x; assume x == t; x = t + 1; inc (): int t; while(*) { havoc t; skip; } havoc t; assume x == t; x = t + 1; SIMULATE

Proof by reduction 13 inc (): int t; while(*) { havoc t; skip; } havoc t; assume x == t; x := t + 1; inc (): int t; havoc t; x := x + 1; REDUCE-LOOP B

ActionPL 14 Program: Procedure bodies Program’s main body Global variables Syntax:

Gated actions 15 x = x + 1; assert (x != 0); y = y / x; x = x + 1; assert (x != 0); y = y / x; Transition: Two-store relation Gate: Assertion on pre-state

Semantics of ActionPL 16 Pre-store violates assertion Pre-store satisfies assertion Pre- and post-store satisfies transition Current dynamic statement Current store Execution: Atomic transitions:

Operational semantics 17

Proof method 18 Current program Program invariant (proof ensures this) Each execution starts from invariant Each transition preserves invariant Proof context Proof step: Governed by a proof rule May strengthen invariant May rewrite program

Soundness Theorem [Preservation] –Each proof step: Let. If goes from to then – goes from to, or – goes wrong from Theorem [Soundness] –Each proof: If goes from to such that then: – goes from to, or – goes wrong from 19 skip, error, other dyn. stmt.

Validating assertions 20 Proof succeeds if For all in, holds. Verifying each assertion is local & sequential

Invariants 21 Each action either goes wrong or preserves new invariant New invariant is stronger x = y; x = x + 1; assert (x > 0); y = y / x; true x = y; x = x + 1; assert (x > 0); y = y / x; (y >= 0) Does not touch y Preserves invariant if assertion is not violated

Validating assertions - example 22 (y >= 0) x = y; x = x + 1; assert (x > 0); y = y / x; assert (y > -1); x = y; x = x + 1; assert (x > 0); y = y / x; (y >= 0) assert (true); x = y; x = x + 1; y = y / x; (y >= 0)  (y > -1)

Auxiliary variables 23 inc (): int t; acquire (lock); a := tid; t := x; t := t + 1 x := t; release(lock); a := 0;

Auxiliary variables 24 We may modify all actions New transitions preserve invariant We add an auxiliary variable New transition modifies new aux. variable Auxiliary variable does not affect rest of transition predicate, cannot block.

Simulation 25 if (x == 1) y = y + 1; if (*) y = y + 1; y = y / x; assert (x > 0); y = y / x; From each store satisfying invariant, goes wrong or simulates. New action preserves invariant Adding behaviors that go wrongAdding non-determinism New action simulates the former

Read abstraction 26 inc (): int t; while(*) { t = x; assume x != t; } t = x; assume x == t; x = t + 1; inc (): int t; while(*) { havoc t; skip; } havoc t; assume x == t; x = t + 1; SIMULATE

Abstraction with assertions 27 inc (): int t; acquire (lock); t := x; t := t + 1 x := t; release(lock); inc (): int t; acquire (lock); a := tid; t := x; t := t + 1 x := t; release(lock); a := 0; AUX-ANNOTATE

Abstraction with assertions 28 inc (): int t; acquire (lock); a := tid; assert a == tid; t := x; assert a == tid; t := t + 1 assert a == tid; x := t; assert a == tid; release(lock); a := 0; inc (): int t; acquire (lock); a := tid; t := x; t := t + 1 x := t; release(lock); a := 0; SIMULATE

Abstraction with assertions 29 inc (): int t; acquire (lock); a := tid; assert a == tid; t := x; assert a == tid; t := t + 1 assert a == tid; x := t; assert a == tid; release(lock); a := 0; inc (): int t; acquire (lock); a := tid; assert a == tid; t := x; assert a == tid; t := t + 1 assert a == tid; x := t; assert a == tid; release(lock); a := 0; REDUCE & RELAX R B B B L Discharges the assertions “Borrowing assertions”: Introduce assertions, use them to prove larger blocks atomic Discharge later, when atomic blocks are large enough.

Reduction 30 Moving to the left makes the execution either - go to same end state or - makes execution go wrong Actions executed by different threads

Reduce - sequential 31

Reduce – nondet. choice 32 CAS(x, t, t + 1): assume (x == t); x = t + 1; return true; assume (x != t); return false; □ CAS(x, t, t + 1): assume (x == t); x = t + 1; return true; assume (x != t); return false; □ DIV (x, y): assert (x != 0); y = y / x; return y; □ DIV(x, y): assert (y != 0); x = x / y; return x; y = y / x; return y; □ x = x / y; return x; assert (x != 0 && y != 0);

Reduce - loop 33 Loop body is either left or right mover Specification preserves invariant Specification is reflexive Specification simulates zero or more iterations

Reduce - parallel 34 Explicitly expand the parallel statement to its possible executions Reduces parallel composition to sequential composition

Experience Implementation: Spec#  BoogiePL  QED –Generate verification condition (VC) for validity of each proof step –VC fed to the Z3 theorem prover Purity benchmarks [Flanagan et.al, 2005] Non-blocking algorithms –Obstruction-free deque [Herlihy et.al. 2003] –Non-blocking stack [Michael, 2004] –Bakery [Lamport, 1974] Multiset Conclusion: –Iteration of abstraction and reduction is powerful –Growing atomic code blocks useful approach 35

Multiset Multiset data structure M = { 2, 3, 3, 9, 8, 8, 5 } Represented by M[1..n] –elt: The element –vld: Is it in the set? 36 M     elt vld LookUp (x) for i = 1 to n acq (M[i]); if (M[i].elt == x && M[i].vld) rel (M[i]); return true; else rel (M[i]); return false;

FindSlot and InsertPair FindSlot (x) r = -1; i = 0; while(i < N && r == -1) { acq (A[i]); if (M[i].elt == null) { M[i].elt= x; rel (M[i]); r = i; } else { rel (M[i]); } i = i + 1; } return r; InsertPair (x, y) i = FindSlot (x); if (i == -1) { return failure; } j = FindSlot (y); if (j == -1) { M[i].elt= null; return failure; } acq (M[i]) acq (M[j]) M[i].vld = true; M[j].vld = true; rel (M[i]); rel (M[j]); return success;

Rewriting the “if” statement 38 FindSlot (x) r = -1; i = 0; while(i < N && r == -1) { acq (A[i]); if (M[i].elt == null) { M[i].elt= x; rel (M[i]); r = i; } else { rel (M[i]); } i = i + 1; } return r; FindSlot (x) r = -1; i = 0; while(i < N && r == -1) { acq (A[i]); assume (M[i].elt == null); M[i].elt= x; rel (M[i]); r = i; acq (A[i]); assume (M[i] != null); rel (M[i]); i = i + 1; } return r; □

mutex (M[i].lock == true) 39 FindSlot (x) r = -1; i = 0; while(i < N && r == -1) { acq (A[i]); assume (M[i].elt == null); M[i].elt= x; rel (M[i]); r = i; acq (A[i]); assume (M[i] != null); rel (M[i]); i = i + 1; } return r; □ REDUCE FindSlot (x) r = -1; i = 0; while(i < N && r == -1) { acq (A[i]); assume (M[i].elt == null); M[i].elt= x; rel (M[i]); r = i; acq (A[i]); assume (M[i] != null); rel (M[i]); i = i + 1; } return r; □

Read abstraction 40 FindSlot (x) r = -1; i = 0; while(i < N && r == -1) { acq (A[i]); assume (M[i].elt == null); M[i].elt= x; rel (M[i]); r = i; acq (A[i]); assume (M[i] != null); rel (M[i]); i = i + 1; } return r; □ FindSlot (x) r = -1; i = 0; while(i < N && r == -1) { acq (A[i]); assume (M[i].elt == null); M[i].elt= x; rel (M[i]); r = i; acq (A[i]); skip rel (M[i]); i = i + 1; } return r; □ SIMULATE

Rewriting 41 FindSlot (x) r = -1; i = 0; while(i < N && r == -1) { acq (A[i]); assume (M[i].elt == null); M[i].elt= x; rel (M[i]); r = i; acq (A[i]); skip; rel (M[i]); i = i + 1; } return r; □ FindSlot (x) r = -1; i = 0; while(i < N && r == -1) { acq (A[i]); assume (M[i].elt == null); M[i].elt= x; rel (M[i]); r = i; skip i = i + 1; } return r; □

□ Reducing loop 42 FindSlot (x) r = -1; i = 0; while(i < N && r == -1) { acq (A[i]); assume (M[i].elt == null); M[i].elt= x; rel (M[i]); r = i; skip i = i + 1; } return r; □ FindSlot (x) r = -1; i = 0; havoc i; assume (0 <= i < N); assume (M[i].elt == null); M[i].elt = x; r = i; skip; return r; R REDUCE-LOOP

Rewriting 43 □ FindSlot (x) r = -1; i = 0; havoc i; assume (0 <= i < N); assume (M[i].elt == null); M[i].elt = x; r = i; skip; return r; □ FindSlot (x) i = 0; havoc i; assume (0 <= i < N); assume (M[i].elt == null); M[i].elt = x; return i; return -1;

FindSlot 44 □ FindSlot (x) i = 0; havoc i; assume (0 <= i < N); assume (M[i].elt == null); M[i].elt = x; return i; return -1; Invariant:  (0 <= i < N): (M[i].elt == null)  (M[i].vld == false)

mutex (M[i].elt != null && M[i] == false) 45 InsertPair (x, y) i = FindSlot (x); if (i == -1) return failure; j = FindSlot (y); if (j == -1) M[i].elt= null; return failure; acq (M[i]) acq (M[j]) M[i].vld = true; M[j].vld = true; rel (M[i]); rel (M[j]); return success; InsertPair (x, y) i = FindSlot (x); if (i == -1) return failure; a[i] = tid; j = FindSlot (y); if (j == -1) M[i].elt= null; return failure; a[j] = tid; acq (M[i]) acq (M[j]) M[i].vld = true; M[j].vld = true; rel (M[i]); rel (M[j]); return success; R R SIMULATE

Reduce 46 InsertPair (x, y) i = FindSlot (x); if (i == -1) return failure; a[i] = tid; j = FindSlot (y); if (j == 0) M[i].elt= null; return failure; a[j] = tid; acq (M[i]) acq (M[j]) M[i].vld = true; M[j].vld = true; rel (M[i]); rel (M[j]); return success; R R InsertPair (x, y) i = FindSlot (x); if (i == -1) return failure; a[i] = tid; j = FindSlot (y); if (j == 0) M[i].elt= null; return failure; a[j] = tid; acq (M[i]) acq (M[j]) M[i].vld = true; M[j].vld = true; rel (M[i]); rel (M[j]); return success; REDUCE-SEQ.

Future work Proof script templates for encoding synchronization idioms –Guidelines for adding annotation and code transformations –Mutual-exclusion, readers/writers lock, barriers –Barriers, event synchronization –Optimistic concurrency Statically checking serializability of marked-atomic blocks Verifying STM implementations using QED 47

Delete Delete (x) for i = 1 to n acq (M[i]); if (M[i].elt == x && M[i].vld) M[i].elt = null; M[i].vld = false; rel(M[i]); return true; else rel(M[i]); return false

Invariant for “a” 52 InsertPair (x, y) i = FindSlot (x); if (i == -1) return failure; a[i] = tid; j = FindSlot (y); if (j == 0) M[i].elt= null; return failure; a[j] = tid; acq (M[i]) acq (M[j]) M[i].vld = true; M[j].vld = true; rel (M[i]); rel (M[j]); return success; R R Invariant:  (0 <= i < N): (M[i].elt != null && M[i].vld == false)  (a[i] != 0)