Pellucid stm
-
Upload
dustin-whitney -
Category
Technology
-
view
1.164 -
download
1
description
Transcript of Pellucid stm
![Page 1: Pellucid stm](https://reader035.fdocuments.us/reader035/viewer/2022062303/5559e932d8b42a39498b50f1/html5/thumbnails/1.jpg)
SOFTWARE TRANSACTIONAL MEMORY@DUSTINWHITNEY
![Page 2: Pellucid stm](https://reader035.fdocuments.us/reader035/viewer/2022062303/5559e932d8b42a39498b50f1/html5/thumbnails/2.jpg)
Alternative to lock-based synchronization
Analogous to database transactions
ACI (ACID with out the ‘D’)
Simple! (well… simplier)
WHAT IS STM?
![Page 3: Pellucid stm](https://reader035.fdocuments.us/reader035/viewer/2022062303/5559e932d8b42a39498b50f1/html5/thumbnails/3.jpg)
libraryDependencies += ("org.scala-stm" %% "scala-stm" %
"0.7")
import scala.concurrent.stm._
val protectedInt = Ref(0)
atomic{ implicit transaction=> val currentValue = protectedInt.get protectedInt.set(currentValue + 1)}
WHAT DOES IT LOOK LIKE?
![Page 4: Pellucid stm](https://reader035.fdocuments.us/reader035/viewer/2022062303/5559e932d8b42a39498b50f1/html5/thumbnails/4.jpg)
ATOMIC
val protectedInt = Ref(0)val anotherProtectedInt = Ref(0)
atomic{ implicit transaction => val currentValue = protectedInt.get protectedInt.set(currentValue + 1) val anotherCurrentValue = anotherProtectedInt.get anotherProtectedInt.set(anotherCurrentValue + 1)}
![Page 5: Pellucid stm](https://reader035.fdocuments.us/reader035/viewer/2022062303/5559e932d8b42a39498b50f1/html5/thumbnails/5.jpg)
CONSISTENT
val protectedInt = Ref(0)
atomic{ transaction => val currentValue = protectedInt.get(transaction) protectedInt.set(currentValue + 1)(transaction)}
![Page 6: Pellucid stm](https://reader035.fdocuments.us/reader035/viewer/2022062303/5559e932d8b42a39498b50f1/html5/thumbnails/6.jpg)
val protectedInt = Ref(0)
atomic{ implicit transaction => val currentValue = protectedInt.get protectedInt.set(currentValue + 1)}
ISOLATED
![Page 7: Pellucid stm](https://reader035.fdocuments.us/reader035/viewer/2022062303/5559e932d8b42a39498b50f1/html5/thumbnails/7.jpg)
STM is not Durable
DURABLE
![Page 8: Pellucid stm](https://reader035.fdocuments.us/reader035/viewer/2022062303/5559e932d8b42a39498b50f1/html5/thumbnails/8.jpg)
ADVANTAGES: DEADLOCK / LIVELOCK
val protectedInt = Ref(0)
atomic{ implicit transaction => val currentValue = protectedInt.get protectedInt.set(currentValue + 1)}
![Page 9: Pellucid stm](https://reader035.fdocuments.us/reader035/viewer/2022062303/5559e932d8b42a39498b50f1/html5/thumbnails/9.jpg)
ADVANTAGES: PRIORITY INVERSION
val protectedInt = Ref(0)
atomic{ implicit transaction => val currentValue = protectedInt.get protectedInt.set(currentValue + 1)}
![Page 10: Pellucid stm](https://reader035.fdocuments.us/reader035/viewer/2022062303/5559e932d8b42a39498b50f1/html5/thumbnails/10.jpg)
ADVANTAGES: COMPOSABILITY
val protectedInt = Ref(0)val anotherProtedtedInt = Ref(0)
atomic{ implicit transaction => val currentValue = protectedInt.get protectedInt.set(currentValue + 1) atomic{ implicit transaction => val anotherCurrentValue = anotherProtectedInt.get val anotherProctedInt.set(anotherCurrentValue + 1) }
}
![Page 11: Pellucid stm](https://reader035.fdocuments.us/reader035/viewer/2022062303/5559e932d8b42a39498b50f1/html5/thumbnails/11.jpg)
GOTCHAS: IMMUTABILITY!
// bad!val badMap= Ref(new java.util.HashMap[String, Int]())val mutableMap = atomic{ implicit transaction => badMap.get }mutableMap.put(“Wrong!”, 666)
// goodval goodMap = Ref(Map(“Good” -> 7))atomic{ implicit transaction => val tempMap = goodMap.get goodMap.set(tempMap + (“Good” -> 777))}
![Page 12: Pellucid stm](https://reader035.fdocuments.us/reader035/viewer/2022062303/5559e932d8b42a39498b50f1/html5/thumbnails/12.jpg)
GOTCHAS: REFERENTIAL TRANSPARENCY
//badval protectedString = Ref("This is a string")val time = System.currentTimeMillisatomic{ implicit transaction => if(time % 2 == 0) protectedString.set("Time was even") else protectedString.set("Time was odd")}
//goodatomic{ implicit transaction => val time = System.currentTimeMillis if(time % 2 == 0) protectedString.set("Time was even") else protectedString.set("Time was odd")}
![Page 13: Pellucid stm](https://reader035.fdocuments.us/reader035/viewer/2022062303/5559e932d8b42a39498b50f1/html5/thumbnails/13.jpg)
EXTENDED EXAMPLE: STM
case class Account(number: Int, balance: Int)
val accounts = Ref(Map( 1 -> Account(1, 100), 2 -> Account(2, 100) ))
def transfer(to: Int, from: Int, amount: Int){ atomic{ implicit transaction => val map = accounts.get val toAccount = map(to) val fromAccount = map(from) accounts.set( map + (to -> (toAccount.copy(balance = toAccount.balance + amount))) + (from -> (fromAccount.copy(balance = fromAccount.balance - amount))) ) } }
![Page 14: Pellucid stm](https://reader035.fdocuments.us/reader035/viewer/2022062303/5559e932d8b42a39498b50f1/html5/thumbnails/14.jpg)
EXTENDED EXAMPLE: SYNCHRONIZED
import java.util._private val accounts = new HashMap[Int, Account]()accounts.put(1, Account(1, 100))accounts.put(2, Account(2, 100))
def transfer(to: Int, from: Int, amount: Int){ accounts.synchronized{ val toAccount = accounts.get(to) val fromAccount = accounts.get(from) accounts.put(to, (toAccount.copy(balance = toAccount.balance + amount))) accounts.put(from, (fromAccount.copy(balance = fromAccount.balance - amount))) }}
![Page 15: Pellucid stm](https://reader035.fdocuments.us/reader035/viewer/2022062303/5559e932d8b42a39498b50f1/html5/thumbnails/15.jpg)
EXTENDED EXAMPLE: SYNCHRONIZED2
import java.util.concurrent._private val accounts = ConcurrentHashMap[Int, Account]()accounts.put(1, Account(1, 100))accounts.put(2, Account(2, 100))
def transfer(to: Int, from: Int, amount: Int){ val toAccount = accounts.get(to) val fromAccount = accounts.get(from) toAccount.synchronized{ fromAccount.synchronized{ accounts.put(to, (toAccount.copy(balance = toAccount.balance + amount))) accounts.put(from, (fromAccount.copy(balance = fromAccount.balance - amount))) } }}
![Page 16: Pellucid stm](https://reader035.fdocuments.us/reader035/viewer/2022062303/5559e932d8b42a39498b50f1/html5/thumbnails/16.jpg)
EXTENDED EXAMPLE: SYNCHRONIZED3
import java.util.concurrent._private val accounts = ConcurrentHashMap[Int, Account]()accounts.put(1, Account(1, 100))accounts.put(2, Account(2, 100))
def transfer(to: Int, from: Int, amount: Int){ val toAccount = accounts.get(to) val fromAccount = accounts.get(from) val (firstLock, secondLock) = if(to > from) (toAccount, fromAccount) else (fromAccount, toAccount) firstLock.synchronized{ secondLock.synchronized{ accounts.put(to, (toAccount.copy(balance = toAccount.balance + amount))) accounts.put(from, (fromAccount.copy(balance = fromAccount.balance - amount))) } }}
![Page 17: Pellucid stm](https://reader035.fdocuments.us/reader035/viewer/2022062303/5559e932d8b42a39498b50f1/html5/thumbnails/17.jpg)
Questions?