Opened 5 years ago

Closed 9 months ago

Last modified 9 months ago

#7325 closed bug (fixed)

threadDelay mistreats minBound and maxBound in some configurations

Reported by: joeyadams Owned by:
Priority: high Milestone: 8.2.1
Component: Runtime System Version: 7.6.1
Keywords: Cc: johan.tibell@…, simonmar, AndreasVoellmy
Operating System: Windows Architecture: Unknown/Multiple
Type of failure: Incorrect result at runtime Test Case: base/tests/T8089
Blocked By: Blocking:
Related Tickets: #9722 Differential Rev(s): Phab:D2861
Wiki Page:

Description

threadDelay currently treats minBound and maxBound incorrectly in some cases. This breaks the following idiom (as seen in the async package):

forever (threadDelay maxBound)

On Linux (Ubuntu 10.04 64-bit) without -threaded, threadDelay maxBound returns immediately. For lower numbers on the same order of magnitude, it behaves non-deterministically. For example, given this program:

import Control.Concurrent
import Control.Monad

main = forM_ [6244222868950683224..] $ \i -> do
    print i
    threadDelay i

threadDelay returns immediately in some cases but not in others. If I compile and run it in bash like this:

ghc-7.6.1 -fforce-recomp threadDelay-maxBound.hs ; ./threadDelay-maxBound

The bug usually appears, but if I run it like this:

ghc-7.6.1 -fforce-recomp threadDelay-maxBound.hs
./threadDelay-maxBound

The bug does not appear (threadDelay blocks like it should). Thus, the program is affected by a very subtle difference in how it is invoked. Perhaps it is sensitive to file descriptor numbers.

On Windows without -threaded, threadDelay maxBound seems to work, but threadDelay minBound blocks rather than returning immediately.

Change History (16)

comment:1 Changed 5 years ago by tibbe

Cc: johan.tibell@… added

comment:2 Changed 5 years ago by simonmar

difficulty: Unknown
Milestone: 7.6.2
Priority: normalhigh

See #6019 for the maxBound problem. I haven't investigated the minBound problem yet.

comment:3 Changed 3 years ago by thoughtpolice

Milestone: 7.6.27.10.1

Moving to 7.10.1.

comment:4 Changed 3 years ago by kim

Cc: simonmar added

On OSX 10.9 and ghc 7.8.x I'm seeing the following behaviour:

  • threadDelay minBound returns immediately (with or without -threaded )
  • threadDelay maxBound without -threaded , the program terminates with:
    maxbound: select: Invalid Argument
    
    (similar to #6019)
  • threadDelay maxBound with -threaded prints on stderr:
    maxbound: c_poll: invalid argument (Invalid argument)
    maxbound: ioManagerWakeup: write: Bad file descriptor
    
    and then appears to hang. When running it on a different thread, which is then killed from the main thread after some time, the following line is printed in after the above:
    maxbound: ioManagerWakeup: write: Bad file descriptor
    
    The program makes no progress after the thread got killed. Curiously, on another machine with same OS and ghc versions but more cores, the program crashes instead of hangs.

(similar to #5544)

  • as described by the reporter, for some values < maxBound but in the same order of magnitude, the errors disappear, but for others they don't.

Please do let me know if providing dtruss output would be helpful.

Last edited 3 years ago by kim (previous) (diff)

comment:5 Changed 3 years ago by AndreasVoellmy

Cc: AndreasVoellmy added

comment:6 Changed 3 years ago by Feuerbach

comment:7 Changed 3 years ago by thoughtpolice

Milestone: 7.10.17.12.1

Moving to 7.12.1

comment:8 Changed 3 years ago by thomie

comment:9 Changed 2 years ago by thomie

Operating System: Unknown/MultipleWindows
Test Case: base/tests/T8089

The issue around threadDelay maxBound on OS X is I think fixed. At least, #8089 added a test for it, which is supposedly passing on OS X.

That makes this a Windows only problem now.

Unexpected failures:

. T8089 [bad exit code] (normal,hpc,optasm)

comment:10 Changed 2 years ago by Thomas Miedema <thomasmiedema@…>

In 1857191/ghc:

Testsuite: mark T8089 expect_broken(#7325) on Windows

comment:11 Changed 2 years ago by thoughtpolice

Milestone: 7.12.18.0.1

Milestone renamed

comment:12 Changed 19 months ago by bgamari

Milestone: 8.0.18.2.1

This won't be fixed in 8.0.1.

comment:13 Changed 9 months ago by bgamari

Differential Rev(s): Phab:D2861
Status: newpatch

threadDelay minBound no longer appears to block on Windows. However, threadDelay maxBound returns immediately. See Phab:D2861 for a fix.

comment:14 Changed 9 months ago by Ben Gamari <ben@…>

In 2d1beb1e/ghc:

rts/win32/IOManager: Fix integer types

This code has been broken on 64-bit systems for some time: the length
and timeout arguments of `addIORequest` and `addDelayRequest`,
respectively, were declared as `int`. However, they were passed Haskell
integers from their respective primops. Integer overflow and madness
ensued. This resulted in #7325 and who knows what else.

Also, there were a few left-over `BOOL`s in here which were not passed
to Windows system calls; these were changed to C99 `bool`s.

However, there is still a bit of signedness inconsistency within the
`delay#` call-chain,

 * `GHC.Conc.IO.threadDelay` and the `delay#` primop accept `Int`
   arguments

 * The `delay#` implementation in `PrimOps.cmm` expects the timeout as
   a `W_`

 * `AsyncIO.c:addDelayRequest` expects an `HsInt` (was `int` prior to
   this patch)

 * `IOManager.c:AddDelayRequest` expects an `HsInt`` (was `int`)

 * The Windows `Sleep` function expects a `DWORD` (which is unsigned)

Test Plan: Validate on Windows

Reviewers: erikd, austin, simonmar, Phyx

Reviewed By: Phyx

Subscribers: thomie

Differential Revision: https://phabricator.haskell.org/D2861

GHC Trac Issues: #7325

comment:15 Changed 9 months ago by bgamari

Resolution: fixed
Status: patchclosed

comment:16 Changed 9 months ago by Ben Gamari <ben@…>

In c0c1f801/ghc:

Mark T8089 as unbroken since #7325 is now resolved
Note: See TracTickets for help on using tickets.