File tree Expand file tree Collapse file tree 5 files changed +47
-6
lines changed
src/Control/Monad/Class/MonadTimer Expand file tree Collapse file tree 5 files changed +47
-6
lines changed Original file line number Diff line number Diff line change 44
55### Breaking changes
66
7- + * Changed ` Time ` show instance, which now is designed for pasting
8- + counterexamples from terminal to an editor.
7+ * Changed ` Time ` show instance, which now is designed for pasting
8+ * counterexamples from terminal to an editor.
99
1010### Non-breaking changes
1111
1212* Improved performance of ` tryReadTBQueueDefault ` .
1313* Added module ` Control.Monad.Class.MonadUnique ` generalising ` Data.Unique ` .
1414* mtl: Added module ` Control.Monad.Class.MonadUnique.Trans ` providing monad transformer instances for ` MonadUnique ` .
15+ * Added ` roundDiffTimeToMicroseconds ` utility function to ` si-timers ` package (in the ` MonadTimer.SI ` module).
1516
1617## 1.8.0.1
1718
Original file line number Diff line number Diff line change @@ -5,6 +5,7 @@ module Control.Monad.Class.MonadTimer.SI
55 -- * Auxiliary functions
66 , diffTimeToMicrosecondsAsInt
77 , microsecondsAsIntToDiffTime
8+ , roundDiffTimeToMicroseconds
89 -- * Re-exports
910 , DiffTime
1011 , MonadFork
@@ -54,6 +55,19 @@ diffTimeToMicrosecondsAsInt d =
5455microsecondsAsIntToDiffTime :: Int -> DiffTime
5556microsecondsAsIntToDiffTime = (/ 1_000_000 ) . fromIntegral
5657
58+ -- | Round to microseconds.
59+ --
60+ -- For negative diff times it rounds towards negative infinity, which is
61+ -- desirable for `MonadTimer` API.
62+ --
63+ roundDiffTimeToMicroseconds :: DiffTime -> DiffTime
64+ roundDiffTimeToMicroseconds d = fromIntegral usec / 1_000_000
65+ where
66+ -- microseconds
67+ usec :: Integer
68+ usec = diffTimeToPicoseconds d `div` 1_000_000
69+
70+
5771class ( MonadTimer. MonadDelay m
5872 , MonadMonotonicTime m
5973 ) => MonadDelay m where
Original file line number Diff line number Diff line change @@ -17,6 +17,8 @@ tests =
1717 prop_diffTimeToMicrosecondsAsIntLeftInverse
1818 , testProperty " diffTimeToMicroseconds right inverse"
1919 prop_diffTimeToMicrosecondsAsIntRightInverse
20+ , testProperty " roundToMicroseconds"
21+ prop_roundDiffTimeToMicroseconds
2022 ]
2123
2224newtype IntDistr = IntDistr Int
@@ -88,3 +90,21 @@ prop_diffTimeToMicrosecondsAsIntRightInverse (DiffTimeDistr a) =
8890 -> " large"
8991 | otherwise
9092 -> " average"
93+
94+
95+ prop_roundDiffTimeToMicroseconds :: DiffTimeDistr -> Property
96+ prop_roundDiffTimeToMicroseconds (DiffTimeDistr d) =
97+ -- rounded is less or equal to d
98+ --
99+ -- NOTE: this guarantees that if `d < 0` then `d' < 0` which is
100+ -- important for `MonadTimer (IOSim s)` instance.
101+ d' <= d
102+ .&&.
103+ -- difference is less than 1 microsecond
104+ abs (d - d') < 0.000_001
105+ .&&.
106+ -- rounded has no fractional microseconds
107+ case properFraction (d' * 1_000_000 ) of
108+ (_ :: Integer , f ) -> f === 0
109+ where
110+ d' = roundDiffTimeToMicroseconds d
Original file line number Diff line number Diff line change 88
99* Added support for unique symbol generation à la ` Data.Unique ` .
1010* Removed a misleading internal comment.
11+ * Round ` si-timers ` ` threadDelay ` to microsecond to match ` IO ` behaviour.
1112
1213## 1.8.0.1
1314
Original file line number Diff line number Diff line change @@ -725,7 +725,8 @@ instance MonadDelay (IOSim s) where
725725
726726instance SI. MonadDelay (IOSim s ) where
727727 threadDelay d =
728- IOSim $ oneShot $ \ k -> ThreadDelay d (k () )
728+ IOSim $ oneShot $ \ k -> ThreadDelay (SI. roundDiffTimeToMicroseconds d)
729+ (k () )
729730
730731data Timeout s = Timeout ! (TVar s TimeoutState ) ! TimeoutId
731732 -- ^ a timeout
@@ -765,11 +766,15 @@ instance SI.MonadTimer (IOSim s) where
765766 timeout d action
766767 | d < 0 = Just <$> action
767768 | d == 0 = return Nothing
768- | otherwise = IOSim $ oneShot $ \ k -> StartTimeout d (runIOSim action) k
769+ | otherwise = IOSim $ oneShot $ \ k ->
770+ StartTimeout (SI. roundDiffTimeToMicroseconds d)
771+ (runIOSim action)
772+ k
769773
770- registerDelay d = IOSim $ oneShot $ \ k -> RegisterDelay d k
774+ registerDelay d = IOSim $ oneShot $ \ k ->
775+ RegisterDelay (SI. roundDiffTimeToMicroseconds d) k
771776 registerDelayCancellable d = do
772- t <- newTimeout d
777+ t <- newTimeout ( SI. roundDiffTimeToMicroseconds d)
773778 return (readTimeout t, cancelTimeout t)
774779
775780newtype TimeoutException = TimeoutException TimeoutId deriving Eq
You can’t perform that action at this time.
0 commit comments