What’s Decidable for Asynchronous Programs? Rupak Majumdar Max Planck Institute for Software Systems Joint work with Pierre Ganty, Michael Emmi, Fernando.

Slides:



Advertisements
Similar presentations
Dataflow Analysis for Datarace-Free Programs (ESOP 11) Arnab De Joint work with Deepak DSouza and Rupesh Nasre Indian Institute of Science, Bangalore.
Advertisements

Automated Theorem Proving Lecture 1. Program verification is undecidable! Given program P and specification S, does P satisfy S?
Modeling issues Book: chapters 4.12, 5.4, 8.4, 10.1.
CS 345: Chapter 9 Algorithmic Universality and Its Robustness
CS 267: Automated Verification Lecture 8: Automata Theoretic Model Checking Instructor: Tevfik Bultan.
Static Provenance Verification for Message Passing Programs Rupak Majumdar Roland MeyerZilong Wang MPI-SWSTU KaiserslauternMPI-SWS.
Models of Concurrency Manna, Pnueli.
Knowledge Based Synthesis of Control for Distributed Systems Doron Peled.
A university for the world real R © 2009, Chapter 3 Advanced Synchronization Moe Wynn Wil van der Aalst Arthur ter Hofstede.
Automatic Verification Book: Chapter 6. What is verification? Traditionally, verification means proof of correctness automatic: model checking deductive:
Abstraction and Modular Reasoning for the Verification of Software Corina Pasareanu NASA Ames Research Center.
Ch. 7 Process Synchronization (1/2) I Background F Producer - Consumer process :  Compiler, Assembler, Loader, · · · · · · F Bounded buffer.
Silberschatz, Galvin and Gagne ©2007 Operating System Concepts with Java – 7 th Edition, Nov 15, 2006 Chapter 6 (a): Synchronization.
Timed Automata.
Chapter 6 Process Synchronization Bernard Chen Spring 2007.
Chapter 6: Process Synchronization
Keeping a Crowd Safe On the Complexity of Parameterized Verification Javier Esparza Technical University of Munich.
From Monotonic Transition Systems to Monotonic Games Parosh Aziz Abdulla Uppsala University.
Race Conditions. Isolated & Non-Isolated Processes Isolated: Do not share state with other processes –The output of process is unaffected by run of other.
Synthesis of Embedded Software Using Free-Choice Petri Nets.
Introduction to Computability Theory
Static Analysis of Embedded C Code John Regehr University of Utah Joint work with Nathan Cooprider.
Concurrency CS 510: Programming Languages David Walker.
Race Checking by Context Inference Tom Henzinger Ranjit Jhala Rupak Majumdar UC Berkeley.
1 Ivan Lanese Computer Science Department University of Bologna Italy Concurrent and located synchronizations in π-calculus.
Semantics with Applications Mooly Sagiv Schrirber html:// Textbooks:Winskel The.
Ranjit Jhala Rupak Majumdar Interprocedural Analysis of Asynchronous Programs.
Part 2: Reachability analysis of stack-based systems.
Model Checking Lecture 5. Outline 1 Specifications: logic vs. automata, linear vs. branching, safety vs. liveness 2 Graph algorithms for model checking.
272: Software Engineering Fall 2012 Instructor: Tevfik Bultan Lecture 4: SMT-based Bounded Model Checking of Concurrent Software.
Maria-Cristina Marinescu Martin Rinard Laboratory for Computer Science Massachusetts Institute of Technology A Synthesis Algorithm for Modular Design of.
0 Deterministic Replay for Real- time Software Systems Alice Lee Safety, Reliability & Quality Assurance Office JSC, NASA Yann-Hang.
What is Concurrent Programming? Maram Bani Younes.
Verifying Concurrent Message- Passing C Programs with Recursive Calls Sagar Chaki, Edmund Clarke, Nicholas Kidd, Thomas Reps, and Tayssir Touili.
Lecture 2 Foundations and Definitions Processes/Threads.
CY2003 Computer Systems Lecture 7 Petri net. © LJMU, 2004CY2003- Week 72 Overview Petri net –concepts –Petri net representation –Firing a transition –Marks.
Introduction to Problem Solving. Steps in Programming A Very Simplified Picture –Problem Definition & Analysis – High Level Strategy for a solution –Arriving.
Reasoning about programs March CSE 403, Winter 2011, Brun.
Verification & Validation By: Amir Masoud Gharehbaghi
CSCI1600: Embedded and Real Time Software Lecture 11: Modeling IV: Concurrency Steven Reiss, Fall 2015.
CSCI1600: Embedded and Real Time Software Lecture 28: Verification I Steven Reiss, Fall 2015.
13-1 Chapter 13 Concurrency Topics Introduction Introduction to Subprogram-Level Concurrency Semaphores Monitors Message Passing Java Threads C# Threads.
Threads-Process Interaction. CONTENTS  Threads  Process interaction.
UML Activity Diagrams.
Ranjit Jhala Rupak Majumdar Interprocedural Analysis of Asynchronous Programs.
Model Checking Lecture 1. Model checking, narrowly interpreted: Decision procedures for checking if a given Kripke structure is a model for a given formula.
Ordering of Events in Distributed Systems UNIVERSITY of WISCONSIN-MADISON Computer Sciences Department CS 739 Distributed Systems Andrea C. Arpaci-Dusseau.
MOPS: an Infrastructure for Examining Security Properties of Software Authors Hao Chen and David Wagner Appears in ACM Conference on Computer and Communications.
Model Checking Lecture 1: Specification Tom Henzinger.
Agenda  Quick Review  Finish Introduction  Java Threads.
Recursively Enumerable and Recursive Languages. Definition: A language is recursively enumerable if some Turing machine accepts it.
Support for Program Analysis as a First-Class Design Constraint in Legion Michael Bauer 02/22/17.
Background on the need for Synchronization
CPE555A: Real-Time Embedded Systems
Processes and Threads Processes and their scheduling
Reasoning About Code.
Reasoning about code CSE 331 University of Washington.
Event Relation Graphs and Extensions in Ptolemy II
Summary.
CSCI1600: Embedded and Real Time Software
CSCI1600: Embedded and Real Time Software
Over-Approximating Boolean Programs with Unbounded Thread Creation
Threads Chapter 4.
Concurrency: Mutual Exclusion and Process Synchronization
CSCI1600: Embedded and Real Time Software
Foundations and Definitions
CSCI1600: Embedded and Real Time Software
From Use Cases to Implementation
Prof. Onur Mutlu Carnegie Mellon University
Presentation transcript:

What’s Decidable for Asynchronous Programs? Rupak Majumdar Max Planck Institute for Software Systems Joint work with Pierre Ganty, Michael Emmi, Fernando Rosa-Velardo

Sequential Imperative Programs Program = Instruction Sequence Input Output Executed sequentially Analysis for Safety and liveness is well-studied: Safety: (Interprocedural) dataflow analysis based on abstract interpretation Liveness: Termination analysis based on well-foundedness

Concurrent Programs Why? Latency hiding Where? Operating Systems Web Servers Everywhere… Two Styles: -Multithreaded programs maintain parallel threads of execution -Asynchronous (event- driven) programs co-operatively schedule tasks Requests Program interacts with a Concurrent environment Responses

Asynchronous Programs Programming Model: Distributed Systems Web Servers Embedded Systems Mobile platforms Languages and Libraries: LibAsync, LibEvent, … Go, Rust, … Javascript/AJAX Android/iOS Requests Requests buffered and executed asynchronously Responses

Asynchronous Program Analysis This Talk: Decidability landscape of safety and (sometimes) liveness for expressive classes of asynchronous programming models [JhalaM07,GantyM.2012,EmmiGantyM.Rosa-Velardo15] Decidability is nontrivial: Not finite state or context free: -potentially unbounded stacks, -potentially unbounded request buffers, events Decidability is useful: basis for static analysis -Often used in correctness critical settings -The style breaks up control flow, making it difficult to reason about code

Simple Asynchronous Programs h1(){ if(b == 0){ async h1(); async h2(); return; } h2(){... b = 1;... return; } main(){... async h1();... } global bit b = 0; main ends in dispatch location Calls asynchronously posted functions Async calls stored in task buffer Scheduler picks a pending task and runs it to completion

Asynchronous Program Execution h1(){ if(b == 0){ async h1(); async h2(); return; } h2(){... b = 1;... return; } main(){... async h1();... } global bit b = 0; PC Execution starts in main Task buffer empty Pending Calls h1 State: b = 0

Asynchronous Program Execution h1(){ if(b == 0){ async h1(); async h2(); return; } h2(){... b = 1;... return; } main(){... async h1();... } global bit b = 0; PC Execution enters dispatch loop Picks pending call and executes it Returns to dispatch loop on return Pending Calls h1 PC h1 h2 State: b = 0

Asynchronous Program Execution h1(){ if(b == 0){ async h1(); async h2(); return; } h2(){... b = 1;... return; } main(){... async h1();... } global bit b = 0; PC Pick another pending call Pending Calls h1 PC h2 State: b = 0 h1 h2

Asynchronous Program Execution h1(){ if(b == 0){ async h1(); async h2(); return; } h2(){... b = 1;... return; } main(){... async h1();... } global bit b = 0; PC Pick some pending task Pending Calls h2 PC h2 h1 State: b = 0State: b = 1

Asynchronous Program Execution h1(){ if(b == 0){ async h1(); async h2(); return; } h2(){... b = 1;... return; } main(){... async h1();... } global bit b = 0; PC Pick some pending task Pending Calls h2 PC h1 State: b = 1

Asynchronous Program Execution h1(){ if(b == 0){ async h1(); async h2(); return; } h2(){... b = 1;... return; } main(){... async h1();... } global bit b = 0; PC And the program terminates Pending Calls h2 PC State: b = 1

Properties: Safety h1(){ if(b == 0){ async h1(); async h2(); return; } h2(){... b = 1;... return; } main(){... async h1();... } global bit b = 0; Given a Boolean asynchronous program and a control location in a handler Is there an execution which reaches the control location? We do not care about the task buffer - Handlers cannot take decisions based on the contents of the task buffer

Properties: Termination h1(){ if(b == 0){ async h1(); async h2(); return; } h2(){... b = 1;... return; } main(){... async h1();... } global bit b = 0; Given a Boolean asynchronous program, Does it terminate? main does not terminate on all runs What if h1 is chosen over h2 forever?

Fairness h1(){ if(b == 0){ async h1(); async h2(); return; } h2(){... b = 1;... return; } main(){... async h1();... } global bit b = 0; An infinite execution is fair if -For every handler h that is pending -The scheduler eventually picks and runs an instance of h -So: the run choosing h1 over h2 always is not fair -Will focus on fair runs -Captures the intuition that scheduling is fair

Fair Termination Given: –A simple asynchronous program with Boolean variables Check: –There is no fair infinite run Two checks: (a)Each called handler terminates (b)There is no infinite fair execution of handlers LTL model checking for pushdown systems [Walukiewicz, BouajjaniEsparzaMaler, Steffen]

First Attempt h1(){ if(b == 0){ async h1(); async h2(); return; } h2(){... b = 1;... return; } main(){... async h1();... } global bit b = 0; Reduce to sequential analysis -Add a counter for each handler (tracks number of pending instances) -An async call increments counter -Dispatch loop chooses a non-zero counter, decrements it and runs corresponding handler

First Attempt h1(){ if(b == 0){ ch1++; ch2++; return; } h2(){... b = 1;... return; } main(){... ch1++; while(ch1>0||ch2>0){ pick h s.t. ch > 0 ch--; h(); } global bit b = 0; ch1=0,ch2=0; Reduce to sequential analysis -Add a counter for each handler (tracks number of pending instances) -An async call increments counter -Dispatch loop chooses a non-zero counter, decrements it and runs corresponding handler -Sound, but decidability not obvious -In general, analyses undecidable for sequential programs with counters

Petri Nets Can convert an asynchronous program into a Petri net in polynomial time s.t. every execution of the async program is equivalent to an execution of the PN In particular: –The asynchronous program is safe iff the Petri net is coverable –The asynchronous program fairly terminates iff the Petri net has no fair infinite runs

General Scheme for the PN Posts add a token to the place for the handler Dispatch takes a token from the scheduler and one from the buffer (nondet) Task completion puts token back on scheduler Petri net representation for the CFG of each handler Scheduler Task buffer: One place for each handler … Places for global state

Removing the Stack Observation: Just the number of async calls matter, not the order in which they are made Parikh’s Lemma: For every context free language L, there is a regular language L’ such that: –For every w in L, there is a permutation of w in L’ and conversely So: can replace a recursive handler with a non- recursive one while maintaining the summary

Polynomial Time Conversion Do not explicitly compute the Parikh image (that FSA can be exponentially bigger) Instead, go from the CFG for a handler to a Petri net: –Places: Terminals + Non-terminals –Transitions: A -> BC takes a token from A and puts a token each in B and C

Example: CFG  PN Problem: How do you know the grammar has a full derivation?  There are no tokens in the variable places Theorem [EsparzaKieferLuttenberger, EsparzaGantyKieferLuttenberger] For a CFG with n nonterminals, the 2n- index language has the same Parikh image So give a budget to the PN S A ab

Petrification b=0 b!=0 set b:=1 Tokens: –Control flow in each handler –Pending handler calls pending h1 dispatch pending h2 h1(){ if(b == 0){ async h1(); async h2(); return; } h2(){... b = 1;... return; } main(){... async h1();... } global bit b = 0; Code for h1

Safety Verification Theorem: Safety verification EXPSPACE- complete Simple async program  Petri net  Coverability Poly time

Fair Termination Theorem: Fair termination for simple async programs is decidable and equivalent to PN reachability Program  PN  Yen’s logic to encode fair termination No implementation yet

An Aside on Implementation Two approaches to verification: 1.Abstract the program, use generic PN coverability tool bfc, mist, iic [KaiserKroeningWahl,Ganty,KloosM.NiksicPiskac] 2. Directly perform analysis on the program [JhalaM.07], using counter abstractions and expand-enlarge-check [GeeraertsRaskinvanBegin] Some initial progress, but no “stable” source-level tools Also, tools for bug finding [EmmiLalQadeer,MaiyaKanadeM.]

A Related Result Theorem: [BozzelliGanty] Backward iteration terminates in doubly exponential many iterations on PN [M.Wang14] EEC terminates in at most doubly exponential many iterations - With space efficient implementations of reachability, EEC is in EXPSPACE

“Real” Asynchronous Programs Cancel tasks Dynamically create task buffers Associate events with tasks, wait and synchronize on events Dynamically create events

Real Asynchronous Programming Programmers create events dynamically Tasks wait in task buffers and are activated by events One or more threads execute tasks from buffers (often, threads are associated with a buffer)

Example p1(){ b = 1; sync e } p2(){ assert (b==1); } main(){ e = new event async p1 {} buf; async p2 {e} buf; } global bit b = 0; event e;

Canceling tasks cancel h remove all pending occurrences of h Safety remains decidable  Go to PN + reset Liveness is undecidable

Dynamic Buffers buf = new buffer … post handler buffer Safety remains decidable: - hierarchical PN: “Buffer” tokens carry their own multiset of pending handlers - depth bounded pi-calculus [Meyer] - direct wqo construction

Events Problem: Tasks can pend on several events, and they are released by the first event that occurs –There can be unbounded chains created by tasks waiting on event sets –Do not see how to encode in depth bounded pi-calculus

Petri Data Nets Tokens carry data from dense linearly ordered domain -Places, transitions as for PN -Transition of arity n has a precondition sequence of length n and a postcondition sequence of length n: - how many tokens of the ith identity are consumed, how many are produced

Example a x<y<z x b z c

Modeling Pending Events I Tokens carry one identity, but tasks can wait on multiple events Attempt 1: Guess which token will fire the task at task creation Does not work – what if event 1 always happens before event 2? –Add spurious behaviors

Modeling Pending Events II Use the linear ordering! Guess the order in which events will fire at event creation time At task creation time, select the minimal event it pends on Plus some bookkeeping to ensure ordering of events is maintained Details are complicated 

Safety Verification Theorem: [EmmiGantyM.Rosa-Velardo] Safety verification decidable (but Ackermann hard) Async program  Petri data net  Coverability Poly time [LazicNewcombOuaknineRoscoeWorrell]

Summary Asynchronous programs are a common programming idiom –High performance –Complicated code –Good static analysis tools can help We now have the theoretical foundations –Decidable safety, decidable liveness under abstraction –But still some ways from scalable tools –In particular, tools that work on source code

Questions?