Skip to content

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
To upload designs, you'll need to enable LFS and have an admin enable hashed storage. More information