[GHC] #986: SMP race condition in getContents
GHC
trac at galois.com
Sat Nov 4 08:25:38 EST 2006
#986: SMP race condition in getContents
-------------------------+--------------------------------------------------
Reporter: int-e | Owner:
Type: bug | Status: new
Priority: normal | Milestone:
Component: Compiler | Version: 6.6
Severity: normal | Keywords:
Difficulty: Unknown | Testcase:
Architecture: x86 | Os: Linux
-------------------------+--------------------------------------------------
This is a problem mentioned in the Haskell on SMP paper in section 3.5. If
a thunk contains an {{{unsafePerformIO}}} or was created by
{{{unsafeInterleaveIO}}}, evaluating it multiple times is harmful. The
code below triggers this problem.
{{{
import Data.List
import Data.Char
import Control.Parallel
import System.IO
{-# NOINLINE fool #-}
-- 'fool' just makes sure CSE doesn't meddle with the code below
fool :: [a] -> [a]
fool (x:xs) = xs
main = do
hSetBuffering stdin NoBuffering
hs <- getContents
let -- create copies of the input
ts = map (:hs) ['a'..'z']
-- sum the characters of each copy
qs = map (foldl' (+) 0 . map ord . fool) ts
-- in parallel
rs = foldr (\x y -> x `par` y `par` (x:y)) [] qs
-- compare the results and print 'True' if they are all equal.
-- This should never print 'False'
print $ all (uncurry (==)) $ zip rs (tail rs)
}}}
Don Steward kindly tried it on an SMP machine with the following results:
{{{
<dons> $ ghc -O A.hs -threaded
<dons> /tmp/ghc5400_0/ghc5400_0.hc:275:0:
<dons> warning: implicit declaration of function 'newSpark'
<dons> -- good sign I got the right rts
<dons> $ yes abqszzzq | head -c 100000 | ./a.out +RTS -N1
<dons> True
<dons> $ yes abqszzzq | head -c 100000 | ./a.out +RTS -N2
<dons> False
<dons> $ uname -msr
<dons> Linux 2.6.15.3-general i686
<dons> with SMP kernel
<dons> CPU7: Intel(R) Xeon(TM) CPU 2.80GHz stepping 08
<dons> Total of 8 processors activated (44807.44 BogoMIPS).
}}}
To solve this problem, we need something like the {{{justOnce}}} suggested
in the paper. It should be used in {{{unsafePerformIO}}} and
{{{unsafeInterleaveIO}}}. Non-locking versions could be provided as
{{{unlockedUnsafePerformIO}}} and {{{unlockedInterleaveIO}}}. This would
allow existing libraries to work on SMP without or with just minor
modifications, as far as I can see. The assumption that a thunk is
evaluated at most once is fairly widespread.
--
Ticket URL: <http://hackage.haskell.org/trac/ghc/ticket/986>
GHC <http://www.haskell.org/ghc/>
The Glasgow Haskell Compiler
More information about the Glasgow-haskell-bugs
mailing list