240 likes | 342 Vues
This project aims to automate the redesign of synchronization skeletons of UPC programs for efficient multithreaded execution. The proposed solution involves transforming synchronization skeletons into guarded commands to ensure properties like deadlock-freedom and mutual exclusion. By generating reachability graphs and finite models, we can automate the revision process to enhance program performance.
E N D
Towards Automating the Redesign of the Synchronization Skeletons of UPC Programs Presenter: Amin Alipour Adviser: Ali Ebnenasir
Motivations • Help developers in • automated behavioral debugging, and • design of synchronization mechanisms of multithreaded programs, i.e., synchronization skeleton
Problem • Deadlock • Need deadlock-freedom
Outline • Problem Statement • Proposed Solution • Case Study
Problem Statement • Input: • A UPC program P • A desired mutual exclusion (e.g., lack of data race) or progress property (e.g., deadlock-freedom), denoted L • P does not meet L • Output: • A revised version of P, denoted P_r • Constraints: • P_r meets L • P_r does not violate other properties of P
Proposed Solution UPC Program Revised UPC Program
Synchronization Skeleton of the UPC Program Synch. Skeleton of thread i // Generate an array element index 0/1 TS_i: { upc_lock(lk[i]); upc_lock(lk[s]); } CS_i: { // Swap ... } // Dont forget to unlock upc_unlock(lk[i]); upc_unlock(lk[s]);
Guarded Commands • State: snapshot valuation to program variables • Guarded command: • <grd_1> stmt_1; • [] <grd_2> stmt_2; • [] … • [] <grd_n> stmt_n; • Example: • (x > y) x := x - y; • [] (y > x) y := y - x; • A set of transitions (s0, s1) • grd is true in s0, and • s1 is reach by atomic execution of stmt
Canonical UPC Programs • For simplicity, we consider a canonical version of the program with • 2 threads • An array with size 2
Case Study-State TSi Trying Section Thread i CSi Critical SectionThread i LKi Lock of Thread i GLKi Lock for Intra-thread Serialization Thread i Si random value selected by Thread i SSi Whether Thread i has selected a random value
Translation of Synchronization Skeleton to Guarded Commands Initial state values: TS_i := true; CS_i := false; sSet_i = false; Ai1: (sSet_i = false) -> s_i := 0|1; sSet_i := true; Ai2: (sSet_i = true) /\ (TS_i = true) /\ (lk[i] = true) /\ (gotLock_i = false) -> lk[i] := false; gotLock_i := true; Ai3: (sSet_i = true) /\ (TS_i = true) /\ (lk[s_i] = true) /\ gotLock_i = true -> lk[s_i] := false; gotLock_i :=false; TS_i := false; CS_i := true; Ai4: (sSet_i = true) /\ (CS_i = true) /\ (lk[i] = false) /\ (lk[s_i] = false) -> lk[i] := true; lk[s_i] := true; CS_i := false;TS_i := true; sSet_i := false;
Reachability Graph Generation • Start with initial states • Check applicable commands • Generate new reachable states • run Steps 1 and 2 until no new state is generated
Revised Thread 1 Thread 1 { A11: (!SS1 !S2) (!SS2 || !S1) ->S1=1; SS1 = true; A12: (TS1 !CS1 LK[0] !GLK1 (S1) SS1)->LK[0] = false;GLK1 = true; A13: (TS1 !CS1 !LK[0] GLK1 (S1) SS1)->LK[1] = false; GLK1=false;TS1 = false;CS1 = true; A14: (!TS1 CS1 !LK[0] !GLK1 (S1) SS1 SS2)->LK[0] = true; LK[1] = true; CS1 = false;TS1 = true;SS1= false; } Avoid s Deadlock Ai1: (sSet_i = false) -> s_i := 0|1; sSet_i := true; Ai2: (sSet_i = true) (TS_i = true) (lk[i] = true) (gotLock_i = false) -> lk[i] := false; gotLock_i := true; Ai3: (sSet_i = true) (TS_i = true) (lk[s_i] = true) gotLock_i = true -> lk[s_i] := false; gotLock_i :=false;TS_i := false;CS_i := true; Ai4: (sSet_i = true) (CS_i = true) (lk[i] = false) (lk[s_i] = false) -> lk[i] := true; lk[s_i] := true; CS_i := false;TS_i := true; sSet_i := false;
Avoids Deadlock Thread 2 { A21: !SS2 ->S2=0; SS2 = true; A22: TS2 !CS2 LK[1] !GLK2 !(S2) S1 SS2 !SS1 ->LK[1] = false;GLK2 = true; A23: TS2 !CS2 !LK[1] GLK2 !(S2) SS2 ->LK[0] = false; GLK2=false;TS2 = false;CS2 = true; A24: !TS2 CS2 !LK[1] !GLK2 !(S2) SS2 ->LK[0] = true; LK[1] = true; CS2 = false;TS2 = true;SS2= false; } Imposes sequential execution Ai1: (sSet_i = false) -> s_i := 0|1; sSet_i := true; Ai2: (sSet_i = true) (TS_i = true) (lk[i] = true) (gotLock_i = false) -> lk[i] := false; gotLock_i := true; Ai3: (sSet_i = true) (TS_i = true) (lk[s_i] = true) gotLock_i = true -> lk[s_i] := false; gotLock_i :=false;TS_i := false; CS_i := true; Ai4: (sSet_i = true) (CS_i = true) (lk[i] = false) (lk[s_i] = false) -> lk[i] := true; lk[s_i] := true; CS_i := false;TS_i := true; sSet_i := false;