Using abstract interpretation to correct synchronization faults - - PowerPoint PPT Presentation

using abstract interpretation to correct synchronization
SMART_READER_LITE
LIVE PREVIEW

Using abstract interpretation to correct synchronization faults - - PowerPoint PPT Presentation

Using abstract interpretation to correct synchronization faults Pietro Ferrara Omer Tripp Peng Liu Eric Koskinen JuliaSoft Google IBM Research Yale University VMCAI 17 January 2017 Concurrency is here to stay. Thread 1 Thread 2


slide-1
SLIDE 1

Using abstract interpretation to correct synchronization faults

Eric Koskinen

Yale University

VMCAI · 17 January 2017 Pietro Ferrara

JuliaSoft

Omer Tripp

Google

Peng Liu

IBM Research

slide-2
SLIDE 2

Concurrency is here to stay.

slide-3
SLIDE 3

Queue HashMap List

Thread 1 Thread n Thread 2

slide-4
SLIDE 4

updateReservation(Slot old_slot, Slot new_slot) : Reservation = { var r = map.remove(old_slot) // remove if exists if (r == null) { r = new Res() } val clobbered = map.replace(new_slot, r) return clobbered; }

Slot Res 10:00 α 11:00 β 12:00 γ 13:00 —

slide-5
SLIDE 5

updateReservation(Slot old_slot, Slot new_slot) : Reservation = { var r = map.remove(old_slot) // remove if exists if (r == null) { r = new Res() } val clobbered = map.replace(new_slot, r) return clobbered; }

Slot Res 10:00 α 11:00 β 12:00 γ 13:00 —

t1 t2

slide-6
SLIDE 6

updateReservation(Slot old_slot, Slot new_slot) : Reservation = { var r = map.remove(old_slot) // remove if exists if (r == null) { r = new Res() } val clobbered = map.replace(new_slot, r) return clobbered; }

t1: remove(10:00) / α t1: if (…) t1: replace(11:00) / δ t1: return δ t2: remove(13:00) / null t2: new Res() / δ t2: replace(11:00) / β t2: return β

Slot Res 10:00 α 11:00 β 12:00 γ 13:00 —

t1 t2

Not serializable! t1 goes first But returns δ ? t2 goes second Returns β ? Now: 11:00 —> α

slide-7
SLIDE 7

updateReservation(Slot old_slot, Slot new_slot) : Reservation = { var r = map.remove(old_slot) // remove if exists if (r == null) { r = new Res() } val clobbered = map.replace(new_slot, r) return clobbered; }

Slot Res 10:00 α 11:00 β 12:00 γ 13:00 —

t1 t2

Slot Res 10:00 — 11:00 α 12:00 γ 13:00 — Slot Res 10:00 — 11:00 δ 12:00 γ 13:00 —

Acceptable Final States: t1 first, returns β t2 second, returns α t2 first, returns β t1 second, returns δ

slide-8
SLIDE 8

updateReservation(Slot old_slot, Slot new_slot) : Reservation = { var r = map.remove(old_slot) // remove if exists if (r == null) { r = new Res() } val clobbered = map.replace(new_slot, r) return clobbered; }

Slot Res 10:00 α 11:00 β 12:00 γ 13:00 —

t1 t2 Existing approaches to enforcing serializability . . .

slide-9
SLIDE 9

t2: lock(13:00);

Pessimistic

updateReservation(Slot old_slot, Slot new_slot) : Reservation = { var r = map.remove(old_slot) // remove if exists if (r == null) { r = new Res() } val clobbered = map.replace(new_slot, r) return clobbered; }

Slot Res 10:00 α 11:00 β 12:00 γ 13:00 —

t1 t2

t1 t1

t1: remove(10:00) / α t1: if (…) t1: replace(11:00) / β t1: return β t1: lock(10:00); lock(11:00)

t2

slide-10
SLIDE 10

t2: lock(13:00); lock(11:00)

Pessimistic

updateReservation(Slot old_slot, Slot new_slot) : Reservation = { var r = map.remove(old_slot) // remove if exists if (r == null) { r = new Res() } val clobbered = map.replace(new_slot, r) return clobbered; }

Slot Res 10:00 α 11:00 β 12:00 γ 13:00 —

t1 t2

t1 t1

t1: remove(10:00) / α t1: if (…) t1: replace(11:00) / β t1: return β t1: lock(10:00); lock(11:00)

t2

slide-11
SLIDE 11

get$ if(…)$ new$ putIfAbsent$ return$ get$ if(…)$ new$ putIfAbsent$ return$

pessimis,c%

t1% t2%

updateReservation(Slot old_slot, Slot new_slot) : Reservation = { var r = map.remove(old_slot) // remove if exists if (r == null) { r = new Res() } val clobbered = map.replace(new_slot, r) return clobbered; }

Pessimistic

remove if replace remove new replace

slide-12
SLIDE 12

Optimistic

t1: remove(10:00) / α t1: if (…) t1: replace(11:00) / β t1: return β t2: remove(13:00) / null t2: new Res() / δ t2: replace(11:00) / β t2: return β

updateReservation(Slot old_slot, Slot new_slot) : Reservation = { var r = map.remove(old_slot) // remove if exists if (r == null) { r = new Res() } val clobbered = map.replace(new_slot, r) return clobbered; }

slide-13
SLIDE 13

Optimistic

t1: remove(10:00) / α t1: if (…) t1: replace(11:00) / β t1: return β t2: remove(13:00) / null t2: new Res() / δ t2: replace(11:00) / β t2: return β

conflict.

updateReservation(Slot old_slot, Slot new_slot) : Reservation = { var r = map.remove(old_slot) // remove if exists if (r == null) { r = new Res() } val clobbered = map.replace(new_slot, r) return clobbered; }

slide-14
SLIDE 14

get$ if(…)$ new$ putIfAbsent$ return$ get$ if(…)$ new$ putIfAbsent$ return$

pessimis,c%

t1% t2%

updateReservation(Slot old_slot, Slot new_slot) : Reservation = { var r = map.remove(old_slot) // remove if exists if (r == null) { r = new Res() } val clobbered = map.replace(new_slot, r) return clobbered; }

Optimistic

remove if replace remove new replace

get$ if(…)$ new$ putIfAbsent$ return$ get$ if(…)$ new$ putIfAbsent$

retry%

  • p,mis,c%

get$ if(…)$ new$ putIfAbsent$ return$ t1% t2%

remove if replace remove new replace remove new replace

slide-15
SLIDE 15

updateReservation(Slot old_slot, Slot new_slot) : Reservation = { var r = map.remove(old_slot) // remove if exists if (r == null) { r = new Res() } val clobbered = map.replace(new_slot, r) return clobbered; }

Other options? Perform a correction!

slide-16
SLIDE 16

updateReservation(Slot old_slot, Slot new_slot) : Reservation = { var r = map.remove(old_slot) // remove if exists if (r == null) { r = new Res() } val clobbered = map.replace(new_slot, r) return clobbered; }

t1: remove(10:00) / α t1: if (…) t1: replace(11:00) / δ t1: return δ t2: remove(13:00) / null t2: new Res() / δ t2: replace(11:00) / β t2: return β

Slot Res 10:00 α 11:00 β 12:00 γ 13:00 —

t1 t2

Not serializable!

slide-17
SLIDE 17

updateReservation(Slot old_slot, Slot new_slot) : Reservation = { var r = map.remove(old_slot) // remove if exists if (r == null) { r = new Res() } val clobbered = map.replace(new_slot, r) return clobbered; }

Slot Res 10:00 α 11:00 β 12:00 γ 13:00 —

t1 t2

slide-18
SLIDE 18

t1: replace(11:00) / δ t1: return δ

updateReservation(Slot old_slot, Slot new_slot) : Reservation = { var r = map.remove(old_slot) // remove if exists if (r == null) { r = new Res() } val clobbered = map.replace(new_slot, r) return clobbered; }

t1: remove(10:00) / α t1: if (…) t2: remove(13:00) / null t2: new Res() / δ t2: replace(11:00) / β t2: return β

Slot Res 10:00 — 11:00 β 12:00 γ 13:00 —

β β α α δ

Serializable Target

Slot Res 10:00 — 11:00

δ

12:00 γ 13:00 —

t1 first, returns β t2 second, returns α

slide-19
SLIDE 19

t1: replace(11:00) / δ t1: return δ

updateReservation(Slot old_slot, Slot new_slot) : Reservation = { var r = map.remove(old_slot) // remove if exists if (r == null) { r = new Res() } val clobbered = map.replace(new_slot, r) return clobbered; }

t1: remove(10:00) / α t1: if (…) t2: remove(13:00) / null t2: new Res() / δ t2: replace(11:00) / β t2: return β

Slot Res 10:00 — 11:00 β 12:00 γ 13:00 —

α

Serializable Target

Slot Res 10:00 — 11:00 α 12:00 γ 13:00 —

t2 first, returns β t1 second, returns δ

slide-20
SLIDE 20

get$ if(…)$ new$ putIfAbsent$ return$ get$ if(…)$ new$ putIfAbsent$ return$

pessimis,c%

t1% t2%

updateReservation(Slot old_slot, Slot new_slot) : Reservation = { var r = map.remove(old_slot) // remove if exists if (r == null) { r = new Res() } val clobbered = map.replace(new_slot, r) return clobbered; }

Corrective

remove if replace remove new replace

get$ if(…)$ new$ putIfAbsent$ return$ get$ if(…)$ new$ putIfAbsent$

retry%

  • p,mis,c%

get$ if(…)$ new$ putIfAbsent$ return$ t1% t2%

remove if replace remove new replace remove new replace

get$ if(…)$ new$ putIfAbsent$ return$

correct%

correc,ve%

get$ if(…)$ new$ putIfAbsent$ return$ t1% t2%

remove if replace remove new replace

slide-21
SLIDE 21

get$ if(…)$ new$ putIfAbsent$ return$

correct%

correc,ve%

get$ if(…)$ new$ putIfAbsent$ return$ t1% t2%

remove if replace remove new replace

Corrective

Challenges & Contributions

  • Is this serializable?


Yes, we have proved so.

  • How to compute each thread’s alternative post-

states?
 Via a static abstract interpretation.

  • Given an incorrect state, how to efficiently recover

to a correct post-state?
 Via a dynamic runtime system.

slide-22
SLIDE 22

get$ if(…)$ new$ putIfAbsent$ return$

correct%

correc,ve%

get$ if(…)$ new$ putIfAbsent$ return$ t1% t2%

remove if replace remove new replace

Corrective

Transition System

Formalization

slide-23
SLIDE 23

get$ if(…)$ new$ putIfAbsent$ return$

correct%

correc,ve%

get$ if(…)$ new$ putIfAbsent$ return$ t1% t2%

remove if replace remove new replace

Corrective

Formalization

Remember where we started

t

slide-24
SLIDE 24

get$ if(…)$ new$ putIfAbsent$ return$

correct%

correc,ve%

get$ if(…)$ new$ putIfAbsent$ return$ t1% t2%

remove if replace remove new replace

Corrective

Formalization

Act sort of optimistically: march ahead w local changes

,opt)

L t

'

Remember the operation that was performed

,Lt•opt)], σ, L)

slide-25
SLIDE 25

get$ if(…)$ new$ putIfAbsent$ return$

correct%

correc,ve%

get$ if(…)$ new$ putIfAbsent$ return$ t1% t2%

remove if replace remove new replace

Corrective

Formalization

Replay the mutations on the shared state Parameterize by property of interest (Serializability) L t

,opt) ,Lt•opt)], σ, L)

slide-26
SLIDE 26

get$ if(…)$ new$ putIfAbsent$ return$

correct%

correc,ve%

get$ if(…)$ new$ putIfAbsent$ return$ t1% t2%

remove if replace remove new replace

Corrective

Formalization

L t

,opt) ,Lt•opt)], σ, L)

slide-27
SLIDE 27

get$ if(…)$ new$ putIfAbsent$ return$

correct%

correc,ve%

get$ if(…)$ new$ putIfAbsent$ return$ t1% t2%

remove if replace remove new replace

Corrective

Formalization

Now let’s add correction . . .

slide-28
SLIDE 28

get$ if(…)$ new$ putIfAbsent$ return$

correct%

correc,ve%

get$ if(…)$ new$ putIfAbsent$ return$ t1% t2%

remove if replace remove new replace

Corrective

Γ,(t,s) ⊢ s ⟶* (T,μ’,σ,L) Γ,(t,s) ⊢ (T,μ,σ,L) ⟶ (T,μ[t ↦ μ’(t)],σ,L) corr t

Recall reference state s for txn t Txn t could have gone to some other μ’ Pretend that it did exactly that.

Formalization

slide-29
SLIDE 29

get$ if(…)$ new$ putIfAbsent$ return$

correct%

correc,ve%

get$ if(…)$ new$ putIfAbsent$ return$ t1% t2%

remove if replace remove new replace

Corrective

Let’s see these rules applied to the example . . .

slide-30
SLIDE 30

t1: replace(11:00) / δ t1: return δ

updateReservation(Slot old_slot, Slot new_slot) : Reservation = { var r = map.remove(old_slot) // remove if exists if (r == null) { r = new Res() } val clobbered = map.replace(new_slot, r) return clobbered; }

t1: remove(10:00) / α t1: if (…) t2: remove(13:00) / null t2: new Res() / δ t2: replace(11:00) / β t2: return β

Slot Res 10:00 — 11:00 β 12:00 γ 13:00 —

β

Serializable Target

Slot Res 10:00 — 11:00

δ

12:00 γ 13:00 —

t1 first, returns β t2 second, returns α

Rules

  • 1. Both run, performing local

β

slide-31
SLIDE 31

t1: replace(11:00) / δ t1: return δ

updateReservation(Slot old_slot, Slot new_slot) : Reservation = { var r = map.remove(old_slot) // remove if exists if (r == null) { r = new Res() } val clobbered = map.replace(new_slot, r) return clobbered; }

t1: remove(10:00) / α t1: if (…) t2: remove(13:00) / null t2: new Res() / δ t2: replace(11:00) / β t2: return β

Slot Res 10:00 — 11:00 β 12:00 γ 13:00 —

α

Serializable Target

Slot Res 10:00 — 11:00

δ

12:00 γ 13:00 —

t1 first, returns β t2 second, returns α

Rules

  • 1. Both run, performing local
  • 2. t1 wants to end:
  • a. t1 performs corr

β β

  • reference state (Γ): initial state
  • target state: where t1 acted alone
  • set 11:00 to α, return β
slide-32
SLIDE 32

t1: replace(11:00) / β t1: return β

updateReservation(Slot old_slot, Slot new_slot) : Reservation = { var r = map.remove(old_slot) // remove if exists if (r == null) { r = new Res() } val clobbered = map.replace(new_slot, r) return clobbered; }

t1: remove(10:00) / α t1: if (…) t2: remove(13:00) / null t2: new Res() / δ t2: replace(11:00) / β t2: return β

Slot Res 10:00 — 11:00 α 12:00 γ 13:00 —

Serializable Target

Slot Res 10:00 — 11:00

δ

12:00 γ 13:00 —

t1 first, returns β t2 second, returns α

Rules

  • 1. Both run, performing local
  • 2. t1 wants to end:
  • a. t1 performs corr
  • b. t1 performs cmt
  • Export the changes


to shared state

slide-33
SLIDE 33

t1: replace(11:00) / δ t1: return δ

updateReservation(Slot old_slot, Slot new_slot) : Reservation = { var r = map.remove(old_slot) // remove if exists if (r == null) { r = new Res() } val clobbered = map.replace(new_slot, r) return clobbered; }

t1: remove(10:00) / α t1: if (…) t2: remove(13:00) / null t2: new Res() / δ t2: replace(11:00) / β t2: return β

Slot Res 10:00 — 11:00 α 12:00 γ 13:00 —

β α α

Serializable Target

Slot Res 10:00 — 11:00

δ

12:00 γ 13:00 —

t1 first, returns β t2 second, returns α

Rules

  • 1. Both run, performing local
  • 2. t1 wants to end:
  • a. t1 performs corr
  • b. t1 performs cmt
  • 3. t2 performs corr

β δ

  • reference state (Γ): initial state
  • use serializable target
  • set 11:00 to δ, return α
slide-34
SLIDE 34

t1: replace(11:00) / δ t1: return δ

updateReservation(Slot old_slot, Slot new_slot) : Reservation = { var r = map.remove(old_slot) // remove if exists if (r == null) { r = new Res() } val clobbered = map.replace(new_slot, r) return clobbered; }

t1: remove(10:00) / α t1: if (…) t2: remove(13:00) / null t2: new Res() / δ t2: replace(11:00) / α t2: return α

Slot Res 10:00 — 11:00 δ 12:00 γ 13:00 —

β

Serializable Target

Slot Res 10:00 — 11:00

δ

12:00 γ 13:00 —

t1 first, returns β t2 second, returns α

Rules

  • 1. Both run, performing local
  • 2. t1 wants to end:
  • a. t1 performs corr
  • b. t1 performs cmt
  • 3. t2 performs corr
  • 4. t2 performs cmt

β

slide-35
SLIDE 35

get$ if(…)$ new$ putIfAbsent$ return$

correct%

correc,ve%

get$ if(…)$ new$ putIfAbsent$ return$ t1% t2%

remove if replace remove new replace

Corrective

Formalization

pessimism is like an almost trivial restriction in which conflicting executions never occur; no need to correct

  • ptimism permits only corrections back to

the initial state (abort)

slide-36
SLIDE 36

get$ if(…)$ new$ putIfAbsent$ return$

correct%

correc,ve%

get$ if(…)$ new$ putIfAbsent$ return$ t1% t2%

remove if replace remove new replace

Corrective

Computing Target States

  • Abstract Interpretation
  • Specialized abstract domain for Java maps
slide-37
SLIDE 37

get$ if(…)$ new$ putIfAbsent$ return$

correct%

correc,ve%

get$ if(…)$ new$ putIfAbsent$ return$ t1% t2%

remove if replace remove new replace

Corrective

Computing Target States

  • Abstract Interpretation
  • Specialized abstract domain for Java maps
slide-38
SLIDE 38

get$ if(…)$ new$ putIfAbsent$ return$

correct%

correc,ve%

get$ if(…)$ new$ putIfAbsent$ return$ t1% t2%

remove if replace remove new replace

Corrective

Computing Target States

  • Abstract Interpretation
  • Specialized abstract domain for Java maps
  • Computes an under-approximation of the serializable

intermedia (or final) states 
 (fixpoint over an inter-procedural cross-product CFG)

  • Target states are “progress-safe” (don’t get stuck after

correction)

slide-39
SLIDE 39

get$ if(…)$ new$ putIfAbsent$ return$

correct%

correc,ve%

get$ if(…)$ new$ putIfAbsent$ return$ t1% t2%

remove if replace remove new replace

Corrective

Computing Target States

  • Output: a relational corrective specification:
  • Maps pre-states to sets of post-states
  • e.g. [k → ⊥, x1 → v] {[k → v, x1 → v]}.



 If we started from a pre-state where k was not in the map and the argument was v,
 then in the post-state k is made to point to the value v pointed-to by the argument k in the pre-state.

slide-40
SLIDE 40

get$ if(…)$ new$ putIfAbsent$ return$

correct%

correc,ve%

get$ if(…)$ new$ putIfAbsent$ return$ t1% t2%

remove if replace remove new replace

Corrective

Using Target States

  • Dynamic runtime system
  • Consumes the relational corrective specification


(what operations to perform)

  • At commit time, detect conflict and perform correction
slide-41
SLIDE 41

get$ if(…)$ new$ putIfAbsent$ return$

correct%

correc,ve%

get$ if(…)$ new$ putIfAbsent$ return$ t1% t2%

remove if replace remove new replace

Corrective

Preliminary Implementation

  • Java static analysis (ainterp) for Map operations.
  • Builds a serialized CFG.
  • Computes a fixpoint over it.
  • Static analysis running times are negligible (<1s).
  • Limitation: prototype assumes all transactions start

simultaneously (e.g. loop parallelization)

slide-42
SLIDE 42

get$ if(…)$ new$ putIfAbsent$ return$

correct%

correc,ve%

get$ if(…)$ new$ putIfAbsent$ return$ t1% t2%

remove if replace remove new replace

Corrective

Evaluation

  • Apache Tomcat web-app container, ApplicationContext
  • dyuproject - Framework for development of Java web
  • applications. StandardConvertorCache (objects to/from

JSON)

  • Flexive - Content repository for development of web

apps FxValueRendererFactory (render transparently certain objects in a language)

  • Gridkit - In-memory data grids. ReflectionPofSerializer

(generic POF serialization via reflection)

slide-43
SLIDE 43

get$ if(…)$ new$ putIfAbsent$ return$

correct%

correc,ve%

get$ if(…)$ new$ putIfAbsent$ return$ t1% t2%

remove if replace remove new replace

Corrective

Evaluation

  • Relative gain of (boosting) STM and corrective synchronization


w.r.t. lock-based synchronization.

  • We aggregate performance results
  • On average, corrective synchronization leads to a gain


that is twice the one obtained by STM.

slide-44
SLIDE 44

get$ if(…)$ new$ putIfAbsent$ return$

correct%

correc,ve%

get$ if(…)$ new$ putIfAbsent$ return$ t1% t2%

remove if replace remove new replace

Corrective

Perf vs Workload Perf vs # of threads

slide-45
SLIDE 45

get$ if(…)$ new$ putIfAbsent$ return$

correct%

correc,ve%

get$ if(…)$ new$ putIfAbsent$ return$ t1% t2%

remove if replace remove new replace

Corrective

Open Questions

  • What are good abstract domains to use?
  • How does this work in more realistic systems?
  • When is it preferred over other options (pessimistic,
  • ptimistic, etc.)?
  • Adaptive approaches?
slide-46
SLIDE 46

Thank you! eric.koskinen@yale.edu