QED: A Simplifier for Concurrent Programs Shaz Qadeer Microsoft Research Joint work with Tayfun ElmasAli SezginSerdar Tasiran.

Slides:



Advertisements
Similar presentations
1 Lecture 5 Towards a Verifying Compiler: Multithreading Wolfram Schulte Microsoft Research Formal Methods 2006 Race Conditions, Locks, Deadlocks, Invariants,
Advertisements

A Framework for describing recursive data structures Kenneth Roe Scott Smith.
Program Analysis using Random Interpretation Sumit Gulwani UC-Berkeley March 2005.
Advanced programming tools at Microsoft
Functional Decompositions for Hardware Verification With a few speculations on formal methods for embedded systems Ken McMillan.
Module 6: Process Synchronization
Summarizing Procedures in Concurrent Programs Shaz Qadeer Sriram K. Rajamani Jakob Rehof Microsoft Research.
Zing: A Systematic State Explorer for Concurrent Software Tony Andrews Shaz Qadeer Sriram K. Rajamani Jakob Rehof Microsoft Research.
Demand-driven inference of loop invariants in a theorem prover
Technologies for finding errors in object-oriented software K. Rustan M. Leino Microsoft Research, Redmond, WA Lecture 0 Summer school on Formal Models.
Automated Theorem Proving Lecture 1. Program verification is undecidable! Given program P and specification S, does P satisfy S?
Zing: Exploiting Program Structure for Model Checking Concurrent Software Tony Andrews Shaz Qadeer Sriram K. Rajamani Jakob Rehof Microsoft Research Yichen.
Modeling Software Systems Lecture 2 Book: Chapter 4.
Lexical Analysis Dragon Book: chapter 3.
Visual Formalisms Message Sequence Charts Book: Chapter 10.
Model Checking and Testing combined
Automatic Verification Book: Chapter 6. How can we check the model? The model is a graph. The specification should refer the the graph representation.
Process Algebra Book: Chapter 8. The Main Issue Q: When are two models equivalent? A: When they satisfy different properties. Q: Does this mean that the.
Modeling issues Book: chapters 4.12, 5.4, 8.4, 10.1.
Distributed systems Total Order Broadcast Prof R. Guerraoui Distributed Programming Laboratory.
Laboratoire d'InfoRmatique en Image et Systèmes d'information UMR July Selecting Web Services.
IBM T. J. Watson Research Center Conditions for Strong Synchronization Maged Michael IBM T J Watson Research Center Joint work with: Martin Vechev, Hagit.
Concurrent programming for dummies (and smart people too) Tim Harris & Keir Fraser.
Global States.
Delta-Oriented Testing for Finite State Machines
Hongjin Liang and Xinyu Feng
Refinement Verification of Concurrent Programs and Its Applications Hongjin Liang Univ. of Science and Technology of China Advisors: Xinyu Feng and Zhong.
Ken McMillan Microsoft Research
Program Verification -- new recipe for old problem Zhou Chaochen Institute of Software, CAS
Architecture-aware Analysis of Concurrent Software Rajeev Alur University of Pennsylvania Amir Pnueli Memorial Symposium New York University, May 2010.
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,
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.
A simple sequential reasoning approach for sound modular verification of mainstream multithreaded programs Wolfram Schulte & Bart Jacobs Microsoft Research.
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.
Summarizing Procedures in Concurrent Programs Shaz Qadeer Sriram K. Rajamani Jakob Rehof Microsoft Research.
1 Thread Modular Model Checking Cormac Flanagan Systems Research Center HP Labs Joint work with Shaz Qadeer (Microsoft Research)
ESC Java. Static Analysis Spectrum Power Cost Type checking Data-flow analysis Model checking Program verification AutomatedManual ESC.
Thread-modular Abstraction Refinement Tom Henzinger Ranjit Jhala Rupak Majumdar [UC Berkeley] Shaz Qadeer [Microsoft Research]
Modular Verification of Multithreaded Software Shaz Qadeer Compaq Systems Research Center Shaz Qadeer Compaq Systems Research Center Joint work with Cormac.
C. Flanagan1Atomicity for Reliable Concurrent Software - PLDI'05 Tutorial Atomicity for Reliable Concurrent Software Joint work with Stephen Freund Shaz.
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.
Verifying Commit-Atomicity Using Model Checking Cormac Flanagan University of California, Santa Cruz.
Part II: Atomicity for Software Model Checking. Class Account { int balance; static int MIN = 0, MAX = 100; bool synchronized deposit(int n) { int t =
Comparison Under Abstraction for Verifying Linearizability Daphna Amit Noam Rinetzky Mooly Sagiv Tom RepsEran Yahav Tel Aviv UniversityUniversity of Wisconsin.
Synchronization CSCI 444/544 Operating Systems Fall 2008.
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.
CS510 Concurrent Systems Introduction to Concurrency.
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.
11/18/20151 Operating Systems Design (CS 423) Elsa L Gunter 2112 SC, UIUC Based on slides by Roy Campbell, Sam.
Concurrent Linked Lists and Linearizability Proofs Companion slides for The Art of Multiprocessor Programming by Maurice Herlihy & Nir Shavit Modified.
Automated and Modular Refinement Reasoning for Concurrent Programs Shaz Qadeer.
/ 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.
CS510 Concurrent Systems Jonathan Walpole. Introduction to Concurrency.
Simplifying Linearizability Proofs Using Reduction and Abstraction Serdar Tasiran Koc University, Istanbul, Turkey Tayfun Elmas, Ali Sezgin, Omer Subasi.
A Calculus of Atomic Actions Serdar Tasiran Koc University, Istanbul, Turkey Tayfun ElmasShaz Qadeer Koc University Microsoft Research.
Håkan Sundell Philippas Tsigas
Joint work with Yong Li, Xinyu Feng, Zhong Shao and Yu Zhang
Verification of Concurrent Programs
Hongjin Liang, Xinyu Feng & Ming Fu
Does Hardware Transactional Memory Change Everything?
An explicit state model checker
CSE 153 Design of Operating Systems Winter 19
EECE.4810/EECE.5730 Operating Systems
Presentation transcript:

QED: A Simplifier for Concurrent Programs Shaz Qadeer Microsoft Research Joint work with Tayfun ElmasAli SezginSerdar Tasiran

Reliable concurrent software? Concurrency results in Heisenbugs – non-deterministic, timing dependent – data corruption, crashes – difficult to detect, reproduce, eliminate Correctness problem – does program behave correctly for all inputs and all interleavings?

P satisfies S Undecidable problem!

P satisfies S Assertions: Provide contracts to decompose problem into a collection of decidable problems pre-condition and post-condition for each procedure loop invariant for each loop

int t; L0: acquire(l); L1: t := x; L2: t := t + 1; L3: x := t; L4: release(l); L5: pre x=c; post x=c+2; int t; M0: acquire(l); M1: t := x; M2: t := t + 1; M3: x := t; M4: release(l); M5: AB  x=c,  x=c+1  x=c,  x=c+1, held(l, A)  x=c,  x=c+1, held(l, A), t=x  x=c,  x=c+1, held(l, A), t=x+1  x=c+1,  x=c+2, held(l, A)  x=c+1,  x=c+2  x=c,  x=c+1  x=c,  x=c+1, held(l, B)  x=c,  x=c+1, held(l, B), t=x  x=c,  x=c+1, held(l, B), t=x+1  x=c+1,  x=c+2, held(l, B)  x=c+1,  x=c+2 Invariant problem

int t; acquire(l); t := x; t := t + 1; x := t; release(l); Abstraction problem int t; t := x; t := t + 1; x := t; x := x+1 ??

int t; L0: acquire(l); L1: t := x; L2: t := t + 1; L3: x := t; L4: release(l); L5: pre x=c; post x=c+2; int t; M0: acquire(l); M1: t := x; M2: t := t + 1; M3: x := t; M4: release(l); M5: Intuitive reasoning with atomic actions

int t; atomic { L0: acquire(l); L1: t := x; L2: t := t + 1; L3: x := t; L4: release(l); } L5: pre x=c; post x=c+2; int t; atomic { M0: acquire(l); M1: t := x; M2: t := t + 1; M3: x := t; M4: release(l); } M5: Intuitive reasoning with atomic actions  x=c,  x=c+1  x=c+1,  x=c+2  x=c,  x=c+1  x=c+1,  x=c+2

pre x=c; post x=c+2; atomic { x := x + 1; } Intuitive reasoning with atomic actions atomic { x := x + 1; }

pre x=c; post x=c+2; atomic { x := x + 1; } Intuitive reasoning with atomic actions Verify using sequential methods!

Do not verify the original program Instead, simplify the program Verify the program once it is simple enough QED I 0,P 0 I 1,P 1 I 2,P 2 I 3,P 3 I,P InvariantProgram text Simplified program has simpler invariants Abstraction of a program is another program

procedure Write(int a, int d) { atomic { m[a] := d; } } procedure Snapshot(int a, int b, out int da, out int db) { atomic { da := m[a]; db := m[b]; } } Atomic snapshot int[] m;

procedure Write(int a, int d) { atomic { m[a].d := d; m[a].v := m[a].v+1; } } procedure Snapshot(int a, int b, out bool s, out int da, out int db) { int va, vb; atomic { va := m[a].v; da := m[a].d; } atomic { vb := m[b].v; db := m[b].d; } s := true; atomic { if (va < m[a].v) { s := false; } } atomic { if (vb < m[b].v) { s := false; } } } Atomic snapshot class VersionedInteger { int v; int d; } VersionedInteger[] m;

QED-simplified atomic snapshot procedure Write(int a, int d) { atomic { m[a].d := d; m[a].v := m[a].v+1; } } procedure Snapshot(int a: int, int b, out bool s, out int da, out int db) { atomic { havoc s, da, db; if (s) { da := m[a].d; db := m[b].d; } } class VersionedInteger { int v; int d; } VersionedInteger[] m;

QED transformations I,PI’,P’ 1.Strengthen invariant 2.Reduce program 3.Abstract program

Rule 1: Strengthen invariant I,PI’,P I’  I

Rule 2: Reduce program atomic { A ; B }atomic { A } ; atomic { B } I,PI,P’

S1S1 S2S2 S3S3 acquirey S1S1 T2T2 S3S3 y S1S1 T2T2 S3S3 releasex S1S1 S2S2 S3S3 x Right and left movers (Lipton 1975) int owner; procedure acquire() { atomic { assume owner == 0; owner := tid; } procedure release() { atomic { assert owner == tid; owner := 0; } Lock

S0S0. S5S5 R* N L*xY... S0S0. S5S5 R* N L* x Y... Reduction theorem Sequence R*;(N+  ); L* is atomic

Rule 3: Abstract program atomic { A }atomic { B } I,PI,P’ From each state x in I, if A can go to y then B can also go to y

QED tool reduce abstract..... reduce check [ QED Correct P1P1 PnPn P2P2 P1P1 PnPn

QED-verified examples Fine-grained locking – Linked-list with hand-over-hand locking [Herlihy-Shavit 08] – Two-lock queue [Michael-Scott 96] Non-blocking algorithms – Bakery [Lamport 74] – Non-blocking stack [Treiber 86] – Obstruction-free deque [Herlihy et al. 03] – Non-blocking stack [Michael 04] – Writer mode of non-blocking readers/writer lock [Krieger et al. 93] – Non-blocking queue [Michael-Scott 96] – Synchronous queue [Scherer-Lea-Scott 06]

QED transformations I,PI’,P’ Strengthen invariant Abstract program Reduce program The rules are symbiotic: Abstraction enables reduction Reduction enables abstraction Program simplification enables simpler invariants Together these rules are surprisingly powerful!

Two examples Atomic snapshot – Abstraction enables reduction Spin lock – Program simplification yields simpler invariants

Atomic Snapshot

class VersionedInteger { int v; int d; } VersionedInteger[] m; procedure Write(int a, int d) { atomic { m[a].d := d; m[a].v := m[a].v+1; } } procedure Snapshot(int a, int b, out bool s, out int da, out int db) { int va, vb; atomic { va := m[a].v; da := m[a].d; } atomic { vb := m[b].v; db := m[b].d; } s := true; atomic { if (va < m[a].v) { s := false; } } atomic { if (vb < m[b].v) { s := false; } } }

class VersionedInteger { int v; int d; } VersionedInteger[] m; procedure Write(int a, int d) { atomic { m[a].d := d; m[a].v := m[a].v+1; } } procedure Snapshot(int a, int b, out bool s, out int da, out int db) { int va, vb; atomic { havoc va, da; assume va <= m[a].v; if (va == m[a].v) { da := m[a].d; } } atomic { havoc vb, db; assume vb <= m[b].v; if (vb == m[b].v) { db := m[b].d; } } s := true; atomic { if (va < m[a].v) { s := false; } if (s) { havoc s; } } atomic { if (vb < m[b].v) { s := false; } if (s) { havoc s; } } } Left Mover Right Mover Left Mover

class VersionedInteger { int v; int d; } VersionedInteger[] m; procedure Write(int a, int d) { atomic { m[a].d := d; m[a].v := m[a].v+1; } } procedure Snapshot(int a, int b, out bool s, out int da, out int db) { int va, vb; atomic { havoc va, da; assume va <= m[a].v; if (va == m[a].v) { da := m[a].d; } havoc vb, db; assume vb <= m[b].v; if (vb == m[b].v) { db := m[b].d; } s := true; if (va < m[a].v) { s := false; } if (s) { havoc s; } if (vb < m[b].v) { s := false; } if (s) { havoc s; } }

class VersionedInteger { int v; int d; } VersionedInteger[] m; procedure Write(int a, int d) { atomic { m[a].d := d; m[a].v := m[a].v+1; } } procedure Snapshot(int a, int b, out bool s, out int da, out int db) { int va, vb; atomic { havoc va, da, vb, db, s; if (s) { va := m[a].v; da := m[a].d; vb := m[b].v; db := m[b].d; s := true; }

class VersionedInteger { int v; int d; } VersionedInteger[] m; procedure Write(int a, int d) { atomic { m[a].d := d; m[a].v := m[a].v+1; } } procedure Snapshot(int a, int b, out bool s, out int da, out int db) { atomic { havoc da, db, s; if (s) { da := m[a].d; db := m[b].d; } Hide va, vb

Spin Lock

bool held; procedure acquire() { while (true) { if (CAS(held, false, true)) { break; } procedure release() { held := false; } int owner; procedure acquire() { atomic { assume owner == 0; owner := tid; } procedure release() { atomic { assert owner == tid; owner := 0; }

bool held; int owner; procedure acquire() { while (true) { if (CAS(held, false, true)) { owner := tid; break; } procedure release() { atomic { assert owner == tid; owner := 0; held := false; }

bool held; int owner; procedure acquire() { while (*) { assume held != false; } atomic { assume held == false; held := true; } owner := tid; } procedure release() { atomic { assert owner == tid; owner := 0; held := false; }

bool held; int owner; procedure acquire() { while (*) { assume true; } atomic { assume held == false; held := true; } owner := tid; } procedure release() { atomic { assert owner == tid; owner := 0; held := false; }

bool held; int owner; procedure acquire() { atomic { assume held == false; held := true; } owner := tid; } procedure release() { atomic { assert owner == tid; owner := 0; held := false; }

bool held; int owner; procedure acquire() { atomic { assume held == false; held := true; } atomic { assert owner == 0; owner := tid; } } procedure release() { atomic { assert owner == tid; owner := 0; held := false; } Left Mover (Not Quite) Invariant: owner == 0  held == false

bool held; int owner; procedure acquire() { atomic { assume held == false; held := true; assert owner == 0; owner := tid; } procedure release() { atomic { assert owner == tid; owner := 0; held := false; }

bool held; int owner; procedure acquire() { atomic { assume held == false; held := true; assert owner == 0; owner := tid; } procedure release() { atomic { assert owner == tid; owner := 0; held := false; } Invariant: owner == 0  held == false

bool held; int owner; procedure acquire() { atomic { assume held == false; held := true; assume owner == 0; owner := tid; } procedure release() { atomic { assert owner == tid; owner := 0; held := false; }

int owner; procedure acquire() { atomic { assume owner == 0; owner := tid; } } procedure release() { atomic { assert owner == tid; owner := 0; } } Hide held

Conclusions QED: A simplifier for concurrent programs – Do not verify the original program – Instead, simplify the program – Verify the program once it is simple enough Other applications – Concurrency testing – Programmer-assisted parallelization