A Separation Logic to Verify Termination of Busy-Waiting for Abrupt Program Exit Tobias Reinhard 1 , Amin Timany 2 , Bart Jacobs 1 1 KU Leuven, imec-DistriNet Research Group 2 Aarhus University, Logic and Semantics Group 23rd July 2020
Motivation Language Verification Work in Progress & Outlook
Motivation Language Verification Work in Progress & Outlook
Motivation ◮ Busy-waiting for other threads common in programs for multiprocessor machines ⇒ Goal: Prove termination of busy-waiting ◮ In this work: Consider specific event ”abrupt termination” ⇒ On-going work: Generalization to arbitrary events thread 1 thread 2 thread 1 thread 2 . . . . . . busy-waiting busy-waiting for abrupt for event E termination abruptly terminate perform entire program approximate event E . event E by . . . "abrupt termination" . .
Motivation Language Verification Work in Progress & Outlook
Motivation Language Verification Work in Progress & Outlook
Language ◮ Abrupt termination of all threads: exit ◮ Infinite busy-waiting loop: loop skip ◮ Forking new thread: fork c ◮ Approach applicable to realistic languages c ∈ Cmds ::= exit | loop skip | fork c | c ; c ◮ Busy-waiting for abrupt termination: fork exit ; loop skip ◮ Thread scheduling non-deterministic ⇒ Need to assume fair scheduling
Motivation Language Verification Work in Progress & Outlook
Motivation Language Verification Work in Progress & Outlook
Termination of Busy-Waiting ◮ Problem: Termination of loop skip depends on other threads ⇒ Need knowledge that other threads exit ◮ Solution: Track which threads eventually exit Ghost resources : ◮ Obligation: Thread must eventually exit ◮ Credit: Local proof that other thread will exit ⇒ Permission to busy-wait ◮ Track which resources each thread holds ◮ Can be spawned & cancelled during ghost steps ⇒ Ensure #obligations = #credits ◮ Can be transferred during forking exit obligation obligation credit fork fork exit; loop skip ghost step fork exit; loop skip loop skip credit
Assertions Separation Logic with ◮ a ∗ b ⇒ Standard separating conjunction ◮ Predicate obs( n ) ⇒ Expresses possession of n obligations ◮ Predicate credit ⇒ Possession of single credit a ∈ A ::= True | False | a ∗ a | obs( n ) | credit ◮ Can be combined with existing logics, e.g., Iris ⇒ Adds possibility to verify termination of busy-waiting
Program Specifications ◮ Hoare triple { A } c { B } ⇒ Given precondition A , ... ◮ c terminates & postcondition B holds or ◮ c diverges or abruptly terminates the program ◮ Postcondition False expresses either ◮ divergence or ◮ abrupt termination, i.e., exit (can conclude anything from False, e.g., obs(0)) ◮ Soundness of verification approach: Discharging all obligations & starting without credits, i.e., { obs( n ) } c { obs(0) } ⇒ Termination under fair scheduling
Proof Rules: Abrupt Termination & Busy-Waiting ◮ exit only way to discharge obligation ◮ Busy-waiting only allowed if thread possesses: ◮ Credit ⇒ Other thread holds obligation, i.e., will exit ⇒ Waiting terminates ◮ No obligations ⇒ Not waiting for itself to exit PR-Exit PR-Loop ⊢ { A } exit { False } ⊢ { obs(0) ∗ credit } loop skip { False } ◮ #obligations chunks = #threads ⇒ obs( n ) ∗ obs( n ′ ) never holds ⇒ PR-Loop ensures that thread holds no obligations ◮ Need way to: ◮ Spawn obligations & credits ◮ Prove that exit discharges obligation, i.e., ⊢ { obs(1) } exit { obs(0) }
Proof Rules: View Shift ◮ View shift A ⇛ B : ◮ Reasoning step independent of program, e.g., drawing conclusion: False ⇛ obs(0) ◮ Ghost step, e.g., Spawning obligation & credit: obs(0) ⇛ obs(1) ∗ credit ⇒ obs(0) ∗ credit means other thread holds obligation VS-SemImp VS-ObCred ∀ R . R � A A → R � A B obs( o ) ⇚ ⇛ obs( o + 1) ∗ credit A ⇛ B VS-Trans A ⇛ C C ⇛ B A ⇛ B ◮ Allows to strengthen precondition and weaken postcondition ⇒ Generalization of Rule of Consequence in Hoare logic PR-ViewShift B ′ ⇛ B A ⇛ A ′ � A ′ � � B ′ � ⊢ c ⊢ { A } c { B }
Proof Rules: exit Example ◮ Can prove that exit discharges obligation, i.e., ⊢ { obs(1) } exit { obs(0) } { obs(1) } exit PR-Exit { False } { obs(0) } PR-ViewShift + VS-SemImp
Proof Rules: Transferring Ghost Resources ◮ Can transfer obligations & credits to forked threads ◮ Forking only way to split obligations chunk obs( n ) PR-Fork ⊢ { obs( o f ) ∗ A } c { obs(0) } ⊢ { obs( o m + o f ) ∗ A } fork c { obs( o m ) } ◮ Only allowed if forked thread discharges all obligations discharge obligation {obs(1)} exit {False} view shift {obs(0)} pass obligation to forked thread {obs(1) * credit} fork exit {obs(0) * credit} terminate thread {obs(0) * credit} done ◮ Also support frame rule and sequencing PR-Seq PR-Frame ⊢ { A } c { B } ⊢ { A } c 1 { B } ⊢ { B } c 2 { C } ⊢ { A ∗ F } c { B ∗ F } ⊢ { A } c 1 ; c 2 { C }
Verification Example ◮ Remember Soundness: ⊢ { obs( n ) } c { obs(0) } ⇒ Termination under fair scheduling ◮ Verify termination of fork exit ; loop skip by proving ⊢ { obs(0) } fork exit ; loop skip { obs(0) } { obs(0) } { obs(1) ∗ credit } PR-ViewShift + VS-ObCred fork PR-Fork { obs(1) } exit ; PR-Exit { False } { obs(0) } PR-ViewShift + VS-SemImp { obs(0) ∗ credit } loop skip PR-Loop { False } { obs(0) } PR-ViewShift + VS-SemImp
Additional Content of the Paper ◮ Operational semantics ◮ Semantics of assertions ◮ Semantics of Hoare triples ◮ Annotated operational semantics (bridging gap between verification & execution) ◮ Soundness theorem & proof
Motivation Language Verification Work in Progress & Outlook
Motivation Language Verification Work in Progress & Outlook
Work in Progress & Outlook ◮ Formalize verification approach in Coq ◮ Generalize approach to Ghost Signals ◮ Obligation to set signal & Permission to wait for it to be set ◮ Allows to verify termination of busy-waiting for arbitrary events ◮ Combine with work on I/O liveness verification ◮ Encode I/O liveness as termination property (cf. server below) ◮ Verify liveness of server below Server S Receiver Thread Responder Thread . . . . . . . . . . Responder Thread insert Queue exit after responding requests to request N . . extract requests Receiver Thread Responder Thread receive req. 1, ..., N, ... respond to requests & "wait for exit" sending requests receiving response Clients
Thank you for your attention! Motivation Language Verification Work in Progress & Outlook
Additional Material: Semantics of Assertions ◮ Ghost resources R := Bags ( N ) × N . ◮ ( O , χ ) ∈ R ⇒ (i) Obligations chunks O and (ii) χ credits ◮ Threads hold single obligations chunk, i.e., ( { [ o ] } , χ ). ◮ ( O 1 , χ 1 ) ⊎ R ( O 2 , χ 2 ) := ( O 1 ⊎ O 2 , χ 1 + χ 2 ) ◮ Semantics of Assertions ◮ obs( n ) must encompass full obligations chunk, i.e., assertion obs( n ) ∗ obs( n ′ ) must not hold for any ( { [ o ] } , χ ) R � A True a 1 ∗ a 2 iff ∃ R 1 , R 2 ∈ R . R = R 1 ⊎ R R 2 R � A ∧ R 1 � A a 1 ∧ R 2 � A a 2 ( O , χ ) � A obs( o ) iff o ∈ O ( O , χ ) credit iff χ ≥ 1 � A ({1}, 0) ⊨ obs(1) exit passing obligation to forked thread ({1}, 1) ⊨ obs(1) * credit ({0}, 1) ⊨ obs(0) * credit fork exit; loop skip loop skip
Recommend
More recommend