higher order concurrent separation logic why and how
play

Higher-Order Concurrent Separation Logic: Why and How Lars Birkedal - PowerPoint PPT Presentation

Higher-Order Concurrent Separation Logic: Why and How Lars Birkedal Aarhus University Nijmegen, Netherlands Dec, 2015 Modular Reasoning about Higher-Order Concurrent Imperative Programs 1 / 33 Introduction Goal Program logics for


  1. Higher-Order Concurrent Separation Logic: Why and How Lars Birkedal Aarhus University Nijmegen, Netherlands Dec, 2015 Modular Reasoning about Higher-Order Concurrent Imperative Programs 1 / 33

  2. Introduction Goal ◮ Program logics for modular reasoning about partial correctness of higher-order, concurrent, imperative code programs. 2 / 33

  3. Outline 1. Why higher-order logic + guarded recursion is useful for expressing such modular specs ◮ via example of layered and recursive abstraction. 2. Why impredicative protocols to govern shared state ◮ via example verification of lock implementation ◮ invariants to enforce protocols ◮ monoids to express protocols (ownership) 3. How the logic is modelled and showed sound (key ideas) ◮ BI-hyperdoctrine over ultra-metric spaces, Kripke model with recursively defined worlds. 4. Overview of resources to learn more ◮ tutorial material ◮ papers: iCAP [ESOP-2014] and Iris [POPL-2015] ◮ paper on formalization: ModuRes Library [ITP-2015] 5. Overview of features in iCAP and Iris not covered today 3 / 33

  4. Higher-Order Programming ◮ Programming features ◮ HO functions ◮ Interfaces in OO languages ◮ Function Pointers in low-level languages ◮ for ◮ Building libraries ◮ Returning libraries ◮ Parameterization ◮ Point: ◮ Features important for modularizing large programs ◮ Allow programming relative to unknown code ◮ Goal: Logics and Models that support correspondingly modular specifications of code. 4 / 33

  5. Example: Layered and Recursive Abstractions ◮ Modular library specifications that supports layering of abstractions and recursive abstractions. 5 / 33

  6. Example: Layered and Recursive Abstractions ◮ Modular library specifications that supports layering of abstractions and recursive abstractions. LinkedList HashMap Lock 5 / 33

  7. Example: Layered and Recursive Abstractions ◮ Modular library specifications that supports layering of abstractions and recursive abstractions. M 2 LinkedList HashMap M 1 Lock 5 / 33

  8. Recursive Abstractions Reentrant Event Loop Library handler ( ) ; delegate void IEventLoop { interface loop ( ) ; void s i g n a l ( ) ; void void when ( handler f ) ; } 6 / 33

  9. Recursive Abstractions Reentrant Event Loop Library handler ( ) ; delegate void IEventLoop { interface loop ( ) ; void s i g n a l ( ) ; void void when ( handler f ) ; } Event handlers are allowed to emit events! 6 / 33

  10. Recursive Abstractions A library that allows us to close Landin’s Knot / perform Reentrant Event Loop Library recursion through the store. handler ( ) ; delegate void IEventLoop { interface loop ( ) ; void s i g n a l ( ) ; void void when ( handler f ) ; } Event handlers are allowed to emit events! 6 / 33

  11. Recursive Abstractions A library that allows us to close Landin’s Knot / perform Reentrant Event Loop Library recursion through the store. handler ( ) ; delegate void IEventLoop { interface loop ( ) ; void s i g n a l ( ) ; void void when ( handler f ) ; } Event handlers are Realistic examples of this form: allowed to emit events! libevent, Node.js, Twisted, ... C5, GUI libraries, Joins library, ... 6 / 33

  12. A Modular Lock Specification ∃ isLock , locked : Val × Prop → Prop . ∀ R : Prop . { R } { isLock(ret , R) } new Lock() { isLock(x , R) } { locked(x , R) ∗ R } x.Acquire() { locked(x , R) ∗ R } { isLock(x , R) } x.Release() ∀ x : Val . isLock(x , R) ⇔ isLock(x , R) ∗ isLock(x , R) 7 / 33

  13. A Modular Lock Specification Standard sep. logic lock specification The resource invariant R describes the resources protected by the lock. ∃ isLock , locked : Val × Prop → Prop . ∀ R : Prop . { R } { isLock(ret , R) } new Lock() { isLock(x , R) } { locked(x , R) ∗ R } x.Acquire() { locked(x , R) ∗ R } { isLock(x , R) } x.Release() ∀ x : Val . isLock(x , R) ⇔ isLock(x , R) ∗ isLock(x , R) 7 / 33

  14. A Modular Lock Specification ∃ isLock , locked : Val × Prop → Prop . ∀ R : Prop . { R } { isLock(ret , R) } new Lock() { isLock(x , R) } { locked(x , R) ∗ R } x.Acquire() { locked(x , R) ∗ R } { isLock(x , R) } x.Release() ∀ x : Val . isLock(x , R) ⇔ isLock(x , R) ∗ isLock(x , R) 7 / 33

  15. A Modular Lock Specification Third-order quantification. ∃ isLock , locked : Val × Prop → Prop . ∀ R : Prop . { R } { isLock(ret , R) } new Lock() { isLock(x , R) } { locked(x , R) ∗ R } x.Acquire() { locked(x , R) ∗ R } { isLock(x , R) } x.Release() ∀ x : Val . isLock(x , R) ⇔ isLock(x , R) ∗ isLock(x , R) 7 / 33

  16. A Modular Lock Specification ∀ R : Prop . ∃ isLock , locked : Val → Prop . { R } { isLock(ret) } new Lock() { isLock(x) } { locked(x) ∗ R } x.Acquire() { locked(x) ∗ R } { isLock(x) } x.Release() ∀ x : Val . isLock(x) ⇔ isLock(x) ∗ isLock(x) 7 / 33

  17. A Modular Lock Specification Second-order quantification. ∀ R : Prop . ∃ isLock , locked : Val → Prop . { R } { isLock(ret) } new Lock() { isLock(x) } { locked(x) ∗ R } x.Acquire() { locked(x) ∗ R } { isLock(x) } x.Release() ∀ x : Val . isLock(x) ⇔ isLock(x) ∗ isLock(x) 7 / 33

  18. A Modular Lock Specification This specification might suffice for layering of abstractions, but not for all recursive abstractions. ∀ R : Prop . ∃ isLock , locked : Val → Prop . { R } { isLock(ret) } new Lock() { isLock(x) } { locked(x) ∗ R } x.Acquire() { locked(x) ∗ R } { isLock(x) } x.Release() ∀ x : Val . isLock(x) ⇔ isLock(x) ∗ isLock(x) 7 / 33

  19. Recursive Abstractions Event Loop Memory Safety Specification ∃ eloop : Val → Prop . { emp } { eloop(ret) } new EventLoop() { eloop(x) } { eloop(x) } x.loop() { eloop(x) } { eloop(x) } x.signal() { eloop(x) ∗ P } { eloop(x) } x.when(f) ∀ x : Val . eloop(x) ⇔ eloop(x) ∗ eloop(x) where P = f �→ { emp }{ emp } 8 / 33

  20. Recursive Abstractions Event Loop Memory Safety Specification ∃ eloop : Val → Prop . { emp } { eloop(ret) } new EventLoop() { eloop(x) } { eloop(x) } x.loop() { eloop(x) } { eloop(x) } x.signal() { eloop(x) ∗ P } { eloop(x) } x.when(f) ∀ x : Val . eloop(x) ⇔ eloop(x) ∗ eloop(x) where P = f �→ { emp }{ emp } Event handler must run without any resources but emitting an event requires an eloop(x) resource! 8 / 33

  21. Recursive Abstractions Reentrant Event Loop Memory Safety Specification ∃ eloop : Val → Prop . { emp } { eloop(ret) } new EventLoop() { eloop(x) } { eloop(x) } x.loop() { eloop(x) } { eloop(x) } x.signal() { eloop(x) ∗ P } { eloop(x) } x.when(f) ∀ x : Val . eloop(x) ⇔ eloop(x) ∗ eloop(x) where P = f �→ { eloop(x) }{ eloop(x) } 8 / 33

  22. Recursive Abstractions Verifying a lock-based event loop implementation ◮ Since we are interested in memory safety, eloop has to specify the memory footprint of the event loop. 9 / 33

  23. Recursive Abstractions Verifying a lock-based event loop implementation ◮ Since we are interested in memory safety, eloop has to specify the memory footprint of the event loop. ◮ Since an event loop can call handlers, its footprint include the footprint of its handlers. ◮ Since handlers can signal events, the footprint of handlers include the footprint of their event loop. 9 / 33

  24. Recursive Abstractions Verifying a lock-based event loop implementation ◮ Since we are interested in memory safety, eloop has to specify the memory footprint of the event loop. ◮ Since an event loop can call handlers, its footprint include the footprint of its handlers. ◮ Since handlers can signal events, the footprint of handlers include the footprint of their event loop. ◮ The footprint of an event loop is thus recursively defined. 9 / 33

  25. Recursive Abstractions Verifying a lock-based event loop implementation ◮ Imagine an implementation that maintains a set of signal handlers and a set of pending signals, protected by a lock: EventLoop : IEventLoop { class Lock lock ; private Set < handler > h a n d l e r s ; private Set < s i g n a l > s i g n a l s ; private . . . } ◮ Tying Landin’s Knot using a reference protected by a lock. 10 / 33

  26. Recursive Abstractions Verifying a lock-based event loop implementation ◮ The footprint of an event loop is thus recursively defined and the recursion “goes through the lock” . 11 / 33

  27. Recursive Abstractions Verifying a lock-based event loop implementation ◮ The footprint of an event loop is thus recursively defined and the recursion “goes through the lock” . ◮ We define eloop using guarded recursion and the third-order isLock representation predicate: eloop = fix ( λ eloop : Val → Prop . λ x : Val . ∃ l . x . lock �→ l ∗ isLock( l , ∃ y , z , A , B . set (y , A ) ∗ set (z , B ) ∗ x . handlers �→ y ∗ x . signals �→ z ∗ ∀ a ∈ A . ⊲ a �→ { eloop(x) }{ eloop(x) } )) 11 / 33

  28. Recursive Abstractions Verifying a lock-based event loop implementation ◮ The footprint of an event loop is thus recursively defined and the recursion “goes through the lock” . ◮ We define eloop using guarded recursion and the third-order isLock representation predicate: eloop = fix ( λ eloop : Val → Prop . λ x : Val . ∃ l . x . lock �→ l ∗ isLock( l , ∃ y , z , A , B . set (y , A ) ∗ set (z , B ) ∗ x . handlers �→ y ∗ x . signals �→ z ∗ ∀ a ∈ A . ⊲ a �→ { eloop(x) }{ eloop(x) } )) 11 / 33

Download Presentation
Download Policy: The content available on the website is offered to you 'AS IS' for your personal information and use only. It cannot be commercialized, licensed, or distributed on other websites without prior consent from the author. To download a presentation, simply click this link. If you encounter any difficulties during the download process, it's possible that the publisher has removed the file from their server.

Recommend


More recommend