@@ -29,12 +29,12 @@ import Data.IntSet (IntSet)
2929import qualified Data.IntSet as Set
3030import Data.Maybe
3131import Data.Tuple.Extra
32+ import Development.IDE.Graph.Classes
3233import qualified Development.IDE.Graph.Internal.Ids as Ids
3334import Development.IDE.Graph.Internal.Intern
3435import qualified Development.IDE.Graph.Internal.Intern as Intern
3536import Development.IDE.Graph.Internal.Rules
3637import Development.IDE.Graph.Internal.Types
37- import Development.IDE.Graph.Classes
3838import System.IO.Unsafe
3939import System.Time.Extra (duration )
4040
@@ -57,8 +57,8 @@ incDatabase db Nothing = do
5757 writeIORef (databaseDirtySet db) Nothing
5858 withLock (databaseLock db) $
5959 Ids. forMutate (databaseValues db) $ \ _ -> second $ \ case
60- Clean x -> Dirty (Just x)
61- Dirty x -> Dirty x
60+ Clean x -> Dirty (Just x)
61+ Dirty x -> Dirty x
6262 Running _ _ x -> Dirty x
6363-- only some keys are dirty
6464incDatabase db (Just kk) = do
@@ -126,25 +126,13 @@ builder db@Database{..} keys = do
126126 pure (id , val)
127127
128128 toForceList <- liftIO $ readIORef toForce
129+ waitAll <- unliftAIO $ mapConcurrentlyAIO_ sequence_ $ increasingChunks toForceList
129130 case toForceList of
130131 [] -> return $ Left results
131132 _ -> return $ Right $ do
132- parallelWait toForceList
133+ waitAll
133134 pure results
134135
135- parallelWait :: [IO () ] -> IO ()
136- parallelWait [] = pure ()
137- parallelWait [one] = one
138- parallelWait many = mapConcurrently_ sequence_ (increasingChunks many)
139-
140- -- >>> increasingChunks [1..20]
141- -- [[1,2],[3,4,5,6],[7,8,9,10,11,12,13,14],[15,16,17,18,19,20]]
142- increasingChunks :: [a ] -> [[a ]]
143- increasingChunks = go 2 where
144- go :: Int -> [a ] -> [[a ]]
145- go _ [] = []
146- go n xx = let (chunk, rest) = splitAt n xx in chunk : go (min 10 (n* 2 )) rest
147-
148136-- | Refresh a key:
149137-- * If no dirty dependencies and we have evaluated the key previously, then we refresh it in the current thread.
150138-- This assumes that the implementation will be a lookup
@@ -256,7 +244,7 @@ asyncWithCleanUp act = do
256244 io <- unliftAIO act
257245 liftIO $ uninterruptibleMask $ \ restore -> do
258246 a <- async $ restore io
259- modifyIORef st (void a : )
247+ atomicModifyIORef'_ st (void a : )
260248 return $ wait a
261249
262250withLockAIO :: Lock -> AIO a -> AIO a
@@ -274,3 +262,22 @@ cleanupAsync ref = uninterruptibleMask_ $ do
274262 asyncs <- readIORef ref
275263 mapM_ (\ a -> throwTo (asyncThreadId a) AsyncCancelled ) asyncs
276264 mapM_ waitCatch asyncs
265+
266+
267+ mapConcurrentlyAIO_ :: (a -> IO () ) -> [a ] -> AIO ()
268+ mapConcurrentlyAIO_ _ [] = pure ()
269+ mapConcurrentlyAIO_ f [one] = liftIO $ f one
270+ mapConcurrentlyAIO_ f many = do
271+ ref <- AIO ask
272+ liftIO $ uninterruptibleMask $ \ restore -> do
273+ asyncs <- liftIO $ traverse async (map (restore . f) many)
274+ liftIO $ atomicModifyIORef'_ ref (asyncs ++ )
275+ traverse_ wait asyncs
276+
277+ -- >>> increasingChunks [1..20]
278+ -- [[1,2],[3,4,5,6],[7,8,9,10,11,12,13,14],[15,16,17,18,19,20]]
279+ increasingChunks :: [a ] -> [[a ]]
280+ increasingChunks = go 2 where
281+ go :: Int -> [a ] -> [[a ]]
282+ go _ [] = []
283+ go n xx = let (chunk, rest) = splitAt n xx in chunk : go (min 10 (n* 2 )) rest
0 commit comments