@@ -153,7 +153,7 @@ newtype NanoSecs = NanoSecs Word64
153153 , Ord
154154 )
155155
156−newtype Count = Count Word64
156+newtype Count = Count Int64
157157 deriving ( Eq
158158 , Read
159159 , Show
@@ -672,14 +672,16 @@ doFork action exHandler =
672672-- througput is high or when the cost of synchronization is high. For example
673673-- if the application is distributed then inc/dec of a shared variable may be
674674-- very costly.
675+--
676+-- Note that we need it to be an Int type so that we have the ability to undo a
677+-- decrement that takes below zero.
675678{-# INLINE decrementYieldLimit #-}
676679decrementYieldLimit :: SVar t m a -> IO Bool
677680decrementYieldLimit sv =
678681 case remainingYields sv of
679682 Nothing -> return True
680683 Just ref -> do
681− r <- atomicModifyIORefCAS ref $ \x ->
682− (if x >= 1 then x - 1 else 0, x)
684+ r <- atomicModifyIORefCAS ref $ \x -> (x - 1, x)
683685 return $ r >= 1
684686
685687-- decrementYieldLimit returns False when the old limit is 0. This one returns
@@ -690,13 +692,9 @@ decrementYieldLimitPost sv =
690692 case remainingYields sv of
691693 Nothing -> return True
692694 Just ref -> do
693− r <- atomicModifyIORefCAS ref $ \x ->
694− (if x >= 1 then x - 1 else 0, x)
695+ r <- atomicModifyIORefCAS ref $ \x -> (x - 1, x)
695696 return $ r > 1
696697
697−-- XXX increment is not safe when the yield limit was already 0
698−-- and therefore was not decremented. We need yield limit to be
699−-- int and negative if we want this to work.
700698{-# INLINE incrementYieldLimit #-}
701699incrementYieldLimit :: SVar t m a -> IO ()
702700incrementYieldLimit sv =
@@ -1143,8 +1141,8 @@ dispatchWorker yieldCount sv = do
11431141 -- style.
11441142 limit <- case remainingYields sv of
11451143 Nothing -> return workerLimit
1146− Just x -> do
1147− n <- liftIO $ readIORef x
1144+ Just ref -> do
1145+ n <- liftIO $ readIORef ref
11481146 return $
11491147 case workerLimit of
11501148 Unlimited -> Limited (fromIntegral n)