SLIDE 1
Towards a separation logic for Multicore OCaml Glen Mvel , - - PowerPoint PPT Presentation
Towards a separation logic for Multicore OCaml Glen Mvel , - - PowerPoint PPT Presentation
Towards a separation logic for Multicore OCaml Glen Mvel , Jacques-Henri Jourdan, Franois Pottier May 25, 2020 PPS seminar, Paris CNRS & Inria, Paris, France The weak memory model Multicore OCaml Extension of the OCaml language with
SLIDE 2
SLIDE 3
Multicore OCaml
Extension of the OCaml language with multicore programming. Research project at OCaml Labs (Cambridge), will be merged eventually. Strengths:
- brings multicore abilities to a functional, statically typed,
memory-safe programming language;
- (gives the programmer a simpler memory model than that of
C11, hopefully;)
- limited performance drop for sequential code.
Goals of this PhD:
- Build a proof system for Multicore OCaml programs.
- Prove interesting concurrent data structures.
1
SLIDE 4
Sequential consistency
Consider this concurrent program: x := 0 y := 0 x := 1 y := 1 A := y B := x Possible outcomes (A, B): (0, 1), (1, 0), (1, 1). Observed (M.OCaml on 2-core x86-64): 91%, 9%, 0.001%.
2
SLIDE 5
Sequential consistency
Consider this concurrent program: x := 0 y := 0 x := 1 y := 1 A := y B := x Possible outcomes (A, B): (0, 1), (1, 0), (1, 1). Observed (M.OCaml on 2-core x86-64): 91%, 9%, 0.001%.
2
SLIDE 6
Sequential consistency
Consider this concurrent program: x := 0 y := 0 x := 1 y := 1 A := y B := x Possible outcomes (A, B): (0, 1), (1, 0), (1, 1). Observed (M.OCaml on 2-core x86-64): 91%, 9%, 0.001%.
2
SLIDE 7
Sequential consistency
Consider this concurrent program: x := 0 y := 0 x := 1 y := 1 A := y B := x Possible outcomes (A, B): (0, 1), (1, 0), (1, 1). Observed (M.OCaml on 2-core x86-64): 91%, 9%, 0.001%.
2
SLIDE 8
A weaker memory model
Consider this concurrent program: x := 0 y := 0 x := 1 y := 1 A := y B := x Possible outcomes (A, B): (0, 1), (1, 0), (1, 1), (0, 0). Observed (M.OCaml on 2-core x86-64): 91%, 9%, 0.001%, 0.1%.
2
SLIDE 9
A weaker memory model
Consider this concurrent program: x := 0 y := 0 x := 1 y := 1 A := y B := x Possible outcomes (A, B): (0, 1), (1, 0), (1, 1), (0, 0). Observed (M.OCaml on 2-core x86-64): 91%, 9%, 0.001%, 0.1%. The compiler may reorder a write after a read. (The processor too.)
2
SLIDE 10
Weak memory models
Sequential consistency is unrealistic. We need a weaker memory model, where different threads have different views of the shared state. The model should be specific to our language. Existing works: Java (2000s), C11 (2010s; also Rust). Candidate model for Multicore OCaml: Dolan, Sivaramakrishnan, Madhavapeddy. Bounding Data Races in Space and Time. PLDI 2018. Two access modes: non-atomic, atomic.
3
SLIDE 11
An operational model for Multicore OCaml: non-atomics
x := x1 y := y1 A := !y B := !x
4
SLIDE 12
An operational model for Multicore OCaml: non-atomics
x := x1 y := y1 A := !y B := !x x : y : x0 y Each non-atomic location has a history, i.e. a map from timestamps to values (timestamps are per location).
4
SLIDE 13
An operational model for Multicore OCaml: non-atomics
x := x1 y := y1 A := !y B := !x x : y : x0 y thread A thread B Each non-atomic location has a history, i.e. a map from timestamps to values (timestamps are per location). Each thread has its own view of the non-atomic store, i.e. a map from non-atomic locations to timestamps.
4
SLIDE 14
An operational model for Multicore OCaml: non-atomics
x := x1 y := y1 A := !y B := !x x : y : x0 x1 y thread B thread A
non-atomic write
- Timestamp must be fresh.
- Timestamp must be newer than
current thread’s view.
- Current thread’s view is updated.
4
SLIDE 15
An operational model for Multicore OCaml: non-atomics
x := x1 y := y1 A := !y B := !x x : y : x0 x1 y y 1 thread B thread A
non-atomic write
- Timestamp must be fresh.
- Timestamp must be newer than
current thread’s view.
- Current thread’s view is updated.
4
SLIDE 16
An operational model for Multicore OCaml: non-atomics
x := x1 y := y1 A := !y B := !x x : y : x0 x1 y y 1 thread B thread A
non-atomic read
- Returns any value at least as
recent as current thread’s view.
- Current thread’s view is unchanged.
4
SLIDE 17
An operational model for Multicore OCaml: non-atomics
x := x1 y := y1 A := !y B := !x x : y : x0 x1 y y 1 thread B thread A
non-atomic read
- Returns any value at least as
recent as current thread’s view.
- Current thread’s view is unchanged.
4
SLIDE 18
An operational model for Multicore OCaml: atomics
Non-atomic locations are useful for updating the state locally, but they don’t provide synchronization. Atomic locations allow the message-passing idiom.
5
SLIDE 19
An operational model for Multicore OCaml: atomics
x := x1 a :=at true REPEAT C := !at a UNTIL C = true B := !x thread A thread B x : x0 a : false
6
SLIDE 20
An operational model for Multicore OCaml: atomics
x := x1 a :=at true REPEAT C := !at a UNTIL C = true B := !x atomic a thread A thread B x : x0 a : false Each atomic location stores one value, and one view of the non-atomic store.
6
SLIDE 21
An operational model for Multicore OCaml: atomics
x := x1 a :=at true REPEAT C := !at a UNTIL C = true B := !x atomic a thread A thread B x : x0 a : false
6
SLIDE 22
An operational model for Multicore OCaml: atomics
x := x1 a :=at true REPEAT C := !at a UNTIL C = true B := !x atomic a thread A thread B x : x0 x1 a : false
6
SLIDE 23
An operational model for Multicore OCaml: atomics
x := x1 a :=at true REPEAT C := !at a UNTIL C = true B := !x atomic a thread A thread B x : x0 x1 a : true
atomic write Merges the writer’s view into the atomic location’s view.
6
SLIDE 24
An operational model for Multicore OCaml: atomics
x := x1 a :=at true REPEAT C := !at a UNTIL C = true B := !x atomic a thread B thread A x : x0 x1 a : true
atomic read Merges the atomic location’s view into the reader’s view.
6
SLIDE 25
An operational model for Multicore OCaml: atomics
x := x1 a :=at true REPEAT C := !at a UNTIL C = true B := !x atomic a thread B thread A x : x0 x1 a : true
6
SLIDE 26
Our program logic
SLIDE 27
Rules of non-atomic locations
The predicate x → v means that we own the non-atomic location x and that we have seen its latest value, which is v. Non-atomic write:
{x → v}
x := v′
{λ(). x → v′}
Non-atomic read:
{x → v}
! x
{λv′. v′ = v ∗ x → v}
7
SLIDE 28
Impact of the weak memory model on our CSL
Invariants are the mechanism by which threads can share propositions in a Concurrent Separation Logic such as Iris:
{P ∗ I} e {Q ∗ I}
e atomic I ⊢ {P} e {Q} The proposition x → v is subjective: its truth depends on the thread’s view of memory. It is unsound to share it via an invariant. Propositions which are true in all threads are called objective:
- “pure” facts, such as v = 5
- ghost state, such as γ ֒
→ ◦ 5
- atomic state, such as a →at (v, V)
Only objective propositions can be put in an invariant.
8
SLIDE 29
Rules of atomic locations (simplified)
The predicate a →at v means that we own the atomic location a, which stores the value v. It is objective. Atomic write:
{a →at v}
a :=at v′
{λ(). a →at v′}
Atomic read:
{a →at v}
!at a
{λv′. v′ = v ∗ a →at v}
9
SLIDE 30
Rules of atomic locations (simplified)
The predicate a →at v means that we own the atomic location a, which stores the value v. It is objective. Atomic write:
{a →at v}
a :=at v′
{λ(). a →at v′}
Atomic read:
{a →at v}
!at a
{λv′. v′ = v ∗ a →at v} views Views are ordered by inclusion. The predicate ↑ V means “the current thread’s view includes V”.
9
SLIDE 31
Rules of atomic locations
The predicate a →at (v, V) means that we own the atomic location a, which stores the value v and a view (at least) V. It is objective. Atomic write:
{a →at (v, V) ∗ ↑ V′}
a :=at v′
{λ(). a →at (v′, V′)}
Atomic read:
{a →at (v, V)}
!at a
{λv′. v′ = v ∗ a →at (v, V) ∗ ↑ V} views Views are ordered by inclusion. The predicate ↑ V means “the current thread’s view includes V”.
9
SLIDE 32
Rules of atomic locations
The predicate a →at (v, V) means that we own the atomic location a, which stores the value v and a view (at least) V. It is objective. Atomic write:
{a →at (v, V) ∗ ↑ V′}
a :=at v′
{λ(). a →at (v′, V′ ⊔ V) ∗ ↑ V}
Atomic read:
{a →at (v, V)}
!at a
{λv′. v′ = v ∗ a →at (v, V) ∗ ↑ V} views Views are ordered by inclusion. The predicate ↑ V means “the current thread’s view includes V”.
9
SLIDE 33
Propositions are monotonic
Subjective propositions are monotonic w.r.t. the thread’s view. One reason: the frame rule:
{a →at v ∗ P}
a :=at v′
{λ(). a →at v′ ∗ P}
10
SLIDE 34
Propositions are monotonic
Subjective propositions are monotonic w.r.t. the thread’s view. One reason: the frame rule:
{a →at v ∗ P
this holds at the thread’s current view} a :=at v′
{λ(). a →at v′ ∗ P
this holds at the thread’s now extended view}
10
SLIDE 35
The message passing idiom
The objective proposition “P at V ” is the subjective proposition P seen at a fixed view V. P ⇐ ⇒ ∃V. (↑ V) ∗ (P at V) (⇒) If P holds now, then it holds at the current view. (⇐) If P holds at some earlier view, then it holds now.
11
SLIDE 36
The message passing idiom
P ⇐ ⇒ ∃V. (↑ V) ∗ (P at V) { P} { P}
11
SLIDE 37
The message passing idiom
P ⇐ ⇒ ∃V. (↑ V) ∗ (P at V) {a →at (false, ∅) ∗ P} a :=at true C := !at a {a →at (true, V) ∗ P}
11
SLIDE 38
The message passing idiom
P ⇐ ⇒ ∃V. (↑ V) ∗ (P at V) {a →at (false, ∅) ∗ P} {a →at (false, ∅) ∗ P at V ∗ ↑ V} a :=at true C := !at a {a →at (true, V) ∗ P}
11
SLIDE 39
The message passing idiom
P ⇐ ⇒ ∃V. (↑ V) ∗ (P at V) {a →at (false, ∅) ∗ P} {a →at (false, ∅) ∗ P at V ∗ ↑ V} a :=at true {a →at (true, V) ∗ P at V} C := !at a {a →at (true, V) ∗ P}
11
SLIDE 40
The message passing idiom
P ⇐ ⇒ ∃V. (↑ V) ∗ (P at V) {a →at (false, ∅) ∗ P} {a →at (false, ∅) ∗ P at V ∗ ↑ V} a :=at true {a →at (true, V) ∗ P at V} C := !at a {a →at (true, V) ∗ P}
This proposition is objective: it can be put in an invariant.
11
SLIDE 41
The message passing idiom
P ⇐ ⇒ ∃V. (↑ V) ∗ (P at V) {a →at (false, ∅) ∗ P} {a →at (false, ∅) ∗ P at V ∗ ↑ V} a :=at true {a →at (true, V) ∗ P at V} {a →at (true, V) ∗ P at V} C := !at a {a →at (true, V) ∗ P} i n v
This proposition is objective: it can be put in an invariant.
11
SLIDE 42
The message passing idiom
P ⇐ ⇒ ∃V. (↑ V) ∗ (P at V) {a →at (false, ∅) ∗ P} {a →at (false, ∅) ∗ P at V ∗ ↑ V} a :=at true {a →at (true, V) ∗ P at V} {a →at (true, V) ∗ P at V} C := !at a {a →at (true, V) ∗ P at V ∗ ↑ V} {a →at (true, V) ∗ P} i n v
This proposition is objective: it can be put in an invariant.
11
SLIDE 43
Example: spin lock
A spin lock implements a lock using an atomic boolean variable.
let rec acquire lk = if CAS lk false true then () else acquire lk let release lk = lk :={at} false
The invariant in the sequentially consistent model is: lockInv lk P lk →at true ∨ ( lk →at false ∗ P)
12
SLIDE 44
Example: spin lock
A spin lock implements a lock using an atomic boolean variable.
let rec acquire lk = if CAS lk false true then () else acquire lk let release lk = lk :={at} false
The invariant in the weak model is: lockInv lk P lk →at true ∨ (∃V. lk →at (false, V) ∗ P at V)
12
SLIDE 45
Example: ticket lock
A ticket lock implements a lock using two atomic integer variables. The invariant in the sequentially consistent model is: lockInv turn next γ P ∃t, n. turn →at t ∗ next →at n ∗ (ticket γ t ∨ (locked γ ∗ P)) ∗ γ ֒ → (• . . .)
13
SLIDE 46
Example: ticket lock
A ticket lock implements a lock using two atomic integer variables. The invariant in the weak model is: lockInv turn next γ P ∃t, n, V. turn →at (t, V) ∗ next →at n ∗ (ticket γ t ∨ (locked γ ∗ P at V)) ∗ γ ֒ → (• . . .)
13
SLIDE 47
Example: Dekker’s mutual exclusion
Dekker’s algorithm solves the mutual exclusion problem using three atomic variables. The invariant and representation predicate in the SC model are: DekkerInv turn flag0 flag1 γ P ∃t, f0, f1, c0, c1.
- ∀i ∈ {0, 1}. flagi →at fi
∗ γi ֒ → • ci
- ∗ ((¬c0 ∧ ¬c1) −
∗ P) ∗ . . . isDekker i γ γi ֒ → ◦ false
14
SLIDE 48
Example: Dekker’s mutual exclusion
Dekker’s algorithm solves the mutual exclusion problem using three atomic variables. The invariant and representation predicate in the weak model are: DekkerInv turn flag0 flag1 γ P ∃t, f0, f1, c0, c1, V0, V1.
- ∀i ∈ {0, 1}. flagi →at (fi, Vi) ∗ γi ֒
→ • ci ∗ γ′
i ֒
→ • Vi
- ∗ ((¬c0 ∧ ¬c1) −
∗ P at (V0 ⊔ V1)) ∗ . . . isDekker i γ ∃V.γi ֒ → ◦ false ∗ γ′
i ֒
→ ◦ V ∗ ↑ V
14
SLIDE 49
Model of the logic in Iris
Propositions are predicates on views: vProp view − → iProp ↑ V0 λV. V0 ⊑ V P ∗ Q λV. P V ∗ Q V P − ∗ Q λV . P V − ∗ Q V
15
SLIDE 50
Model of the logic in Iris
Propositions are monotonic predicates on views: vProp view
mon
− → iProp ↑ V0 λV. V0 ⊑ V P ∗ Q λV. P V ∗ Q V P − ∗ Q λV1. ∀V ⊒ V1. P V − ∗ Q V
15
SLIDE 51
Model of the logic in Iris
Propositions are monotonic predicates on views: vProp view
mon
− → iProp ↑ V0 λV. V0 ⊑ V P ∗ Q λV. P V ∗ Q V P − ∗ Q λV1. ∀V ⊒ V1. P V − ∗ Q V 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: WP e ϕ λV1. ∀V ⊒ V1. WP e, V
- λv, V′. ϕ v V′
where ϕ : val → vProp
15
SLIDE 52
Future work
Plans for the future:
- Prove more elaborate shared data structures
- e.g. bounded queues with a circular buffer
- Data races on non-atomics:
- How to allow them?
- What are they useful for?