#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

Reply via email to