on master help sign in
Use eager dispatch when dispatching from consumer loop
commit13563a0032a20450d9dbc2faa693cb442dc838f0 authorHarendra Kumar <harendra@composewell.com> dateFri 7 Oct 2022, 01:30 (4 years ago) parent07b2539
5 files changed+17−14
src/Streamly/Internal/Data/Stream/Async/Channel/Append.hs+2−2 src/Streamly/Internal/Data/Stream/Async/Channel/Consumer.hs+4−4 src/Streamly/Internal/Data/Stream/Async/Channel/Dispatcher.hs+6−6 src/Streamly/Internal/Data/Stream/Async/Channel/Interleave.hs+2−2 src/Streamly/Internal/Data/Stream/Channel/Types.hs+3
src/Streamly/Internal/Data/Stream/Async/Channel/Append.hs+2−2
@@ -295,11 +295,11 @@ getLifoSVar mrun cfg = do
295295 case getStreamRate cfg of
296296 Nothing ->
297297 case getYieldLimit cfg of
298− Nothing -> getSVar sv readOutputQBounded
298+ Nothing -> getSVar sv (readOutputQBounded eager)
299299 postProcessBounded
300300 isWorkFinished
301301 workLoopLIFO
302− Just _ -> getSVar sv readOutputQBounded
302+ Just _ -> getSVar sv (readOutputQBounded eager)
303303 postProcessBounded
304304 isWorkFinishedLimited
305305 workLoopLIFOLimited
src/Streamly/Internal/Data/Stream/Async/Channel/Consumer.hs+4−4
@@ -39,8 +39,8 @@ readOutputQChan sv = do
3939 in readOutputQRaw (outputQueue sv) ss
4040
4141readOutputQBounded :: (MonadIO m, MonadBaseControl IO m) =>
42− Channel m a -> m [ChildEvent a]
43−readOutputQBounded sv = do
42+ Bool -> Channel m a -> m [ChildEvent a]
43+readOutputQBounded eager sv = do
4444 (list, len) <- liftIO $ readOutputQChan sv
4545 -- When there is no output seen we dispatch more workers to help
4646 -- out if there is work pending in the work queue.
@@ -64,7 +64,7 @@ readOutputQBounded sv = do
6464
6565 {-# INLINE blockingRead #-}
6666 blockingRead = do
67− sendWorkerWait sendWorkerDelay (dispatchWorker 0) sv
67+ sendWorkerWait eager sendWorkerDelay (dispatchWorker 0) sv
6868 liftIO (fst `fmap` readOutputQChan sv)
6969
7070readOutputQPaced :: (MonadIO m, MonadBaseControl IO m) =>
@@ -83,7 +83,7 @@ readOutputQPaced sv = do
8383
8484 {-# INLINE blockingRead #-}
8585 blockingRead = do
86− sendWorkerWait sendWorkerDelayPaced dispatchWorkerPaced sv
86+ sendWorkerWait False sendWorkerDelayPaced dispatchWorkerPaced sv
8787 liftIO (fst `fmap` readOutputQChan sv)
8888
8989postProcessPaced :: (MonadIO m, MonadBaseControl IO m) => Channel m a -> m Bool
src/Streamly/Internal/Data/Stream/Async/Channel/Dispatcher.hs+6−6
@@ -286,19 +286,19 @@ dispatchWorkerPaced sv = do
286286{-# NOINLINE sendWorkerWait #-}
287287sendWorkerWait
288288 :: MonadIO m
289− => (Channel m a -> IO ())
289+ => Bool
290+ -> (Channel m a -> IO ())
290291 -> (Channel m a -> m Bool)
291292 -> Channel m a
292293 -> m ()
293−sendWorkerWait delay dispatch sv = do
294+sendWorkerWait eager delay dispatch sv = do
294295 -- Note that we are guaranteed to have at least one outstanding worker when
295296 -- we enter this function. So if we sleep we are guaranteed to be woken up
296297 -- by an outputDoorBell, when the worker exits.
297298
298299 liftIO $ delay sv
299300 (_, n) <- liftIO $ readIORef (outputQueue sv)
300− -- XXX or eagerDispatch is true
301− when (n <= 0) $ do
301+ when (n <= 0 || eager) $ do
302302 -- The queue may be empty temporarily if the worker has dequeued the
303303 -- work item but has not enqueued the remaining part yet. For the same
304304 -- reason, a worker may come back if it tries to dequeue and finds the
@@ -356,7 +356,7 @@ sendWorkerWait delay dispatch sv = do
356356 -- forever.
357357
358358 if canDoMore
359− then sendWorkerWait delay dispatch sv
359+ then sendWorkerWait eager delay dispatch sv
360360 else do
361361 liftIO
362362 $ withDiagMVar
@@ -365,7 +365,7 @@ sendWorkerWait delay dispatch sv = do
365365 "sendWorkerWait: nothing to do"
366366 $ takeMVar (outputDoorBell sv)
367367 (_, len) <- liftIO $ readIORef (outputQueue sv)
368− when (len <= 0) $ sendWorkerWait delay dispatch sv
368+ when (len <= 0) $ sendWorkerWait eager delay dispatch sv
369369
370370-- | Start the evaluation of the channel's work queue by kicking off a worker.
371371-- Note: Work queue must not be empty otherwise the worker will exit without
src/Streamly/Internal/Data/Stream/Async/Channel/Interleave.hs+2−2
@@ -216,11 +216,11 @@ getFifoSVar mrun cfg = do
216216 case getStreamRate cfg of
217217 Nothing ->
218218 case getYieldLimit cfg of
219− Nothing -> getSVar sv readOutputQBounded
219+ Nothing -> getSVar sv (readOutputQBounded False)
220220 postProcessBounded
221221 isWorkFinished
222222 workLoopFIFO
223− Just _ -> getSVar sv readOutputQBounded
223+ Just _ -> getSVar sv (readOutputQBounded False)
224224 postProcessBounded
225225 isWorkFinishedLimited
226226 workLoopFIFOLimited
src/Streamly/Internal/Data/Stream/Channel/Types.hs+3
@@ -478,6 +478,9 @@ getInspectMode = _inspectMode
478478-- option is on the evaluation is aggressive and does not wait for consumption
479479-- to proceed, the only reason it might block is because of 'maxThreads' or
480480-- 'maxBuffer' limitation.
481+--
482+-- Note that this option does nothing for interleave operations or when rate
483+-- has been specified.
481484eagerEval :: Config -> Config
482485eagerEval st = st { _eagerDispatch = True }
483486