Skip to content

Commit 325538a

Browse files
committed
io-sim: Add support for unique symbol generation
1 parent 3905bde commit 325538a

File tree

6 files changed

+38
-5
lines changed

6 files changed

+38
-5
lines changed

io-sim/CHANGELOG.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@
66

77
### Non-breaking changes
88

9+
* Added support for unique symbol generation à la `Data.Unique`.
10+
911
### 1.8.0.1
1012

1113
* Added support for `ghc-9.2`.

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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@ module Control.Monad.IOSim
4848
, ThreadLabel
4949
, IOSimThreadId (..)
5050
, Labelled (..)
51+
, IOSimUnique
5152
-- ** Dynamic Tracing
5253
, traceM
5354
, traceSTM

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

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
{-# LANGUAGE DeriveAnyClass #-}
22
{-# LANGUAGE DerivingStrategies #-}
33
{-# LANGUAGE DerivingVia #-}
4+
{-# LANGUAGE RoleAnnotations #-}
45

56
-- | Common types shared between `IOSim` and `IOSimPOR`.
67
--
@@ -28,6 +29,7 @@ module Control.Monad.IOSim.CommonTypes
2829
, BlockedReason (..)
2930
, Labelled (..)
3031
, ppLabelled
32+
, IOSimUnique(..)
3133
-- * Utils
3234
, ppList
3335
) where
@@ -202,6 +204,12 @@ ppLabelled :: (a -> String) -> Labelled a -> String
202204
ppLabelled pp Labelled { l_labelled = a, l_label = Nothing } = pp a
203205
ppLabelled pp Labelled { l_labelled = a, l_label = Just lbl } = concat ["Labelled ", pp a, " ", lbl]
204206

207+
-- | Abstract unique symbols à la "Data.Unique".
208+
type role IOSimUnique nominal
209+
newtype IOSimUnique s = MkUnique{ unMkUnique :: Integer }
210+
deriving stock (Eq, Ord)
211+
deriving newtype (Hashable, NFData)
212+
205213
--
206214
-- Utils
207215
--

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

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -142,8 +142,9 @@ data SimState s a = SimState {
142142
timers :: !(Timeouts s),
143143
-- | list of clocks
144144
clocks :: !(Map ClockId UTCTime),
145-
nextVid :: !VarId, -- ^ next unused 'VarId'
146-
nextTmid :: !TimeoutId -- ^ next unused 'TimeoutId'
145+
nextVid :: !VarId, -- ^ next unused 'VarId'
146+
nextTmid :: !TimeoutId, -- ^ next unused 'TimeoutId'
147+
nextUniq :: !(IOSimUnique s) -- ^ next unused @'IOSimUnique' s@
147148
}
148149

149150
initialState :: SimState s a
@@ -155,7 +156,8 @@ initialState =
155156
timers = PSQ.empty,
156157
clocks = Map.singleton (ClockId []) epoch1970,
157158
nextVid = 0,
158-
nextTmid = TimeoutId 0
159+
nextTmid = TimeoutId 0,
160+
nextUniq = MkUnique 0
159161
}
160162
where
161163
epoch1970 = UTCTime (fromGregorian 1970 1 1) 0
@@ -197,7 +199,7 @@ schedule !thread@Thread{
197199
threads,
198200
timers,
199201
clocks,
200-
nextVid, nextTmid,
202+
nextVid, nextTmid, nextUniq,
201203
curTime = time
202204
} =
203205
invariant (Just thread) simstate $
@@ -631,6 +633,11 @@ schedule !thread@Thread{
631633
thread' = thread { threadControl = ThreadControl k' ctl }
632634
schedule thread' simstate
633635

636+
NewUnique k -> do
637+
let thread' = thread{ threadControl = ThreadControl (k nextUniq) ctl }
638+
simstate' = simstate{ nextUniq = MkUnique (unMkUnique nextUniq + 1) }
639+
schedule thread' simstate'
640+
634641

635642
threadInterruptible :: Thread s a -> Bool
636643
threadInterruptible thread =

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

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,7 @@ import Control.Monad.Class.MonadTime.SI qualified as SI
9393
import Control.Monad.Class.MonadTimer
9494
import Control.Monad.Class.MonadTimer.SI (TimeoutState (..))
9595
import Control.Monad.Class.MonadTimer.SI qualified as SI
96+
import Control.Monad.Class.MonadUnique
9697
import Control.Monad.Primitive qualified as Prim
9798
import Control.Monad.ST.Lazy
9899
import Control.Monad.ST.Strict qualified as StrictST
@@ -104,6 +105,7 @@ import Control.Monad.Fail qualified as Fail
104105
import Data.Bifoldable
105106
import Data.Bifunctor (bimap)
106107
import Data.Dynamic (Dynamic, toDyn)
108+
import Data.Hashable (Hashable(hash))
107109
import Data.List.Trace qualified as Trace
108110
import Data.Map.Strict (Map)
109111
import Data.Maybe (fromMaybe)
@@ -193,6 +195,7 @@ data SimA s a where
193195
ExploreRaces :: SimA s b -> SimA s b
194196

195197
Fix :: (x -> IOSim s x) -> (x -> SimA s r) -> SimA s r
198+
NewUnique :: (IOSimUnique s -> SimA s r) -> SimA s r
196199

197200

198201
newtype STM s a = STM { unSTM :: forall r. (a -> StmA s r) -> StmA s r }
@@ -626,6 +629,11 @@ instance MonadTraceMVar (IOSim s) where
626629
instance MonadLabelledMVar (IOSim s) where
627630
labelMVar = labelMVarDefault
628631

632+
instance MonadUnique (IOSim s) where
633+
type Unique (IOSim s) = IOSimUnique s
634+
newUnique = IOSim (oneShot NewUnique)
635+
hashUnique = hash
636+
629637
data Async s a = Async !IOSimThreadId (STM s (Either SomeException a))
630638

631639
instance Eq (Async s a) where

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

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -200,6 +200,7 @@ data SimState s a = SimState {
200200
nextTmid :: !TimeoutId, -- ^ next unused 'TimeoutId'
201201
-- | previous steps (which we may race with).
202202
-- Note this is *lazy*, so that we don't compute races we will not reverse.
203+
nextUniq :: !(IOSimUnique s), -- ^ next unused @'IOSimUnique' s@
203204
races :: Races,
204205
-- | control the schedule followed, and initial value
205206
control :: !ScheduleControl,
@@ -220,6 +221,7 @@ initialState =
220221
clocks = Map.singleton (ClockId []) epoch1970,
221222
nextVid = 0,
222223
nextTmid = TimeoutId 0,
224+
nextUniq = MkUnique 0,
223225
races = noRaces,
224226
control = ControlDefault,
225227
control0 = ControlDefault,
@@ -273,7 +275,7 @@ schedule thread@Thread{
273275
threads,
274276
timers,
275277
clocks,
276-
nextVid, nextTmid,
278+
nextVid, nextTmid, nextUniq,
277279
curTime = time,
278280
control,
279281
perStepTimeLimit
@@ -814,6 +816,11 @@ schedule thread@Thread{
814816
let thread' = thread { threadControl = ThreadControl k ctl }
815817
schedule thread' simstate
816818

819+
NewUnique k -> do
820+
let thread' = thread{ threadControl = ThreadControl (k nextUniq) ctl }
821+
simstate' = simstate{ nextUniq = MkUnique (unMkUnique nextUniq + 1) }
822+
schedule thread' simstate'
823+
817824

818825
threadInterruptible :: Thread s a -> Bool
819826
threadInterruptible thread =

0 commit comments

Comments
 (0)