Skip to content

Commit 2126b8b

Browse files
author
Yogesh Sajanikar
committed
Generalise OrElseLeft/Right frame
OrElseLeftFrame and OrElseRightFrame represent a control structure that has a alternative branch that is executed when `retry` is applied. A `catch` has a similar execution model when a `throw` is applied. The control frame is generalised to BranchFrame that can hold an alternative statement. If the execution context is `left` side of the branch then the BranchFrame contains `right` statement. When we are executing in the `right` context, the branch frame contains an empty statement.
1 parent e4fd24f commit 2126b8b

File tree

3 files changed

+19
-49
lines changed

3 files changed

+19
-49
lines changed

io-sim/src/Control/Monad/IOSim/Internal.hs

Lines changed: 5 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -881,7 +881,7 @@ execAtomically !time !tid !tlbl !nextVid0 action0 k0 =
881881
(mapMaybe traceString $ ds ++ ds')
882882
nextVid
883883

884-
OrElseLeftFrame _b k writtenOuter writtenOuterSeq createdOuterSeq ctl' -> do
884+
BranchFrame _b k writtenOuter writtenOuterSeq createdOuterSeq ctl' -> do
885885
-- Commit the TVars written in this sub-transaction that are also
886886
-- in the written set of the outer transaction
887887
!_ <- traverse_ (\(SomeTVar tvar) -> commitTVar tvar)
@@ -895,21 +895,6 @@ execAtomically !time !tid !tlbl !nextVid0 action0 k0 =
895895
-- Skip the orElse right hand and continue with the k continuation
896896
go ctl' read written' writtenSeq' createdOuterSeq nextVid (k x)
897897

898-
OrElseRightFrame k writtenOuter writtenOuterSeq createdOuterSeq ctl' -> do
899-
-- Commit the TVars written in this sub-transaction that are also
900-
-- in the written set of the outer transaction
901-
!_ <- traverse_ (\(SomeTVar tvar) -> commitTVar tvar)
902-
(Map.intersection written writtenOuter)
903-
-- Merge the written set of the inner with the outer
904-
let written' = Map.union written writtenOuter
905-
writtenSeq' = filter (\(SomeTVar tvar) ->
906-
tvarId tvar `Map.notMember` writtenOuter)
907-
writtenSeq
908-
++ writtenOuterSeq
909-
createdSeq' = createdSeq ++ createdOuterSeq
910-
-- Continue with the k continuation
911-
go ctl' read written' writtenSeq' createdSeq' nextVid (k x)
912-
913898
ThrowStm e ->
914899
{-# SCC "execAtomically.go.ThrowStm" #-} do
915900
-- Revert all the TVar writes
@@ -925,15 +910,15 @@ execAtomically !time !tid !tlbl !nextVid0 action0 k0 =
925910
-- Return vars read, so the thread can block on them
926911
k0 $! StmTxBlocked $! (Map.elems read)
927912

928-
OrElseLeftFrame b k writtenOuter writtenOuterSeq createdOuterSeq ctl' ->
913+
BranchFrame (OrElseStmA b) k writtenOuter writtenOuterSeq createdOuterSeq ctl' ->
929914
{-# SCC "execAtomically.go.OrElseLeftFrame" #-} do
930915
-- Revert all the TVar writes within this orElse
931916
!_ <- traverse_ (\(SomeTVar tvar) -> revertTVar tvar) written
932917
-- Execute the orElse right hand with an empty written set
933-
let ctl'' = OrElseRightFrame k writtenOuter writtenOuterSeq createdOuterSeq ctl'
918+
let ctl'' = BranchFrame EmptyStmA k writtenOuter writtenOuterSeq createdOuterSeq ctl'
934919
go ctl'' read Map.empty [] [] nextVid b
935920

936-
OrElseRightFrame _k writtenOuter writtenOuterSeq createdOuterSeq ctl' ->
921+
BranchFrame _ _k writtenOuter writtenOuterSeq createdOuterSeq ctl' ->
937922
{-# SCC "execAtomically.go.OrElseRightFrame" #-} do
938923
-- Revert all the TVar writes within this orElse branch
939924
!_ <- traverse_ (\(SomeTVar tvar) -> revertTVar tvar) written
@@ -944,7 +929,7 @@ execAtomically !time !tid !tlbl !nextVid0 action0 k0 =
944929
OrElse a b k ->
945930
{-# SCC "execAtomically.go.OrElse" #-} do
946931
-- Execute the left side in a new frame with an empty written set
947-
let ctl' = OrElseLeftFrame b k written writtenSeq createdSeq ctl
932+
let ctl' = BranchFrame (OrElseStmA b) k written writtenSeq createdSeq ctl
948933
go ctl' read Map.empty [] [] nextVid a
949934

950935
NewTVar !mbLabel x k ->

io-sim/src/Control/Monad/IOSim/Types.hs

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ module Control.Monad.IOSim.Types
2828
, runSTM
2929
, StmA (..)
3030
, StmTxResult (..)
31+
, BranchStmA (..)
3132
, StmStack (..)
3233
, Timeout (..)
3334
, TimeoutException (..)
@@ -832,26 +833,25 @@ data StmTxResult s a =
832833
--
833834
| StmTxAborted [SomeTVar s] SomeException
834835

836+
837+
-- | OrElse/Catch give rise to an alternate branch. A branch of a branch is an
838+
-- empty one.
839+
data BranchStmA s a = OrElseStmA (StmA s a) | EmptyStmA
840+
835841
data StmStack s b a where
836842
-- | Executing in the context of a top level 'atomically'.
837843
AtomicallyFrame :: StmStack s a a
838844

839-
-- | Executing in the context of the /left/ hand side of an 'orElse'
840-
OrElseLeftFrame :: StmA s a -- orElse right alternative
845+
-- | Executing in the context of the /left/ hand side of a branch.
846+
-- A right branch is represented by a frame containing empty statement.
847+
BranchFrame :: BranchStmA s a -- right alternative, can be empty
841848
-> (a -> StmA s b) -- subsequent continuation
842849
-> Map TVarId (SomeTVar s) -- saved written vars set
843850
-> [SomeTVar s] -- saved written vars list
844851
-> [SomeTVar s] -- created vars list
845852
-> StmStack s b c
846853
-> StmStack s a c
847854

848-
-- | Executing in the context of the /right/ hand side of an 'orElse'
849-
OrElseRightFrame :: (a -> StmA s b) -- subsequent continuation
850-
-> Map TVarId (SomeTVar s) -- saved written vars set
851-
-> [SomeTVar s] -- saved written vars list
852-
-> [SomeTVar s] -- created vars list
853-
-> StmStack s b c
854-
-> StmStack s a c
855855

856856
---
857857
--- Schedules

io-sim/src/Control/Monad/IOSimPOR/Internal.hs

Lines changed: 5 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1092,7 +1092,7 @@ execAtomically time tid tlbl nextVid0 action0 k0 =
10921092
(mapMaybe traceString $ ds ++ ds')
10931093
nextVid
10941094

1095-
OrElseLeftFrame _b k writtenOuter writtenOuterSeq createdOuterSeq ctl' -> do
1095+
BranchFrame _b k writtenOuter writtenOuterSeq createdOuterSeq ctl' -> do
10961096
-- Commit the TVars written in this sub-transaction that are also
10971097
-- in the written set of the outer transaction
10981098
!_ <- traverse_ (\(SomeTVar tvar) -> commitTVar tvar)
@@ -1106,21 +1106,6 @@ execAtomically time tid tlbl nextVid0 action0 k0 =
11061106
-- Skip the orElse right hand and continue with the k continuation
11071107
go ctl' read written' writtenSeq' createdOuterSeq nextVid (k x)
11081108

1109-
OrElseRightFrame k writtenOuter writtenOuterSeq createdOuterSeq ctl' -> do
1110-
-- Commit the TVars written in this sub-transaction that are also
1111-
-- in the written set of the outer transaction
1112-
!_ <- traverse_ (\(SomeTVar tvar) -> commitTVar tvar)
1113-
(Map.intersection written writtenOuter)
1114-
-- Merge the written set of the inner with the outer
1115-
let written' = Map.union written writtenOuter
1116-
writtenSeq' = filter (\(SomeTVar tvar) ->
1117-
tvarId tvar `Map.notMember` writtenOuter)
1118-
writtenSeq
1119-
++ writtenOuterSeq
1120-
createdSeq' = createdSeq ++ createdOuterSeq
1121-
-- Continue with the k continuation
1122-
go ctl' read written' writtenSeq' createdSeq' nextVid (k x)
1123-
11241109
ThrowStm e ->
11251110
{-# SCC "execAtomically.go.ThrowStm" #-} do
11261111
-- Revert all the TVar writes
@@ -1136,15 +1121,15 @@ execAtomically time tid tlbl nextVid0 action0 k0 =
11361121
-- Return vars read, so the thread can block on them
11371122
k0 $! StmTxBlocked $! Map.elems read
11381123

1139-
OrElseLeftFrame b k writtenOuter writtenOuterSeq createdOuterSeq ctl' ->
1124+
BranchFrame (OrElseStmA b) k writtenOuter writtenOuterSeq createdOuterSeq ctl' ->
11401125
{-# SCC "execAtomically.go.OrElseLeftFrame" #-} do
11411126
-- Revert all the TVar writes within this orElse
11421127
!_ <- traverse_ (\(SomeTVar tvar) -> revertTVar tvar) written
11431128
-- Execute the orElse right hand with an empty written set
1144-
let ctl'' = OrElseRightFrame k writtenOuter writtenOuterSeq createdOuterSeq ctl'
1129+
let ctl'' = BranchFrame EmptyStmA k writtenOuter writtenOuterSeq createdOuterSeq ctl'
11451130
go ctl'' read Map.empty [] [] nextVid b
11461131

1147-
OrElseRightFrame _k writtenOuter writtenOuterSeq createdOuterSeq ctl' ->
1132+
BranchFrame _ _k writtenOuter writtenOuterSeq createdOuterSeq ctl' ->
11481133
{-# SCC "execAtomically.go.OrElseRightFrame" #-} do
11491134
-- Revert all the TVar writes within this orElse branch
11501135
!_ <- traverse_ (\(SomeTVar tvar) -> revertTVar tvar) written
@@ -1155,7 +1140,7 @@ execAtomically time tid tlbl nextVid0 action0 k0 =
11551140
OrElse a b k ->
11561141
{-# SCC "execAtomically.go.OrElse" #-} do
11571142
-- Execute the left side in a new frame with an empty written set
1158-
let ctl' = OrElseLeftFrame b k written writtenSeq createdSeq ctl
1143+
let ctl' = BranchFrame (OrElseStmA b) k written writtenSeq createdSeq ctl
11591144
go ctl' read Map.empty [] [] nextVid a
11601145

11611146
NewTVar !mbLabel x k ->

0 commit comments

Comments
 (0)