@@ -70,6 +70,8 @@ module Streamly.SVar
71 , queueEmptyAhead
71 , queueEmptyAhead
72 , dequeueAhead
72 , dequeueAhead
74+ , HeapDequeueResult(..)
73 , dequeueFromHeap
75 , dequeueFromHeap
74 , dequeueFromHeapSeq
76 , dequeueFromHeapSeq
75 , requeueOnHeapTop
77 , requeueOnHeapTop
@@ -366,7 +368,8 @@ data SVar t m a = SVar
366 , svarRef :: Maybe (IORef ())
368 , svarRef :: Maybe (IORef ())
367#ifdef DIAGNOSTICS
369#ifdef DIAGNOSTICS
368 , svarCreator :: ThreadId
370 , svarCreator :: ThreadId
369− , outputHeap :: IORef (Heap (Entry Int (AheadHeapEntry t m a)) , Int)
371+ , outputHeap :: IORef ( Heap (Entry Int (AheadHeapEntry t m a))
370 -- Shared work queue (stream, seqNo)
373 -- Shared work queue (stream, seqNo)
371 , aheadWorkQueue :: IORef ([t m a], Int)
374 , aheadWorkQueue :: IORef ([t m a], Int)
@@ -1137,17 +1140,9 @@ dequeueAhead q = liftIO $ do
1137 (x : [], n) -> (([], n), Just (x, n))
1140 (x : [], n) -> (([], n), Just (x, n))
1138 _ -> error "more than one item on queue"
1141 _ -> error "more than one item on queue"
1140−{-# INLINE dequeueFromHeap #-}
1143+-------------------------------------------------------------------------------
1141−dequeueFromHeap
1144+-- Heap manipulation
1142− :: IORef (Heap (Entry Int (AheadHeapEntry t m a)), Int)
1145+-------------------------------------------------------------------------------
1143− -> IO (Maybe (Entry Int (AheadHeapEntry t m a)))
1144−dequeueFromHeap hpVar =
1145− atomicModifyIORef hpVar $ \pair@(hp, snum) -> do
1146− let r = H.uncons hp
1148− Just (ent@(Entry seqNo _ev), hp') | seqNo == snum ->
1149− ((hp', snum), Just ent)
1150− _ -> (pair, Nothing)
1152withIORef :: IORef a -> (a -> IO b) -> IO b
1147withIORef :: IORef a -> (a -> IO b) -> IO b
1153withIORef ref f = readIORef ref >>= f
1148withIORef ref f = readIORef ref >>= f
@@ -1156,46 +1151,72 @@ atomicModifyIORef_ :: IORef a -> (a -> a) -> IO ()
1156atomicModifyIORef_ ref f =
1151atomicModifyIORef_ ref f =
1157 atomicModifyIORef ref $ \x -> (f x, ())
1152 atomicModifyIORef ref $ \x -> (f x, ())
1154+data HeapDequeueResult t m a =
1157+ | Ready (Entry Int (AheadHeapEntry t m a))
1159+{-# INLINE dequeueFromHeap #-}
1161+ :: IORef (Heap (Entry Int (AheadHeapEntry t m a)), Maybe Int)
1162+ -> IO (HeapDequeueResult t m a)
1163+dequeueFromHeap hpVar =
1164+ atomicModifyIORef hpVar $ \pair@(hp, snum) ->
1166+ Nothing -> (pair, Clearing)
1168+ let r = H.uncons hp
1170+ Just (ent@(Entry seqNo _ev), hp') | seqNo == n ->
1171+ ((hp', Nothing), Ready ent)
1172+ _ -> (pair, Waiting n)
1159{-# INLINE canDequeueFromHeap #-}
1174{-# INLINE canDequeueFromHeap #-}
1160canDequeueFromHeap
1175canDequeueFromHeap
1161− :: IORef (Heap (Entry Int (AheadHeapEntry t m a)), Int)
1176+ :: IORef (Heap (Entry Int (AheadHeapEntry t m a)), Maybe Int)
1162 -> IO Bool
1177 -> IO Bool
1163canDequeueFromHeap hpVar =
1178canDequeueFromHeap hpVar =
1164− withIORef hpVar $ \(hp, snum) -> do
1179+ withIORef hpVar $ \(hp, snum) ->
1181+ Nothing -> return True
1165− let r = H.uncons hp
1183+ let r = H.uncons hp
1166− case r of
1184+ case r of
1167− Just ((Entry seqNo _ev), _) -> return $ seqNo == snum
1185+ Just ((Entry seqNo _ev), _) -> return $ seqNo == n
1168− _ -> return False
1186+ _ -> return False
1170{-# INLINE dequeueFromHeapSeq #-}
1188{-# INLINE dequeueFromHeapSeq #-}
1171dequeueFromHeapSeq
1189dequeueFromHeapSeq
1172− :: IORef (Heap (Entry Int (AheadHeapEntry t m a)), Int)
1190+ :: IORef (Heap (Entry Int (AheadHeapEntry t m a)), Maybe Int)
1174− -> IO (Maybe (Entry Int (AheadHeapEntry t m a)))
1192+ -> IO (HeapDequeueResult t m a)
1175−dequeueFromHeapSeq hpVar snum =
1193+dequeueFromHeapSeq hpVar i =
1176− atomicModifyIORef hpVar $ \(hp, _) -> do
1194+ atomicModifyIORef hpVar $ \(hp, snum) ->
1177− let r = H.uncons hp
1197+ let r = H.uncons hp
1178− case r of
1198+ case r of
1179− Just (ent@(Entry seqNo _ev), hp') | seqNo == snum ->
1199+ Just (ent@(Entry seqNo _ev), hp') | seqNo == i ->
1180− ((hp', snum), Just ent)
1200+ ((hp', Nothing), Ready ent)
1181− _ -> ((hp, snum), Nothing)
1201+ _ -> ((hp, Just i), Waiting i)
1202+ Just _ -> error "dequeueFromHeapSeq: unreachable"
1183{-# INLINE requeueOnHeapTop #-}
1204{-# INLINE requeueOnHeapTop #-}
1184requeueOnHeapTop
1205requeueOnHeapTop
1185− :: IORef (Heap (Entry Int (AheadHeapEntry t m a)), Int)
1206+ :: IORef (Heap (Entry Int (AheadHeapEntry t m a)), Maybe Int)
1186 -> Entry Int (AheadHeapEntry t m a)
1207 -> Entry Int (AheadHeapEntry t m a)
1188 -> IO ()
1209 -> IO ()
1189requeueOnHeapTop hpVar ent seqNo =
1210requeueOnHeapTop hpVar ent seqNo =
1190− atomicModifyIORef_ hpVar $ \(hp, _) -> (H.insert ent hp, seqNo)
1211+ atomicModifyIORef_ hpVar $ \(hp, _) -> (H.insert ent hp, Just seqNo)
1192{-# INLINE updateHeapSeq #-}
1213{-# INLINE updateHeapSeq #-}
1193updateHeapSeq
1214updateHeapSeq
1194− :: IORef (Heap (Entry Int (AheadHeapEntry t m a)), Int)
1215+ :: IORef (Heap (Entry Int (AheadHeapEntry t m a)), Maybe Int)
1196 -> IO ()
1217 -> IO ()
1197updateHeapSeq hpVar seqNo =
1218updateHeapSeq hpVar seqNo =
1198− atomicModifyIORef_ hpVar $ \(hp, _) -> (hp, seqNo)
1219+ atomicModifyIORef_ hpVar $ \(hp, _) -> (hp, Just seqNo)
1200-------------------------------------------------------------------------------
1221-------------------------------------------------------------------------------
1201-- WAhead
1222-- WAhead
@@ -1958,7 +1979,7 @@ getYieldRateInfo st = do
1958getAheadSVar :: MonadAsync m
1979getAheadSVar :: MonadAsync m
1959 => State t m a
1980 => State t m a
1960 -> ( IORef ([t m a], Int)
1981 -> ( IORef ([t m a], Int)
1961− -> IORef (Heap (Entry Int (AheadHeapEntry t m a)), Int)
1982+ -> IORef (Heap (Entry Int (AheadHeapEntry t m a)), Maybe Int)
1962 -> State t m a
1983 -> State t m a
1963 -> SVar t m a
1984 -> SVar t m a
1964 -> Maybe WorkerInfo
1985 -> Maybe WorkerInfo
@@ -1966,7 +1987,10 @@ getAheadSVar :: MonadAsync m
1966 -> IO (SVar t m a)
1987 -> IO (SVar t m a)
1967getAheadSVar st f = do
1988getAheadSVar st f = do
1968 outQ <- newIORef ([], 0)
1989 outQ <- newIORef ([], 0)
1990+ -- the second component of the tuple is "Nothing" when heap is being
1991+ -- cleared, "Just n" when we are expecting sequence number n to arrive
1992+ -- before we can start clearing the heap.
1969− outH <- newIORef (H.empty, 0)
1993+ outH <- newIORef (H.empty, Just 0)
1970 outQMv <- newEmptyMVar
1994 outQMv <- newEmptyMVar
1971 active <- newIORef 0
1995 active <- newIORef 0
1972 wfw <- newIORef False
1996 wfw <- newIORef False
@@ -2157,7 +2181,7 @@ newAheadVar :: MonadAsync m
2157 => State t m a
2181 => State t m a
2158 -> t m a
2182 -> t m a
2159 -> ( IORef ([t m a], Int)
2183 -> ( IORef ([t m a], Int)
2160− -> IORef (Heap (Entry Int (AheadHeapEntry t m a)), Int)
2184+ -> IORef (Heap (Entry Int (AheadHeapEntry t m a)), Maybe Int)
2161 -> State t m a
2185 -> State t m a
2162 -> SVar t m a
2186 -> SVar t m a
2163 -> Maybe WorkerInfo
2187 -> Maybe WorkerInfo