
[moving to glasgow-haskell-bugs] On Wed, Nov 15, 2006 at 11:40:12PM +0000, Neil Davies wrote:
however when -threaded is used you get some interesting effects, including returning too early:
Tgt/Actual = 0.000125/0.000034s, diff = -0.000091s
Thanks for the report; I can reproduce it on Linux/amd64. OK, so the bug here is that threadDelay n might return after less than n microseconds. This looks like it's caused by truncation problems when converting times to ticks (where a tick is 1/50 of a second), e.g. while trying to sleep for 1.953125s one run started at 1164157960.773726s which is (Int) 1164157960 * 50 + 773726 * 50 / 1000000 = (Int) 58207898038.6863 = 58207898038 ticks and woke the thread up at 1164157962.708609s which is (Int) 1164157962 * 50 + 708609 * 50 / 1000000 = (Int) 58207898135.4305 = 58207898135 ticks The difference is 58207898135 - 58207898038 = 97 ticks. Meanwhile we're trying to sleep for (Int) 50 * 1.953125 = (Int) 97.65625 = 97 ticks However, 1164157962.708609s - 1164157960.773726s = 1.93488311767578s which is 0.0182418823242201s too short. The problem is that we have counted 0.6863 ticks before the start time, not counted 0.4305 ticks before the finish time and have been waiting 0.65625 ticks too short a time. Thus we have counted (0.6863-0.4305 + 0.65625) / 50 == 0.018241 too much time. I think the answer is that let target = now + usecs `quot` tick_usecs in GHC/Conc.lhs should be let target = 1 + now + (usecs + tick_usecs - 1) `quot` tick_usecs I'm also a bit dubious about the use of the constant "50" for the number of ticks per second, but the results with +RTS -V0.001 don't look any more wrong so perhaps I just need to get some sleep. You can get the same symptoms with the non-threaded RTS with +RTS -V0.001, although they are less frequent. I suspect we need a similar fix to target = (R1 / (TO_W_(RtsFlags_MiscFlags_tickInterval(RtsFlags))*1000)) + time; in delayzh_fast in PrimOps.cmm. Thanks Ian