@@ -1,6 +1,7 @@
1{-# LANGUAGE CPP #-}
1{-# LANGUAGE CPP #-}
2{-# LANGUAGE KindSignatures #-}
2{-# LANGUAGE KindSignatures #-}
3{-# LANGUAGE ConstraintKinds #-}
3{-# LANGUAGE ConstraintKinds #-}
4+{-# LANGUAGE ExistentialQuantification #-}
4{-# LANGUAGE FlexibleContexts #-}
5{-# LANGUAGE FlexibleContexts #-}
5{-# LANGUAGE FlexibleInstances #-}
6{-# LANGUAGE FlexibleInstances #-}
6{-# LANGUAGE GeneralizedNewtypeDeriving #-}
7{-# LANGUAGE GeneralizedNewtypeDeriving #-}
@@ -79,6 +80,10 @@ module Streamly.SVar
79 , delThread
80 , delThread
81 , toStreamVar
82 , toStreamVar
@@ -122,6 +127,7 @@ import Control.Concurrent.MVar (tryTakeMVar)
122import Control.Exception
127import Control.Exception
123 (catches, throwIO, Handler(..), BlockedIndefinitelyOnMVar(..),
128 (catches, throwIO, Handler(..), BlockedIndefinitelyOnMVar(..),
124 BlockedIndefinitelyOnSTM(..))
129 BlockedIndefinitelyOnSTM(..))
130+import Data.Maybe (isJust)
125import System.IO (hPutStrLn, stderr)
131import System.IO (hPutStrLn, stderr)
@@ -258,6 +264,19 @@ data YieldRateInfo = YieldRateInfo
258 , workerStopTimeStamp :: IORef TimeSpec
264 , workerStopTimeStamp :: IORef TimeSpec
268+data SVarStats = SVarStats {
269+ totalDispatches :: IORef Int
270+ , maxWorkers :: IORef Int
271+ , maxOutQSize :: IORef Int
272+ , maxHeapSize :: IORef Int
273+ , maxWorkQSize :: IORef Int
274+ -- , avgLatency :: IORef NanoSecs
275+ -- , minLatency :: IORef NanoSecs
276+ -- , maxLatency :: IORef NanoSecs
261data Limit = Unlimited | Limited Word deriving Show
280data Limit = Unlimited | Limited Word deriving Show
263data SVar t m a = SVar
282data SVar t m a = SVar
@@ -290,14 +309,12 @@ data SVar t m a = SVar
290 , workerStopMVar :: MVar ()
309 , workerStopMVar :: MVar ()
292#ifdef DIAGNOSTICS
311#ifdef DIAGNOSTICS
312+ -- to track garbage collection of SVar
313+ , svarRef :: Maybe (IORef ())
293 , outputHeap :: IORef (Heap (Entry Int (AheadHeapEntry t m a)) , Int)
314 , outputHeap :: IORef (Heap (Entry Int (AheadHeapEntry t m a)) , Int)
294 -- Shared work queue (stream, seqNo)
315 -- Shared work queue (stream, seqNo)
295− , aheadWorkQueue :: IORef ([t m a], Int)
316+ , aheadWorkQueue :: IORef ([t m a], Int)
296− , totalDispatches :: IORef Int
317+ , svarStats :: SVarStats
297− , maxWorkers :: IORef Int
298− , maxOutQSize :: IORef Int
299− , maxHeapSize :: IORef Int
300− , maxWorkQSize :: IORef Int
@@ -439,6 +456,22 @@ getStreamLatency = _streamLatency
439-------------------------------------------------------------------------------
456-------------------------------------------------------------------------------
441#ifdef DIAGNOSTICS
458#ifdef DIAGNOSTICS
459+dumpSVarStats :: SVarStats -> SVarStyle -> Bool -> IO String
460+dumpSVarStats ss style _paced = do
461+ dispatches <- readIORef $ totalDispatches ss
462+ maxWrk <- readIORef $ maxWorkers ss
463+ maxOq <- readIORef $ maxOutQSize ss
464+ maxHp <- readIORef $ maxHeapSize ss
467+ [ "total dispatches = " ++ show dispatches
468+ , "max workers = " ++ show maxWrk
469+ , "max outQSize = " ++ show maxOq
470+ , if style == AheadVar
471+ then "heap max size = " ++ show maxHp
442{-# NOINLINE dumpSVar #-}
475{-# NOINLINE dumpSVar #-}
443dumpSVar :: SVar t m a -> IO String
476dumpSVar :: SVar t m a -> IO String
444dumpSVar sv = do
477dumpSVar sv = do
@@ -450,38 +483,39 @@ dumpSVar sv = do
451 (oheap, oheapSeq) <- readIORef $ outputHeap sv
484 (oheap, oheapSeq) <- readIORef $ outputHeap sv
452 (wq, wqSeq) <- readIORef $ aheadWorkQueue sv
485 (wq, wqSeq) <- readIORef $ aheadWorkQueue sv
453− maxHp <- readIORef $ maxHeapSize sv
454 return $ unlines
486 return $ unlines
455 [ "heap length = " ++ show (H.size oheap)
487 [ "heap length = " ++ show (H.size oheap)
456 , "heap seqeunce = " ++ show oheapSeq
488 , "heap seqeunce = " ++ show oheapSeq
457 , "work queue length = " ++ show (length wq)
489 , "work queue length = " ++ show (length wq)
458 , "work queue sequence = " ++ show wqSeq
490 , "work queue sequence = " ++ show wqSeq
459− , "heap max size = " ++ show maxHp
461 else return []
492 else return []
494+ let style = svarStyle sv
496+ if style /= ParallelVar
463− waiting <- readIORef $ needDoorBell sv
497+ then readIORef $ needDoorBell sv
464 rthread <- readIORef $ workerThreads sv
499 rthread <- readIORef $ workerThreads sv
465 workers <- readIORef $ workerCount sv
500 workers <- readIORef $ workerCount sv
466− maxWrk <- readIORef $ maxWorkers sv
501+ stats <- dumpSVarStats (svarStats sv) (svarStyle sv)
467− dispatches <- readIORef $ totalDispatches sv
502+ (isJust (yieldRateInfo sv))
468− maxOq <- readIORef $ maxOutQSize sv
470 return $ unlines
504 return $ unlines
471 [ "tid = " ++ show tid
505 [ "tid = " ++ show tid
472 , "style = " ++ show (svarStyle sv)
506 , "style = " ++ show (svarStyle sv)
507+ , "---------CURRENT STATE-----------"
473 , "outputQueue length computed = " ++ show (length oqList)
508 , "outputQueue length computed = " ++ show (length oqList)
474 , "outputQueue length maintained = " ++ show oqLen
509 , "outputQueue length maintained = " ++ show oqLen
475− , "output outputDoorBell = " ++ show db
510+ , "outputDoorBell = " ++ show db
476− , "total dispatches = " ++ show dispatches
477− , "max workers = " ++ show maxWrk
478− , "max outQSize = " ++ show maxOq
480 ++ aheadDump ++ unlines
512 ++ aheadDump ++ unlines
481 [ "needDoorBell = " ++ show waiting
513 [ "needDoorBell = " ++ show waiting
482 , "running threads = " ++ show rthread
514 , "running threads = " ++ show rthread
483 , "running thread count = " ++ show workers
515 , "running thread count = " ++ show workers
517+ ++ "---------STATS-----------\n"
486{-# NOINLINE mvarExcHandler #-}
520{-# NOINLINE mvarExcHandler #-}
487mvarExcHandler :: SVar t m a -> String -> BlockedIndefinitelyOnMVar -> IO ()
521mvarExcHandler :: SVar t m a -> String -> BlockedIndefinitelyOnMVar -> IO ()
@@ -961,9 +995,9 @@ handleChildException sv e = do
961recordMaxWorkers :: MonadIO m => SVar t m a -> m ()
995recordMaxWorkers :: MonadIO m => SVar t m a -> m ()
962recordMaxWorkers sv = liftIO $ do
996recordMaxWorkers sv = liftIO $ do
963 active <- readIORef (workerCount sv)
997 active <- readIORef (workerCount sv)
964− maxWrk <- readIORef (maxWorkers sv)
998+ maxWrk <- readIORef (maxWorkers $ svarStats sv)
965− when (active > maxWrk) $ writeIORef (maxWorkers sv) active
999+ when (active > maxWrk) $ writeIORef (maxWorkers $ svarStats sv) active
966− modifyIORef (totalDispatches sv) (+1)
1000+ modifyIORef (totalDispatches $ svarStats sv) (+1)
969{-# NOINLINE pushWorker #-}
1003{-# NOINLINE pushWorker #-}
@@ -1383,8 +1417,8 @@ readOutputQRaw :: SVar t m a -> IO ([ChildEvent a], Int)
1383readOutputQRaw sv = do
1417readOutputQRaw sv = do
1384 (list, len) <- atomicModifyIORefCAS (outputQueue sv) $ \x -> (([],0), x)
1418 (list, len) <- atomicModifyIORefCAS (outputQueue sv) $ \x -> (([],0), x)
1385#ifdef DIAGNOSTICS
1419#ifdef DIAGNOSTICS
1386− oqLen <- readIORef (maxOutQSize sv)
1420+ oqLen <- readIORef (maxOutQSize $ svarStats sv)
1387− when (len > oqLen) $ writeIORef (maxOutQSize sv) len
1421+ when (len > oqLen) $ writeIORef (maxOutQSize $ svarStats sv) len
1389 return (list, len)
1423 return (list, len)
@@ -1540,13 +1574,16 @@ getAheadSVar st f = do
1540 , accountThread = delThread sv
1574 , accountThread = delThread sv
1541 , workerStopMVar = stopMVar
1575 , workerStopMVar = stopMVar
1542#ifdef DIAGNOSTICS
1576#ifdef DIAGNOSTICS
1577+ , svarRef = Nothing
1543 , aheadWorkQueue = q
1578 , aheadWorkQueue = q
1544 , outputHeap = outH
1579 , outputHeap = outH
1580+ , svarStats = SVarStats
1545− , totalDispatches = disp
1581+ { totalDispatches = disp
1546− , maxWorkers = maxWrk
1582+ , maxWorkers = maxWrk
1547− , maxOutQSize = maxOq
1583+ , maxOutQSize = maxOq
1548− , maxHeapSize = maxHs
1584+ , maxHeapSize = maxHs
1549− , maxWorkQSize = maxWq
1585+ , maxWorkQSize = maxWq
@@ -1611,13 +1648,16 @@ getParallelSVar = do
1611 , accountThread = modifyThread sv
1648 , accountThread = modifyThread sv
1612 , workerStopMVar = undefined
1649 , workerStopMVar = undefined
1613#ifdef DIAGNOSTICS
1650#ifdef DIAGNOSTICS
1651+ , svarRef = Nothing
1614 , aheadWorkQueue = undefined
1652 , aheadWorkQueue = undefined
1615 , outputHeap = undefined
1653 , outputHeap = undefined
1654+ , svarStats = SVarStats
1616− , totalDispatches = disp
1655+ { totalDispatches = disp
1617− , maxWorkers = maxWrk
1656+ , maxWorkers = maxWrk
1618− , maxOutQSize = maxOq
1657+ , maxOutQSize = maxOq
1619− , maxHeapSize = maxHs
1658+ , maxHeapSize = maxHs
1620− , maxWorkQSize = maxWq
1659+ , maxWorkQSize = maxWq
1623 in return sv
1663 in return sv