@@ -1,6 +1,7 @@
11{-# LANGUAGE CPP #-}
22{-# LANGUAGE KindSignatures #-}
33{-# LANGUAGE ConstraintKinds #-}
4+{-# LANGUAGE ExistentialQuantification #-}
45{-# LANGUAGE FlexibleContexts #-}
56{-# LANGUAGE FlexibleInstances #-}
67{-# LANGUAGE GeneralizedNewtypeDeriving #-}
@@ -79,6 +80,10 @@ module Streamly.SVar
7980 , delThread
8081
8182 , toStreamVar
83+#ifdef DIAGNOSTICS
84+ , SVarStats (..)
85+ , dumpSVar
86+#endif
8287 )
8388where
8489
@@ -122,6 +127,7 @@ import Control.Concurrent.MVar (tryTakeMVar)
122127import Control.Exception
123128 (catches, throwIO, Handler(..), BlockedIndefinitelyOnMVar(..),
124129 BlockedIndefinitelyOnSTM(..))
130+import Data.Maybe (isJust)
125131import System.IO (hPutStrLn, stderr)
126132#endif
127133
@@ -258,6 +264,19 @@ data YieldRateInfo = YieldRateInfo
258264 , workerStopTimeStamp :: IORef TimeSpec
259265 }
260266
267+#ifdef DIAGNOSTICS
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
277+}
278+#endif
279+
261280data Limit = Unlimited | Limited Word deriving Show
262281
263282data SVar t m a = SVar
@@ -290,14 +309,12 @@ data SVar t m a = SVar
290309 , workerStopMVar :: MVar ()
291310
292311#ifdef DIAGNOSTICS
312+ -- to track garbage collection of SVar
313+ , svarRef :: Maybe (IORef ())
293314 , outputHeap :: IORef (Heap (Entry Int (AheadHeapEntry t m a)) , Int)
294315 -- Shared work queue (stream, seqNo)
295− , aheadWorkQueue :: IORef ([t m a], Int)
296− , totalDispatches :: IORef Int
297− , maxWorkers :: IORef Int
298− , maxOutQSize :: IORef Int
299− , maxHeapSize :: IORef Int
300− , maxWorkQSize :: IORef Int
316+ , aheadWorkQueue :: IORef ([t m a], Int)
317+ , svarStats :: SVarStats
301318#endif
302319 }
303320
@@ -439,6 +456,22 @@ getStreamLatency = _streamLatency
439456-------------------------------------------------------------------------------
440457
441458#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
465+
466+ return $ unlines
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
472+ else ""
473+ ]
474+
442475{-# NOINLINE dumpSVar #-}
443476dumpSVar :: SVar t m a -> IO String
444477dumpSVar sv = do
@@ -450,38 +483,39 @@ dumpSVar sv = do
450483 then do
451484 (oheap, oheapSeq) <- readIORef $ outputHeap sv
452485 (wq, wqSeq) <- readIORef $ aheadWorkQueue sv
453− maxHp <- readIORef $ maxHeapSize sv
454486 return $ unlines
455487 [ "heap length = " ++ show (H.size oheap)
456488 , "heap seqeunce = " ++ show oheapSeq
457489 , "work queue length = " ++ show (length wq)
458490 , "work queue sequence = " ++ show wqSeq
459− , "heap max size = " ++ show maxHp
460491 ]
461492 else return []
462493
463− waiting <- readIORef $ needDoorBell sv
494+ let style = svarStyle sv
495+ waiting <-
496+ if style /= ParallelVar
497+ then readIORef $ needDoorBell sv
498+ else return False
464499 rthread <- readIORef $ workerThreads sv
465500 workers <- readIORef $ workerCount sv
466− maxWrk <- readIORef $ maxWorkers sv
467− dispatches <- readIORef $ totalDispatches sv
468− maxOq <- readIORef $ maxOutQSize sv
501+ stats <- dumpSVarStats (svarStats sv) (svarStyle sv)
502+ (isJust (yieldRateInfo sv))
469503
470504 return $ unlines
471505 [ "tid = " ++ show tid
472506 , "style = " ++ show (svarStyle sv)
507+ , "---------CURRENT STATE-----------"
473508 , "outputQueue length computed = " ++ show (length oqList)
474509 , "outputQueue length maintained = " ++ show oqLen
475− , "output outputDoorBell = " ++ show db
476− , "total dispatches = " ++ show dispatches
477− , "max workers = " ++ show maxWrk
478− , "max outQSize = " ++ show maxOq
510+ , "outputDoorBell = " ++ show db
479511 ]
480512 ++ aheadDump ++ unlines
481513 [ "needDoorBell = " ++ show waiting
482514 , "running threads = " ++ show rthread
483515 , "running thread count = " ++ show workers
484516 ]
517+ ++ "---------STATS-----------\n"
518+ ++ stats
485519
486520{-# NOINLINE mvarExcHandler #-}
487521mvarExcHandler :: SVar t m a -> String -> BlockedIndefinitelyOnMVar -> IO ()
@@ -961,9 +995,9 @@ handleChildException sv e = do
961995recordMaxWorkers :: MonadIO m => SVar t m a -> m ()
962996recordMaxWorkers sv = liftIO $ do
963997 active <- readIORef (workerCount sv)
964− maxWrk <- readIORef (maxWorkers sv)
965− when (active > maxWrk) $ writeIORef (maxWorkers sv) active
966− modifyIORef (totalDispatches sv) (+1)
998+ maxWrk <- readIORef (maxWorkers $ svarStats sv)
999+ when (active > maxWrk) $ writeIORef (maxWorkers $ svarStats sv) active
1000+ modifyIORef (totalDispatches $ svarStats sv) (+1)
9671001#endif
9681002
9691003{-# NOINLINE pushWorker #-}
@@ -1383,8 +1417,8 @@ readOutputQRaw :: SVar t m a -> IO ([ChildEvent a], Int)
13831417readOutputQRaw sv = do
13841418 (list, len) <- atomicModifyIORefCAS (outputQueue sv) $ \x -> (([],0), x)
13851419#ifdef DIAGNOSTICS
1386− oqLen <- readIORef (maxOutQSize sv)
1387− when (len > oqLen) $ writeIORef (maxOutQSize sv) len
1420+ oqLen <- readIORef (maxOutQSize $ svarStats sv)
1421+ when (len > oqLen) $ writeIORef (maxOutQSize $ svarStats sv) len
13881422#endif
13891423 return (list, len)
13901424
@@ -1540,13 +1574,16 @@ getAheadSVar st f = do
15401574 , accountThread = delThread sv
15411575 , workerStopMVar = stopMVar
15421576#ifdef DIAGNOSTICS
1577+ , svarRef = Nothing
15431578 , aheadWorkQueue = q
15441579 , outputHeap = outH
1545− , totalDispatches = disp
1546− , maxWorkers = maxWrk
1547− , maxOutQSize = maxOq
1548− , maxHeapSize = maxHs
1549− , maxWorkQSize = maxWq
1580+ , svarStats = SVarStats
1581+ { totalDispatches = disp
1582+ , maxWorkers = maxWrk
1583+ , maxOutQSize = maxOq
1584+ , maxHeapSize = maxHs
1585+ , maxWorkQSize = maxWq
1586+ }
15501587#endif
15511588 }
15521589
@@ -1611,13 +1648,16 @@ getParallelSVar = do
16111648 , accountThread = modifyThread sv
16121649 , workerStopMVar = undefined
16131650#ifdef DIAGNOSTICS
1651+ , svarRef = Nothing
16141652 , aheadWorkQueue = undefined
16151653 , outputHeap = undefined
1616− , totalDispatches = disp
1617− , maxWorkers = maxWrk
1618− , maxOutQSize = maxOq
1619− , maxHeapSize = maxHs
1620− , maxWorkQSize = maxWq
1654+ , svarStats = SVarStats
1655+ { totalDispatches = disp
1656+ , maxWorkers = maxWrk
1657+ , maxOutQSize = maxOq
1658+ , maxHeapSize = maxHs
1659+ , maxWorkQSize = maxWq
1660+ }
16211661#endif
16221662 }
16231663 in return sv