getCPUTime implementation incorrect?

I've just noticed that getCPUTime is returning erratic results for me: GHCi, version 7.0.3: http://www.haskell.org/ghc/ :? for help Loading package ghc-prim ... linking ... done. Loading package integer-gmp ... linking ... done. Loading package base ... linking ... done. Loading package ffi-1.0 ... linking ... done. Loading package filepath-1.2.0.0 ... linking ... done. Prelude> :m System.CPUTime Prelude System.CPUTime> getCPUTime 9696631700340362000000 Prelude System.CPUTime> getCPUTime 1333572622260398592000000 Prelude System.CPUTime> getCPUTime 21577331579851694000000 Prelude System.CPUTime> getCPUTime 21577331579861838000000 Prelude System.CPUTime> getCPUTime 1061231477620269514000000 Prelude System.CPUTime> getCPUTime 9965140170836829000000 This is ghc 7.0.3, OS X 10.6.7, and it's the x86_64 version downloaded from http://www.haskell.org/ghc/download_ghc_7_0_3 So, I looked at the CPUTime.hsc source in the base library, and it uses CTime to get tv_sec and tv_usec fields from the struct timeval. Unfortunately, and I never knew this, tv_usec is not time_t, but is suseconds_t. On my OS X, these are different types: time_t is 64 bits but suseconds_t is 32 bits. After writing my own getCPUTime that uses Int32 for tv_usec it's back to working again. But the proper way to do this is probably to introduce CSUSeconds (I'm guessing it stands for signed microseconds), which I guess means editing the autoconfig to put a new define in HsBaseConfig.h. I dont know anything about autoconfig, but it's probably easy enough for someone is :)

On 31/05/2011 04:37, Evan Laforge wrote:
I've just noticed that getCPUTime is returning erratic results for me:
GHCi, version 7.0.3: http://www.haskell.org/ghc/ :? for help Loading package ghc-prim ... linking ... done. Loading package integer-gmp ... linking ... done. Loading package base ... linking ... done. Loading package ffi-1.0 ... linking ... done. Loading package filepath-1.2.0.0 ... linking ... done. Prelude> :m System.CPUTime Prelude System.CPUTime> getCPUTime 9696631700340362000000 Prelude System.CPUTime> getCPUTime 1333572622260398592000000 Prelude System.CPUTime> getCPUTime 21577331579851694000000 Prelude System.CPUTime> getCPUTime 21577331579861838000000 Prelude System.CPUTime> getCPUTime 1061231477620269514000000 Prelude System.CPUTime> getCPUTime 9965140170836829000000
This is ghc 7.0.3, OS X 10.6.7, and it's the x86_64 version downloaded from http://www.haskell.org/ghc/download_ghc_7_0_3
So, I looked at the CPUTime.hsc source in the base library, and it uses CTime to get tv_sec and tv_usec fields from the struct timeval. Unfortunately, and I never knew this, tv_usec is not time_t, but is suseconds_t. On my OS X, these are different types: time_t is 64 bits but suseconds_t is 32 bits. After writing my own getCPUTime that uses Int32 for tv_usec it's back to working again.
But the proper way to do this is probably to introduce CSUSeconds (I'm guessing it stands for signed microseconds), which I guess means editing the autoconfig to put a new define in HsBaseConfig.h. I dont know anything about autoconfig, but it's probably easy enough for someone is :)
See http://hackage.haskell.org/trac/ghc/ticket/4247 and http://hackage.haskell.org/trac/ghc/ticket/4970 We ought to fix this in 7.0.4, since getCPUTime is pretty broken on OSX 64-bit right now, but the fix involves an API change (to Foreign.C.Types). Ian - could we apply a fix that doesn't change APIs? Cheers, Simon

See
http://hackage.haskell.org/trac/ghc/ticket/4247
and
http://hackage.haskell.org/trac/ghc/ticket/4970
We ought to fix this in 7.0.4, since getCPUTime is pretty broken on OSX 64-bit right now, but the fix involves an API change (to Foreign.C.Types). Ian - could we apply a fix that doesn't change APIs?
At least getCPUTime could be, since its use of CTime is internal. Adding new types to Foreign.C shouldn't break anyone, and if you change getCPUTime to internally use the new type no one outside will be the wiser. Except they can remove their OS X workarounds :)
participants (2)
-
Evan Laforge
-
Simon Marlow