• Aucun résultat trouvé

Cosmo: a concurrent separation logic for Multicore OCaml

N/A
N/A
Protected

Academic year: 2022

Partager "Cosmo: a concurrent separation logic for Multicore OCaml"

Copied!
38
0
0

Texte intégral

(1)

Cosmo: a concurrent separation logic for Multicore OCaml

Glen Mével, Jacques-Henri Jourdan, François Pottier August, 2020

ICFP, “New York”

LRI & Inria, Paris, France

(2)

This talk

Our aim:

• Verifying

• fine-grained concurrent programs

• in the setting of Multicore OCaml’s memory model.

Our contribution: A concurrent separation logic with views.

(3)

Multicore OCaml

Multicore OCaml: OCaml language with multicore programming.

Weak memory model for Multicore OCaml:

• Formalized in PLDI 2018.

• Two flavours of locations: “atomic”, “non-atomic”.

(Also at ICFP 2020: Retrofitting Parallelism onto OCaml)

(4)

In traditional fine-grained concurrent separation logics...

We can assert ownership of a location and specify its value:

{x7→42}

x:=44 {x7→44}

Ownership can be shared between all threads via an invariant:

∃n∈N, x7→n ∗ n is even ` {True}

x:=44 {True}

(5)

The challenge: subjectivity

With weak memory, each thread has its ownviewof memory.

Some assertions aresubjective:

• Their validity relies on the thread’s view.

Invariants areobjective:

• They cannot share subjective assertions.

How to keep a simple and powerful enough logic?

(6)

Key idea: modeling subjectivity with views

A thread knows a subsetU of all writes to the memory.

• Affects how the thread interacts with memory.

• U is the thread’sview.

New assertions:

• ↑ U : wehave seen U, i.e. we know all writes in U.

• P @U : having seenU is objectivelyenough for P to hold.

(7)

Key idea: decomposing subjective assertions

Decompose subjective assertions:

P ⇐⇒ ∃U. P@U

| {z }

objective

∗ ↑ U

|{z}

subjective

Share parts via distinct mechanisms:

• P @U : viaobjective invariants, as usual.

• ↑ U : via synchronizationoffered by the memory model.

(8)

Our program logic

(9)

Rules of atomic locations, simplified

x7→atv : the atomiclocationx storesthe valuev.

• Sequentially consistent.

• Objective.

• Standard rules:

{x7→atv}

x :=atv0 {λ().x7→atv0}

{x7→atv}

!atx

{λv0.v0 =v ∗ x7→atv}

(10)

Rules of non-atomic locations

x7→v : we knowthe latest valuev of the non-atomiclocationx.

• Relaxed.

• Subjective— cannot appear in an invariant.

• Standard rules too!

{x7→v}

x :=v0 {λ().x7→v0}

{x7→v}

!x

{λv0.v0 =v ∗ x7→v}

(11)

Example: transferring an assertion through a spin lock

{P}

{∃U. P@U ∗ ↑ U }

// release lock:

lock :=at false

// acquire lock:

while CAS lock false true = false do () done

// CAS succeeds {∃U. P@U ∗ ↑ U }

{P}

• P @U : transferred viaobjective invariants, as usual.

• ↑ U : transferred via “atomic” accesses.

(12)

Example: transferring an assertion through a spin lock {P}

{∃U. P@U ∗ ↑ U }

// release lock:

lock :=at false

// acquire lock:

while CAS lock false true = false do () done

// CAS succeeds {∃U. P@U ∗ ↑ U }

{P}

• P @U : transferred viaobjective invariants, as usual.

• ↑ U : transferred via “atomic” accesses.

(13)

Example: transferring an assertion through a spin lock {P}

{∃U. P@U ∗ ↑ U }

// release lock:

lock :=at false

// acquire lock:

while

CAS lock false true

= false

// CAS succeeds

{∃U. P@U ∗ ↑ U }

{P}

• P @U : transferred viaobjective invariants, as usual.

• ↑ U : transferred via “atomic” accesses.

(14)

Example: transferring an assertion through a spin lock

{P}

{∃U. P@U ∗ ↑ U } // release lock:

lock :=at false

// acquire lock:

while

CAS lock false true

= false

// CAS succeeds {∃U. P@U ∗ ↑ U } {P}

• P @U : transferred viaobjective invariants, as usual.

• ↑ U : transferred via “atomic” accesses.

(15)

Example: transferring an assertion through a spin lock

{P}

{∃U. P@U ∗ ↑ U } // release lock:

lock :=at false

// acquire lock:

while

CAS lock false true

= false

// CAS succeeds {∃U. P@U ∗ ↑ U } {P}

• P @U : transferred viaobjective invariants, as usual.

• ↑ U : transferred via “atomic” accesses.

(16)

Example: transferring an assertion through a spin lock

{P}

{∃U. P@U ∗ ↑ U} // release lock:

lock :=at false

// acquire lock:

while

CAS lock false true

= false

// CAS succeeds {∃U. P@U ∗ ↑ U} {P}

• P @U : transferred viaobjective invariants, as usual.

(17)

Example: transferring an assertion through a spin lock

{P}

{∃U. P@U ∗ ↑ U} // release lock:

lock :=at false

// acquire lock:

while

CAS lock false true

= false

// CAS succeeds {∃U. P@U ∗ ↑ U} {P}

happens before

• P @U : transferred viaobjective invariants, as usual.

(18)

Rules of atomic locations, simplified

x7→at v : the atomic location x stores the valuev.

• Sequentially consistent behavior forv.

• Release/acquirebehavior for U.

• Objective.

• Rules:

{x7→at v} x :=atv0 {λ().x7→ v0}

{x7→at v}

!atx

{λv0.v0 =v ∗ x7→ v}

(19)

Rules of atomic locations

x7→at(v,U) : the atomic location x stores the valuev and a view(at least)U.

• Sequentially consistent behavior forv.

• Release/acquirebehavior for U.

• Objective (still).

• Rules:

{x7→at(v,U) ∗ ↑ U0} x :=atv0

{λ().x7→ (v0,U0)}

{x7→at(v,U)}

!atx

{λv0.v0 =v ∗ x7→ (v,U) ∗ ↑ U}

(20)

Rules of atomic locations

x7→at(v,U) : the atomic location x stores the valuev and a view(at least)U.

• Sequentially consistent behavior forv.

• Release/acquirebehavior for U.

• Objective (still).

• Rules:

{x7→at(v,U) ∗ ↑ U0} x :=atv0

{λ().x7→ (v0,U0)}

{x7→at(v,U)}

!atx

{λv0.v0 =v ∗ x7→ (v,U) ∗ ↑ U} release

(21)

Rules of atomic locations

x7→at(v,U) : the atomic location x stores the valuev and a view(at least)U.

• Sequentially consistent behavior forv.

• Release/acquirebehavior for U.

• Objective (still).

• Rules:

{x7→at(v,U) ∗ ↑ U0} x :=atv0

{λ().x7→ (v0,U0)}

{x7→at(v,U)}

!atx

{λv0.v0 =v ∗ x7→ (v,U) ∗ ↑ U} acquire

(22)

Application: the spin lock

(23)

The spin lock

A spin lock implements a lock using an atomic boolean variable:

let r e l e a s e lk = lk :={at} f a l s e

let rec a c q u i r e lk = if CAS lk f a l s e t r u e t h e n ()

e l s e a c q u i r e lk

Interface:

isLocklkP `

{P}release lk{True}

{True}acquire lk{P}

(24)

The spin lock

A spin lock implements a lock using an atomic boolean variable:

let r e l e a s e lk = lk :={at} f a l s e

let rec a c q u i r e lk = if CAS lk f a l s e t r u e t h e n ()

e l s e a c q u i r e lk

Invariant in traditional CSL:

lk7→attrue ∨ (

∃U.

lk7→at false ∗ P) `

{P}release lk{True}

{True}acquire lk{P}

(25)

The spin lock

A spin lock implements a lock using an atomic boolean variable:

let r e l e a s e lk = lk :={at} f a l s e

let rec a c q u i r e lk = if CAS lk f a l s e t r u e t h e n ()

e l s e a c q u i r e lk

Invariant in our logic (whereP is subjective!):

lk7→attrue ∨ (∃U.lk7→at(false,U) ∗ P@U) `

{P}release lk{True}

{True}acquire lk{P}

(26)

Methodology

More case studies:

• Ticket lock

• Dekker mutual exclusion algorithm

• Peterson mutual exclusion algorithm

Method for proving correctness under weak memory:

1. Start with the invariant under sequential consistency;

2. Identify how information flows between threads;

• i.e. where are the synchronization points;

(27)

Conclusion

(28)

Conclusion

Key idea: The logic of views enables concise and natural reasoning about how threads synchronize.

In the paper:

• Model of the logic.

• A lower-level logic.

• More case studies.

Fully mechanized in Coq with the Iris framework.

Future work:

(29)

Questions?

(30)
(31)

Verifying the spin lock

// release lk:

{ isLock lkP ∗ P} { lk7→at_ ∗ P}

∃U.lk7→at_ ∗ z }| {

↑ U ∗ P @U

lk :=at false

{∃U.lk7→at(false,U) ∗ P @U } { isLock lkP}

// acquire lk:

{isLocklkP}

( (∃U.lk7→at(false,U) ∗ P@U)

∨ lk7→attrue

)

if CAS lk false true then

∃U.lk7→attrue ∗ ↑ U ∗ P @U

| {z }

{ lk7→at_ ∗ P} { isLocklkP ∗ P} else

{lk7→attrue}

(32)

Model of the logic in Iris

Assertions are predicates on views:

vProp,view−→iProp

↑ U0,λU.U0 v U P ∗ Q,λU.P U ∗ Q U P −∗Q,λU .

∀U w U1.

P U −∗Q U

We equip a language-with-view with an operational semantics:

exprWithView,expr×view

Iris builds a WP calculus for exprWithView in iProp.

We derive a WP calculus for expr in vProp and prove adequacy:

∀U w U1.

(33)

Model of the logic in Iris

Assertions aremonotonic predicates on views:

vProp,view−→mon iProp

↑ U0,λU.U0 v U P ∗ Q,λU.P U ∗ Q U

P −∗Q,λU1.∀U w U1.P U −∗Q U

We equip a language-with-view with an operational semantics:

exprWithView,expr×view

Iris builds a WP calculus for exprWithView in iProp.

We derive a WP calculus for expr in vProp and prove adequacy:

(34)

Model of the logic in Iris

Assertions aremonotonic predicates on views:

vProp,view−→mon iProp

↑ U0,λU.U0 v U P ∗ Q,λU.P U ∗ Q U

P −∗Q,λU1.∀U w U1.P U −∗Q U

We equip a language-with-view with an operational semantics:

exprWithView,expr×view

Iris builds a WP calculus for exprWithView in iProp.

We derive a WP calculus for expr in vProp and prove adequacy:

(35)

Assertions are monotonic

Subjective assertions aremonotonicw.r.t. the thread’s view.

One reason is the frame rule:

{x7→v ∗ P} x:=v0

{λ().x7→v0 ∗ P}

(36)

Assertions are monotonic

Subjective assertions aremonotonicw.r.t. the thread’s view.

One reason is the frame rule:

{x7→v ∗ P — holds at the thread’s current view}

x:=v0

{λ().x7→v0 ∗ P — holds at the thread’s now extended view}

(37)

Decomposition of subjective assertions

This theorem allows us to decompose a subjective assertionP: P ⇐⇒ ∃U. ↑ U

|{z}

subjective

∗ P@U

| {z }

objective

We also have:

P @U =⇒Objectively(↑ U −∗P)

where ObjectivelyQ ⇐⇒(∀U.Q@U)⇐⇒Q@∅

(38)

Decomposition of subjective assertions

This theorem allows us to decompose a subjective assertionP: P ⇐⇒ ∃U. ↑ U

|{z}

subjective

∗ P@U

| {z }

objective

We also have:

P @U ⇐⇒Objectively(↑ U −∗P) where ObjectivelyQ ⇐⇒(∀U.Q@U)⇐⇒Q@∅

Références

Documents relatifs

In our case, the smash product is a lifting to the Eilenberg-Moore category of the the Cartesian product on asynchronous graphs, in that they commute with both the forgetful functor

The specification of this operation could be seq ^>> fun s -> interval 0 (R.length s) ^> element. The dependent function combinator ^>> is used to bind the variable

We have presented a powerful Separation Logic with support for user-defined effects and effect handlers, both shallow and deep.. It is restricted to

of the abstract state of the counter (note the γ Z ⇒ q ◦ m in the precondition of the Hoare triple); this captures the idea that no other thread can have full ownership of the

As discussed above, while Bierhoff and Aldrich’s linear typestate system [BA07] is suitable for verifying iterator clients, it may not be expressive enough to verify iterator

The concurrent machine context-switches only for fully concurrent operations (lock, unlock, and fork). However, our operational semantics permits only well-synchronized programs

This fragment consists at least of the rules that govern access to nonatomic locations and can be extended by allowing the use of concurrent data structures whose specification

O’Hearn showed that, just using the standard rules of separation logic plus a simple rule for resource invariants, one could elegantly verify the safety of rather