Investigate use of floating-point arithmetic in I/O Event-handler
I was asked/made aware of some questionable use of floating-point arithmetic in GHC.Event.TimerManager;
Specifically, I can't explain why getMonotonicTime first gets a timestamp as Word64, only to perform a not-necessarily cheap floating-point division, and returns a Double...
-- | Return monotonic time in seconds, since some unspecified starting point
getMonotonicTime :: IO Double
getMonotonicTime = do w <- getMonotonicNSec
return (fromIntegral w / 1000000000)
foreign import ccall unsafe "getMonotonicNSec"
getMonotonicNSec :: IO Word64
which then gets used e.g. by
updateTimeout :: TimerManager -> TimeoutKey -> Int -> IO ()
updateTimeout mgr (TK key) us = do
now <- getMonotonicTime
let expTime = fromIntegral us / 1000000.0 + now
editTimeouts mgr (Q.adjust (const expTime) key)
wakeManager mgr
Whereas, the priority queue (GHC.Event.PSQ) then uses Doubles for its priorities...
For correctness and performance reasons, I'd expect the use of fixed-width integers (i.e. Word64 or Int64) for such codepaths...
Trac metadata
| Trac field | Value |
|---|---|
| Version | 8.0.1 |
| Type | Task |
| TypeOfFailure | OtherFailure |
| Priority | normal |
| Resolution | Unresolved |
| Component | libraries/base |
| Test case | |
| Differential revisions | |
| BlockedBy | |
| Related | |
| Blocking | |
| CC | davean |
| Operating system | |
| Architecture |