B3CC: Concurrency 05: Software Transactional Memory (1)
Trevor L. McDonell Utrecht University, B2 2020-2021
B3CC: Concurrency 05: Software Transactional Memory (1) Trevor L. - - PowerPoint PPT Presentation
B3CC: Concurrency 05: Software Transactional Memory (1) Trevor L. McDonell Utrecht University, B2 2020-2021 Announcement From next week (Nov 30) we will o ff er the online werkcollege: - Monday 13:15 - 15:00 - Thursday 9:00 - 10:45 As
B3CC: Concurrency 05: Software Transactional Memory (1)
Trevor L. McDonell Utrecht University, B2 2020-2021
Announcement
2
Critical sections
3
Example: bank accounts
transferring money between accounts
has been withdrawn from one account but yet to be deposited into the target account
4
Account 1 $500 Account 2 $300 Account 3 $200
Thread A $150 Thread B $200
Example: bank accounts
5
Account 1 $500 Account 2 $300 Account 3 $200
Thread A $150 Thread B $200
Example: bank accounts
6
Account 1 $500 Account 2 $300 Account 3 $200
Thread A $150 Thread B $200
Example: bank accounts
7
Account 1 $500 Account 2 $300 Account 3 $200
Thread A $150 Thread B $200
Example: bank accounts
8
Account 1 $500 Account 2 $300 Account 3 $200
Thread A $150 Thread B $200
Example: bank accounts
9
Account 1 $500 Account 2 $300 Account 3 $200
Thread A $150 Thread B $200
Example: bank accounts
10
Account 1 $500 Account 2 $100 Account 3 $400
Thread A $150 Thread B $200
Example: bank accounts
11
Account 1 $650 Account 2 $150 Account 3 $400
Thread A $150 Thread B $200
Attempt #1
12
type Account = IORef Int deposit ::; Int ->. Account ->. IO () deposit amount acc = do balance <.- readIORef acc writeIORef acc (balance + amount) withdraw ::; Int ->. Account ->. IO () withdraw amount acc = deposit (-amount) acc
Attempt #2
13
type Account = MVar Int deposit ::; Int ->. Account ->. IO () deposit amount acc = modifyMVar_ acc $ \balance ->. return (balance + amount)) transfer ::; Int ->. Account ->. Account ->. IO () transfer amount from to = do withdraw amount from deposit amount to
inconsistent state!
Attempt #3
14
type Account = MVar Int transfer ::; Int ->. Account ->. Account ->. IO () transfer amount from to = modifyMVar_ from $ \fromBalance ->. do modifyMVar_ to $ \toBalance ->. return (toBalance + amount) return (fromBalance - amount)
transfer 100 acc1 acc2 transfer 200 acc2 acc1
P0: P1:
Attempt #4
15
type Account = MVar Int transfer ::; Int ->. Account ->. Account ->. IO () transfer amount from to = if from < to then modifyMVar_ from $ \fromBalance ->. modifyMVar_ to $ \toBalance ->. ..../ else modifyMVar_ to $ \toBalance ->. modifyMVar_ from $ \fromBalance ->. ..../
Extending the example
16
Locks are bad
17
Locks are bad
(correctly working) functions withdraw and deposit
18
Atomic blocks
19
An alternative
Can we do the same for locks? What would that look like?
20
Software transactional memory
necessary (more on this later)
21
import Control.Concurrent.STM data STM a --. abstract instance Monad STM --. among other things atomically ::; STM a ->. IO a
Software transactional memory
22
import Control.Concurrent.STM.TVar newTVar ::; a ->. STM (TVar a) readTVar ::; TVar a ->. STM a writeTVar ::; TVar a ->. a ->. STM ()
Software transactional memory
23
import Control.Concurrent.STM.TMVar newTMVar ::; a ->. STM (TMVar a) newEmptyTMVar ::; STM (TMVar) readTMVar ::; TMVar a ->. STM a writeTMVar ::; TMVar a ->. a ->. STM ()
Revisiting accounts
24
type Account = TVar Int deposit ::; Int ->. Account ->. STM () deposit amount account = do balance <.- readTVar account writeTVar (balance + amount) account withdraw ::; Int ->. Account ->. STM () withdraw amount = deposit (-amount)
Revisiting accounts
25
transfer ::; Int ->. Account ->. Account ->. IO () transfer amount from to = atomically $ do withdraw amount from deposit amount to
STM
26
bad ::; Int ->. Account ->. STM () bad amount account = do putStrLn “withdrawing!” --. ::; IO () withdraw amount account --. ::; STM () good ::; Int ->. Account ->. IO () good amount account = do putStrLn “withdrawing!” --. ::; IO () atomically $ withdraw amount account --. ::; IO ()
Implementing transactional memory
27
Implementing transactional memory
TVars
28
Implementing transactional memory
and writes to TVars
29
atomically $ do x <.- readTVar xv y <.- readTVar yv if x > y then brexit --. ::; IO () side effects! else return ()
Summary (so far)
30
Photo by JC Gellidon