@@ -148,6 +148,7 @@ import GHC.Fingerprint
148
148
import Language.LSP.Types.Capabilities
149
149
import OpenTelemetry.Eventlog
150
150
151
+ import Control.Concurrent.STM.Stats (atomicallyNamed )
151
152
import Control.Exception.Extra hiding (bracket_ )
152
153
import Data.Aeson (toJSON )
153
154
import qualified Data.ByteString.Char8 as BS8
@@ -342,11 +343,11 @@ lastValueIO s@ShakeExtras{positionMapping,persistentKeys,state} k file = do
342
343
MaybeT $ pure $ (,del,ver) <$> fromDynamic dv
343
344
case mv of
344
345
Nothing -> do
345
- void $ atomically $ STM. focus (Focus. alter (alterValue $ Failed True )) (toKey k file) state
346
+ void $ atomicallyNamed " lastValueIO 1 " $ STM. focus (Focus. alter (alterValue $ Failed True )) (toKey k file) state
346
347
return Nothing
347
348
Just (v,del,ver) -> do
348
- void $ atomically $ STM. focus (Focus. alter (alterValue $ Stale (Just del) ver (toDyn v))) (toKey k file) state
349
- atomically $ Just . (v,) . addDelta del <$> mappingForVersion positionMapping file ver
349
+ void $ atomicallyNamed " lastValueIO 2 " $ STM. focus (Focus. alter (alterValue $ Stale (Just del) ver (toDyn v))) (toKey k file) state
350
+ atomicallyNamed " lastValueIO 3 " $ Just . (v,) . addDelta del <$> mappingForVersion positionMapping file ver
350
351
351
352
-- We got a new stale value from the persistent rule, insert it in the map without affecting diagnostics
352
353
alterValue new Nothing = Just (ValueWithDiagnostics new mempty ) -- If it wasn't in the map, give it empty diagnostics
@@ -356,13 +357,13 @@ lastValueIO s@ShakeExtras{positionMapping,persistentKeys,state} k file = do
356
357
-- Something already succeeded before, leave it alone
357
358
_ -> old
358
359
359
- atomically (STM. lookup (toKey k file) state) >>= \ case
360
+ atomicallyNamed " lastValueIO 4 " (STM. lookup (toKey k file) state) >>= \ case
360
361
Nothing -> readPersistent
361
362
Just (ValueWithDiagnostics v _) -> case v of
362
363
Succeeded ver (fromDynamic -> Just v) ->
363
- atomically $ Just . (v,) <$> mappingForVersion positionMapping file ver
364
+ atomicallyNamed " lastValueIO 5 " $ Just . (v,) <$> mappingForVersion positionMapping file ver
364
365
Stale del ver (fromDynamic -> Just v) ->
365
- atomically $ Just . (v,) . maybe id addDelta del <$> mappingForVersion positionMapping file ver
366
+ atomicallyNamed " lastValueIO 6 " $ Just . (v,) . maybe id addDelta del <$> mappingForVersion positionMapping file ver
366
367
Failed p | not p -> readPersistent
367
368
_ -> pure Nothing
368
369
@@ -439,7 +440,7 @@ deleteValue
439
440
-> k
440
441
-> NormalizedFilePath
441
442
-> IO ()
442
- deleteValue ShakeExtras {dirtyKeys, state} key file = atomically $ do
443
+ deleteValue ShakeExtras {dirtyKeys, state} key file = atomicallyNamed " deleteValue " $ do
443
444
STM. delete (toKey key file) state
444
445
modifyTVar' dirtyKeys $ HSet. insert (toKey key file)
445
446
@@ -450,7 +451,7 @@ recordDirtyKeys
450
451
-> [NormalizedFilePath ]
451
452
-> IO ()
452
453
recordDirtyKeys ShakeExtras {dirtyKeys} key file = withEventTrace " recordDirtyKeys" $ \ addEvent -> do
453
- atomically $ modifyTVar' dirtyKeys $ \ x -> foldl' (flip HSet. insert) x (toKey key <$> file)
454
+ atomicallyNamed " recordDirtyKeys " $ modifyTVar' dirtyKeys $ \ x -> foldl' (flip HSet. insert) x (toKey key <$> file)
454
455
addEvent (fromString $ " dirty " <> show key) (fromString $ unlines $ map fromNormalizedFilePath file)
455
456
456
457
@@ -626,8 +627,8 @@ shakeRestart IdeState{..} reason acts =
626
627
(\ runner -> do
627
628
(stopTime,() ) <- duration (cancelShakeSession runner)
628
629
res <- shakeDatabaseProfile shakeDb
629
- backlog <- readTVarIO ( dirtyKeys shakeExtras)
630
- queue <- atomically $ peekInProgress $ actionQueue shakeExtras
630
+ backlog <- readTVarIO $ dirtyKeys shakeExtras
631
+ queue <- atomicallyNamed " actionQueue - peek " $ peekInProgress $ actionQueue shakeExtras
631
632
let profile = case res of
632
633
Just fp -> " , profile saved at " <> fp
633
634
_ -> " "
@@ -660,7 +661,7 @@ notifyTestingLogMessage extras msg = do
660
661
shakeEnqueue :: ShakeExtras -> DelayedAction a -> IO (IO a )
661
662
shakeEnqueue ShakeExtras {actionQueue, logger} act = do
662
663
(b, dai) <- instantiateDelayedAction act
663
- atomically $ pushQueue dai actionQueue
664
+ atomicallyNamed " actionQueue - push " $ pushQueue dai actionQueue
664
665
let wait' b =
665
666
waitBarrier b `catches`
666
667
[ Handler (\ BlockedIndefinitelyOnMVar ->
@@ -669,7 +670,7 @@ shakeEnqueue ShakeExtras{actionQueue, logger} act = do
669
670
, Handler (\ e@ AsyncCancelled -> do
670
671
logPriority logger Debug $ T. pack $ actionName act <> " was cancelled"
671
672
672
- atomically $ abortQueue dai actionQueue
673
+ atomicallyNamed " actionQueue - abort " $ abortQueue dai actionQueue
673
674
throw e)
674
675
]
675
676
return (wait' b >>= either throwIO return )
@@ -684,7 +685,7 @@ newSession
684
685
-> IO ShakeSession
685
686
newSession extras@ ShakeExtras {.. } shakeDb acts reason = do
686
687
IdeOptions {optRunSubset} <- getIdeOptionsIO extras
687
- reenqueued <- atomically $ peekInProgress actionQueue
688
+ reenqueued <- atomicallyNamed " actionQueue - peek " $ peekInProgress actionQueue
688
689
allPendingKeys <-
689
690
if optRunSubset
690
691
then Just <$> readTVarIO dirtyKeys
@@ -693,14 +694,14 @@ newSession extras@ShakeExtras{..} shakeDb acts reason = do
693
694
-- A daemon-like action used to inject additional work
694
695
-- Runs actions from the work queue sequentially
695
696
pumpActionThread otSpan = do
696
- d <- liftIO $ atomically $ popQueue actionQueue
697
+ d <- liftIO $ atomicallyNamed " action queue - pop " $ popQueue actionQueue
697
698
actionFork (run otSpan d) $ \ _ -> pumpActionThread otSpan
698
699
699
700
-- TODO figure out how to thread the otSpan into defineEarlyCutoff
700
701
run _otSpan d = do
701
702
start <- liftIO offsetTime
702
703
getAction d
703
- liftIO $ atomically $ doneQueue d actionQueue
704
+ liftIO $ atomicallyNamed " actionQueue - done " $ doneQueue d actionQueue
704
705
runTime <- liftIO start
705
706
let msg = T. pack $ " finish: " ++ actionName d
706
707
++ " (took " ++ showDuration runTime ++ " )"
@@ -759,11 +760,11 @@ instantiateDelayedAction (DelayedAction _ s p a) = do
759
760
760
761
getDiagnostics :: IdeState -> IO [FileDiagnostic ]
761
762
getDiagnostics IdeState {shakeExtras = ShakeExtras {diagnostics}} = do
762
- atomically $ getAllDiagnostics diagnostics
763
+ atomicallyNamed " getAllDiagnostics " $ getAllDiagnostics diagnostics
763
764
764
765
getHiddenDiagnostics :: IdeState -> IO [FileDiagnostic ]
765
766
getHiddenDiagnostics IdeState {shakeExtras = ShakeExtras {hiddenDiagnostics}} = do
766
- atomically $ getAllDiagnostics hiddenDiagnostics
767
+ atomicallyNamed " getAllDiagnostics - hidden " $ getAllDiagnostics hiddenDiagnostics
767
768
768
769
-- | Find and release old keys from the state Hashmap
769
770
-- For the record, there are other state sources that this process does not release:
@@ -803,7 +804,7 @@ garbageCollectKeys label maxAge checkParents agedKeys = do
803
804
| age > maxAge
804
805
, Just (kt,_) <- fromKeyType k
805
806
, not (kt `HSet.member` preservedKeys checkParents)
806
- = atomically $ do
807
+ = atomicallyNamed " GC " $ do
807
808
gotIt <- STM. focus (Focus. member <* Focus. delete) k values
808
809
when gotIt $
809
810
modifyTVar' dk (HSet. insert k)
@@ -907,7 +908,7 @@ useWithStaleFast' key file = do
907
908
wait <- delayedAction $ mkDelayedAction (" C:" ++ show key ++ " :" ++ fromNormalizedFilePath file) Debug $ use key file
908
909
909
910
s@ ShakeExtras {state} <- askShake
910
- r <- liftIO $ atomically $ getValues state key file
911
+ r <- liftIO $ atomicallyNamed " useStateFast " $ getValues state key file
911
912
liftIO $ case r of
912
913
-- block for the result if we haven't computed before
913
914
Nothing -> do
@@ -1016,7 +1017,7 @@ defineEarlyCutoff' doDiagnostics cmp key file old mode action = do
1016
1017
(if optSkipProgress options key then id else inProgress progress file) $ do
1017
1018
val <- case old of
1018
1019
Just old | mode == RunDependenciesSame -> do
1019
- v <- liftIO $ atomically $ getValues state key file
1020
+ v <- liftIO $ atomicallyNamed " defineEarlyCutoff - read 1 " $ getValues state key file
1020
1021
case v of
1021
1022
-- No changes in the dependencies and we have
1022
1023
-- an existing successful result.
@@ -1035,10 +1036,10 @@ defineEarlyCutoff' doDiagnostics cmp key file old mode action = do
1035
1036
(do v <- action; liftIO $ evaluate $ force v) $
1036
1037
\ (e :: SomeException ) -> do
1037
1038
pure (Nothing , ([ideErrorText file $ T. pack $ show e | not $ isBadDependency e],Nothing ))
1038
- modTime <- liftIO $ (currentValue . fst =<< ) <$> atomically (getValues state GetModificationTime file)
1039
+ modTime <- liftIO $ (currentValue . fst =<< ) <$> atomicallyNamed " defineEarlyCutoff - read 2 " (getValues state GetModificationTime file)
1039
1040
(bs, res) <- case res of
1040
1041
Nothing -> do
1041
- staleV <- liftIO $ atomically $ getValues state key file
1042
+ staleV <- liftIO $ atomicallyNamed " defineEarlyCutoff -read 3 " $ getValues state key file
1042
1043
pure $ case staleV of
1043
1044
Nothing -> (toShakeValue ShakeResult bs, Failed False )
1044
1045
Just v -> case v of
@@ -1049,7 +1050,7 @@ defineEarlyCutoff' doDiagnostics cmp key file old mode action = do
1049
1050
(Failed b, _) ->
1050
1051
(toShakeValue ShakeResult bs, Failed b)
1051
1052
Just v -> pure (maybe ShakeNoCutoff ShakeResult bs, Succeeded (vfsVersion =<< modTime) v)
1052
- liftIO $ atomically $ setValues state key file res (Vector. fromList diags)
1053
+ liftIO $ atomicallyNamed " defineEarlyCutoff - write " $ setValues state key file res (Vector. fromList diags)
1053
1054
doDiagnostics diags
1054
1055
let eq = case (bs, fmap decodeShakeValue old) of
1055
1056
(ShakeResult a, Just (ShakeResult b)) -> cmp a b
@@ -1061,7 +1062,7 @@ defineEarlyCutoff' doDiagnostics cmp key file old mode action = do
1061
1062
(if eq then ChangedRecomputeSame else ChangedRecomputeDiff )
1062
1063
(encodeShakeValue bs) $
1063
1064
A res
1064
- liftIO $ atomically $ modifyTVar' dirtyKeys (HSet. delete $ toKey key file)
1065
+ liftIO $ atomicallyNamed " defineEarlyCutoff - dirtyKeys " $ modifyTVar' dirtyKeys (HSet. delete $ toKey key file)
1065
1066
return res
1066
1067
1067
1068
traceA :: A v -> String
@@ -1149,7 +1150,7 @@ updateFileDiagnostics :: MonadIO m
1149
1150
-> [(ShowDiagnostic ,Diagnostic )] -- ^ current results
1150
1151
-> m ()
1151
1152
updateFileDiagnostics fp k ShakeExtras {logger, diagnostics, hiddenDiagnostics, publishedDiagnostics, state, debouncer, lspEnv} current = liftIO $ do
1152
- modTime <- (currentValue . fst =<< ) <$> atomically (getValues state GetModificationTime fp)
1153
+ modTime <- (currentValue . fst =<< ) <$> atomicallyNamed " diagnostics - read " (getValues state GetModificationTime fp)
1153
1154
let (currentShown, currentHidden) = partition ((== ShowDiag ) . fst ) current
1154
1155
uri = filePathToUri' fp
1155
1156
ver = vfsVersion =<< modTime
@@ -1159,13 +1160,13 @@ updateFileDiagnostics fp k ShakeExtras{logger, diagnostics, hiddenDiagnostics, p
1159
1160
-- published. Otherwise, we might never publish certain diagnostics if
1160
1161
-- an exception strikes between modifyVar but before
1161
1162
-- publishDiagnosticsNotification.
1162
- newDiags <- liftIO $ atomically $ update (map snd currentShown) diagnostics
1163
- _ <- liftIO $ atomically $ update (map snd currentHidden) hiddenDiagnostics
1163
+ newDiags <- liftIO $ atomicallyNamed " diagnostics - update " $ update (map snd currentShown) diagnostics
1164
+ _ <- liftIO $ atomicallyNamed " diagnostics - hidden " $ update (map snd currentHidden) hiddenDiagnostics
1164
1165
let uri = filePathToUri' fp
1165
1166
let delay = if null newDiags then 0.1 else 0
1166
1167
registerEvent debouncer delay uri $ do
1167
1168
join $ mask_ $ do
1168
- lastPublish <- atomically $ STM. focus (Focus. lookupWithDefault [] <* Focus. insert newDiags) uri publishedDiagnostics
1169
+ lastPublish <- atomicallyNamed " diagnostics - publish " $ STM. focus (Focus. lookupWithDefault [] <* Focus. insert newDiags) uri publishedDiagnostics
1169
1170
let action = when (lastPublish /= newDiags) $ case lspEnv of
1170
1171
Nothing -> -- Print an LSP event.
1171
1172
logInfo logger $ showDiagnosticsColored $ map (fp,ShowDiag ,) newDiags
@@ -1224,7 +1225,7 @@ getAllDiagnostics =
1224
1225
1225
1226
updatePositionMapping :: IdeState -> VersionedTextDocumentIdentifier -> List TextDocumentContentChangeEvent -> IO ()
1226
1227
updatePositionMapping IdeState {shakeExtras = ShakeExtras {positionMapping}} VersionedTextDocumentIdentifier {.. } (List changes) =
1227
- atomically $ STM. focus (Focus. alter f) uri positionMapping
1228
+ atomicallyNamed " updatePositionMapping " $ STM. focus (Focus. alter f) uri positionMapping
1228
1229
where
1229
1230
uri = toNormalizedUri _uri
1230
1231
f = Just . f' . fromMaybe mempty
0 commit comments