CIS 540 Principles of Embedded Computation Spring 2015 http://www.seas.upenn.edu/~cis540/ Instructor: Rajeev Alur alur@cis.upenn.edu Asynchronous Execution P P2 P1 in x out y What can happen in a single step of this asynchronous model P? P1 synchronizes with the environment to accept input on in P2 synchronizes with the environment to send output on out P1 performs some internal computation (one of its internal tasks) P2 performs some internal computation (one of its internal tasks) P1 produces output on channel x, followed by its consumption by P2 P2 produces output on channel y, followed by its consumption by P1 CIS 540 Spring 2015; Lecture Feb 23 Shared Memory Programs AtomicReg nat x := 0 Process P1 nat y1:=0 y1 := x x := y1 +1 Process P2 nat y2:=0 y2 := x x := y2 +1 Declaration of shared variables + Code for each process Key restriction: Each statement of a process either changes local variables, reads a single shared var, or writes a single shared var Execution model: execute one step of one of the processes Can be formalized as asynchronous processes CIS 540 Spring 2015; Lecture Feb 23 Shared Memory Processes x.write2 x.write1 x.read1 P1 x y.write2 y.write1 y.read1 x.read2 y P2 y.read2 Processes P1 and P2 communicate by reading/writing shared variables Each shared variable can be modeled as an asynchronous process State of each such process is the value of corresponding variable In implementation, shared memory can be a separate subsystem Read and write channel between each process and each shared variable To write x, P1 synchronizes with x on “x.write1” channel To read y, P2 synchronizes with y on “y.read2” channel CIS 540 Spring 2015; Lecture Feb 23 Atomic Registers x.write2 x.write1 x.read1 P1 x y.write2 y.write1 y.read1 x.read2 y P2 y.read2 By definition of our asynchronous model, each step of above is either internal to P1 or P2, or involves exactly one synchronization: either read or write of one shared variable by one of the processes Atomic register: Basic primitives are read and write To “increment” such a register, a process first needs to read and then write back incremented value But these two are separate steps, and register value can be changed in between by another process CIS 540 Spring 2015; Lecture Feb 23 Shared Memory Programs AtomicReg nat x := 0 Process P1 nat y1:=0 y1 := x x := y1 +1 Process P2 nat y2:=0 y2 := x x := y2 +1 Declaration of shared variables + Code for each process Key restriction: Each statement of a process either changes local variables, reads a single shared var, or writes a single shared var Execution model: execute one step of one of the processes Can be formalized as asynchronous processes CIS 540 Spring 2015; Lecture Feb 23 Data Races AtomicReg nat x := 0 Process P1 Process P2 nat y1:=0 nat y2:=0 R1: y1 := x R2: y2 := x W1: x := y1 +1 W2: x := y2 +1 What are the possible values of x after all steps are executed? x can be 1 or 2 Possible executions: R1, R2, W1, W2 R1, W1, R2, W2 R1, R2, W2, W1 R2, R1, W1, W2, R2, W2, R1, W1 R2, R1, W2, W1 Data race: Concurrent accesses to shared object where the result depends on order of execution, Should be avoided!! CIS 540 Spring 2015; Lecture Feb 23 Puzzle AtomicReg nat x := 1 Process P2 Process P1 nat u2,v2 nat u1,v1 u2 := x u1 := x x := u2 + v2 x := u1 + v1 v1 := x v2 := x What possible values can the shared register x take? CIS 540 Spring 2015; Lecture Feb 23 Mutual Exclusion Problem Process P2 Process P1 To be designed Entry Code Critical Section Entry Code Critical Section Critical Section: Part of code that an asynchronous process should execute without interference from others Critical section can include code to update shared objects/database Mutual Exclusion Problem: Design code to be executed before entering critical section by each process Coordination using shared atomic registers No assumption about how long a process stays in critical section A process may want to enter critical section repeatedly CIS 540 Spring 2015; Lecture Feb 23 Mutual Exclusion Problem Process P1 Process P2 To be designed Entry Code Critical Section Entry Code Critical Section Safety Requirement: Both processes should not be in critical section simultaneously (can be formalized using invariants) Absence of deadlocks: If a process is trying to enter, then some process should be able to enter CIS 540 Spring 2015; Lecture Feb 23 Mutual Exclusion: First Attempt AtomicReg bool flag1 := 0; flag2 := 0 Process P1 else Idle flag1 := 1 flag2=0 ? Try Crit flag1 := 0 Is this correct? Process P2 else Idle flag2 := 1 Try flag1=0 ? Crit flag2 := 0 CIS 540 Spring 2015; Lecture Feb 23 Peterson’s Mutual Exclusion Protocol AtomicReg bool flag1 := 0; flag2 := 0; {1,2} turn Process P1 else Idle flag1 := 1 Try1 turn := 1 Try2 flag2=1? Try3 turn=2 ? Crit else flag1 := 0 Process P2 else Idle flag2 := 1 Try1 turn := 2 Try2 flag1=1? Try3 else flag2 := 0 CIS 540 Spring 2015; Lecture Feb 23 turn=1 ? Crit Test&Set Register Beyond atomic registers: In one (atomic) step, can do more than just read or write Stronger synchronization primitives Test&Set Register: Holds a Booleans value Reset operation: Changes the value to 0 Test&Set operation: Returns the old value and changes value to 1 If two processes are competing to execute Test&Set on a register with value 0, one will get back 0 and other will get back 1 Modern processors support strong “atomic” operations Compare-and-swap Load-linked-store-conditional Implementation is expensive (compared to read/write operations)! CIS 540 Spring 2015; Lecture Feb 23 Mutual Exclusion using Test&Set Register Test&SetReg free:= 0 Process P1 else Idle t&s(free)=0 ? Try Crit reset(free) Is this correct? Process P2 else Idle Try t&s(free)=0 ? Crit reset(free) CIS 540 Spring 2015; Lecture Feb 23 Another Look at Asynchronous Execution Model nat x:=0; y:=0 Ax: x := x+1 Ay: y :=y+1 Tasks Ax and Ay execute in an arbitrary order Motivation: If we establish that all possible executions of this asynchronous design satisfy some requirement, then this will hold in every implementation of this Are the following realistic executions? (0,0) -Ax-> (1,0) -Ax-> (2,0) -Ax-> (3,0) … -Ax-> (105,0) -Ax-> … (0,0) -Ax-> (1,0) -Ax-> (2,0) -Ay-> (2,1) -Ay-> (2,2) … -Ay-> (2,105) -Ay->… Does the system satisfy the following requirement: “In every execution, values of both x and y eventually exceed 10” CIS 540 Spring 2015; Lecture Feb 23 Fairness Assumption nat x:=0; y:=0 Ax: x := x+1 Ay: y :=y+1 Fairness assumption for a task Assumption about the underlying platform/scheduler Informally, an infinite execution is unfair for a task if the task does not get a chance to execute Unfair to Ay: (0,0) -Ax-> (1,0) -Ax-> (2,0) -Ax-> (3,0) … -Ax-> (105,0) … Unfair to Ax: (0,0) -Ax-> (1,0) -Ax-> (2,0) -Ay-> (2,1) -Ay-> (2,2) … (2,105)… Fairness assumptions restrict the set of “possible” executions to realistic ones without putting concrete bounds on relative speeds CIS 540 Spring 2015; Lecture Feb 23 Formalizing Fairness Process P1 Process P2 nat x:=0; y:=0 nat x:=0; y:=0 Ax: x := x+1 Bx: x := x+1 Ay: y :=y+1 By: x=0 y :=y+1 Definition 1: An infinite execution is fair to a task A, if the task A is executed repeatedly (i.e. infinitely often) during this execution Is this fair to task By of P2? (0,0) -Bx-> (1,0) -Bx-> (2,0) -Bx-> (3,0) -Bx-> … (105,0) -Bx-> … After first step, the task By is not enabled, and thus, cannot be executed. So this execution is a possible execution, and so should be considered fair Definition 2: An infinite execution is fair to a task A, if repeatedly, either task A is executed or is disabled CIS 540 Spring 2015; Lecture Feb 23 Weak vs Strong Fairness Process P3 nat x:=0; y:=0 Ax: x := x+1 Ay: even(x) y :=y+1 Is this fair to task Ay of P3? (0,0) -Ax-> (1,0) -Ax-> (2,0) -Ax-> (3,0) … -Ax-> (105,0) -Ax-> … Task Ay is not continuously enabled, and thus, this is fair according to definition 2 (called weak fairness) Definition 3 (Strong fairness): An infinite execution is fair to a task A, if task A is either executed repeatedly, or disabled from a certain step onwards Above execution is weakly-fair to task Ay, but not strongly-fair CIS 540 Spring 2015; Lecture Feb 23 Fairness Assumption Fairness assumption for an asynchronous process P: for each output and internal task: No assumption Weak-fairness assumption, or Strong-fairness assumption Restricts the set of possible infinite executions If weak-fairness is assumed for a task A, then the execution must be weakly-fair for task A If strong-fairness is assumed for a task A, then the execution must be strongly-fair for task A Affects whether the process meets a requirement: Maybe not all executions satisfy the given requirement, but all fair executions satisfy the requirement CIS 540 Spring 2015; Lecture Feb 23 Requirements under Fairness Assumptions Process P1 Process P3 nat x:=0; y:=0 nat x:=0; y:=0 Ax: x := x+1 Bx: x := x+1 Ay: y :=y+1 By: even(x) y :=y+1 Under what fairness assumptions do P1 and P3 satisfy following? Requirement: Eventually (x+y > 10) Both satisfy this without any fairness assumption Requirement: Eventually (x > 10) P1 with weak-fairness for Ax, P3 with weak-fairness for Bx Requirement: Eventually (y > 10) P1 with weak-fairness for Ay, P3 with strong-fairness for By Requirement: Eventually (x > y) Not satisfied, no matter what fairness assumption we make! CIS 540 Spring 2015; Lecture Feb 23