[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