Programming and Proving with Concurrent Resources Ilya Sergey - - PowerPoint PPT Presentation

programming and proving with concurrent resources
SMART_READER_LITE
LIVE PREVIEW

Programming and Proving with Concurrent Resources Ilya Sergey - - PowerPoint PPT Presentation

Programming and Proving with Concurrent Resources Ilya Sergey joint work with Aleks Nanevski, Anindya Banerjee, Ruy Ley-Wild and Germn Delbianco What and why Concurrency parallelism efficiency A gap between informal


slide-1
SLIDE 1

Programming and Proving
 with 
 Concurrent Resources

joint work with 
 Aleks Nanevski, Anindya Banerjee, Ruy Ley-Wild and Germán Delbianco

Ilya Sergey

slide-2
SLIDE 2

What and why

  • Concurrency ⇒ parallelism ⇒ efficiency
  • A gap between informal and formal reasoning
  • Scalable formalisation requires compositionality
slide-3
SLIDE 3

This talk

A logical framework 
 for implementation 
 and compositional verification


  • f concurrent programs.
slide-4
SLIDE 4

Owicki-Gries (1976) CSL (2004) Rely-Guarantee (1983) SAGL (2007) RGSep (2007) Deny-Guarantee (2009) CAP (2010) Liang-Feng (2013) LRG (2009) SCSL (2013) HOCAP (2013) iCAP (2014) Iris (2015) CaReSL (2013) FCSL (2014) TaDA (2014) CoLoSL (2015) Gotsman-al (2007) HLRG (2010) Bornat-al (2005) RGSim (2012) GPS (2014) Total-TaDA (2016) Iris 2.0 (2016) FTCSL (2015)

Jacobs-Piessens (2011)

RSL (2013) LiLi (2016) Bell-al (2010) Hobor-al (2008) FSL (2016)

slide-5
SLIDE 5

Owicki-Gries (1976) CSL (2004) Rely-Guarantee (1983) SAGL (2007) RGSep (2007) Deny-Guarantee (2009) CAP (2010) Liang-Feng (2013) LRG (2009) SCSL (2013) HOCAP (2013) iCAP (2014) Iris (2015) CaReSL (2013) FCSL (2014) TaDA (2014) CoLoSL (2015) Gotsman-al (2007) HLRG (2010) Bornat-al (2005) RGSim (2012) GPS (2014) Total-TaDA (2016) Iris 2.0 (2016) FTCSL (2015)

Jacobs-Piessens (2011)

RSL (2013) LiLi (2016) Bell-al (2010) Hobor-al (2008) FSL (2016)

slide-6
SLIDE 6

Key insights

  • Subjectivity
  • Time-stamped Histories
  • Reasoning about Deep Sharing
slide-7
SLIDE 7
  • Subjectivity
  • Time-stamped Histories
  • Reasoning about Deep Sharing

Key insights

slide-8
SLIDE 8

Hoare-style program specifications

If the initial state satisfies P , 
 then, after c terminates, 
 the final state satisfies Q.

{ P } { Q }

precondition postcondition

c

slide-9
SLIDE 9

push(x) pop()

Abstract specifications for a stack

slide-10
SLIDE 10

push(x)

{ S = xs } { S′= x :: xs }

pop()

{ S = xs }

Suitable for sequential case

{ res = None ⋀ S = Nil ⋁ ∃x, xs′. res = Some x ⋀ 
 xs = x :: xs′ ⋀ S′ = xs′ }

Abstract specifications for a stack

slide-11
SLIDE 11

push(x)

{ S = xs } { S′= x :: xs }

pop()

{ S = xs }

Not so good for concurrent use: useless in the presence of interference

Abstract specifications for a stack

{ res = None ⋀ S = Nil ⋁ ∃x, xs′. res = Some x ⋀ 
 xs = x :: xs′ ⋀ S′ = xs′ }

slide-12
SLIDE 12

y := pop();

{ y = ??? } { S = Nil }

slide-13
SLIDE 13

y := pop();

{ y ∈ Some {1, 2} ⋁ y = None }

  • push(1);

push(2);

{ S = Nil }

slide-14
SLIDE 14

y := pop();

{ S = Nil }

{ y ∈ Some {1, 2, 3} ⋁ y = None }

  • push(1);

push(2);

  • push(3);
slide-15
SLIDE 15

y := pop();

{ y = ??? } { S = Nil }

Thread-modular spec for pop?

slide-16
SLIDE 16

Capture the effect of self, 
 abstract over the others.

Idea

(subjective specification)

slide-17
SLIDE 17

y := pop();

{ y = None ⋁ y = Some(v), where v ∈ Ho } { Hs = ∅ }

  • Hs — history of my pushes/pops to the stack
  • Ho — history of pushes/pops by all other threads

Subjective stack specifications

slide-18
SLIDE 18

y := pop();

{ y = None ⋁ y = Some(v), where v ∈ Ho } { Hs = ∅ }

  • Hs — history of my pushes/pops to the stack
  • Ho — history of pushes/pops by all other threads

Subjective stack specifications

| {z }

what I popped depends


  • n what the others have pushed
slide-19
SLIDE 19

{ y = None ⋁ y = Some(v), where v ∈ Ho }

Valid only if the history is changed by registering actual push/pops.

| {z }

what I popped depends


  • n what the others have pushed

y := pop();

{ Hs = ∅ }

Subjective stack specifications

slide-20
SLIDE 20

{ P } { Q } C ⊢

Specifies expected
 thread interference y := pop();

slide-21
SLIDE 21

Model of shared state
 with manifested interference

slide-22
SLIDE 22

Concurrent Resources

Shared state

slide-23
SLIDE 23

Auxiliary state Shared state

Owicki, Gries [CACM’77]

Concurrent Resources

slide-24
SLIDE 24

Auxiliary state, 
 controlled by this thread

Auxiliary state, 
 controlled by others

Subjective Concurrent Resources

Shared state

Ley-Wild, Nanevski [POPL’13]

slide-25
SLIDE 25

Transitions, allowed 
 to the others
 (Rely) Changes (transitions) 
 allowed to myself
 (Guarantee)

What I have = what I can do and what I have done.

Subjective Concurrent Resources

Jones [TOPLAS’83]

slide-26
SLIDE 26

State Transition Systems
 with 
 Subjective Auxiliary State

Concurrent Resources =

Nanevski et al [ESOP’14]

slide-27
SLIDE 27

Self

Other Joint

  • Self — state controlled by me
  • Other — state controlled by all other threads
  • Joint — modified by everyone, as allowed by transitions

Resource-based specifications

slide-28
SLIDE 28

C =

{ P } c { Q }

| {z }

defines resources, touched by c, their transitions and invariants

@ C C ⊢

Self

Other Joint

Resource-based specifications

slide-29
SLIDE 29

C =

{ P } c { Q }@ C

Self

Other Joint

specify self/other/joint parts

Resource-based specifications

slide-30
SLIDE 30

Fine-grained Concurrent Separation Logic

Nanevski, Ley-Wild, Sergey, Delbianco [ESOP’14]

  • Logic for reasoning with (fine-grained)

concurrent resources

  • Emphasis on subjective specifications
slide-31
SLIDE 31

Key insights

  • Subjectivity
  • Histories
  • Deep Sharing
slide-32
SLIDE 32
  • Subjectivity — reasoning with self and other
  • Histories
  • Deep Sharing

Key insights

slide-33
SLIDE 33
  • Subjectivity — reasoning with self and other
  • Histories
  • Deep Sharing

Key insights

slide-34
SLIDE 34

Partial Commutative Monoids

  • A set S of elements
  • Join (⊕): commutative, associative, partial
  • Unit element 0: ∀e ∈ S, e⊕0 = 0⊕e = e

(S, ⊕, 0)

slide-35
SLIDE 35

child1 child2

||

s1 ⊕ s2

parent

{ s1 ⊕ s2 }

  • commutative
  • associative
  • unit — idle thread
  • partial

Logical state split

slide-36
SLIDE 36

parent child1 || State that belongs to child1 child2

||

s1

{ s1 } { s1 ⊕ s2 }

Logical state split

slide-37
SLIDE 37

child1 || State that belongs to child2 child2

||

s2

{ s1 } { s2 }

parent

{ s1 ⊕ s2 }

Logical state split

slide-38
SLIDE 38

|| ||

z2

{ s2 } { s1 } { z1 } { z2 } { s1 ⊕ s2 }

Logical state split

child1 child2 parent

slide-39
SLIDE 39

z1 ⊕ z2

||

New state that belongs to parent′

||

parent′

{ s2 } { s1 } { z1 } { z2 } { s1 ⊕ s2 } { z1 ⊕ z2 }

Logical state split

child1 child2 parent

slide-40
SLIDE 40

PCMs: a uniform interface for splittable state

slide-41
SLIDE 41

Familiar PCM: finite heaps

  • Heaps are partial finite maps nat →

Val

  • Join operation ⊕ is disjoint union
  • Unit element 0 is the empty heap ∅
slide-42
SLIDE 42

hs

  • hs — heap, logically owned by this thread
  • ho — heap, owned by others
  • Transitions — writes into hs

ho ∅

Resource for thread-local state

Concurrent Separation Logic
 O’Hearn [CONCUR’04]

slide-43
SLIDE 43

*x := 5; *y := 7;

{ hs = x ↦ - ⊕ y ↦ - ⋀ ho = h }

{ hs = x ↦ - ⋀ ho = y ↦ - ⊕ h } { hs = y ↦ - ⋀ ho = x ↦ - ⊕ h } { hs = x ↦ 5 ⋀ ho = y ↦ - ⊕ h } { hs = y ↦ 7 ⋀ ho = x ↦ - ⊕ h }

{ hs = x ↦ 5 ⊕ y ↦ 7 ⋀ ho = h }

  • disjoint by resource definition
slide-44
SLIDE 44

Less familiar PCM: histories

Describing atomic state updates
 via auxiliary state

Sergey, Nanevski, Banerjee [ESOP’15]

slide-45
SLIDE 45

push(x)

{ S = xs } { S′ = x :: xs }

Atomic stack specifications

slide-46
SLIDE 46

x :: xs

Atomic stack specifications

xs

“timestamp”

tk →

slide-47
SLIDE 47

tk → tk+1 →

tk+2 → tk+3 →

……

tk+n →

| {z }

time increased at 
 every abstract operation

tk+4 →

slide-48
SLIDE 48

Changes by this thread Changes by other threads

tk+4 →

tk+1 →

tk+3 → tk+n →

tk →

tk+2 →

……

slide-49
SLIDE 49

tk+4 →

tk+1 →

tk+3 → tk+n →

tk →

tk+2 →

……

Hs Ho

Hs, Ho — self/other contributions to the resource history

slide-50
SLIDE 50

Histories are like heaps!

  • Histories are partial finite maps nat → AbsOp
  • Join operation ⊕ is disjoint union
  • Unit element 0 is the empty history ∅
slide-51
SLIDE 51

push(x)

{ ∃t, xs. Hs = t ↦ (xs, x::xs) ⋀ H ⊆ Ho ⋀ H < t }@Cstack

Stack specification

{ Hs = ∅ ⋀ H ⊆ Ho }

self-contribution is a single entry t allocated during the call

slide-52
SLIDE 52

{ res. if (res = Some x) then ∃t, xs. H ⊆ Ho ⋀ H < t ⋀ Hs = t ↦ (x::xs, xs)) else ∃t. H ⊆ Ho ⋀ H ≤ t ⋀ Hs = ∅ ⋀ t ↦ (_, Nil) ⊆ Ho }@Cstack

Stack specification

pop()

{ Hs = ∅ ⋀ H ⊆ Ho }

  • pop has hit Nil during its execution at the moment t
slide-53
SLIDE 53

{ res. if (res = Some x) then ∃t, xs. H ⊆ Ho ⋀ H < t ⋀ Hs = t ↦ (x::xs, xs)) else ∃t. H ⊆ Ho ⋀ H ≤ t ⋀ Hs = ∅ ⋀ t ↦ (_, Nil) ⊆ Ho }@Cstack

Stack specification

pop()

{ Hs = ∅ ⋀ H ⊆ Ho }

no self-contributions initially?

slide-54
SLIDE 54

Framing in FCSL

{ }

my_program

{ }

slide-55
SLIDE 55

Framing in FCSL

{ }

my_program

{ }

Works for any PCM, not just heaps (e.g., SL and CSL)!

slide-56
SLIDE 56

push(x)

{ ∃t, xs. H ⊆ Ho ⋀ H < t ⋀ Hs = t ↦ (xs, x::xs) }@Cstack { Hs = ∅ ⋀ H ⊆ Ho }

Framing histories

slide-57
SLIDE 57

push(x)

{ ∃t, xs. H2 ⊆ Ho ⋀ H1 ⊕ H2 < t ⋀ Hs = H1 ⊕ t ↦ (xs, x::xs) }@Cstack

{ Hs = H1 ⋀ H2 ⊆ Ho }

Framing histories

initial self-contribution final self-contribution t is later than H1 ⊕ H2

slide-58
SLIDE 58

How clients use
 splittable histories?

slide-59
SLIDE 59

A stack client program

  • Two threads: producer and consumer
  • Ap — an n-element producer array
  • Ac — an n-element consumer array
  • A shared concurrent stack S is used as a buffer
  • Goal: prove the exchange correct
slide-60
SLIDE 60
  • Pushed H E iff 


E is a multiset of elements, pushed in H

  • Popped H E iff 


E is a multiset of elements, popped in H

Auxiliary Predicates

slide-61
SLIDE 61

letrec produce(i : nat) = { if (i == n) then return; else { S.push(Ap[i]); produce(i+1); } }

{ Ap ↦ L ⋀ Pushed Hs L[< i] ⋀ Popped Hs ∅ } { Ap ↦ L ⋀ Pushed Hs L[< n] ⋀ Popped Hs ∅ }

slide-62
SLIDE 62

letrec consume(i : nat) = { if (i == n) then return; else { t ← S.pop(); if t == Some v 
 then { Ac[i] := v; consume(i+1); } else consume(i); } }

{∃L, Ac ↦ L ⋀ Pushed Hs ∅ ⋀ Popped Hs L[< i] } {∃L, Ac ↦ L ⋀ Pushed Hs ∅ ⋀ Popped Hs L[< n] }

slide-63
SLIDE 63

consume(0) produce(0)

     

      

No other threads
 can interfere on S

hide Cstack(hS) in

slide-64
SLIDE 64

consume(0) produce(0)

     

      

{ Ap ↦ L ⊕ Ac ↦ L′ ⊕ hS }

hide Cstack(hS) in

slide-65
SLIDE 65

consume(0) produce(0)

     

      

{ Ap ↦ L ⊕ Ac ↦ L′ ⊕ hS }

{ Ap ↦ L { Ac ↦ L′ ⋀ Pushed Hs ∅ ⋀ Popped Hs ∅ } ⋀ Pushed Hs ∅ ⋀ Popped Hs ∅ }

hide Cstack(hS) in

slide-66
SLIDE 66

consume(0) produce(0)

     

      

{ Ap ↦ L ⊕ Ac ↦ L′ ⊕ hS }

{ Ap ↦ L { Ac ↦ L′ ⋀ Pushed Hs ∅ ⋀ Popped Hs ∅ } ⋀ Pushed Hs ∅ ⋀ Popped Hs ∅ } { Ap ↦ L ⋀ 
 Pushed Hs L[< n] ⋀ 
 Popped Hs ∅ } { Ac ↦ L′′ ⋀ 
 Pushed Hs ∅ ⋀ 
 Popped Hs L′′[<n] }

These are the only changes 
 in the stack’s history

hide Cstack(hS) in

slide-67
SLIDE 67

consume(0) produce(0)

     

      

{ Ap ↦ L ⊕ Ac ↦ L′ ⊕ hS }

{ Ap ↦ L { Ac ↦ L′ ⋀ Pushed Hs ∅ ⋀ Popped Hs ∅ } ⋀ Pushed Hs ∅ ⋀ Popped Hs ∅ } { Ap ↦ L ⋀ 
 Pushed Hs L[< n] ⋀ 
 Popped Hs ∅ } { Ac ↦ L′′ ⋀ 
 Pushed Hs ∅ ⋀ 
 Popped Hs L′′[<n] }

{ Ap ↦ L ⊕ Ac ↦ L′′ ⊕ hS′ ⋀ L =set L′′}

hide Cstack(hS) in

slide-68
SLIDE 68

Key insights

  • Subjectivity — reasoning with self and other
  • Histories
  • Deep Sharing
slide-69
SLIDE 69
  • Subjectivity — reasoning with self and other
  • Histories — temporal specification via state
  • Deep Sharing

Key insights

slide-70
SLIDE 70
  • Subjectivity — reasoning with self and other
  • Histories — temporal specification via state
  • Deep Sharing

Key insights

slide-71
SLIDE 71

a b c e d

Ramified data structures

slide-72
SLIDE 72

letrec span (x : ptr) : bool = { if x == null then return false; else b ← CAS(x->m, 0, 1); if b then (rl,rr) ← (span(x->l) || span(x->r)); if ¬rl then x->l := null; if ¬rr then x->r := null; return true; else return false; }

mark the node x

run in parallel for successors prune redundant edges

m l r

... ...

x

In-place concurrent spanning tree construction

slide-73
SLIDE 73

a b c e d

slide-74
SLIDE 74

a b c e d

✔ ✔

slide-75
SLIDE 75

a b c e d

✔ ✔ ✔ ✔

✗ ✗

slide-76
SLIDE 76

a b c e d

✔ ✔ ✔ ✔

✗ ✗

slide-77
SLIDE 77

a b c e d

✔ ✔

slide-78
SLIDE 78

a b c e d

slide-79
SLIDE 79

Why verifying span is difficult?

The recursion scheme does not 
 follow the shape of the structure.

a b c e d a b c e d a b c e d

| t | P V Q | i s t h a t i n c l u d i n g | t

} | P V Q

is that including

slide-80
SLIDE 80

Assumptions for correctness

  • The graph modified only by the commands of span
  • The initial call is done from a root node

letrec span (x : ptr) : bool = { if x == null then return false; else b ← CAS(x->m, 0, 1); if b then (rl,rr) ← (span(x->l) || span(x->r)); if ¬rl then x->l := null; if ¬rr then x->r := null; return true; else return false; }

slide-81
SLIDE 81

Graph Resource: State

shared state (heap)

a b c e d

slide-82
SLIDE 82

a b c e d

b a

c

Auxiliary state


  • f this thread

Auxiliary state


  • f all other threads

Graph Resource: State

slide-83
SLIDE 83

Graph Resource: marking a node

a b c e d

mark(b)

a b c e d b

marked by this thread
 (Guarantee)

slide-84
SLIDE 84

a b c e d

mark(b)T

a b c e d b

marked by other thread
 (Rely)

Graph Resource: marking a node

slide-85
SLIDE 85

Graph Resource: pruning an edge

p r u n e ( b

  • >

r )

a b c e d

b

a b c e d

No other thread can do it!

b

slide-86
SLIDE 86

Specification for span

{ P } span(x) { Q }@CSpanTree

slide-87
SLIDE 87

Specification for span

span(x) : span_tp (x, CSpanTree, P , Q)

slide-88
SLIDE 88

Definition span_tp (x : ptr) := {i (g1 : graph (joint i))}, STsep [SpanTree] (fun s1 => i = s1 ⋀ (x == null ⋁ x ∈ dom (joint s1)), fun (r : bool) s2 => exists g2 : graph (joint s2), subgraph g1 g2 ⋀ if r then x != null ⋀ exists (t : set ptr), self s2 = self i ⊕ t ⋀ tree g2 x t ⋀ maximal g2 t ⋀ front g1 t (self s2 ⊕ other s2) else (x == null ⋁ mark g2 x) ⋀ self s2 = self i).

Specification for span

slide-89
SLIDE 89

Definition span_tp (x : ptr) := {i (g1 : graph (joint i))}, STsep [SpanTree] (fun s1 => i = s1 ⋀ (x == null ⋁ x ∈ dom (joint s1)), fun (r : bool) s2 => exists g2 : graph (joint s2), subgraph g1 g2 ⋀ if r then x != null ⋀ exists (t : set ptr), self s2 = self i ⊕ t ⋀ tree g2 x t ⋀ maximal g2 t ⋀ front g1 t (self s2 ⊕ other s2) else (x == null ⋁ mark g2 x) ⋀ self s2 = self i).

Specification for span

concurrent resource

slide-90
SLIDE 90

Definition span_tp (x : ptr) := {i (g1 : graph (joint i))}, STsep [SpanTree] (fun s1 => i = s1 ⋀ (x == null ⋁ x ∈ dom (joint s1)), fun (r : bool) s2 => exists g2 : graph (joint s2), subgraph g1 g2 ⋀ if r then x != null ⋀ exists (t : set ptr), self s2 = self i ⊕ t ⋀ tree g2 x t ⋀ maximal g2 t ⋀ front g1 t (self s2 ⊕ other s2) else (x == null ⋁ mark g2 x) ⋀ self s2 = self i).

Specification for span

precondition

slide-91
SLIDE 91

Definition span_tp (x : ptr) := {i (g1 : graph (joint i))}, STsep [SpanTree] (fun s1 => i = s1 ⋀ (x == null ⋁ x ∈ dom (joint s1)), fun (r : bool) s2 => exists g2 : graph (joint s2), subgraph g1 g2 ⋀ if r then x != null ⋀ exists (t : set ptr), self s2 = self i ⊕ t ⋀ tree g2 x t ⋀ maximal g2 t ⋀ front g1 t (self s2 ⊕ other s2) else (x == null ⋁ mark g2 x) ⋀ self s2 = self i).

Specification for span

postcondition

slide-92
SLIDE 92

Definition span_tp (x : ptr) := {i (g1 : graph (joint i))}, STsep [SpanTree] (fun s1 => i = s1 ⋀ (x == null ⋁ x ∈ dom (joint s1)), fun (r : bool) s2 => exists g2 : graph (joint s2), subgraph g1 g2 ⋀ if r then x != null ⋀ exists (t : set ptr), self s2 = self i ⊕ t ⋀ tree g2 x t ⋀ maximal g2 t ⋀ front g1 t (self s2 ⊕ other s2) else (x == null ⋁ mark g2 x) ⋀ self s2 = self i).

Specification for span

logical variables

slide-93
SLIDE 93

Definition span_tp (x : ptr) := {i (g1 : graph (joint i))}, STsep [SpanTree] (fun s1 => i = s1 ⋀ (x == null ⋁ x ∈ dom (joint s1)), fun (r : bool) s2 => exists g2 : graph (joint s2), subgraph g1 g2 ⋀ if r then x != null ⋀ exists (t : set ptr), self s2 = self i ⊕ t ⋀ tree g2 x t ⋀ maximal g2 t ⋀ front g1 t (self s2 ⊕ other s2) else (x == null ⋁ mark g2 x) ⋀ self s2 = self i).

Specification for span

slide-94
SLIDE 94

Definition span_tp (x : ptr) := {i (g1 : graph (joint i))}, STsep [SpanTree] (fun s1 => i = s1 ⋀ (x == null ⋁ x ∈ dom (joint s1)), fun (r : bool) s2 => exists g2 : graph (joint s2), subgraph g1 g2 ⋀ if r then x != null ⋀ exists (t : set ptr), self s2 = self i ⊕ t ⋀ tree g2 x t ⋀ maximal g2 t ⋀ front g1 t (self s2 ⊕ other s2) else (x == null ⋁ mark g2 x) ⋀ self s2 = self i).

Specification for span

slide-95
SLIDE 95

a b c e x d

Definition span_tp (x : ptr) := {i (g1 : graph (joint i))}, STsep [SpanTree] (fun s1 => i = s1 ⋀ (x == null ⋁ x ∈ dom (joint s1)), fun (r : bool) s2 => exists g2 : graph (joint s2), subgraph g1 g2 ⋀ if r then x != null ⋀ exists (t : set ptr), self s2 = self i ⊕ t ⋀ tree g2 x t ⋀ maximal g2 t ⋀ front g1 t (self s2 ⊕ other s2) else (x == null ⋁ mark g2 x) ⋀ self s2 = self i).

Specification for span

t

slide-96
SLIDE 96

a b c e x d

Definition span_tp (x : ptr) := {i (g1 : graph (joint i))}, STsep [SpanTree] (fun s1 => i = s1 ⋀ (x == null ⋁ x ∈ dom (joint s1)), fun (r : bool) s2 => exists g2 : graph (joint s2), subgraph g1 g2 ⋀ if r then x != null ⋀ exists (t : set ptr), self s2 = self i ⊕ t ⋀ tree g2 x t ⋀ maximal g2 t ⋀ front g1 t (self s2 ⊕ other s2) else (x == null ⋁ mark g2 x) ⋀ self s2 = self i).

Specification for span

t

slide-97
SLIDE 97

a b c e x d

Definition span_tp (x : ptr) := {i (g1 : graph (joint i))}, STsep [SpanTree] (fun s1 => i = s1 ⋀ (x == null ⋁ x ∈ dom (joint s1)), fun (r : bool) s2 => exists g2 : graph (joint s2), subgraph g1 g2 ⋀ if r then x != null ⋀ exists (t : set ptr), self s2 = self i ⊕ t ⋀ tree g2 x t ⋀ maximal g2 t ⋀ front g1 t (self s2 ⊕ other s2) else (x == null ⋁ mark g2 x) ⋀ self s2 = self i).

Specification for span

slide-98
SLIDE 98

a b c e x d

Definition span_tp (x : ptr) := {i (g1 : graph (joint i))}, STsep [SpanTree] (fun s1 => i = s1 ⋀ (x == null ⋁ x ∈ dom (joint s1)), fun (r : bool) s2 => exists g2 : graph (joint s2), subgraph g1 g2 ⋀ if r then x != null ⋀ exists (t : set ptr), self s2 = self i ⊕ t ⋀ tree g2 x t ⋀ maximal g2 t ⋀ front g1 t (self s2 ⊕ other s2) else (x == null ⋁ mark g2 x) ⋀ self s2 = self i).

Specification for span

front g1 t (self s2 ⊕ other s2)

Open world assumption (assuming other-interference)

slide-99
SLIDE 99

a b c e x d

Cancelling the interference

front g1 t (self s2 ⊕ other s2)

slide-100
SLIDE 100

a b c e x d

front g1 t (self s2 ⊕ other s2)

hide CSpanTree(h1) in { span(a) }

donated local heap

Cancelling the interference

no other threads at the end

slide-101
SLIDE 101

a x c e d

front g1 t (self s2)

hide CSpanTree(h1) in { span(a) }

Cancelling the interference

slide-102
SLIDE 102

a x c e d

tree g2 a t ⋀ maximal g2 t ⋀ is_root a g1 ⋀ subgraph g1 g2 ⋀ t = self s2 ⋀ front g1 t (self s2)

⇒ spanning t g1

Cancelling the interference

{

follow from postcondition
 and graph connectivity

slide-103
SLIDE 103
  • Subjectivity — reasoning with self and other
  • Histories — temporal specification via state
  • Deep Sharing

Key insights

slide-104
SLIDE 104
  • Subjectivity — reasoning with self and other
  • Histories — temporal specification via state
  • Deep Sharing — splitting auxiliary state

Key insights

slide-105
SLIDE 105

Bonus

slide-106
SLIDE 106

Composing programs and proofs

CAS-lock Ticketed lock Allocator Increment Abstract lock Treiber stack Producer/Consumer Sequential stack Flat combiner FC stack

slide-107
SLIDE 107

Composing programs and proofs

CAS-lock Ticketed lock Allocator Increment Abstract lock Treiber stack Producer/Consumer Sequential stack Flat combiner FC stack Abstract stack

//TODO

slide-108
SLIDE 108

Composing programs and proofs

CAS-lock Ticketed lock Allocator Increment Abstract lock Producer/ Consumer Sequential 
 stack Flat combiner FC stack Abstract stack Treiber stack Exchanger Counting network Quiescent
 client Quantitatively relaxed client Jayanti’s
 snapshot Snapshot client Atomic
 snapshot

non-linearizable data structures tricky linearizability argument

slide-109
SLIDE 109

To take away

Thanks!

  • Subjectivity: 


thread-modularity = reasoning in terms of self and other

  • Histories: capturing temporal aspects via auxiliary state
  • Deep Sharing: reasoning about ramified data

structures by splitting not real, but auxiliary state