concurrency unlocked transactional memory for composable concurrency tim harris maurice herlihy...

47
Concurrency Concurrency unlocked unlocked transactional memory transactional memory for for composable concurrency composable concurrency Tim Harris Tim Harris Maurice Herlihy Maurice Herlihy Simon Marlow Simon Marlow Simon Peyton Jones Simon Peyton Jones

Upload: brayden-cheesman

Post on 31-Mar-2015

238 views

Category:

Documents


3 download

TRANSCRIPT

Page 1: Concurrency unlocked transactional memory for composable concurrency Tim Harris Maurice Herlihy Simon Marlow Simon Peyton Jones

Concurrency unlockedConcurrency unlockedtransactional memory transactional memory

for for composable concurrencycomposable concurrency

Tim HarrisTim Harris

Maurice HerlihyMaurice Herlihy

Simon MarlowSimon Marlow

Simon Peyton JonesSimon Peyton Jones

Page 2: Concurrency unlocked transactional memory for composable concurrency Tim Harris Maurice Herlihy Simon Marlow Simon Peyton Jones

Concurrent programming is very

difficult

Despite lots of work (and some excellent tools) we still don’t have much clue how to do it

Page 3: Concurrency unlocked transactional memory for composable concurrency Tim Harris Maurice Herlihy Simon Marlow Simon Peyton Jones

Locks (market leader) are brokenLocks (market leader) are broken

RacesRaces: due to forgotten locks : due to forgotten locks

DeadlockDeadlock: locks acquired in “wrong” order. : locks acquired in “wrong” order.

Lost wakeupsLost wakeups: : forgotten notify to condition forgotten notify to condition variablevariable

Error recovery trickyError recovery tricky: need to restore : need to restore invariants and release locks in exception invariants and release locks in exception handlershandlers

Simplicity vs scalability tensionSimplicity vs scalability tension

...but worst of all......but worst of all...

Page 4: Concurrency unlocked transactional memory for composable concurrency Tim Harris Maurice Herlihy Simon Marlow Simon Peyton Jones

You cannot build a big working program from You cannot build a big working program from small working piecessmall working pieces

A.withdraw(3):A.withdraw(3): withdraw $3 from account A. withdraw $3 from account A. Easy; use a synchronised methodEasy; use a synchronised method

A.withdraw(3); B.deposit(3)A.withdraw(3); B.deposit(3)Uh oh: an observer could see a state in Uh oh: an observer could see a state in which the money was in neither accountwhich the money was in neither account

Locks do not compose

Page 5: Concurrency unlocked transactional memory for composable concurrency Tim Harris Maurice Herlihy Simon Marlow Simon Peyton Jones

Loss of compositionLoss of compositionExpose the lockingExpose the locking

A.lock(); B.lock(); A.withdraw(3);A.lock(); B.lock(); A.withdraw(3);B.deposit(3); A.unlock(); B.unlock()B.deposit(3); A.unlock(); B.unlock()

Uh oh. Danger of deadlockUh oh. Danger of deadlockif A<B then if A<B then

A.lock(); B.lock()A.lock(); B.lock()elseelse

B.lock(); A.lock()B.lock(); A.lock()end ifend if

Now transfer money from A’s deposit account if Now transfer money from A’s deposit account if A doesn’t have enough money....A doesn’t have enough money....

Page 6: Concurrency unlocked transactional memory for composable concurrency Tim Harris Maurice Herlihy Simon Marlow Simon Peyton Jones

Composition of alternativesComposition of alternativesMethod Method m1m1 does a does a WaitAny(h1,h2)WaitAny(h1,h2) on two on two WaitHandles WaitHandles h1h1, , h2h2. Ditto . Ditto m2m2

Can we Can we WaitAny(WaitAny(m1m1,,m2m2)). No way!. No way!

Instead, we break the abstraction and Instead, we break the abstraction and bubble up the WaitHandles we want to bubble up the WaitHandles we want to wait on to a top-level WaitAny, and then wait on to a top-level WaitAny, and then dispatch back to the handler codedispatch back to the handler code

Same in Unix (select)Same in Unix (select)

Page 7: Concurrency unlocked transactional memory for composable concurrency Tim Harris Maurice Herlihy Simon Marlow Simon Peyton Jones

This way lies This way lies madness...madness...

Locks emasculate our main weaponLocks emasculate our main weapon

Our main weapon in controlling program complexity is modular decomposition: build a big program by gluing together

smaller ones

Page 8: Concurrency unlocked transactional memory for composable concurrency Tim Harris Maurice Herlihy Simon Marlow Simon Peyton Jones

Transactional memoryTransactional memory

Steal ideas from the database folkSteal ideas from the database folk

atomicatomic does what it says on the tin does what it says on the tin

Directly supports what the programmer is trying Directly supports what the programmer is trying to do: an atomic transaction against memoryto do: an atomic transaction against memory

““Write the simple sequential code, and wrap Write the simple sequential code, and wrap atomicatomic around it”. around it”.

atomicatomicA.withdraw(3)A.withdraw(3)B.deposit(3)B.deposit(3)

endend

IDEA!

Herlihy/Moss ISCA 1993Herlihy/Moss ISCA 1993

Page 9: Concurrency unlocked transactional memory for composable concurrency Tim Harris Maurice Herlihy Simon Marlow Simon Peyton Jones

How does it work?How does it work?

Execute <body> without taking any locksExecute <body> without taking any locks

Each read and write in <body> is logged to a Each read and write in <body> is logged to a thread-local transaction logthread-local transaction log

Writes go to the log only, not to memoryWrites go to the log only, not to memory

At the end, the transaction tries to At the end, the transaction tries to commitcommit to to memorymemory

Commit may fail; then transaction is re-runCommit may fail; then transaction is re-run

Optimistic concurrency

atomicatomic<body><body>

Page 10: Concurrency unlocked transactional memory for composable concurrency Tim Harris Maurice Herlihy Simon Marlow Simon Peyton Jones

Transactional memoryTransactional memoryNo racesNo races: no locks, so you can’t forget to : no locks, so you can’t forget to take onetake one

No lock-induced deadlockNo lock-induced deadlock, because no , because no lockslocks

No lost wake-upsNo lost wake-ups, because no wake-up , because no wake-up calls to forget calls to forget [needs [needs retryretry; wait a few slides]; wait a few slides]

Error recovery trivialError recovery trivial: an exception inside : an exception inside atomic aborts the transactionatomic aborts the transaction

Simple code is scalableSimple code is scalable

Page 11: Concurrency unlocked transactional memory for composable concurrency Tim Harris Maurice Herlihy Simon Marlow Simon Peyton Jones

Tailor made for (pure) functional Tailor made for (pure) functional languages!languages!

Every memory read and write has to be Every memory read and write has to be trackedtracked

So there had better not be too many of So there had better not be too many of themthem

The compiler had better not miss any The compiler had better not miss any effectseffects

Haskell programmers are fully trained in Haskell programmers are fully trained in making effects explicitmaking effects explicit

Page 12: Concurrency unlocked transactional memory for composable concurrency Tim Harris Maurice Herlihy Simon Marlow Simon Peyton Jones

STM in HaskellSTM in Haskellatomic atomic :: STM a -> IO a:: STM a -> IO anewTVar newTVar :: a -> STM (TVar a):: a -> STM (TVar a)readTVar readTVar :: TVar a -> STM a:: TVar a -> STM awriteTVar writeTVar :: TVar a -> a -> STM ():: TVar a -> a -> STM ()

incR :: TVar Int -> incR :: TVar Int -> STMSTM () ()incR r = do { v <- incR r = do { v <- readTVarreadTVar r r

; ; writeTVarwriteTVar r (v+1) } r (v+1) }

main = do { r <- main = do { r <- atomicatomic ( (newTVarnewTVar 0) 0); fork (atomic (incR r)); fork (atomic (incR r)); atomic (incR r); atomic (incR r); ... }; ... }

atomicatomic is a is a function, not a function, not a

syntactic syntactic constructconstruct

““Transactional Transactional variable”variable”

STM monad; impoverished STM monad; impoverished version of IOversion of IO

Page 13: Concurrency unlocked transactional memory for composable concurrency Tim Harris Maurice Herlihy Simon Marlow Simon Peyton Jones

STM in HaskellSTM in Haskell

Can’t fiddle with TVars outside atomic Can’t fiddle with TVars outside atomic block [good]block [good]

Can’t do IO inside atomic block [sad, but Can’t do IO inside atomic block [sad, but also good]also good]

atomic :: STM a -> IO aatomic :: STM a -> IO anewTVar :: a -> STM (TVar a)newTVar :: a -> STM (TVar a)readTVar :: TVar a -> STM areadTVar :: TVar a -> STM awriteTVar :: TVar a -> a -> STM ()writeTVar :: TVar a -> a -> STM ()

Page 14: Concurrency unlocked transactional memory for composable concurrency Tim Harris Maurice Herlihy Simon Marlow Simon Peyton Jones

Transaction logsTransaction logs

atomicatomic (do { (do { v <- read bal ; v <- read bal ; write bal (v+1) write bal (v+1)

})})

WhatWhat Value Value readread

Value Value writtenwritten

balbal

WhatWhat Value Value readread

Value Value writtenwritten

balbal

6

bal

Transaction log

Thread 1 Thread 2

Transaction log

atomicatomic (do { (do { v <- read bal ; v <- read bal ; write bal (v-3) write bal (v-3)

})})

Page 15: Concurrency unlocked transactional memory for composable concurrency Tim Harris Maurice Herlihy Simon Marlow Simon Peyton Jones

Transaction logsTransaction logs

WhatWhat Value Value readread

Value Value writtenwritten

balbal

WhatWhat Value Value readread

Value Value writtenwritten

balbal 66

6

bal

Transaction log

Thread 1 Thread 2

Transaction log

atomicatomic (do { (do { v <- read bal ; v <- read bal ; write bal (v+1) write bal (v+1)

})})

atomicatomic (do { (do { v <- read bal ; v <- read bal ; write bal (v-3) write bal (v-3)

})})

Page 16: Concurrency unlocked transactional memory for composable concurrency Tim Harris Maurice Herlihy Simon Marlow Simon Peyton Jones

Transaction logsTransaction logs

WhatWhat Value Value readread

Value Value writtenwritten

balbal 66

WhatWhat Value Value readread

Value Value writtenwritten

balbal 66

6

bal

Transaction log

Thread 1 Thread 2

Transaction log

atomicatomic (do { (do { v <- read bal ; v <- read bal ; write bal (v+1) write bal (v+1)

})})

atomicatomic (do { (do { v <- read bal ; v <- read bal ; write bal (v-3) write bal (v-3)

})})

Page 17: Concurrency unlocked transactional memory for composable concurrency Tim Harris Maurice Herlihy Simon Marlow Simon Peyton Jones

Transaction logsTransaction logs

WhatWhat Value Value readread

Value Value writtenwritten

balbal 66 77

WhatWhat Value Value readread

Value Value writtenwritten

balbal 66

6

bal

Transaction log

Thread 1 Thread 2

Transaction log

atomicatomic (do { (do { v <- read bal ; v <- read bal ; write bal (v+1) write bal (v+1)

})})

atomicatomic (do { (do { v <- read bal ; v <- read bal ; write bal (v-3) write bal (v-3)

})})

Page 18: Concurrency unlocked transactional memory for composable concurrency Tim Harris Maurice Herlihy Simon Marlow Simon Peyton Jones

Transaction logsTransaction logs

WhatWhat Value Value readread

Value Value writtenwritten

balbal 66 77

WhatWhat Value Value readread

Value Value writtenwritten

balbal 66 33

6

bal

Transaction log

Thread 1 Thread 2

Transaction log

atomicatomic (do { (do { v <- read bal ; v <- read bal ; write bal (v+1) write bal (v+1)

})})

atomicatomic (do { (do { v <- read bal ; v <- read bal ; write bal (v-3) write bal (v-3)

})})

Page 19: Concurrency unlocked transactional memory for composable concurrency Tim Harris Maurice Herlihy Simon Marlow Simon Peyton Jones

Transaction logsTransaction logs

WhatWhat Value Value readread

Value Value writtenwritten

balbal 66 33

7

bal

• Thread 1 commits• Shared ‘bal’ is written• Transaction log discarded

Thread 1 Thread 2

Transaction log

atomicatomic (do { (do { v <- read bal ; v <- read bal ; write bal (v+1) write bal (v+1)

})})

atomicatomic (do { (do { v <- read bal ; v <- read bal ; write bal (v-3) write bal (v-3)

})})

Page 20: Concurrency unlocked transactional memory for composable concurrency Tim Harris Maurice Herlihy Simon Marlow Simon Peyton Jones

Transaction logsTransaction logs

WhatWhat Value Value readread

Value Value writtenwritten

7

bal

• Attempt to commit thread 2 fails, because value in memory value in log

• Transaction re-runs from the beginning

Thread 1 Thread 2

Transaction log

atomicatomic (do { (do { v <- read bal ; v <- read bal ; write bal (v+1) write bal (v+1)

})})

atomicatomic (do { (do { v <- read bal ; v <- read bal ; write bal (v-3) write bal (v-3)

})})

Page 21: Concurrency unlocked transactional memory for composable concurrency Tim Harris Maurice Herlihy Simon Marlow Simon Peyton Jones

Two new ideas

Page 22: Concurrency unlocked transactional memory for composable concurrency Tim Harris Maurice Herlihy Simon Marlow Simon Peyton Jones

Idea 1: modular blockingIdea 1: modular blocking

retryretry means “abort the current transaction means “abort the current transaction and re-execute it from the beginning”.and re-execute it from the beginning”.

Implementation avoids the busy wait by Implementation avoids the busy wait by using reads in the transaction log (i.e. using reads in the transaction log (i.e. accacc) ) to wait simultaneously on all read to wait simultaneously on all read variablesvariables

withdraw :: TVar Int -> Int -> STM ()withdraw :: TVar Int -> Int -> STM ()withdraw acc n = do { bal <- readTVar accwithdraw acc n = do { bal <- readTVar acc

; if bal < n then ; if bal < n then retryretry;;; writeTVar acc (bal-n) }; writeTVar acc (bal-n) }retry :: STM ()retry :: STM ()

Page 23: Concurrency unlocked transactional memory for composable concurrency Tim Harris Maurice Herlihy Simon Marlow Simon Peyton Jones

No condition variablesNo condition variablesNo condition variables! No condition variables!

Retrying thread is woken up automatically Retrying thread is woken up automatically when when accacc is written. No lost wake-ups! is written. No lost wake-ups!

No danger of forgetting to test everything No danger of forgetting to test everything again when woken up; the transaction again when woken up; the transaction runs again from the beginning.runs again from the beginning.e.g. e.g. atomic (do { withdraw a1 3atomic (do { withdraw a1 3

; withdraw a2 7 }); withdraw a2 7 })

Page 24: Concurrency unlocked transactional memory for composable concurrency Tim Harris Maurice Herlihy Simon Marlow Simon Peyton Jones

Idea 2: ChoiceIdea 2: Choice

atomicatomic (do {(do {withdraw a1 3withdraw a1 3

`̀orelseorelse`̀withdraw a2 3withdraw a2 3

;; deposit b 3 })deposit b 3 })

Try this

...and if it retries, try this

...and and then do this

orElse :: STM a -> STM a -> STM aorElse :: STM a -> STM a -> STM a

Page 25: Concurrency unlocked transactional memory for composable concurrency Tim Harris Maurice Herlihy Simon Marlow Simon Peyton Jones

Choice is composable tooChoice is composable tootransfer :: TVar Int -> TVar Inttransfer :: TVar Int -> TVar Int

-> TVar Int -> STM () -> TVar Int -> STM ()

transfer a1 a2 b = dotransfer a1 a2 b = do{ withdraw a1 3{ withdraw a1 3

`orElse``orElse` withdraw a2 3 withdraw a2 3

; deposit b 3; deposit b 3endend

atomicatomic(transfer a1 a2 b(transfer a1 a2 b

`orElse``orElse` transfer a3 a4 b)transfer a3 a4 b)

transfertransfer has an has an orElseorElse, but calls to , but calls to transfertransfer can still be composed with can still be composed with orElseorElse

Page 26: Concurrency unlocked transactional memory for composable concurrency Tim Harris Maurice Herlihy Simon Marlow Simon Peyton Jones

SummarySummaryTransactional memory is fantastic: a ray of light in Transactional memory is fantastic: a ray of light in the darknessthe darkness

It’s a classic abstraction: a simple interface hides a It’s a classic abstraction: a simple interface hides a complex and subtle implementationcomplex and subtle implementation

Like high-level language vs assembly code: whole Like high-level language vs assembly code: whole classes of low-level errors are cut off at the kneesclasses of low-level errors are cut off at the knees

No silver bullet: you can still write buggy programsNo silver bullet: you can still write buggy programs

STM is aimed at shared memory. Distribution is a STM is aimed at shared memory. Distribution is a whole different ball game (latency, failure, security, whole different ball game (latency, failure, security, versioning); needs different abstractions.versioning); needs different abstractions.

Page 27: Concurrency unlocked transactional memory for composable concurrency Tim Harris Maurice Herlihy Simon Marlow Simon Peyton Jones

Farsite project (Jon Howell MSR)Farsite project (Jon Howell MSR)““Your idea of using the writes from one transaction Your idea of using the writes from one transaction to wake up sleepy transactions is wonderful.  We to wake up sleepy transactions is wonderful.  We wanted to report on the effect your paper draft has wanted to report on the effect your paper draft has already hadalready had on our project. on our project.

““...I told JD that I'd try to hack the Harris-and-...I told JD that I'd try to hack the Harris-and-company unblocking scheme into our stuff, but that company unblocking scheme into our stuff, but that he should slap me around if it ended up taking too he should slap me around if it ended up taking too long. We decided to check in after three days, and long. We decided to check in after three days, and abandon after five. It took a day and a half.... abandon after five. It took a day and a half....

““...In summary, using your composable blocking ...In summary, using your composable blocking model is wonderful: it rips out a big chunk of our model is wonderful: it rips out a big chunk of our control flow related to liveness, and takes with it a control flow related to liveness, and takes with it a whole class of potential bugs.”whole class of potential bugs.”

Page 28: Concurrency unlocked transactional memory for composable concurrency Tim Harris Maurice Herlihy Simon Marlow Simon Peyton Jones

Odds and ends

Page 29: Concurrency unlocked transactional memory for composable concurrency Tim Harris Maurice Herlihy Simon Marlow Simon Peyton Jones

Why “modular blocking”?Why “modular blocking”?Because Because retryretry can appear anywhere inside an can appear anywhere inside an atomic block, including nested deep within a call.atomic block, including nested deep within a call.

Contrast:Contrast:atomic (n > 0) { ...stuff... }atomic (n > 0) { ...stuff... }

which breaks the abstraction inside “...stuff...”which breaks the abstraction inside “...stuff...”

Difficult to do that in a lock-based world, Difficult to do that in a lock-based world, because you must release locks before blocking; because you must release locks before blocking; but which locks?but which locks?

With TM, no locks => no danger of blocking With TM, no locks => no danger of blocking while holding locks. This is a very strong while holding locks. This is a very strong property.property.

Page 30: Concurrency unlocked transactional memory for composable concurrency Tim Harris Maurice Herlihy Simon Marlow Simon Peyton Jones

ExceptionsExceptionsSTM monad supports exceptions:STM monad supports exceptions:

In the call (In the call (atomic satomic s), if s throws an ), if s throws an exception, the transaction is aborted with exception, the transaction is aborted with no effect; and the exception is propagated no effect; and the exception is propagated into the IO monadinto the IO monad

No need to restore invariants, or release No need to restore invariants, or release locks!locks!

throw :: Exception -> STM athrow :: Exception -> STM acatch :: STM a -> (Exception -> STM a) -> STM acatch :: STM a -> (Exception -> STM a) -> STM a

Page 31: Concurrency unlocked transactional memory for composable concurrency Tim Harris Maurice Herlihy Simon Marlow Simon Peyton Jones

Input/outputInput/outputYou can’t do I/O in a memory transaction You can’t do I/O in a memory transaction (because there’s no general way to undo (because there’s no general way to undo it)it)

The STM monad ensures you don’t make The STM monad ensures you don’t make a mistake about thisa mistake about this

To support transactional I/O:To support transactional I/O:

Shared (transational

) memory

Transactional output I/O thread

Page 32: Concurrency unlocked transactional memory for composable concurrency Tim Harris Maurice Herlihy Simon Marlow Simon Peyton Jones

Transactional inputTransactional inputSame plan as for output, where input Same plan as for output, where input request size is knownrequest size is known

Variable-sized input is harder, because if Variable-sized input is harder, because if there is not enough data in the buffer, the there is not enough data in the buffer, the transaction may block (as it should), but transaction may block (as it should), but has no observable effect. has no observable effect.

So the I/O thread doesn’t know to get So the I/O thread doesn’t know to get more data :-(more data :-(

Still thinking about what to do about Still thinking about what to do about this...not sure it matters that muchthis...not sure it matters that much

Page 33: Concurrency unlocked transactional memory for composable concurrency Tim Harris Maurice Herlihy Simon Marlow Simon Peyton Jones

ProgressProgressA worry: could the system “thrash” by A worry: could the system “thrash” by continually colliding and re-executing?continually colliding and re-executing?

No: one transaction can be forced to re-No: one transaction can be forced to re-execute only if another succeeds in execute only if another succeeds in committing. That gives a strong progress committing. That gives a strong progress guarantee.guarantee.

But a particular thread could perhaps But a particular thread could perhaps starve.starve.

Page 34: Concurrency unlocked transactional memory for composable concurrency Tim Harris Maurice Herlihy Simon Marlow Simon Peyton Jones

Is this all a pipe dream?Is this all a pipe dream?Surely it’s impractical to log every read and write?Surely it’s impractical to log every read and write?

1.1. Do you want working programs or not?Do you want working programs or not?

2.2. Tim built an implementation of TM for Java that Tim built an implementation of TM for Java that showed a 2x perf hit. Things can only showed a 2x perf hit. Things can only improve!improve!

3.3. We only need to log reads and writes to We only need to log reads and writes to persistentpersistent variables (ones outside the variables (ones outside the transaction); many variables are not.transaction); many variables are not.

4.4. Caches already do much of this stuff; maybe Caches already do much of this stuff; maybe we could get hardware support.we could get hardware support.

5.5. ...but in truth this is an open question...but in truth this is an open question

Page 35: Concurrency unlocked transactional memory for composable concurrency Tim Harris Maurice Herlihy Simon Marlow Simon Peyton Jones

What we have nowWhat we have nowA complete implementation of A complete implementation of transactional memory in Concurrent transactional memory in Concurrent Haskell [in GHC 6.4]. Try it!Haskell [in GHC 6.4]. Try it!

http://haskell.org/ghchttp://haskell.org/ghc

A C# transactional-memory library. A bit A C# transactional-memory library. A bit clunky, and few checks, but works with clunky, and few checks, but works with unchanged C# [Marurice Herlihy]unchanged C# [Marurice Herlihy]

PPoPP’05 paperPPoPP’05 paper

http://research.microsoft.com/~simonpjhttp://research.microsoft.com/~simonpj

Page 36: Concurrency unlocked transactional memory for composable concurrency Tim Harris Maurice Herlihy Simon Marlow Simon Peyton Jones

Open questionsOpen questionsAre our claims that transactional memory Are our claims that transactional memory supports “higher-level programming” supports “higher-level programming” validated by practice?validated by practice?

You can’t do I/O within a transaction, You can’t do I/O within a transaction, because it can’t be undone. How because it can’t be undone. How inconvenient is that?inconvenient is that?

Can performance be made good enough?Can performance be made good enough?

Starvation: a long-running transaction may Starvation: a long-running transaction may be repeatedly “bumped” by short be repeatedly “bumped” by short transactions that committransactions that commit

Page 37: Concurrency unlocked transactional memory for composable concurrency Tim Harris Maurice Herlihy Simon Marlow Simon Peyton Jones

CMLCMLCML, a fine design, is the nearest CML, a fine design, is the nearest competitorcompetitor

receive :: Chan a -> Event areceive :: Chan a -> Event aguard :: guard :: IOIO (Event a) -> Event a (Event a) -> Event awrap :: Event a -> (a->wrap :: Event a -> (a->IOIO b) -> Event b) -> Event

bbchoose :: [Event a] -> Event achoose :: [Event a] -> Event async :: Event a -> sync :: Event a -> IOIO a a

A lot of the program gets stuffed inside the A lot of the program gets stuffed inside the events => somewhat inside-out structureevents => somewhat inside-out structure

Page 38: Concurrency unlocked transactional memory for composable concurrency Tim Harris Maurice Herlihy Simon Marlow Simon Peyton Jones

CMLCMLNo way to wait for complex conditionsNo way to wait for complex conditions

No atomicity guaranteesNo atomicity guarantees

An event is a little bit like a transaction: it An event is a little bit like a transaction: it happens or it doesn’t; but explicit user undo:happens or it doesn’t; but explicit user undo:

wrapAbort :: Event a -> IO () -> Event awrapAbort :: Event a -> IO () -> Event a

Events have a single “commit point”. Non Events have a single “commit point”. Non compositional:compositional:

??? :: Event a -> Event b -> Event (a,b)??? :: Event a -> Event b -> Event (a,b)

Page 39: Concurrency unlocked transactional memory for composable concurrency Tim Harris Maurice Herlihy Simon Marlow Simon Peyton Jones

AlgebraAlgebraNice equations:Nice equations:

– orElse is associative (but not commutative)orElse is associative (but not commutative)

– retry `orElse` s = sretry `orElse` s = s

– s `orElse` retry = ss `orElse` retry = s

[Haskell afficionados] STM is an instance of MonadPlus.[Haskell afficionados] STM is an instance of MonadPlus.

Page 40: Concurrency unlocked transactional memory for composable concurrency Tim Harris Maurice Herlihy Simon Marlow Simon Peyton Jones

But what does it all But what does it all mean?mean?

Everything so far is intuitive and arm-waveyEverything so far is intuitive and arm-wavey

But what happens if it’s raining, and you are inside an But what happens if it’s raining, and you are inside an orElse and you throw an exception that contains a value orElse and you throw an exception that contains a value that mentions...?that mentions...?

We need a precise specificationWe need a precise specification

Page 41: Concurrency unlocked transactional memory for composable concurrency Tim Harris Maurice Herlihy Simon Marlow Simon Peyton Jones

But what does it all mean?But what does it all mean?Small-step transition rulesSmall-step transition rules

Page 42: Concurrency unlocked transactional memory for composable concurrency Tim Harris Maurice Herlihy Simon Marlow Simon Peyton Jones

Administrative stepsAdministrative steps

Page 43: Concurrency unlocked transactional memory for composable concurrency Tim Harris Maurice Herlihy Simon Marlow Simon Peyton Jones

TransactionsTransactions

Page 44: Concurrency unlocked transactional memory for composable concurrency Tim Harris Maurice Herlihy Simon Marlow Simon Peyton Jones

STM transitionsSTM transitions

Easy ones:Easy ones:

Page 45: Concurrency unlocked transactional memory for composable concurrency Tim Harris Maurice Herlihy Simon Marlow Simon Peyton Jones

RetryRetry

Here are the rules for retry:Here are the rules for retry:

Page 46: Concurrency unlocked transactional memory for composable concurrency Tim Harris Maurice Herlihy Simon Marlow Simon Peyton Jones

RetryRetry

Here are the rules for retry:Here are the rules for retry:

...there are none ...there are none (apart from an admin transition)...(apart from an admin transition)...

In particular, no rule forIn particular, no rule for

P[P[atomicatomic retryretry], ], -> ... -> ...

Page 47: Concurrency unlocked transactional memory for composable concurrency Tim Harris Maurice Herlihy Simon Marlow Simon Peyton Jones

orElseorElse

First branch

succeeds

First branch retries

First branch raises

exception