#5865: threadDelay is disrupted by system clock changes
-----------------------------------------+----------------------------------
Reporter: joeyadams | Owner:
Type: bug | Status: new
Priority: normal | Component: Runtime System
Version: 7.4.1 | Keywords:
Os: Unknown/Multiple | Architecture: Unknown/Multiple
Failure: Incorrect result at runtime | Testcase:
Blockedby: | Blocking:
Related: |
-----------------------------------------+----------------------------------
threadDelay is sensitive to changes to the system clock. Two behaviors
are observed:
* When the system clock is moved forward, threadDelay will timeout
prematurely, because it thinks that amount of time elapsed.
* When the system clock is moved backward, threadDelay will take longer
to complete, because it's waiting for the system clock to catch up.
Whether these behaviors are present depends on both the operating system
and the use of -threaded. Here are the configurations I tested:
* ghc-7.4.1 Linux 64-bit: Disrupted by both forward and backward clock
changes
* ghc-7.4.1 Linux 64-bit, '''-threaded''': Disrupted only by backward
clock changes
* ghc-7.2.2 Windows 32-bit: Not disrupted by clock changes (behaves
correctly)
* ghc-7.2.2 Windows 32-bit, '''-threaded''': Disrupted only by backward
clock changes
To reproduce the problem, first compile the attached program. It uses
System.Posix.Clock from the "clock" package to get the time, unaffected by
system clock changes. Then run it. It will produce output like this:
{{{
0: 0s
1: 10s
}}}
Set the system clock forward by a minute. On Linux without -threaded, it
will print something like this:
{{{
5: 50s
6: 52s
}}}
6 is printed 2 seconds after 5, because threadDelay didn't wait a full 10
seconds like it should have.
Now set the system clock backward by a minute. On Windows with -threaded,
or on Linux with or without -threaded, it will print something like this:
{{{
3: 30s
4: 101s
}}}
4 is printed over a minute after 3, because threadDelay waited for the
system clock to recover the time subtracted by changing the time.
For convenience, here's a way to fix the system clock on Linux after
fiddling around with it:
{{{
sudo ntpdate pool.ntp.org
}}}
Digging through the source, each configuration seems to boil down to the
following system calls:
* Linux: gettimeofday (via getourtimeofday in posix/Itimer.c)
* Linux, '''-threaded''': gettimeofday, epoll_wait
* Windows: [http://msdn.microsoft.com/en-
us/library/windows/desktop/ms686298%28v=vs.85%29.aspx Sleep]
* Windows, '''-threaded''': [http://msdn.microsoft.com/en-
us/library/windows/desktop/ms724397%28v=vs.85%29.aspx
GetSystemTimeAsFileTime], [http://msdn.microsoft.com/en-
us/library/windows/desktop/ms687032%28v=vs.85%29.aspx WaitForSingleObject]
Perhaps the calls to gettimeofday and GetSystemTimeAsFileTime should be
replaced with monotonic time functions (i.e. ones not affected by system
clock changes):
* Linux, FreeBSD: http://stackoverflow.com/q/211055/149391
* Mac OS X: http://stackoverflow.com/a/6725161/149391
* Windows: http://stackoverflow.com/q/211257/149391
--
Ticket URL: <http://hackage.haskell.org/trac/ghc/ticket/5865>
GHC <http://www.haskell.org/ghc/>
The Glasgow Haskell Compiler
_______________________________________________
Glasgow-haskell-bugs mailing list
[email protected]
http://www.haskell.org/mailman/listinfo/glasgow-haskell-bugs