Review: Linearizability Defini3on Given some component C - - PowerPoint PPT Presentation

review linearizability defini3on
SMART_READER_LITE
LIVE PREVIEW

Review: Linearizability Defini3on Given some component C - - PowerPoint PPT Presentation

Review: Linearizability Defini3on Given some component C (say, a class) And some opera3ons O1, O2, .. (say, methods) An opera)on is linearizable


slide-1
SLIDE 1

Review: ¡Linearizability ¡

slide-2
SLIDE 2

Defini3on ¡

  • Given ¡some ¡component ¡C ¡(say, ¡a ¡class) ¡
  • And ¡some ¡opera3ons ¡O1, ¡O2, ¡.. ¡(say, ¡methods) ¡
  • An ¡opera)on ¡is ¡linearizable ¡if ¡it ¡always ¡appears ¡

to ¡take ¡effect ¡at ¡a ¡single ¡instant ¡of ¡)me ¡(called ¡ the ¡commit ¡point) ¡which ¡happens ¡some)me ¡ a<er ¡the ¡opera)on ¡is ¡called ¡and ¡before ¡it ¡

  • returns. ¡
  • Linearizable ¡opera3ons ¡are ¡some3mes ¡called ¡

atomic, ¡but ¡that ¡term ¡is ¡overused. ¡

slide-3
SLIDE 3

Example ¡1: ¡Stack ¡

  • The ¡following ¡history ¡is ¡linearizable. ¡

Thread ¡1 ¡ Push(10) ¡ TIME ¡ Push(20) ¡ Ok ¡ Ok ¡ Thread ¡2 ¡ TryPop ¡() ¡ 10 ¡ Thread ¡2 ¡ Fail ¡ TryPop() ¡

slide-4
SLIDE 4

Example ¡1: ¡Stack ¡

  • The ¡following ¡history ¡is ¡linearizable. ¡

Thread ¡1 ¡ Push(10) ¡ TIME ¡ Push(20) ¡ Ok ¡ Ok ¡ Thread ¡2 ¡ TryPop ¡() ¡ 10 ¡ Thread ¡2 ¡ TryPop() ¡ Fail ¡

slide-5
SLIDE 5

Example ¡2: ¡Stack ¡

  • The ¡following ¡history ¡is ¡not ¡linearizable. ¡

TIME ¡ Thread ¡1 ¡ Push(10) ¡ TryPop() ¡ 10 ¡ Ok ¡ Thread ¡2 ¡ TryPop ¡() ¡ Fail ¡ Push(10) ¡ Ok ¡

slide-6
SLIDE 6

Example ¡2: ¡Stack ¡

  • The ¡following ¡history ¡is ¡not ¡linearizable. ¡

TIME ¡ Thread ¡1 ¡ Push(10) ¡ TryPop() ¡ 10 ¡ Ok ¡ Thread ¡2 ¡ TryPop ¡() ¡ Fail ¡ Push(10) ¡ Ok ¡ At ¡this ¡point, ¡both ¡pushes ¡have ¡ ¡ taken ¡effect. ¡So ¡there ¡can ¡not ¡be ¡less ¡ Than ¡1 ¡element ¡in ¡the ¡stack. ¡

slide-7
SLIDE 7

Quick ¡Ques3on ¡

  • Q: ¡What ¡is ¡the ¡most ¡frequently ¡used ¡

linearizable ¡data ¡type? ¡

slide-8
SLIDE 8

Quick ¡Ques3on ¡

  • Q: ¡What ¡is ¡the ¡most ¡frequently ¡used ¡ ¡

linearizable ¡data ¡type? ¡

  • A: ¡an ¡atomic ¡register ¡(historic ¡name) ¡

Example: ¡ C ¡= ¡integer ¡ O ¡= ¡{ ¡int ¡get(), ¡ void ¡set(int ¡val), ¡ ¡ int ¡increment() ¡} ¡ Plain ¡fields ¡and ¡variables ¡are ¡ ¡ not ¡linearizable ¡by ¡default! ¡

integer ¡ variable ¡ get ¡ set ¡ increment ¡

slide-9
SLIDE 9

Atomic ¡Registers ¡in ¡C# ¡

  • Use ¡vola3le ¡declara3on, ¡e.g. ¡ ¡

¡ ¡ ¡ ¡volatile ¡int ¡x; ¡

– Lets ¡compiler ¡know ¡that ¡you ¡would ¡like ¡to ¡read ¡& ¡ write ¡this ¡field ¡atomically. ¡Important ¡to ¡avoid ¡memory ¡ model ¡issues. ¡ – Does ¡not ¡work ¡with ¡longs, ¡structs ¡

  • Use ¡“Interlocked” ¡opera3ons ¡if ¡you ¡need ¡an ¡

atomic ¡modifica3on ¡

– Interlocked.Increment, ¡Interlocked.Decrement, ¡ Interlocked.Add ¡ – Interlocked.CompareExchange, ¡Interlocked.Exchange ¡ – Interlocked.Read ¡(for ¡reading ¡64-­‑bit ¡longs) ¡

slide-10
SLIDE 10

Example: ¡Vola3le/Interlockeds ¡Can ¡ Replace ¡Locks ¡

class ¡MyCounter() ¡ { ¡ ¡ ¡ ¡ ¡Object ¡mylock ¡= ¡ ¡new ¡Object(); ¡ ¡ ¡ ¡ ¡int ¡balance; ¡ ¡ ¡ ¡ ¡public ¡void ¡Deposit(int ¡what) ¡ ¡ ¡ ¡ ¡ ¡{ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡lock(mylock) ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡balance ¡= ¡balance ¡+ ¡what; ¡ ¡ ¡ ¡ ¡ ¡} ¡ ¡ ¡ ¡ ¡ ¡public ¡int ¡GetBalance() ¡ ¡ ¡ ¡ ¡ ¡{ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡lock(mylock) ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡return ¡balance; ¡ ¡ ¡ ¡ ¡ ¡} ¡ ¡ ¡ ¡ ¡ ¡public ¡void ¡SetBalance(int ¡val) ¡ ¡ ¡ ¡ ¡ ¡{ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡lock(mylock) ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡balance ¡= ¡val; ¡ ¡ ¡ ¡ ¡ ¡} ¡ class ¡MyCounter() ¡ { ¡ ¡ ¡ ¡ ¡vola,le ¡int ¡balance; ¡ ¡ ¡ ¡ ¡public ¡void ¡Deposit(int ¡what) ¡ ¡ ¡ ¡ ¡{ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡Interlocked.Add(ref ¡balance, ¡what) ¡ ¡ ¡ ¡ ¡} ¡ ¡ ¡ ¡ ¡ ¡public ¡int ¡GetBalance() ¡ ¡ ¡ ¡ ¡ ¡{ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡return ¡balance; ¡/* ¡vola3le ¡read ¡*/ ¡ ¡ ¡ ¡ ¡ ¡} ¡ ¡ ¡ ¡ ¡ ¡public ¡int ¡GetBalance(int ¡val) ¡ ¡ ¡ ¡ ¡ ¡{ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡balance ¡= ¡val; ¡/* ¡vola3le ¡write ¡*/ ¡ ¡ ¡ ¡ ¡ ¡} ¡ } ¡

slide-11
SLIDE 11

The ¡Composi3on ¡Problem ¡

  • Atomic ¡Registers ¡& ¡Linearizable ¡Objects ¡are ¡

great ¡if ¡you ¡do ¡1 ¡thing ¡at ¡a ¡3me. ¡ ¡

  • What ¡if ¡you ¡need ¡to ¡do ¡more ¡than ¡one ¡thing ¡at ¡

a ¡3me? ¡

slide-12
SLIDE 12

Stack ¡Example ¡

Linearizable? ¡

void ¡Insert(x) ¡ { ¡ ¡ ¡stack.Push(x); ¡ ¡ ¡if(x.Important) ¡ ¡ ¡ ¡ ¡Interlocked.Increment(ref ¡count); ¡ } ¡ bool ¡Clear(x) ¡ { ¡ ¡ ¡if ¡(count ¡== ¡0) ¡ ¡ ¡{ ¡ ¡ ¡ ¡ ¡ ¡ ¡stack.Clear(); ¡ ¡ ¡ ¡ ¡ ¡return ¡true; ¡ ¡ ¡} ¡ ¡ ¡else ¡ ¡ ¡{ ¡ ¡ ¡ ¡ ¡ ¡return ¡false; ¡ ¡ ¡} ¡ } ¡ class ¡SpecialStack ¡ { ¡ ¡ ¡LinearizableStack<Elt> ¡stack; ¡ ¡ ¡ ¡volatile ¡int ¡count; ¡ ¡// ¡counts ¡number ¡of ¡important ¡elts ¡in ¡stack ¡ } ¡

slide-13
SLIDE 13

Not ¡linearizable. ¡

void ¡Insert(x) ¡ { ¡ ¡ ¡stack.Push(x); ¡ ¡ ¡if(x.Important) ¡ ¡ ¡ ¡ ¡Interlocked.Increment(ref ¡count); ¡ } ¡ bool ¡Clear(x) ¡ { ¡ ¡ ¡if ¡(count ¡== ¡0) ¡ ¡ ¡{ ¡ ¡ ¡ ¡ ¡ ¡ ¡stack.Clear(); ¡ ¡ ¡ ¡ ¡ ¡return ¡true; ¡ ¡ ¡} ¡ ¡ ¡else ¡ ¡ ¡{ ¡ ¡ ¡ ¡ ¡ ¡return ¡false; ¡ ¡ ¡} ¡ } ¡ Thread ¡1 ¡ Insert(x) ¡ Ok ¡ Thread ¡2 ¡ Clear(10) ¡ Ok ¡ Stack.Push ¡(x) ¡ Interlocked.Increment ¡ get ¡count ¡ stack.Clear() ¡

Final ¡state: ¡stack ¡empty, ¡count=1 ¡

slide-14
SLIDE 14

Why ¡so ¡complicated? ¡Just ¡use ¡a ¡lock. ¡ Linearizability ¡Restored. ¡

void ¡Insert(x) ¡ ¡ { ¡ ¡ ¡ ¡lock(this) ¡ ¡ ¡ ¡{ ¡ ¡ ¡ ¡ ¡ ¡if(x.Important) ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡count++; ¡ ¡ ¡ ¡ ¡ ¡stack.Push(x); ¡ ¡ ¡ ¡} ¡ } ¡ bool ¡Clear(x) ¡ { ¡ ¡ ¡lock(this) ¡ ¡ ¡{ ¡ ¡ ¡ ¡ ¡if ¡(count ¡== ¡0) ¡ ¡ ¡ ¡ ¡{ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡stack.Clear(); ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡return ¡true; ¡ ¡ ¡ ¡ ¡} ¡ ¡ ¡ ¡ ¡else ¡ ¡ ¡ ¡ ¡{ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡return ¡false; ¡ ¡ ¡ ¡ ¡} ¡ ¡ ¡} ¡ } ¡ class ¡SpecialStack ¡ { ¡ ¡ ¡Stack<Elt> ¡stack; ¡ ¡ ¡ ¡int ¡count; ¡ } ¡

slide-15
SLIDE 15

Transac3ons ¡& ¡ ¡ Concurrency ¡Control ¡

Unit ¡8.c ¡

Prac3cal ¡Parallel ¡and ¡Concurrent ¡ Programming ¡DRAFT: ¡comments ¡to ¡ msrpcpcp@microson.com ¡ ¡ ¡ 1 ¡ 8/17/2010 ¡

slide-16
SLIDE 16

Acknowledgments ¡

  • Authored ¡by ¡

– ¡Sebas3an ¡Burckhardt, ¡MSR ¡Redmond ¡

5/3/11 ¡ Prac3cal ¡Parallel ¡and ¡Concurrent ¡ Programming ¡DRAFT: ¡comments ¡to ¡ msrpcpcp@microson.com ¡ ¡ 16 ¡

slide-17
SLIDE 17

Transac3ons ¡

  • Clients ¡vs. ¡Data ¡

– Clients ¡are ¡concurrent ¡ (e.g. ¡threads, ¡processes, ¡computers) ¡ – Data ¡may ¡be ¡spread ¡out ¡ (e.g. ¡across ¡processes, ¡files, ¡servers) ¡

  • Clients ¡perform ¡transac3ons ¡

– bounded ¡sequence ¡of ¡opera3ons ¡

READ(location), ¡WRITE(location, ¡value) ¡

– May ¡include ¡data-­‑dependent ¡branching ¡or ¡ looping ¡ – May ¡have ¡real-­‑world ¡significance, ¡e.g. ¡ represent ¡a ¡purchase ¡or ¡a ¡reserva3on ¡ – What ¡could ¡possibly ¡go ¡wrong? ¡

Data ¡2 ¡ Data ¡1 ¡

slide-18
SLIDE 18

Example ¡1: ¡Bank ¡Accounts ¡

  • If ¡interleaved, ¡may ¡present ¡incorrect ¡total ¡balance. ¡

BEGIN_TRANSACTION ¡ int ¡x ¡= ¡READ(account1); ¡ int ¡y ¡= ¡READ(account2); ¡ Print(“total=“, ¡x+y); ¡ COMMIT ¡ BEGIN_TRANSACTION ¡ int ¡x ¡= ¡READ(account1); ¡ if ¡(x ¡>= ¡100) ¡ { ¡ ¡ ¡ ¡ ¡WRITE(account1, ¡x-­‑100); ¡ ¡ ¡ ¡ ¡int ¡y ¡= ¡READ(account2); ¡ ¡ ¡ ¡ ¡WRITE(account2, ¡y+100); ¡ } ¡ COMMIT ¡

Balance ¡Inquiry ¡ Transfer ¡100 ¡from ¡ ¡ account1 ¡to ¡account2 ¡

slide-19
SLIDE 19

Example ¡2: ¡Bank ¡Accounts ¡

  • If ¡interleaved, ¡may ¡lose ¡or ¡create ¡money. ¡

BEGIN_TRANSACTION ¡ int ¡x ¡= ¡READ(account1); ¡ if ¡(x ¡>= ¡100) ¡ { ¡ ¡ ¡ ¡ ¡WRITE(account1, ¡x-­‑100); ¡ ¡ ¡ ¡ ¡int ¡y ¡= ¡READ(account2); ¡ ¡ ¡ ¡ ¡WRITE(account2, ¡y+100); ¡ } ¡ COMMIT ¡

Transfer ¡100 ¡from ¡ ¡ account1 ¡to ¡account2 ¡

BEGIN_TRANSACTION ¡ int ¡x ¡= ¡READ(account1); ¡ if ¡(x ¡>= ¡100) ¡ { ¡ ¡ ¡ ¡ ¡WRITE(account1, ¡x-­‑100); ¡ ¡ ¡ ¡ ¡int ¡y ¡= ¡READ(account2); ¡ ¡ ¡ ¡ ¡WRITE(account2, ¡y+100); ¡ } ¡ COMMIT ¡

Transfer ¡100 ¡from ¡ ¡ account1 ¡to ¡account2 ¡

slide-20
SLIDE 20

Atomicity ¡Consistency ¡Isola3on ¡Durability ¡ ¡

  • ACID ¡proper3es ¡represent ¡some ¡

common ¡expecta3ons ¡on ¡behavior ¡of ¡a ¡ transac3on ¡processing ¡system. ¡

  • Databases ¡implement ¡basic ¡ACID ¡
  • ACID ¡is ¡not ¡a ¡completely ¡precise ¡defini3on, ¡ ¡

but ¡good ¡to ¡know ¡for ¡reference. ¡ ¡

slide-21
SLIDE 21

Transac,on ¡ ¡ State ¡

Transac3on ¡States ¡

  • Client ¡program ¡starts ¡and ¡ends ¡transac3ons. ¡
  • Start ¡transac3on ¡

– Begins ¡in ¡state ¡Running ¡ – Can ¡read ¡and ¡modify ¡data ¡

  • End ¡transac3on ¡

– Move ¡to ¡state ¡Complete ¡ – System ¡determines ¡ ¡ whether ¡transac3on ¡ commits ¡or ¡fails ¡

Running ¡ Complete ¡ Failed ¡ Commired ¡

slide-22
SLIDE 22

Atomicity: ¡All-­‑or-­‑nothing ¡

  • All ¡changes ¡by ¡a ¡commired ¡transac3on ¡take ¡effect ¡
  • No ¡changes ¡by ¡a ¡failed ¡transac3on ¡take ¡effect ¡
  • (Note: ¡the ¡atomicity ¡property ¡refers ¡to ¡Complete ¡

transac3ons ¡only, ¡not ¡Running ¡transac3ons) ¡

Transac,on ¡ ¡ State ¡ Running ¡ Complete ¡ Failed ¡ Commired ¡

slide-23
SLIDE 23

Consistency ¡

  • If ¡a ¡transac3on ¡starts ¡in ¡a ¡consistent ¡state, ¡then ¡

it ¡ends ¡in ¡a ¡consistent ¡state ¡

  • How ¡do ¡we ¡define ¡“consistent” ¡? ¡ ¡

– (A) ¡“sa3sfies ¡specific ¡consistency ¡proper3es” ¡

  • such ¡as ¡declared ¡by ¡a ¡database ¡schema ¡
  • such ¡as ¡general ¡sanity ¡condi3ons, ¡e.g. ¡no ¡dangling ¡pointers ¡ ¡

– (B) ¡“sa3sfies ¡design ¡invariants ¡required ¡for ¡correct ¡program ¡func3on” ¡

  • those ¡are ¡not ¡usually ¡documented ¡or ¡even ¡known ¡
  • Databases ¡use ¡defini3on ¡(A) ¡

– Database ¡must ¡abort ¡transac3ons ¡that ¡violate ¡consistency ¡

slide-24
SLIDE 24

Isola3on ¡

  • A ¡transac3on ¡may ¡not ¡observe ¡changes ¡made ¡

by ¡another ¡running ¡transac3on. ¡

  • That ¡is, ¡changes ¡by ¡a ¡transac3on ¡A ¡are ¡not ¡

visible ¡to ¡a ¡transac3on ¡B ¡before ¡A ¡commits. ¡

Transac,on ¡ ¡ State ¡ Running ¡ Complete ¡ Failed ¡ Commired ¡

slide-25
SLIDE 25

Durability ¡

  • Once ¡commired, ¡the ¡effects ¡of ¡a ¡transac3on ¡are ¡

permanent ¡even ¡if ¡system ¡failures ¡occur. ¡

  • For ¡some ¡defini3on ¡of ¡‘system ¡failure’. ¡

– For ¡example, ¡power ¡outage. ¡

  • Database ¡systems ¡use ¡disk-­‑logs ¡to ¡guarantee ¡this. ¡

Transac,on ¡ ¡ State ¡ Running ¡ Complete ¡ Failed ¡ Commired ¡

slide-26
SLIDE 26

How ¡strong ¡is ¡ACID? ¡

  • Not ¡as ¡strong ¡as ¡you ¡may ¡think. ¡
  • A+C+I ¡does ¡not ¡add ¡up ¡to ¡linearizability. ¡
  • Linearizability ¡Defini3on: ¡ ¡

Successful ¡transac)ons ¡appear ¡to ¡execute ¡without ¡ interrup)on, ¡at ¡a ¡single ¡instant ¡of ¡)me ¡(called ¡the ¡ commit ¡point) ¡which ¡happens ¡some)me ¡a<er ¡the ¡ transac)on ¡starts ¡and ¡before ¡it ¡ends. ¡

  • Why ¡is ¡A+C+I ¡not ¡enough? ¡
slide-27
SLIDE 27

Non-­‑Repeatable ¡Read ¡

  • Second ¡read ¡of ¡x ¡may ¡return ¡different ¡value ¡than ¡first. ¡
  • This ¡execu3on ¡is ¡not ¡linearizable, ¡but ¡sa3sfies ¡ACID ¡! ¡

– Not ¡equivalent ¡to ¡any ¡sequen3al ¡execu3on ¡of ¡the ¡commired ¡transac3ons ¡ – But ¡Isola3on ¡is ¡sa3sfied: ¡reads ¡see ¡effects ¡of ¡commired ¡transac3ons ¡only ¡

  • Problem: ¡the ¡defini3on ¡of ¡ ¡I ¡in ¡ACID ¡is ¡too ¡weak… ¡we ¡should ¡

consider ¡alterna3ves. ¡

BEGIN_TRANSACTION ¡ int ¡r1 ¡= ¡READ(x); ¡ int ¡r2 ¡= ¡READ(x); ¡ COMMIT ¡ BEGIN_TRANSACTION ¡ WRITE(x,10) ¡ COMMIT ¡

slide-28
SLIDE 28

Isola3on ¡Levels ¡

Some ¡Isola3on ¡Levels ¡offered ¡by ¡commercial ¡DB ¡systems: ¡

  • READ_UNCOMMITTED ¡

¡(no ¡isola3on) ¡

– Can ¡see ¡changes ¡of ¡other ¡running ¡transac3ons ¡

  • READ_COMMITTED

¡ ¡(weak ¡isola3on) ¡

– Can ¡only ¡see ¡changes ¡of ¡commired ¡transac3ons ¡

  • SNAPSHOT

¡ ¡ ¡(strong ¡isola3on) ¡

– Work ¡on ¡isolated ¡copy, ¡then ¡check ¡for ¡write ¡conflicts ¡at ¡end ¡

  • SERIALIZABLE

¡ ¡ ¡(more ¡than ¡isola3on) ¡

– Prery ¡much ¡the ¡same ¡as ¡linearizability ¡ (technically, ¡serializable ¡is ¡slightly ¡weaker ¡as ¡commit ¡points ¡ may ¡be ¡outside ¡the ¡transac3on ¡range) ¡

slide-29
SLIDE 29

TRANSACTIONS ¡AND ¡ TRANSACTIONAL ¡MEMORY ¡

slide-30
SLIDE 30

Using ¡Transac3ons ¡

  • Consider ¡more ¡specific ¡situa3on ¡

– Single ¡mul3-­‑processor ¡machine ¡ – Many ¡threads ¡opera3ng ¡on ¡shared ¡data ¡ – Threads ¡want ¡to ¡perform ¡linearizable ¡transac3ons ¡

  • Can ¡we ¡use ¡a ¡DB ¡to ¡do ¡the ¡work ¡for ¡us? ¡

– Yes, ¡if ¡it ¡performs ¡well ¡enough ¡and ¡isn’t ¡too ¡

  • expensive. ¡
  • But ¡how ¡could ¡we ¡do ¡it ¡from ¡scratch? ¡
slide-31
SLIDE 31

Sonware ¡Transac3onal ¡Memory ¡(STM) ¡

  • Sonware ¡Transac3ons ¡are ¡the ¡“universal ¡

linearizable ¡datatype” ¡– ¡they ¡assume ¡no ¡ par3cular ¡data ¡structure, ¡nor ¡a ¡par3cular ¡ access ¡parern. ¡

  • STMs ¡not ¡actually ¡common ¡in ¡prac3ce. ¡

– Despite ¡loads ¡of ¡research ¡

  • But: ¡Understanding ¡STM ¡is ¡an ¡excellent ¡

exercise ¡for ¡building ¡linearizable ¡components. ¡

slide-32
SLIDE 32

Outline ¡

  • Let’s ¡build ¡a ¡simple ¡but ¡fully ¡func3onal ¡STM ¡ ¡

– (full ¡code ¡on ¡codeplex) ¡

  • Several ¡steps: ¡

– Define ¡a ¡transac3on ¡API ¡ – Build ¡a ¡wrong ¡implementa3on ¡ – Build ¡a ¡lock-­‑based ¡pessimis3c ¡implementa3on ¡ (2-­‑phase ¡locking) ¡ – Build ¡a ¡simple ¡op3mis3c ¡implementa3on ¡ (speculate ¡on ¡absence ¡of ¡conflicts) ¡

slide-33
SLIDE 33

Simple ¡Transac3on ¡API ¡

public ¡class ¡TransactionProcessor ¡ { ¡ ¡ ¡ ¡ ¡// ¡start ¡a ¡new ¡transaction ¡ ¡ ¡ ¡ ¡public ¡Transaction ¡StartTransaction() ¡{ ¡… ¡} ¡ } ¡ public ¡class ¡Transaction ¡ { ¡ ¡ ¡ ¡ ¡// ¡read ¡from ¡the ¡given ¡location ¡ ¡ ¡ ¡ ¡int ¡ReadLocation(Location ¡l) ¡{ ¡… ¡} ¡ ¡ ¡ ¡ ¡// ¡write ¡to ¡the ¡given ¡location ¡ ¡ ¡ ¡ ¡ ¡void ¡WriteLocation(Location ¡l, ¡int ¡value) ¡{ ¡… ¡} ¡ ¡ ¡ ¡ ¡// ¡try ¡to ¡commit ¡transaction ¡ ¡ ¡ ¡ ¡void ¡Commit() ¡{ ¡… ¡} ¡ ¡ ¡ ¡ ¡// ¡abort ¡this ¡transaction ¡ ¡ ¡ ¡ ¡void ¡Abort() ¡{ ¡… ¡} ¡ } ¡ // ¡thrown ¡by ¡{ ¡ReadLocation, ¡WriteLocation, ¡Commit ¡} ¡ public ¡class ¡TransactionFailedException ¡: ¡Exception ¡{ ¡ ¡… ¡} ¡

slide-34
SLIDE 34

How ¡to ¡use ¡API ¡

Transaction ¡t ¡= ¡p.StartTransaction(); ¡ try ¡ { ¡ ¡ ¡ ¡int ¡x ¡= ¡t.ReadLocation(acc1); ¡ ¡ ¡ ¡if ¡(x ¡>= ¡100) ¡ ¡ ¡ ¡{ ¡ ¡ ¡ ¡ ¡ ¡ ¡t.WriteLocation(acc1, ¡x ¡-­‑ ¡100); ¡ ¡ ¡ ¡ ¡ ¡ ¡int ¡y ¡= ¡t.ReadLocation(acc2); ¡ ¡ ¡ ¡ ¡ ¡ ¡t.WriteLocation(acc2, ¡y ¡+ ¡100); ¡ ¡ ¡ ¡} ¡ ¡ ¡ ¡t.Commit(); ¡ } ¡ catch ¡(TransactionFailedException) ¡ { ¡ ¡ ¡ ¡… ¡ } ¡ BEGIN_TRANSACTION ¡ int ¡x ¡= ¡READ(acc1); ¡ if ¡(x ¡>= ¡100) ¡ { ¡ ¡ ¡ ¡ ¡WRITE(acc1, ¡x-­‑100); ¡ ¡ ¡ ¡ ¡int ¡y ¡= ¡READ(acc2); ¡ ¡ ¡ ¡ ¡WRITE(acc2, ¡y+100); ¡ } ¡ COMMIT ¡

Transfer ¡100 ¡from ¡ ¡ acc1 ¡to ¡acc2 ¡

slide-35
SLIDE 35

Conflicts ¡& ¡Concurrency ¡

  • Classify ¡conflicts ¡

– Read-­‑Write ¡conflict ¡ Transac3on ¡A ¡writes ¡to ¡the ¡same ¡loca3on ¡that ¡ Transac3on ¡B ¡reads ¡from. ¡ – Write-­‑Write ¡conflict ¡ Transac3on ¡A ¡and ¡B ¡both ¡write ¡to ¡the ¡same ¡loca3on. ¡

  • Transac3ons ¡without ¡conflicts ¡can ¡execute ¡

concurrently ¡(at ¡least ¡in ¡principle) ¡

  • Transac3ons ¡with ¡conflicts ¡need ¡more ¡cau3on ¡
  • Don’t ¡know ¡in ¡advance ¡if ¡transac)ons ¡conflict! ¡

– Can ¡use ¡locks ¡to ¡order ¡conflicts. ¡

slide-36
SLIDE 36

1st ¡Implementa3on: ¡ ¡ “Pessimis3c” ¡Concurrency ¡Control ¡

  • Protect ¡loca3ons ¡using ¡locks ¡

– One ¡lock ¡per ¡loca3on, ¡or ¡ – One ¡lock ¡for ¡all ¡loca3ons, ¡or ¡ ¡ – One ¡lock ¡for ¡a ¡group ¡of ¡loca3ons ¡

  • Ensure ¡you ¡hold ¡lock ¡while ¡reading ¡or ¡wri3ng ¡a ¡
  • loca3on. ¡
  • Is ¡that ¡enough? ¡ ¡
slide-37
SLIDE 37

Naïve ¡implementa3on ¡(BROKEN) ¡

¡class ¡Transaction ¡ ¡{ ¡ ¡ ¡ ¡ ¡ ¡// ¡read ¡from ¡the ¡given ¡location ¡ ¡ ¡ ¡ ¡ ¡public ¡int ¡ReadLocation(Location ¡l) ¡ ¡ ¡ ¡ ¡ ¡{ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡lock ¡(l) ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡{ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡return ¡l.value; ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡} ¡ ¡ ¡ ¡ ¡ ¡ ¡} ¡ ¡ ¡ ¡ ¡ ¡// ¡write ¡to ¡the ¡given ¡location ¡ ¡ ¡ ¡ ¡ ¡public ¡void ¡WriteLocation(Location ¡l, ¡int ¡value) ¡ ¡ ¡ ¡ ¡ ¡{ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡lock ¡(l) ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡{ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡l.value ¡= ¡value; ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡} ¡ ¡ ¡ ¡ ¡ ¡} ¡ ¡ ¡ ¡ ¡ ¡// ¡try ¡to ¡commit ¡transaction ¡ ¡ ¡ ¡ ¡ ¡public ¡void ¡Commit() ¡ ¡ ¡ ¡ ¡ ¡{ ¡ ¡ ¡ ¡ ¡ ¡} ¡ } ¡

slide-38
SLIDE 38

Visualiza3on ¡of ¡Broken ¡Implementa3on ¡

  • Need ¡to ¡hold ¡locks ¡long ¡enough ¡to ¡guarantee ¡atomicity! ¡

Transac,on ¡2 ¡

BEGIN_TRANSACTION ¡ int ¡x ¡= ¡READ(acc); ¡ WRITE(acc, ¡x+100); ¡ COMMIT ¡

Transac,on ¡1 ¡

BEGIN_TRANSACTION ¡ int ¡x ¡= ¡READ(acc); ¡ WRITE(acc, ¡x+100); ¡ COMMIT ¡ T1 ¡ acc ¡ TIME ¡ T1 ¡ acc ¡

Blue ¡Segments: ¡ ¡ ¡ ¡Transac3ons ¡(begin/end) ¡ Orange ¡Segments: ¡ ¡ ¡ ¡Locks ¡(acquire/release) ¡

slide-39
SLIDE 39

2-­‑Phase ¡Locking ¡

  • All ¡loca3ons ¡are ¡protected ¡by ¡some ¡lock. ¡
  • Transac3ons ¡can ¡access ¡loca3ons ¡only ¡while ¡

holding ¡their ¡lock. ¡

  • Transac3ons ¡must ¡follow ¡2 ¡phases ¡

– Expanding ¡phase: ¡May ¡acquire ¡new ¡locks ¡but ¡not ¡ release ¡any ¡held ¡locks ¡ – Shrinking ¡phase: ¡May ¡release ¡held ¡locks ¡but ¡not ¡ acquire ¡any ¡new ¡locks ¡

  • Following ¡this ¡protocol ¡guarantees ¡linearizability! ¡

[Bernstein ¡et ¡al. ¡1987]. ¡

slide-40
SLIDE 40

2-­‑Phase ¡Locking ¡Illustra3on ¡

Time: ¡len ¡to ¡right ¡ Blue ¡Segments: ¡Transac3ons ¡(begin/end) ¡ Orange ¡Segments: ¡Locks ¡(acquire/release) ¡ Red ¡circles: ¡Commit ¡Points ¡

T1 ¡ T2 ¡ D ¡ D ¡ A ¡B ¡ C ¡ E ¡

  • Commits ¡while ¡holding ¡all ¡locks ¡of ¡all ¡accessed ¡loca3ons ¡
  • Therefore, ¡all ¡read ¡& ¡wriren ¡values ¡consistent ¡with ¡commit ¡order ¡
slide-41
SLIDE 41

Simple ¡2PL-­‑implementa3on ¡(1/2) ¡

¡class ¡Transaction ¡ ¡ ¡ ¡ ¡{ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡// ¡store ¡current ¡set ¡of ¡held ¡locks ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡HashSet<Location> ¡locks_held ¡= ¡new ¡HashSet<Location>(); ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡// ¡read ¡from ¡the ¡given ¡location ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡public ¡int ¡ReadLocation(Location ¡l) ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡{ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡if ¡(!locks_held.Contains(l)) ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡{ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡System.Threading.Monitor.Enter(l); ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡locks_held.Add(l); ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡} ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡return ¡l.value; ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡} ¡

slide-42
SLIDE 42

Simple ¡2PL-­‑implementa3on ¡(2/2) ¡

¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡// ¡write ¡to ¡the ¡given ¡location ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡public ¡void ¡WriteLocation(Location ¡l, ¡int ¡value) ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡{ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡if ¡(!locks_held.Contains(l)) ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡{ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡System.Threading.Monitor.Enter(l); ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡locks_held.Add(l); ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡} ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡l.value ¡= ¡value; ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡} ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡// ¡try ¡to ¡commit ¡transaction ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡public ¡void ¡Commit() ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡{ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡// ¡shrinking ¡phase… ¡release ¡all ¡the ¡locks ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡foreach ¡(Location ¡l ¡in ¡locks_held) ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡System.Threading.Monitor.Exit(l); ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡} ¡

slide-43
SLIDE 43

Simple ¡2PL-­‑implementa3on ¡BUSTED: ¡ Deadlock ¡Example ¡

BEGIN_TRANSACTION ¡ int ¡x ¡= ¡READ(account1); ¡ int ¡y ¡= ¡READ(account2); ¡ Print(“total=“, ¡x+y); ¡ COMMIT ¡

Balance ¡Inquiry ¡1 ¡

BEGIN_TRANSACTION ¡ int ¡y ¡= ¡READ(account2); ¡ int ¡x ¡= ¡READ(account1); ¡ Print(“total=“, ¡x+y); ¡ COMMIT ¡

Balance ¡Inquiry ¡2 ¡

Balance ¡Inquiry ¡1 ¡ acc1 ¡ (wai3ng ¡for ¡lock ¡on ¡acc2) ¡ Balance ¡Inquiry ¡2 ¡ acc2 ¡ (wai3ng ¡for ¡lock ¡on ¡acc1) ¡

slide-44
SLIDE 44

Simple ¡2PL-­‑implementa3on ¡FIXED ¡(1/2): ¡ Time ¡Out ¡and ¡Abort ¡

¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡const ¡int ¡LOCK_TIMEOUT_MILLISECONDS ¡= ¡…; ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡public ¡void ¡TryAcquire(Location ¡l) ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡{ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡if ¡(System.Threading.Monitor.TryEnter(l, ¡LOCK_TIMEOUT_MILLISECONDS)) ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡{ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡locks_held.Add(l); ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡} ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡else ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡{ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡Abort(); ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡throw ¡new ¡TransactionFailedException("lock ¡timed ¡out"); ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡} ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡} ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡public ¡void ¡Abort() ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡{ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡// ¡first, ¡restore ¡old ¡values ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡foreach ¡(KeyValuePair<Location, ¡int> ¡kvp ¡in ¡savedvalues) ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡kvp.Key.value ¡= ¡kvp.Value; ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡// ¡then, ¡release ¡all ¡the ¡locks ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡foreach ¡(Location ¡h ¡in ¡locks_held) ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡System.Threading.Monitor.Exit(h); ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡} ¡

slide-45
SLIDE 45

Simple ¡2PL-­‑implementa3on ¡FIXED ¡(2/2): ¡ Time ¡Out ¡and ¡Abort ¡

¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡// ¡store ¡overwritten ¡values ¡in ¡case ¡we ¡need ¡to ¡roll ¡back ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡Dictionary<Location, ¡int> ¡savedvalues ¡= ¡new ¡Dictionary<Location, ¡int>(); ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡// ¡write ¡to ¡the ¡given ¡location ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡public ¡void ¡WriteLocation(Location ¡l, ¡int ¡value) ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡{ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡if ¡(!locks_held.Contains(l)) ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡// ¡we ¡are ¡not ¡already ¡holding ¡a ¡lock ¡on ¡this.. ¡try ¡to ¡acquire ¡it ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡TryAcquire(l); ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡// ¡save ¡old ¡value ¡if ¡this ¡is ¡the ¡first ¡write ¡by ¡this ¡transaction ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡if ¡(!savedvalues.ContainsKey(l)) ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡savedvalues[l] ¡= ¡l.value; ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡l.value ¡= ¡value; ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡} ¡

slide-46
SLIDE 46

2PL ¡implementa3on ¡now ¡works. ¡

  • Linearizable ¡and ¡simple. ¡
  • Some ¡things ¡are ¡not ¡so ¡nice ¡though: ¡

– Does ¡not ¡allow ¡concurrent ¡reads. ¡ – May ¡keep ¡loca3ons ¡locked ¡for ¡a ¡prery ¡long ¡3me. ¡ ¡

  • Can ¡we ¡write ¡an ¡implementa3on ¡with ¡less ¡

locking ¡and ¡more ¡concurrency? ¡

slide-47
SLIDE 47

Op3mism ¡vs. ¡Pessimism ¡

slide-48
SLIDE 48

Suppose ¡conflicts ¡are ¡rare. ¡

  • For ¡many ¡workloads, ¡most ¡writes ¡go ¡to ¡loca3ons ¡

that ¡are ¡not ¡at ¡the ¡same ¡3me ¡being ¡read ¡or ¡ wriren ¡by ¡another ¡transac3on. ¡ ¡

  • We ¡can ¡use ¡specula)on: ¡Execute ¡transac3on ¡
  • p3mis3cally ¡(i.e. ¡elide ¡locking ¡and ¡hope ¡there ¡

are ¡no ¡conflicts), ¡keeping ¡changes ¡in ¡a ¡‘sandbox’ ¡ ¡

  • If ¡specula3on ¡fails, ¡abort ¡transac3on ¡and ¡discard ¡
  • changes. ¡Otherwise, ¡make ¡changes ¡permanent. ¡
slide-49
SLIDE 49

Simple ¡op3mis3c ¡implementa3on ¡(1/4) ¡

¡class ¡Transaction ¡ ¡{ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡// ¡temporary ¡data ¡for ¡transaction. ¡For ¡each ¡location ¡accessed: ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡// ¡-­‑ ¡stores ¡first ¡value ¡read ¡if ¡first ¡access ¡was ¡a ¡read ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡// ¡-­‑ ¡stores ¡last ¡value ¡written ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡SortedDictionary<Location, ¡Entry> ¡scratch ¡= ¡new ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡SortedDictionary<Location,Entry>(); ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡class ¡Entry ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡{ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡// ¡has ¡this ¡transaction ¡written ¡to ¡this ¡location? ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡// ¡if ¡yes, ¡what ¡was ¡the ¡last ¡value ¡written? ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡public ¡bool ¡written; ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡public ¡int ¡last_value_written; ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡// ¡was ¡the ¡first ¡access ¡by ¡this ¡transaction ¡a ¡read? ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡// ¡if ¡yes, ¡what ¡value ¡was ¡read? ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡public ¡bool ¡first_access_was_read; ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡public ¡int ¡value_read; ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡} ¡

slide-50
SLIDE 50

¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡// ¡read ¡from ¡the ¡given ¡location ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡public ¡int ¡ReadLocation(Location ¡l) ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡{ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡Entry ¡s; ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡// ¡if ¡this ¡location ¡is ¡not ¡in ¡scratch, ¡put ¡it ¡there. ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡if ¡(! ¡scratch.TryGetValue(l, ¡out ¡s)) ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡{ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡s ¡= ¡new ¡Entry(); ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡s.first_access_was_read ¡= ¡true; ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡s.value_read ¡= ¡l.value; ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡scratch[l] ¡= ¡s; ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡} ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡return ¡(s.written ¡? ¡s.last_value_written ¡: ¡s.value_read); ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡} ¡

Simple ¡op3mis3c ¡implementa3on ¡(2/4) ¡

class ¡Entry ¡ { ¡ ¡ ¡ ¡// ¡has ¡this ¡transaction ¡written ¡to ¡this ¡location? ¡ ¡ ¡ ¡// ¡if ¡yes, ¡what ¡was ¡the ¡last ¡value ¡written? ¡ ¡ ¡ ¡public ¡bool ¡written; ¡ ¡ ¡ ¡public ¡int ¡last_value_written; ¡ ¡ ¡ ¡// ¡was ¡the ¡first ¡access ¡by ¡this ¡transaction ¡a ¡read? ¡ ¡ ¡ ¡ ¡// ¡if ¡yes, ¡what ¡value ¡was ¡read? ¡ ¡ ¡ ¡public ¡bool ¡first_access_was_read; ¡ ¡ ¡ ¡public ¡int ¡value_read; ¡ } ¡

Reads ¡vola3le ¡field ¡without ¡lock ¡

slide-51
SLIDE 51

¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡// ¡write ¡to ¡the ¡given ¡location ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡public ¡void ¡WriteLocation(Location ¡l, ¡int ¡value) ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡{ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡Entry ¡s; ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡// ¡if ¡this ¡location ¡is ¡not ¡in ¡scratch, ¡put ¡it ¡there. ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡if ¡(!scratch.TryGetValue(l, ¡out ¡s)) ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡{ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡s ¡= ¡new ¡Entry(); ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡s.first_access_was_read ¡= ¡false; ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡scratch[l] ¡= ¡s; ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡} ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡s.last_value_written ¡= ¡value; ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡s.written ¡= ¡true; ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡} ¡

Simple ¡op3mis3c ¡implementa3on ¡(3/4) ¡

class ¡Entry ¡ { ¡ ¡ ¡ ¡// ¡has ¡this ¡transaction ¡written ¡to ¡this ¡location? ¡ ¡ ¡ ¡// ¡if ¡yes, ¡what ¡was ¡the ¡last ¡value ¡written? ¡ ¡ ¡ ¡public ¡bool ¡written; ¡ ¡ ¡ ¡public ¡int ¡last_value_written; ¡ ¡ ¡ ¡// ¡was ¡the ¡first ¡access ¡by ¡this ¡transaction ¡a ¡read? ¡ ¡ ¡ ¡ ¡// ¡if ¡yes, ¡what ¡value ¡was ¡read? ¡ ¡ ¡ ¡public ¡bool ¡first_access_was_read; ¡ ¡ ¡ ¡public ¡int ¡value_read; ¡ } ¡

Writes ¡value ¡to ¡temp ¡storage ¡only, ¡ without ¡lock ¡

slide-52
SLIDE 52

Simple ¡op3mis3c ¡implementa3on ¡(4/4) ¡

¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡// ¡try ¡to ¡commit ¡transaction ¡using ¡2-­‑phase ¡locking. ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡public ¡void ¡Commit() ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡{ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡bool ¡failed ¡= ¡false; ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡// ¡phase ¡1 ¡(expanding) ¡grab ¡all ¡locks, ¡and ¡validate ¡reads ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡foreach ¡(KeyValuePair<Location, ¡Entry> ¡kvp ¡in ¡scratch) ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡{ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡// ¡acquire ¡lock ¡(no ¡deadlock ¡since ¡ordering ¡is ¡respected) ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡System.Threading.Monitor.Enter(kvp.Key); ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡// ¡if ¡this ¡location ¡was ¡read, ¡check ¡if ¡value ¡would ¡read ¡the ¡same ¡right ¡now ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡if ¡(kvp.Value.first_access_was_read ¡&& ¡kvp.Value.value_read ¡!= ¡kvp.Key.value) ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡failed ¡= ¡true; ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡} ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡// ¡phase ¡2 ¡(shrinking) ¡release ¡all ¡locks, ¡and ¡make ¡writes ¡permanent ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡foreach ¡(KeyValuePair<Location, ¡Entry> ¡kvp ¡in ¡scratch) ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡{ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡// ¡if ¡this ¡transaction ¡is ¡successful, ¡write ¡back ¡the ¡last ¡value ¡written ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡if ¡(!failed ¡&& ¡kvp.Value.written) ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡kvp.Key.value ¡= ¡kvp.Value.last_value_written; ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡// ¡release ¡lock ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡System.Threading.Monitor.Exit(kvp.Key); ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡} ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡if ¡(failed) ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡throw ¡new ¡TransactionFailedException("optimism ¡failure ¡-­‑ ¡read ¡value ¡changed"); ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡} ¡

slide-53
SLIDE 53

Illustra3on ¡

Blue ¡Segments: ¡Transac3ons ¡(begin/end) ¡ Orange ¡Segments: ¡Locks ¡(acquire/release) ¡ Orange ¡Dots: ¡Vola3le ¡Loads ¡ Red ¡circles: ¡Commit ¡Points ¡ T1 ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡r(B) ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡r(D) ¡ ¡ ¡ ¡w(A) ¡ ¡ ¡ ¡ ¡ ¡ ¡r(B) ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡commit ¡ T2 ¡ ¡ ¡ ¡r(C) ¡ ¡r(C) ¡ ¡ ¡ ¡ ¡ ¡ ¡w(E) ¡ ¡ ¡w(D) ¡ ¡w(C) ¡ ¡ ¡r(C) ¡ ¡ ¡w(C) ¡ ¡ ¡ ¡ ¡ ¡ ¡commit ¡ D ¡ D ¡ A ¡B ¡ C ¡ E ¡

  • First ¡read ¡access ¡samples ¡value ¡
  • Everything ¡else ¡is ¡completely ¡isolated ¡un3l ¡commit ¡
  • Commit ¡replays ¡all ¡reads ¡and ¡makes ¡all ¡writes ¡permanent ¡

B ¡ D ¡ C ¡

slide-54
SLIDE 54

Other ¡STM ¡implementa3ons ¡

  • Well-­‑known ¡op3mis3c ¡implementa3ons ¡exist ¡that ¡

are ¡faster ¡than ¡the ¡simple ¡one ¡we ¡just ¡looked ¡at ¡

  • Example: ¡TL2 ¡algorithm ¡by ¡Dice, ¡Shalev, ¡Shavit ¡
  • Does ¡not ¡hold ¡locks ¡for ¡read ¡loca3ons ¡during ¡commit ¡
  • Uses ¡global ¡version ¡clock, ¡and ¡version ¡number ¡for ¡each ¡

loca3on ¡to ¡detect ¡conflicts ¡

  • Uses ¡Bloom ¡filter ¡to ¡check ¡set ¡membership ¡efficiently ¡(with ¡

nonzero ¡one-­‑sided ¡error ¡probability) ¡

  • Does ¡not ¡order ¡locks, ¡but ¡handles ¡deadlock ¡with ¡3me-­‑out ¡

and ¡abort ¡(“sor3ng ¡write-­‑sets ¡was ¡not ¡worth ¡the ¡effort”). ¡

slide-55
SLIDE 55

Recap ¡ Pessimis3c ¡vs. ¡Op3mis3c ¡

  • Pessimis3c ¡Concurrency ¡Control ¡

– Use ¡locks ¡to ¡prevent ¡conflicts ¡ – If ¡deadlocked, ¡roll ¡back ¡changes ¡and ¡abort ¡ – Example: ¡2-­‑Phase ¡Locking ¡

  • Op3mis3c ¡Concurrency ¡Control ¡

– Proceed ¡specula)vely ¡(assume ¡no ¡conflicts), ¡ and ¡keep ¡all ¡changes ¡separate ¡ ¡ – At ¡commit ¡3me, ¡detect ¡conflicts ¡ – If ¡conflicts, ¡roll ¡back ¡changes ¡(if ¡necessary) ¡and ¡abort ¡ – Examples: ¡replay-­‑reads-­‑algorithm, ¡TL2 ¡algorithm ¡(Dice, ¡Shalev, ¡ Shavit) ¡

slide-56
SLIDE 56

Op3mis3c ¡Concurrency ¡Control ¡ ¡is ¡not ¡a ¡Panacea ¡

  • Doesn’t ¡work ¡with ¡permanent ¡side ¡effects ¡ ¡

– Can ¡not ¡always ¡roll ¡back ¡ (e.g. ¡dispense ¡cash ¡on ¡ATM) ¡

  • Conflicts ¡aren’t ¡always ¡rare ¡

– Some ¡tasks ¡always ¡conflict ¡ – If ¡conflicts ¡are ¡frequent, ¡pessimis3c ¡performs ¡berer ¡

  • But ¡don’t ¡despair: ¡there ¡is ¡another ¡solu3on ¡that ¡

works ¡in ¡those ¡cases: ¡Concurrent ¡Revisions ¡