How to Make a Correct Multiprocess Program Execute Correctly on a Multiprocessor

Transcription

1 How to Make a Correct Multiprocess Program Execute Correctly on a Multiprocessor Leslie Lamport 1 Digital Equipment Corporation February 14, 1993 Minor revisions January 18, 1996 and September 14, 1996 Abstract A multiprocess program executing on a modern multiprocessor must issue explicit commands to synchronize memory accesses. A method is proposed for deriving the necessary commands from a correctness proof of the underlying algorithm in a formalism based on temporal relations among operation executions. index terms concurrency, memory consistency, multiprocessor, synchronization, verification 1 Author s current address: Digital Equipment Corporation, Systems Research Center, 130 Lytton Avenue, Palo Alto, CA 94301

2 1 The Problem Accessing a single memory location in a multiprocessor is traditionally assumed to be atomic. Such atomicity is a fiction; a memory access consists of a number of hardware actions, and different accesses may be executed concurrently. Early multiprocessors maintained this fiction, but more modern ones usually do not. Instead, they provide special commands with which processes themselves can synchronize memory accesses. The programmer must determine, for each particular computer, what synchronization commands are needed to make his program correct. One proposed method for achieving the necessary synchronization is with a constrained style of programming specific to a particular type of multiprocessor architecture [7, 8]. Another method is to reason about the program in a mathematical abstraction of the architecture [5]. We take a different approach and derive the synchronization commands from a proof of correctness of the algorithm. The commonly used formalisms for describing multiprocess programs assume atomicity of memory accesses. When an assumption is built into a formalism, it is difficult to discover from a proof where the assumption is actually needed. Proofs based on these formalisms, including invariance proofs [4, 16] and temporal-logic proofs [17], therefore seem incapable of yielding the necessary synchronization requirements. We derive these requirements from proofs based on a little-used formalism that makes no atomicity assumptions [11, 12, 14]. This proof method is quite general and has been applied to a number of algorithms. The method of extracting synchronization commands from a proof is described by an example a simple mutual exclusion algorithm. It can be applied to the proof of any algorithm. Most programs are written in higher-level languages that provide abstractions, such as locks for shared data, that free the programmer from concerns about the memory architecture. The compiler generates synchronization commands to implement the abstractions. However, some algorithms especially within the operating system require more efficient implementations than can be achieved with high-level language abstractions. It is to these algorithms, as well as to algorithms for implementing the higher-level abstractions, that our method is directed. 1

3 2 The Formalism An execution of a program is represented by a collection of operation executions with the two relations (read precedes)and (read can affect). An operation execution can be interpreted as a nonempty set of events, where the relations and have the following meanings. A B: every event in A precedes every event in B. A B: someeventina precedes some event in B. However, this interpretation serves only to aid our understanding. Formally, we just assume that the following axioms hold, for any operation executions A, B, C, andd. A1. is transitive (A B C implies A C) and irreflexive (A / A). A2. A B implies A B and B / A. A3. A B C or A B C implies A C. A4. A B C D implies A D. A5. For any A there are only a finite number of B such that A / B. The last axiom essentially asserts that all operation executions terminate; nonterminating operations satisfy a different axiom that is not relevant here. Axiom A5 is useful only for proving liveness properties; safety properties are proved with Axioms A1 A4. properties. Anger [3] and Abraham and Ben- David [1] introduced the additional axiom A6. A B C D implies A D. and showed that A1 A6 form a complete axiom system for the interpretation based on operation executions as sets of events. Axioms A1 A6 are independent of what the operation executions do. Reasoning about a multiprocess program requires additional axioms to capture the semantics of its operations. The appropriate axioms for read and write operations will depend on the nature of the memory system. The only assumptions we make about operation executions are axioms A1 A5 and axioms about read and write operations. We do not assume that and are the relations obtained by interpreting an operation 2

4 execution as the set of all its events. For example, sequential consistency [10] is equivalent to the condition that is a total ordering on the set of operation executions a condition that can be satisfied even though the events comprising different operation executions are actually concurrent. This formalism was developed in an attempt to provide elegant proofs of concurrent algorithms proofs that replace conventional behavioral arguments with axiomatic reasoning in terms of the two relations and. Although the simplicity of such proofs has been questioned [6], they do tend to capture the essence of why an algorithm works. 3 An Example 3.1 An Algorithm and its Proof Figure 1 shows process i of a simple N-process mutual exclusion algorithm [13]. We prove that the algorithm guarantees mutual exclusion (two processes are never concurrently in their critical sections). The algorithm is also deadlock-free (some critical section is eventually executed unless all processes halt in their noncritical sections), but we do not consider this liveness property. Starvation of individual processes is possible. The algorithm uses a standard protocol to achieve mutual exclusion. Before entering its critical section, each process i must first set x i true and then find x j false, for all other processes j. Mutual exclusion is guaranteed because, when process i finds x j false, process j cannot enter its critical section until it sets x j true and finds x i false, which is impossible until i has exited the critical section and reset x i. The proof of correctness formalizes this argument. To prove mutual exclusion, we first name the following operation executions that occur during the n th iteration of process i s repeat loop. L n i The last execution of statement l prior to entering the critical section. This operation execution sets x i to true. R n i,j The last read of x j before entering the critical section. This read obtains the value false. CS n i X n i The execution of the critical section. The write to x i after exiting the critical section. It writes the value false. 3

5 repeat forever noncritical section; l: x i := true; for j := 1 until i 1 do if x j then x i := false; while x j do od; goto l fiod; for j := i +1until N do while x j do od od; critical section; x i := false end repeat Figure 1: Process i of an N-process mutual-exclusion algorithm. Mutual exclusion asserts that CS n i and CS m j are not concurrent, for all m and n, ifi j. 1 Two operations are nonconcurrent if one precedes ( ) the other. Thus, mutual exclusion is implied by the assertion that, for all m and n, eithercs n i CS m j or CS m j CS n i,ifi j. The proof of mutual exclusion, using axioms A1 A4 and assumptions B1 B4 below, appears in Figure 2. It is essentially the same proof as in [13], except that the properties required of the memory system have been isolated and named B1 B4. (In [13], these properties are deduced from other assumptions.) B1 B4 are as follows, where universal quantification over n, m, i, andj is assumed. B4 is discussed below. B1. L n i B2. R n i,j B3. CS n i R n i,j CS n i X n i B4. If R n i,j / L m j then X m j exists and X m j R n i,j. Although B4 cannot be proved without additional assumptions, it merits an informal justification. The hypothesis, Ri,j n / L m j, asserts that process i s read Ri,j n of x j occurred too late for any of its events to have preceded any 1 Except where indicated otherwise, all assertions have as an unstated hypothesis the assumption that the operation executions they mention actually occur. For example, the theorem in Figure 2 has the hypothesis that CS n i and CS m j occur. 4

6 Theorem For all m, n, i, andj such that i j, eithercs n i CS n i. CS m j CS m j or Case A: Ri,j n L m j. 1. L n i Rj,i m Proof : B1, case assumption, B1 (applied to L m j and Rj,i m ), and A4. 2. Rj,i m / L n i Proof : 1 and A2. 3. Xi n Rj,i m Proof : 2 and B4 (applied to Rj,i m, Ln i,andxn i ). 4. CS n i CS m j Proof : B3, 3, B2 (applied to Rj,i m and CS m j ), and A4. Case B: Ri,j n / L m j. 1. Xj m Ri,j n Proof : Case assumption and B4. 2. CS m j CS n i. Proof : B3 (applied to CS m j and Xj m ), 1, B2, and A4. Figure 2: Proof of mutual exclusion for the algorithm of Figure 1. of the events in process j s write L m j of x j. It is reasonable to infer that the value obtained by the read was written by L m j or a later write to x j.since L m j writes true and Ri,j n is a read of false, Rn i,j must read the value written by a later write. The first write of x j issued after L m j is Xj m, so we expect Xj m Ri,j n to hold. 3.2 The Implementation Implementing the algorithm for a particular memory architecture may require synchronization commands to assure B1 B4. Most proposed memory systems satisfy the following property. C1. All write operations to a single memory cell by any one process are observed by other processes in the order in which they were issued. They also provide some form of synchronization command, synch, (for example, a cache flush operation) satisfying C2. A synch command causes the issuing process to wait until all previously issued memory accesses have completed. 5

7 Properties C1 and C2 are rather informal. We restate them more precisely as follows. C1. If the value obtained by a read A issued by process i is the one written by process j, then that value is the one written by the last-issued write B in process j such that B A. C2. If operation executions A, B, andc are issued in that order by a single process, and B is a synch, thena C. Property C2 implies that B1 B3 are guaranteed if synch operations are inserted in process i s code immediately after statement l (for B1), immediately before the critical section (for B2), and immediately after the critical section (for B3). Assumption B4 follows from C1. Now let us consider a more specialized memory architecture in which each process has its own cache, and a write operation (asynchronously) updates every copy of the memory cell that resides in the caches. In such an architecture, the following additional condition is likely to hold: C3. A read of a memory cell that resides in the process s cache precedes ( ) every operation execution issued subsequently by the same process. If the memory system provides some way of ensuring that a memory cell is permanently resident in a process s cache, then B2 can be satisfied by keeping all the variables x j in process i s cache. In this case, the synch immediately preceding the critical section is not needed. 3.3 Observations One might think that the purpose of memory synchronization commands is to enforce orderings between commands issued by different processes. However, B1 B3 are precedence relations between operations issued by the same process. In general, one process cannot directly observe all the events in the execution of an operation by another process. Hence, when viewing a particular execution of an algorithm, the results of executing two operation executions A and D in different processes can permit the deduction only of a causality ( ) relation between A and D. Only if A and D occur in the same process can A D be deduced by direct observation. Otherwise, deducing A D requires the existence of an operation B in thesameprocessasa and an operation C inthesameprocessasd such 6

8 that A B C D. Synchronization commands can guarantee the relations A B and C D. The example of the mutual exclusion algorithm illustrates how a set of properties sufficient to guarantee correctness can be extracted directly from a correctness proof. Implementations of the algorithm on different memory architectures can be derived from the assumptions, with no further reasoning about the algorithm. An implementation will be efficient only if the architecture provides synchronization primitives that efficiently implement the assumed properties. 4 Further Remarks The atomicity condition traditionally assumed for multiprocess programs is sequential consistency, meaning that the program behaves as if the memory accesses of all processes were interleaved and then executed sequentially [10]. It has been proposed that, when sequential consistency is not provided by the memory system, it can be achieved by a constrained style of programming. Synchronization commands are added either explicitly by the programmer, or automatically from hints he provides. The method of [7, 8] can be applied to our simple example, if the x i are identified by the programmer as synchronization variables. However, in general, deducing what synchronization commands are necessary requires analyzing all possible executions of the program, which is seldom feasible. Such an analysis is needed to find the precedence relations that, in the approach described here, are derived from the proof. Deriving synchronization commands from a correctness proof guarantees correctness of the implementation. However, the set of synchronization commands will be minimal only if the proof is based on a minimal set of synchronization assumptions. The set of assumptions is minimal if a counterexample to the theorem can be found when any assumption is eliminated. In practice, unnecessary assumptions are often uncovered simply because they are not used in the proof. Although it replaces traditional informal reasoning with a more rigorous, axiomatic style, the proof method we have used is essentially behavioral one reasons directly about the set of operation executions. Behavioral methods do not seem to scale well, and our approach is unlikely to be practical for large, complicated algorithms. Most multiprocess programs for modern multiprocessors are best written in terms of higher-level abstractions. The 7

9 method presented here can be applied to the algorithms that implement these abstractions and to those algorithms, usually in the depths of the operating system, where efficiency and correctness are crucial. Assertional proofs are practical for more complicated algorithms. The obvious way to reason assertionally about algorithms with nonatomic memory operations is to represent a memory access by a sequence of atomic operations [2, 9]. With this approach, the memory architecture and synchronization operations are encoded in the algorithm. Therefore, a new proof is needed for each architecture, and the proofs are unlikely to help discover what synchronization operations are needed. A less obvious approach uses the predicate transformers win (weakest invariant) and sin (strongest invariant) to write assertional proofs for algorithms in which no atomic operations are assumed, requirements on the memory architecture being described by axioms [15]. Such a proof would establish the correctness of an algorithm for a large class of memory architectures. However, in this approach, all intraprocess relations are encoded in the algorithm, so the proofs are unlikely to help discover the very precedence relations that lead to the introduction of synchronization operations. Acknowledgments I wish to thank Allan Heydon, Michael Merritt, David Probst, Garrett Swart, Fred Schneider, and Chuck Thacker for their comments on earlier versions. 8

CHAPTER 7 GENERAL PROOF SYSTEMS 1 Introduction Proof systems are built to prove statements. They can be thought as an inference machine with special statements, called provable statements, or sometimes

LOGICAL INFERENCE & PROOFs Debdeep Mukhopadhyay Dept of CSE, IIT Madras Defn A theorem is a mathematical assertion which can be shown to be true. A proof is an argument which establishes the truth of a

Enforcing Security Policies Rahul Gera Brief overview Security policies and Execution Monitoring. Policies that can be enforced using EM. An automata based formalism for specifying those security policies.

Introducing Formal Methods Formal Methods for Software Specification and Analysis: An Overview 1 Software Engineering and Formal Methods Every Software engineering methodology is based on a recommended

Real Time Programming: Concepts Radek Pelánek Plan at first we will study basic concepts related to real time programming then we will have a look at specific programming languages and study how they realize

Stages in Teaching Formal Methods A. J. Cowling Structure of Presentation Introduction to Issues Motivation for this work. Analysis of the Role of Formal Methods Define their scope; Review their treatment

Mutual Exclusion using Monitors Some programming languages, such as Concurrent Pascal, Modula-2 and Java provide mutual exclusion facilities called monitors. They are similar to modules in languages that

Part III Synchronization Critical Section and Mutual Exclusion Fall 2016 The question of whether computers can think is just like the question of whether submarines can swim 1 Edsger W. Dijkstra Process

Control, University of Bath, UK, September ID- IMPACT OF DEPENDENCY AND LOAD BALANCING IN MULTITHREADING REAL-TIME CONTROL ALGORITHMS M A Hossain and M O Tokhi Department of Computing, The University of

Firewall Verification and Redundancy Checking are Equivalent H. B. Acharya University of Texas at Austin acharya@cs.utexas.edu M. G. Gouda National Science Foundation University of Texas at Austin mgouda@nsf.gov

The "Hoare Logic" of CSP, and All That LESLIE LAMPORT SRI International and FRED B. SCHNEIDER Cornell University Generalized Hoare Logic is a formal logical system for deriving invariance properties of

Is Sometime Ever Better Than Alway? DAVID GRIES Cornell University The "intermittent assertion" method for proving programs correct is explained and compared with the conventional method. Simple conventional

Seminal Research Articles in Programming Languages Abstract The research articles listed here cover the period 1963 to the present. They are all important articles, and they are relevant to this offering

Computing basics Ruurd Kuiper October 29, 2009 Overview (cf Schaum Chapter 1) Basic computing science is about using computers to do things for us. These things amount to processing data. The way a computer

Chapter 9 Transaction Management and Concurrency Control Database Systems: Design, Implementation, and Management, Sixth Edition, Rob and Coronel 1 In this chapter, you will learn: What a database transaction

PROGRAMMING METHODOLOGY Making a Science Out of an Art by David Gries and Fred B. Schneider It doesn 't take too long for an intelligent, scientifically oriented person to learn to cobble programs together

Chapter 4 PRINCIPLE OF MATHEMATICAL INDUCTION Analysis and natural philosophy owe their most important discoveries to this fruitful means, which is called induction Newton was indebted to it for his theorem

CSE373: Data Structures and Algorithms Lecture 2: Proof by Induction Linda Shapiro Winter 2015 Background on Induction Type of mathematical proof Typically used to establish a given statement for all natural

2. METHODS OF PROOF 69 2. Methods of Proof 2.1. Types of Proofs. Suppose we wish to prove an implication p q. Here are some strategies we have available to try. Trivial Proof: If we know q is true then

Principles and characteristics of distributed systems and environments Definition of a distributed system Distributed system is a collection of independent computers that appears to its users as a single

University of Texas at El Paso DigitalCommons@UTEP Departmental Technical Reports (CS) Department of Computer Science 8-1-2007 Using Patterns and Composite Propositions to Automate the Generation of Complex

4CHAPTER 1. INTRODUCTORY MATERIAL: SETS, FUNCTIONS AND MATHEMATICAL INDU 1.3 Induction and Other Proof Techniques The purpose of this section is to study the proof technique known as mathematical induction.

Answer first, then check at the end. Review questions for Chapter 9 True/False 1. A compiler translates a high-level language program into the corresponding program in machine code. 2. An interpreter is

4.5 Linear Dependence and Linear Independence 267 32. {v 1, v 2 }, where v 1, v 2 are collinear vectors in R 3. 33. Prove that if S and S are subsets of a vector space V such that S is a subset of S, then

Analytical Learning Introduction Lehrstuhl Explanation is used to distinguish the relevant features of the training examples from the irrelevant ones, so that the examples can be generalised Introduction

How to Build a Highly Available System Using Consensus Butler W. Lampson 1 Microsoft 180 Lake View Av., Cambridge, MA 02138 Abstract. Lamport showed that a replicated deterministic state machine is a general

Termination Checking: Comparing Structural Recursion and Sized Types by Examples David Thibodeau Decemer 3, 2011 Abstract Termination is an important property for programs and is necessary for formal proofs

Factoring & Primality Lecturer: Dimitris Papadopoulos In this lecture we will discuss the problem of integer factorization and primality testing, two problems that have been the focus of a great amount

https://runtimeverification.com Grigore Rosu Founder, President and CEO Professor of Computer Science, University of Illinois Runtime Verification, Inc. (RV): startup company aimed at bringing the best