#3159: QSem fails with negative quantities
-----------------------------+----------------------------------------------
Reporter:  NeilMitchell      |          Owner:                  
    Type:  bug               |         Status:  new             
Priority:  normal            |      Component:  libraries/base  
 Version:  6.10.2            |       Severity:  major           
Keywords:                    |       Testcase:                  
      Os:  Unknown/Multiple  |   Architecture:  Unknown/Multiple
-----------------------------+----------------------------------------------
 The following program should always give 100 (I think). It doesn't:

 {{{
 import Data.IORef
 import Control.Concurrent

 main = do
    sem <- newQSem (-99)
    r <- newIORef 0
    let incRef = atomicModifyIORef r (\a -> (a+1,a))
    sequence_ $ replicate 100 $ forkIO $ incRef >> signalQSem sem
    waitQSem sem
    v <- readIORef r
    print v
 }}}

 With a 2 processor machine on Windows, using GHC 6.8.3 and 6.10.2 and +RTS
 -N3 I usually get 100, but occasionally get answers such as 49, 82, 95.
 With +RTS -N2 it almost always works.

 From reading the implementation of QSem, it doesn't seem that negative
 availability was considered. A quick look suggests a better implementation
 might be:

 {{{
 -- Invariant: avail >= 1 ==> null blocked

 waitQSem :: QSem -> IO ()
 waitQSem (QSem sem) = do
   (avail,blocked) <- takeMVar sem  -- gain ex. access
   if avail > 0 then
     putMVar sem (avail-1,[])
    else do
     block <- newEmptyMVar
     putMVar sem (avail, blocked++[block])   -- changed line
     takeMVar block

 signalQSem :: QSem -> IO ()
 signalQSem (QSem sem) = do
   (avail,blocked) <- takeMVar sem
   -- changed below
   if null blocked || avail < 0 then
      putMVar sem (avail+1,blocked)
   else
      putMVar sem (avail, tail blocked)
      putMVar (head blocked) ()
 }}}

 Writing parallel code is hard, so I could have easily got this wrong.
 I haven't looked at QSemN, which may need similar fixes (or may
 already deal with this)

 Marking as severity major because it can cause incorrect parallel
 behaviour.

-- 
Ticket URL: <http://hackage.haskell.org/trac/ghc/ticket/3159>
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