Data.Concurrent.Deque.Reference: exported symbols usage examples

Symbols

  • _is_using_CAS No usage example found for this symbol :( Collapse [-]
    newBoundedQ No usage example found for this symbol :( Collapse [-]
    newQ No usage example found for this symbol :( Collapse [-]
    nullQ See 5 Occurences [+] Collapse [-]
    Found in Data.Concurrent.Deque.Tests from the package abstract-deque-tests
                 Nothing -> return (cnt,acc)
                 Just n  -> loop (cnt+1) (acc+n)
         in loop 0 0
            
       let finalSum = Prelude.sum (map snd consumer_sums ++ 
                                   map snd prod_ls ++ 
                                   map snd leftovers)
       dbgPrintLn 0$ "Final sum: "++ show finalSum ++ ", producer/consumer/leftover sums: "++show (prod_ls, consumer_sums, leftovers)
       dbgPrintLn 1$ "Total pop events: "++ show (Prelude.sum (map fst consumer_sums ++ 
                                                               map fst prod_ls ++ 
                                                               map fst leftovers))
                     ++" should be "++ (show$ realtotal)
       dbgPrintLn 1$ "Checking that queue is finally null..."
       assertEqual "Correct final sum" (fromIntegral producers * expectedSum perthread) finalSum
       bs <- mapM nullQ qs
       if all id bs
         then dbgPrintLn 1$ "Sum matched expected, test passed."
         else assertFailure "Queue was not empty!!"
    

    Found in Data.Concurrent.Deque.Tests from the package abstract-deque-tests
                  m <- spinPopN 100 (tryPopR (arr ! ix))
                  case m of
                    Just x -> do
                      when (i < 10) $ dbgPrint 1 $ printf " [%d] popped #%d = %d\n" ind i x
                      consume_loop (summ+x) (i+1)
                    Nothing ->
                      consume_loop summ i
            in consume_loop 0 0
    
       dbgPrintLn 1 "Reading sums from MVar..." 
       let finalSum = Prelude.sum sums
       dbgPrintLn 1$ "Final sum: "++ show finalSum ++ ", per-consumer sums: "++show sums
       dbgPrintLn 1$ "Checking that queue is finally null..."
       assertEqual "Correct final sum" (fromIntegral producers * expectedSum perthread) finalSum
       bs <- mapM nullQ qs
       if all id bs
         then dbgPrintLn 1$ "Sum matched expected, test passed."
         else assertFailure "Queue was not empty!!"
    
    -- Sum of first N numbers, starting with ZERO
    

    Found in Data.Concurrent.Deque.Tests from the package abstract-deque-tests
                    when (i < 10) $ dbgPrint 1 $ printf " [%d] popped #%d = %d \n" id i x
                    unless (x == fromIntegral i) $
                      error $ "Message out of order! Expected "++show i++" recevied "++show x
                    consume_loop (sum+x) (max maxiters iters) (i+1)
              pr <- consume_loop 0 0 0
    	  putMVar mv pr
    
         dbgPrint 1 $ printf "Reading sums from MVar...\n" 
         ls <- mapM (\_ -> takeMVar mv) [1..consumers]
         let finalSum = Prelude.sum (map fst ls)
         dbgPrintLn 1$ "Consumers DONE.  Maximum retries for each consumer thread: "++ show (map snd ls)
         dbgPrintLn 1$ "All messages received in order.  Final sum: "++ show finalSum
         assertEqual "Correct final sum" (fromIntegral producers * expectedSum (fromIntegral perthread)) finalSum          
         dbgPrintLn 1$ "Checking that queue is finally null..."
         bs <- mapM nullQ qs
         if all id bs
           then dbgPrintLn 1$ "Sum matched expected, test passed."
           else assertFailure "Queue was not empty!!"
    

    Found in Data.Concurrent.Deque.Tests from the package abstract-deque-tests
              let mymax = if ind==0 then perthread2 + remain else perthread2
                  consume_loop summ maxiters i | i == mymax = return (summ, maxiters)
                  consume_loop !summ !maxiters i = do
                    (x,iters) <- if doBackoff then spinPopBkoff q 
                                              else spinPopHard  q
                    when (i >= mymax - 10) $ dbgPrint 1 $ printf " [c%d] popped #%d = %d \n" ind i x
                    consume_loop (summ+x) (max maxiters iters) (i+1)
              in consume_loop 0 0 0
    
         let finalSum = Prelude.sum (map fst ls)
         dbgPrintLn 1$ "Consumers DONE.  Maximum retries for each consumer thread: "++ show (map snd ls)
         dbgPrintLn 1$ "Final sum: "++ show finalSum
         assertEqual "Correct final sum" (expectedSum (fromIntegral$ producers * perthread)) finalSum
         dbgPrintLn 1$ "Checking that queue is finally null..."
         b <- nullQ q
         if b then dbgPrintLn 1$ "Sum matched expected, test passed."
              else assertFailure "Queue was not empty!!"
    
    -- | This test uses a separate queue per producer/consumer pair.  The queues
    -- are used in a single-writer single-reader.
    

    Found in Data.Concurrent.Deque.Tests from the package abstract-deque-tests
    -- consumers which all communicate through a SINGLE queue.  Each
    -- thread performs its designated operation as fast as possible.  The
    -- 'Int' argument 'total' designates how many total items should be
    -- communicated (irrespective of 'numAgents').
    test_fifo_OneBottleneck :: DequeClass d => Bool -> Int -> d Elt -> IO ()
    test_fifo_OneBottleneck doBackoff total q = 
      do
         assertBool "test_fifo_OneBottleneck requires thread safe left end"  (leftThreadSafe q)
         assertBool "test_fifo_OneBottleneck requires thread safe right end" (rightThreadSafe q)
        
         dbgPrintLn 1$ "\nTest FIFO queue: producers & consumers thru 1 queue"
                   ++(if doBackoff then " (with backoff)" else "(hard busy wait)")
         dbgPrintLn 1 "======================================================"       
    
         bl <- nullQ q
         dbgPrintLn 1$ "Check that queue is initially null: "++show bl
    
         numAgents <- getNumAgents      
         let producers = max 1 (round$ producerRatio * (fromIntegral numAgents) / (producerRatio + 1))
    	 consumers = max 1 (numAgents - producers)
    

    pushL See 11 Occurences [+] Collapse [-]
    Found in Data.Concurrent.Deque.Tests from the package abstract-deque-tests
    test_parfib_work_stealing :: (DequeClass d, PopL d) => Elt -> IO (d Elt) -> IO ()
    test_parfib_work_stealing origInput newqueue = do
      putStrLn$ " [parfib] Computing fib("++show origInput++")"
      numAgents <- getNumAgents
      qs <- sequence (replicate numAgents newqueue)
      let arr = A.listArray (0,numAgents - 1) qs 
      
      let parfib !myId !myQ !mySum !num
            | num <= 2  =
              do x <- tryPopL myQ
                 case x of
                   Nothing -> trySteal myId myQ (mySum+1)
                   Just n  -> parfib myId myQ   (mySum+1) n
            | otherwise = do 
              pushL       myQ       (num-1)
              parfib myId myQ mySum (num-2)
              
          trySteal !myId !myQ !mySum =
            let loop ind
                  -- After we finish one sweep... we're completely done.
    

    Found in Data.Concurrent.Deque.Tests from the package abstract-deque-tests
            let loop :: Elt -> Elt -> Elt -> IO ()
                loop i !pops !acc 
                  | i == perthread = putMVar prod_results (pops,acc)
                  | otherwise = do 
                     -- Randomly push or pop:
                     b   <-  randomIO  :: IO Bool
                     if b then do
                       x <- spinPopN 100 (tryPopL myQ)
                       -- In the case where we pop, we do NOT advance 'i', saving that
                       -- for the next iteration that acutally does a push.
                       case x of
                         Nothing -> loop i  pops    acc
                         Just n  -> loop i (pops+1) (n+acc)
                       else do
                       pushL myQ i
                       -- when (i - ind*producers < 10) $ dbgPrint 1 $ printf " [%d] pushed %d \n" ind i
                       loop (i+1) pops acc
            in loop 0 0 0
    
       -- In this version
    

    Found in Data.Concurrent.Deque.Tests from the package abstract-deque-tests
    -- | Trivial test: push then pop.
    test_ws_triv1 :: PopL d => d [Char] -> IO ()
    test_ws_triv1 q = do
      pushL q "hi" 
      Just x <- tryPopL q 
      assertEqual "test_ws_triv1" x "hi"
    
    -- | Trivial test: push left, pop left and right.
    test_ws_triv2 :: PopL d => d [Char] -> IO ()
    test_ws_triv2 q = do
      pushL q "one" 
      pushL q "two" 
      pushL q "three" 
      pushL q "four" 
      ls <- sequence [tryPopR q, tryPopR q, 
    		  tryPopL q, tryPopL q,
    		  tryPopL q, tryPopR q ]
      assertEqual "test_ws_triv2" ls 
        [Just "one",Just "two",Just "four",Just "three",Nothing,Nothing]
    

    Found in Data.Concurrent.Deque.Tests from the package abstract-deque-tests
    ----------------------------------------------------------------------------------------------------
    
    -- | Trivial test: push then pop.
    test_ws_triv1 :: PopL d => d [Char] -> IO ()
    test_ws_triv1 q = do
      pushL q "hi" 
      Just x <- tryPopL q 
      assertEqual "test_ws_triv1" x "hi"
    
    -- | Trivial test: push left, pop left and right.
    test_ws_triv2 :: PopL d => d [Char] -> IO ()
    test_ws_triv2 q = do
      pushL q "one" 
      pushL q "two" 
      pushL q "three" 
      pushL q "four" 
      ls <- sequence [tryPopR q, tryPopR q, 
    		  tryPopL q, tryPopL q,
    		  tryPopL q, tryPopR q ]
      assertEqual "test_ws_triv2" ls 
    

    Found in Data.Concurrent.Deque.Tests from the package abstract-deque-tests
    -- Test a Work-stealing queue:
    ----------------------------------------------------------------------------------------------------
    
    -- | Trivial test: push then pop.
    test_ws_triv1 :: PopL d => d [Char] -> IO ()
    test_ws_triv1 q = do
      pushL q "hi" 
      Just x <- tryPopL q 
      assertEqual "test_ws_triv1" x "hi"
    
    -- | Trivial test: push left, pop left and right.
    test_ws_triv2 :: PopL d => d [Char] -> IO ()
    test_ws_triv2 q = do
      pushL q "one" 
      pushL q "two" 
      pushL q "three" 
      pushL q "four" 
      ls <- sequence [tryPopR q, tryPopR q, 
    		  tryPopL q, tryPopL q,
    		  tryPopL q, tryPopR q ]
    

    Found in Data.Concurrent.Deque.Tests from the package abstract-deque-tests
    ----------------------------------------------------------------------------------------------------
    -- Test a Work-stealing queue:
    ----------------------------------------------------------------------------------------------------
    
    -- | Trivial test: push then pop.
    test_ws_triv1 :: PopL d => d [Char] -> IO ()
    test_ws_triv1 q = do
      pushL q "hi" 
      Just x <- tryPopL q 
      assertEqual "test_ws_triv1" x "hi"
    
    -- | Trivial test: push left, pop left and right.
    test_ws_triv2 :: PopL d => d [Char] -> IO ()
    test_ws_triv2 q = do
      pushL q "one" 
      pushL q "two" 
      pushL q "three" 
      pushL q "four" 
      ls <- sequence [tryPopR q, tryPopR q, 
    		  tryPopL q, tryPopL q,
    

    Found in Data.Concurrent.Deque.Tests from the package abstract-deque-tests
      [ TestLabel "test_fifo_filldrain"           (TestCase$ assertT $ newq >>= test_fifo_filldrain)
      , TestLabel "test_contention_free_parallel" (TestCase$ assertT $ test_contention_free_parallel True numElems newq)
      ]
    
    assertT :: IO () -> IO ()
    assertT = timeit . assert
    
    ----------------------------------------------------------------------------------------------------
    -- Test a Work-stealing queue:
    ----------------------------------------------------------------------------------------------------
    
    -- | Trivial test: push then pop.
    test_ws_triv1 :: PopL d => d [Char] -> IO ()
    test_ws_triv1 q = do
      pushL q "hi" 
      Just x <- tryPopL q 
      assertEqual "test_ws_triv1" x "hi"
    
    -- | Trivial test: push left, pop left and right.
    test_ws_triv2 :: PopL d => d [Char] -> IO ()
    

    Found in Data.Concurrent.Deque.Tests from the package abstract-deque-tests
       numAgents <- getNumAgents
       let producers = max 1 (round$ producerRatio * (fromIntegral numAgents) / (producerRatio + 1))
           consumers = max 1 (numAgents - producers)
           perthread           = fromIntegral (total `quot` producers)
           (perthread2,remain) = total `quotRem` consumers
       
       dbgPrintLn 1 $ printf "Forking %d producer threads, each producing %d elements.\n" producers perthread
       dbgPrintLn 1 $ printf "Forking %d consumer threads, each consuming ~%d elements.\n" consumers perthread2
    
       forM_ [0..producers-1] $ \ ind -> 
          myfork "producer thread" $
            for_ 0 perthread $ \ i -> do
               -- Randomly pick a position:
               ix <- randomRIO (0,size - 1) :: IO Int
               pushL (arr ! ix) i
               -- when (i - ind*producers < 10) $ dbgPrint 1 $ printf " [%d] pushed %d \n" ind i
    
       -- Each consumer doesn't quit until it has popped "perthread":
       sums <- forkJoin consumers $ \ ind ->
            let mymax = if ind==0 then perthread2 + remain else perthread2
    

    Found in Data.Concurrent.Deque.Tests from the package abstract-deque-tests
    	 perthread  = total `quot` producers
         qs <- sequence (replicate consumers newqueue)
    
         numCap <- getNumCapabilities 
         when (not doBackoff && (numCap == 1 || numCap < producers + consumers)) $ 
           error$ "The aggressively busy-waiting version of the test can only run with the right thread settings."
         
         dbgPrint 1 $ printf "Forking %d producer threads, each producing %d elements.\n" producers perthread
         dbgPrint 1 $ printf "Forking %d consumer threads, each consuming %d elements.\n" consumers perthread
        
         forM_ (zip [0..producers-1] qs) $ \ (id, q) -> 
     	myfork "producer thread" $
              let start = id*perthread in
              forI_ 0 perthread $ \ i -> do 
    	     pushL q i
                 -- when (i - id*producers < 10) $ dbgPrint 1 $ printf " [%d] pushed %d \n" id i
    
         forM_ (zip [0..consumers-1] qs) $ \ (id, q) -> 
     	myfork "consumer thread" $ do 
              let consume_loop sum maxiters i | i == perthread = return (sum, maxiters)
    

    Found in Data.Concurrent.Deque.Tests from the package abstract-deque-tests
             (perthread2,remain) = total `quotRem` consumers
    
         numCap <- getNumCapabilities     
         when (not doBackoff && (numCap == 1 || numCap < producers + consumers)) $ 
           error$ "The aggressively busy-waiting version of the test can only run with the right thread settings."
         
         dbgPrint 1 $ printf "Forking %d producer threads, each producing %d elements.\n" producers perthread
         dbgPrint 1 $ printf "Forking %d consumer threads, each consuming ~%d elements.\n" consumers perthread2
        
         forM_ [0..producers-1] $ \ ind -> 
     	myfork "producer thread" $ do
              let start = ind * perthread 
              dbgPrint 1 $ printf "  * Producer thread %d pushing ints from %d to %d \n" ind start (start+perthread - 1)
              forI_ start (start+perthread) $ \ i -> do 
    	     pushL q i
                 -- when (i < start + 10) $ dbgPrint 1 $ printf " [p%d] pushed %d \n" ind i
    
         ls <- forkJoin consumers $ \ ind ->         
              let mymax = if ind==0 then perthread2 + remain else perthread2
                  consume_loop summ maxiters i | i == mymax = return (summ, maxiters)
    

    Found in Data.Concurrent.Deque.Tests from the package abstract-deque-tests
    -- The type of data that we push over the queues.
    type Elt = Int64
    
    -- | This test serially fills up a queue and then drains it.
    test_fifo_filldrain :: DequeClass d => d Elt -> IO ()
    test_fifo_filldrain q = 
      do
         dbgPrintLn 1 "\nTest FIFO queue: sequential fill and then drain"
         dbgPrintLn 1 "==============================================="
    --     let n = 1000
         let n = fromIntegral numElems
         dbgPrintLn 1$ "Done creating queue.  Pushing "++show n++" elements:"
         forM_ [1..n] $ \i -> do 
           pushL q i
           when (i < 200) $ dbgPrint 1 $ printf " %d" i
         dbgPrintLn 1 "\nDone filling queue with elements.  Now popping..."
         
         let loop 0 !sumR = return sumR
             loop i !sumR = do 
    

    pushR No usage example found for this symbol :( Collapse [-]
    tryPopL See 6 Occurences [+] Collapse [-]
    Found in Data.Concurrent.Deque.Tests from the package abstract-deque-tests
         then dbgPrintLn 1$ "Sum matched expected, test passed."
         else assertFailure "Queue was not empty!!"
    
    
    {-# INLINE test_parfib_work_stealing #-}
    test_parfib_work_stealing :: (DequeClass d, PopL d) => Elt -> IO (d Elt) -> IO ()
    test_parfib_work_stealing origInput newqueue = do
      putStrLn$ " [parfib] Computing fib("++show origInput++")"
      numAgents <- getNumAgents
      qs <- sequence (replicate numAgents newqueue)
      let arr = A.listArray (0,numAgents - 1) qs 
      
      let parfib !myId !myQ !mySum !num
            | num <= 2  =
              do x <- tryPopL myQ
                 case x of
                   Nothing -> trySteal myId myQ (mySum+1)
                   Just n  -> parfib myId myQ   (mySum+1) n
            | otherwise = do 
              pushL       myQ       (num-1)
    

    Found in Data.Concurrent.Deque.Tests from the package abstract-deque-tests
       dbgPrint 1 $ printf "Forking %d producer threads, each producing %d elements.\n" producers perthread
       dbgPrint 1 $ printf "Forking %d consumer threads, each consuming ~%d elements.\n" consumers perthread2
       
       prod_results <- newEmptyMVar
       forM_ (zip [0..producers-1] qs) $ \ (ind,myQ) -> do 
          myfork "producer thread" $
            let loop :: Elt -> Elt -> Elt -> IO ()
                loop i !pops !acc 
                  | i == perthread = putMVar prod_results (pops,acc)
                  | otherwise = do 
                     -- Randomly push or pop:
                     b   <-  randomIO  :: IO Bool
                     if b then do
                       x <- spinPopN 100 (tryPopL myQ)
                       -- In the case where we pop, we do NOT advance 'i', saving that
                       -- for the next iteration that acutally does a push.
                       case x of
                         Nothing -> loop i  pops    acc
                         Just n  -> loop i (pops+1) (n+acc)
    

    Found in Data.Concurrent.Deque.Tests from the package abstract-deque-tests
    test_ws_triv1 q = do
      pushL q "hi" 
      Just x <- tryPopL q 
      assertEqual "test_ws_triv1" x "hi"
    
    -- | Trivial test: push left, pop left and right.
    test_ws_triv2 :: PopL d => d [Char] -> IO ()
    test_ws_triv2 q = do
      pushL q "one" 
      pushL q "two" 
      pushL q "three" 
      pushL q "four" 
      ls <- sequence [tryPopR q, tryPopR q, 
    		  tryPopL q, tryPopL q,
    		  tryPopL q, tryPopR q ]
      assertEqual "test_ws_triv2" ls 
        [Just "one",Just "two",Just "four",Just "three",Nothing,Nothing]
    
    
    {-# INLINE test_random_work_stealing #-}
    

    Found in Data.Concurrent.Deque.Tests from the package abstract-deque-tests
    test_ws_triv1 :: PopL d => d [Char] -> IO ()
    test_ws_triv1 q = do
      pushL q "hi" 
      Just x <- tryPopL q 
      assertEqual "test_ws_triv1" x "hi"
    
    -- | Trivial test: push left, pop left and right.
    test_ws_triv2 :: PopL d => d [Char] -> IO ()
    test_ws_triv2 q = do
      pushL q "one" 
      pushL q "two" 
      pushL q "three" 
      pushL q "four" 
      ls <- sequence [tryPopR q, tryPopR q, 
    		  tryPopL q, tryPopL q,
    		  tryPopL q, tryPopR q ]
      assertEqual "test_ws_triv2" ls 
        [Just "one",Just "two",Just "four",Just "three",Nothing,Nothing]
    

    Found in Data.Concurrent.Deque.Tests from the package abstract-deque-tests
    test_ws_triv1 :: PopL d => d [Char] -> IO ()
    test_ws_triv1 q = do
      pushL q "hi" 
      Just x <- tryPopL q 
      assertEqual "test_ws_triv1" x "hi"
    
    -- | Trivial test: push left, pop left and right.
    test_ws_triv2 :: PopL d => d [Char] -> IO ()
    test_ws_triv2 q = do
      pushL q "one" 
      pushL q "two" 
      pushL q "three" 
      pushL q "four" 
      ls <- sequence [tryPopR q, tryPopR q, 
    		  tryPopL q, tryPopL q,
    		  tryPopL q, tryPopR q ]
      assertEqual "test_ws_triv2" ls 
        [Just "one",Just "two",Just "four",Just "three",Nothing,Nothing]
    

    Found in Data.Concurrent.Deque.Tests from the package abstract-deque-tests
      , TestLabel "test_contention_free_parallel" (TestCase$ assertT $ test_contention_free_parallel True numElems newq)
      ]
    
    assertT :: IO () -> IO ()
    assertT = timeit . assert
    
    ----------------------------------------------------------------------------------------------------
    -- Test a Work-stealing queue:
    ----------------------------------------------------------------------------------------------------
    
    -- | Trivial test: push then pop.
    test_ws_triv1 :: PopL d => d [Char] -> IO ()
    test_ws_triv1 q = do
      pushL q "hi" 
      Just x <- tryPopL q 
      assertEqual "test_ws_triv1" x "hi"
    
    -- | Trivial test: push left, pop left and right.
    test_ws_triv2 :: PopL d => d [Char] -> IO ()
    test_ws_triv2 q = do
    

    tryPopR See 9 Occurences [+] Collapse [-]
    Found in Data.Concurrent.Deque.Tests from the package abstract-deque-tests
                                 hFlush stdout
    			     yield -- At LEAST yield... you'd think this is pretty strong backoff.
    		     loop (n+1)
           Just x  -> return (x, n)
    
    
    -- | This is always a crazy and dangerous thing to do -- GHC cannot deschedule this
    -- spinning thread because it does not allocate.  Thus one can run into a deadlock
    -- situation where the consumer holds the capabilitity hostage, not letting the
    -- producer run (and therefore unblock it).
    spinPopHard :: (DequeClass d) => d t -> IO (t, Int)
    spinPopHard q = loop 1
     where 
      loop n = do
         x <- tryPopR q 
         case x of 
           Nothing -> do loop (n+1)
           Just x  -> return (x, n)
    
    spinPopN :: Int -> IO (Maybe t) -> IO (Maybe t)
    

    Found in Data.Concurrent.Deque.Tests from the package abstract-deque-tests
    -- | Pop from the right end more gently.
    spinPopBkoff :: DequeClass d => d t -> IO (t, Int)
    spinPopBkoff q = loop 1
     where 
      hardspinfor = 10
      sleepevery = 1000
      warnafter  = 5000
      errorafter = 1 * 1000 * 1000
      loop n = do
         when (n == warnafter)
    	  (dbgPrintLn 0$ "Warning: Failed to pop "++ show warnafter ++ 
    	             " times consecutively.  That shouldn't happen in this benchmark.")
    --     when (n == errorafter) (error "This can't be right.  A queue consumer spun 1M times.")
         x <- tryPopR q 
         case x of 
           -- This yields EVERY time.  And yet we get these real bursts / runs of failure.
           Nothing -> do 
                         -- Every `sleepevery` times do a significant delay:
    		     if n `mod` sleepevery == 0 
    

    Found in Data.Concurrent.Deque.Tests from the package abstract-deque-tests
              do x <- tryPopL myQ
                 case x of
                   Nothing -> trySteal myId myQ (mySum+1)
                   Just n  -> parfib myId myQ   (mySum+1) n
            | otherwise = do 
              pushL       myQ       (num-1)
              parfib myId myQ mySum (num-2)
              
          trySteal !myId !myQ !mySum =
            let loop ind
                  -- After we finish one sweep... we're completely done.
                  | ind == myId     = return mySum
                  | ind == size arr = loop 0
                  | otherwise = do
                      x <- tryPopR (arr ! ind)
                      case x of
                        Just n  -> parfib myId myQ mySum n
                        Nothing -> do yield
                                      loop (ind+1)
            in loop (myId+1)
    

    Found in Data.Concurrent.Deque.Tests from the package abstract-deque-tests
                      when (i < 10) $ dbgPrint 1 $ printf " [%d] popped try#%d = %d\n" ind i x
                      consume_loop (summ+x) (successes+1) (i+1)
                    Nothing ->
                      consume_loop summ successes (i+1) -- Increment even if we don't get a result.
            in do dbgPrintLn 1 ("   Beginning consumer thread loop for "++show mymax ++" attempts.")
                  consume_loop 0 0 0
       -- <-- Consumers are finished as of here.
    
       dbgPrintLn 1  "Reading sums from MVar..."
       prod_ls <- mapM (\_ -> takeMVar prod_results) [1..producers]
    
       -- We sequentially read out the leftovers after all the parallel tasks are done:
       leftovers <- forM qs $ \ q ->
         let loop !cnt !acc = do
               x <- tryPopR q -- This should work as a popR OR a popL.
               case x of
                 Nothing -> return (cnt,acc)
                 Just n  -> loop (cnt+1) (acc+n)
         in loop 0 0
            
    

    Found in Data.Concurrent.Deque.Tests from the package abstract-deque-tests
                       pushL myQ i
                       -- when (i - ind*producers < 10) $ dbgPrint 1 $ printf " [%d] pushed %d \n" ind i
                       loop (i+1) pops acc
            in loop 0 0 0
    
       -- In this version
       consumer_sums <- forkJoin consumers $ \ ind ->
            let mymax = if ind==0 then perthread2 + remain else perthread2             
                consume_loop !summ !successes i 
                   | i == mymax = return (successes, summ)
                   | otherwise  = do 
                  -- Randomly pick a position:
                  ix <- randomRIO (0,producers - 1) :: IO Int
                  -- Try to pop something, but not too hard:
                  m <- spinPopN 100 (tryPopR (arr ! ix))
                  case m of
                    Just x -> do
                      when (i < 10) $ dbgPrint 1 $ printf " [%d] popped try#%d = %d\n" ind i x
                      consume_loop (summ+x) (successes+1) (i+1)
                    Nothing ->
    

    Found in Data.Concurrent.Deque.Tests from the package abstract-deque-tests
    test_ws_triv1 q = do
      pushL q "hi" 
      Just x <- tryPopL q 
      assertEqual "test_ws_triv1" x "hi"
    
    -- | Trivial test: push left, pop left and right.
    test_ws_triv2 :: PopL d => d [Char] -> IO ()
    test_ws_triv2 q = do
      pushL q "one" 
      pushL q "two" 
      pushL q "three" 
      pushL q "four" 
      ls <- sequence [tryPopR q, tryPopR q, 
    		  tryPopL q, tryPopL q,
    		  tryPopL q, tryPopR q ]
      assertEqual "test_ws_triv2" ls 
        [Just "one",Just "two",Just "four",Just "three",Nothing,Nothing]
    
    
    {-# INLINE test_random_work_stealing #-}
    

    Found in Data.Concurrent.Deque.Tests from the package abstract-deque-tests
    -- | Trivial test: push then pop.
    test_ws_triv1 :: PopL d => d [Char] -> IO ()
    test_ws_triv1 q = do
      pushL q "hi" 
      Just x <- tryPopL q 
      assertEqual "test_ws_triv1" x "hi"
    
    -- | Trivial test: push left, pop left and right.
    test_ws_triv2 :: PopL d => d [Char] -> IO ()
    test_ws_triv2 q = do
      pushL q "one" 
      pushL q "two" 
      pushL q "three" 
      pushL q "four" 
      ls <- sequence [tryPopR q, tryPopR q, 
    		  tryPopL q, tryPopL q,
    		  tryPopL q, tryPopR q ]
      assertEqual "test_ws_triv2" ls 
        [Just "one",Just "two",Just "four",Just "three",Nothing,Nothing]
    

    Found in Data.Concurrent.Deque.Tests from the package abstract-deque-tests
    -- | Trivial test: push then pop.
    test_ws_triv1 :: PopL d => d [Char] -> IO ()
    test_ws_triv1 q = do
      pushL q "hi" 
      Just x <- tryPopL q 
      assertEqual "test_ws_triv1" x "hi"
    
    -- | Trivial test: push left, pop left and right.
    test_ws_triv2 :: PopL d => d [Char] -> IO ()
    test_ws_triv2 q = do
      pushL q "one" 
      pushL q "two" 
      pushL q "three" 
      pushL q "four" 
      ls <- sequence [tryPopR q, tryPopR q, 
    		  tryPopL q, tryPopL q,
    		  tryPopL q, tryPopR q ]
      assertEqual "test_ws_triv2" ls 
        [Just "one",Just "two",Just "four",Just "three",Nothing,Nothing]
    

    Found in Data.Concurrent.Deque.Tests from the package abstract-deque-tests
            for_ 0 perthread $ \ i -> do
               -- Randomly pick a position:
               ix <- randomRIO (0,size - 1) :: IO Int
               pushL (arr ! ix) i
               -- when (i - ind*producers < 10) $ dbgPrint 1 $ printf " [%d] pushed %d \n" ind i
    
       -- Each consumer doesn't quit until it has popped "perthread":
       sums <- forkJoin consumers $ \ ind ->
            let mymax = if ind==0 then perthread2 + remain else perthread2
                consume_loop summ  i | i == mymax = return summ
                consume_loop !summ i = do
                  -- Randomly pick a position:
                  ix <- randomRIO (0,size-1) :: IO Int
                  -- Try to pop something, but not too hard:
                  m <- spinPopN 100 (tryPopR (arr ! ix))
                  case m of
                    Just x -> do
                      when (i < 10) $ dbgPrint 1 $ printf " [%d] popped #%d = %d\n" ind i x
                      consume_loop (summ+x) (i+1)
                    Nothing ->
    

    tryPushL No usage example found for this symbol :( Collapse [-]
    tryPushR No usage example found for this symbol :( Collapse [-]
    SimpleDeque No usage example found for this symbol :( Collapse [-]