Skip to content

Commit 2479e6b

Browse files
committed
io-sim: Add support for unique symbol generation
1 parent 630af74 commit 2479e6b

File tree

6 files changed

+50
-4
lines changed

6 files changed

+50
-4
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+
, Unique
5152
-- ** Dynamic Tracing
5253
, traceM
5354
, traceSTM

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

Lines changed: 12 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+
, Unique (..)
3133
-- * Utils
3234
, ppList
3335
) where
@@ -202,6 +204,16 @@ 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+
newtype Unique s = MkUnique{ unMkUnique :: Integer }
209+
deriving stock (Eq, Ord)
210+
deriving newtype NFData
211+
type role Unique nominal
212+
213+
instance Hashable (Unique s) where
214+
hash = fromInteger . unMkUnique
215+
hashWithSalt = defaultHashWithSalt
216+
205217
--
206218
-- Utils
207219
--

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

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -143,7 +143,8 @@ data SimState s a = SimState {
143143
-- | list of clocks
144144
clocks :: !(Map ClockId UTCTime),
145145
nextVid :: !VarId, -- ^ next unused 'VarId'
146-
nextTmid :: !TimeoutId -- ^ next unused 'TimeoutId'
146+
nextTmid :: !TimeoutId, -- ^ next unused 'TimeoutId'
147+
nextUniq :: !(Unique s) -- ^ next unused @'Unique' 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,13 @@ 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+
n = unMkUnique nextUniq
639+
simstate' = simstate{ nextUniq = MkUnique (n + 1) }
640+
SimTrace time tid tlbl (EventUniqueCreated n)
641+
<$> schedule thread' simstate'
642+
634643

635644
threadInterruptible :: Thread s a -> Bool
636645
threadInterruptible thread =

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

Lines changed: 13 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)
@@ -122,6 +124,7 @@ import GHC.Generics (Generic)
122124
import Quiet (Quiet (..))
123125

124126
import Control.Monad.IOSim.CommonTypes
127+
import Control.Monad.IOSim.CommonTypes qualified as Sim
125128
import Control.Monad.IOSim.STM
126129
import Control.Monad.IOSimPOR.Types
127130

@@ -193,6 +196,7 @@ data SimA s a where
193196
ExploreRaces :: SimA s b -> SimA s b
194197

195198
Fix :: (x -> IOSim s x) -> (x -> SimA s r) -> SimA s r
199+
NewUnique :: (Sim.Unique s -> SimA s r) -> SimA s r
196200

197201

198202
newtype STM s a = STM { unSTM :: forall r. (a -> StmA s r) -> StmA s r }
@@ -626,6 +630,11 @@ instance MonadTraceMVar (IOSim s) where
626630
instance MonadLabelledMVar (IOSim s) where
627631
labelMVar = labelMVarDefault
628632

633+
instance MonadUnique (IOSim s) where
634+
type Unique (IOSim s) = Sim.Unique s
635+
newUnique = IOSim (oneShot NewUnique)
636+
hashUnique = hash
637+
629638
data Async s a = Async !IOSimThreadId (STM s (Either SomeException a))
630639

631640
instance Eq (Async s a) where
@@ -1056,6 +1065,9 @@ data SimEventType
10561065
| EventThreadUnhandled SomeException
10571066
-- ^ thread terminated by an unhandled exception
10581067

1068+
| EventUniqueCreated Integer
1069+
-- ^ created the n-th 'Unique'
1070+
10591071
--
10601072
-- STM events
10611073
--
@@ -1163,6 +1175,7 @@ ppSimEventType = \case
11631175
EventThreadFinished -> "ThreadFinished"
11641176
EventThreadUnhandled a ->
11651177
"ThreadUnhandled " ++ show a
1178+
EventUniqueCreated n -> "UniqueCreated " ++ show n
11661179
EventTxCommitted written created mbEff ->
11671180
concat [ "TxCommitted ",
11681181
ppList (ppLabelled show) written, " ",

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

Lines changed: 10 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 :: !(Unique s), -- ^ next unused @'Unique' 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,13 @@ 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+
n = unMkUnique nextUniq
822+
simstate' = simstate{ nextUniq = MkUnique (n + 1) }
823+
SimPORTrace time tid tstep tlbl (EventUniqueCreated n)
824+
<$> schedule thread' simstate'
825+
817826

818827
threadInterruptible :: Thread s a -> Bool
819828
threadInterruptible thread =

0 commit comments

Comments
 (0)