@@ -16,53 +16,56 @@ module Development.IDE.Core.Tracing
16
16
)
17
17
where
18
18
19
- import Control.Concurrent.Async (Async , async )
20
- import Control.Concurrent.Extra ( Var , modifyVar_ , newVar ,
21
- readVar , threadDelay )
22
- import Control.Exception (evaluate )
23
- import Control.Exception.Safe (SomeException , catch ,
24
- generalBracket )
25
- import Control.Monad (forM_ , forever , void , when ,
26
- (>=>) )
27
- import Control.Monad.Catch (ExitCase (.. ), MonadMask )
28
- import Control.Monad.Extra (whenJust )
19
+ import Control.Concurrent.Async (Async , async )
20
+ import Control.Concurrent.Extra ( modifyVar_ , newVar , readVar ,
21
+ threadDelay )
22
+ import Control.Exception (evaluate )
23
+ import Control.Exception.Safe (SomeException , catch ,
24
+ generalBracket )
25
+ import Control.Monad (forM_ , forever , void , when ,
26
+ (>=>) )
27
+ import Control.Monad.Catch (ExitCase (.. ), MonadMask )
28
+ import Control.Monad.Extra (whenJust )
29
29
import Control.Monad.IO.Unlift
30
- import Control.Seq (r0 , seqList , seqTuple2 , using )
31
- import Data.ByteString (ByteString )
32
- import Data.ByteString.Char8 (pack )
33
- import Data.Dynamic (Dynamic )
34
- import qualified Data.HashMap.Strict as HMap
35
- import Data.IORef (modifyIORef' , newIORef ,
36
- readIORef , writeIORef )
37
- import Data.String (IsString (fromString ))
38
- import qualified Data.Text as T
39
- import Data.Text.Encoding (encodeUtf8 )
40
- import Data.Typeable (TypeRep , typeOf )
41
- import Data.Word (Word16 )
42
- import Debug.Trace.Flags (userTracingEnabled )
43
- import Development.IDE.Core.RuleTypes (GhcSession (GhcSession ),
44
- GhcSessionDeps (GhcSessionDeps ),
45
- GhcSessionIO (GhcSessionIO ))
46
- import Development.IDE.Graph (Action )
30
+ import Control.Monad.STM (atomically )
31
+ import Control.Seq (r0 , seqList , seqTuple2 ,
32
+ using )
33
+ import Data.ByteString (ByteString )
34
+ import Data.ByteString.Char8 (pack )
35
+ import qualified Data.HashMap.Strict as HMap
36
+ import Data.IORef (modifyIORef' , newIORef ,
37
+ readIORef , writeIORef )
38
+ import Data.String (IsString (fromString ))
39
+ import qualified Data.Text as T
40
+ import Data.Text.Encoding (encodeUtf8 )
41
+ import Data.Typeable (TypeRep , typeOf )
42
+ import Data.Word (Word16 )
43
+ import Debug.Trace.Flags (userTracingEnabled )
44
+ import Development.IDE.Core.RuleTypes (GhcSession (GhcSession ),
45
+ GhcSessionDeps (GhcSessionDeps ),
46
+ GhcSessionIO (GhcSessionIO ))
47
+ import Development.IDE.Graph (Action )
47
48
import Development.IDE.Graph.Rule
48
- import Development.IDE.Types.Diagnostics (FileDiagnostic , showDiagnostics )
49
- import Development.IDE.Types.Location (Uri (.. ))
50
- import Development.IDE.Types.Logger (Logger (Logger ), logDebug ,
51
- logInfo )
52
- import Development.IDE.Types.Shake (Value ,
53
- ValueWithDiagnostics (.. ),
54
- Values , fromKeyType )
55
- import Foreign.Storable (Storable (sizeOf ))
56
- import HeapSize (recursiveSize , runHeapsize )
57
- import Ide.PluginUtils (installSigUsr1Handler )
58
- import Ide.Types (PluginId (.. ))
59
- import Language.LSP.Types (NormalizedFilePath ,
60
- fromNormalizedFilePath )
61
- import Numeric.Natural (Natural )
62
- import OpenTelemetry.Eventlog (SpanInFlight (.. ), addEvent ,
63
- beginSpan , endSpan ,
64
- mkValueObserver , observe ,
65
- setTag , withSpan , withSpan_ )
49
+ import Development.IDE.Types.Diagnostics (FileDiagnostic ,
50
+ showDiagnostics )
51
+ import Development.IDE.Types.Location (Uri (.. ))
52
+ import Development.IDE.Types.Logger (Logger (Logger ), logDebug ,
53
+ logInfo )
54
+ import Development.IDE.Types.Shake (ValueWithDiagnostics (.. ),
55
+ Values , fromKeyType )
56
+ import Foreign.Storable (Storable (sizeOf ))
57
+ import HeapSize (recursiveSize , runHeapsize )
58
+ import Ide.PluginUtils (installSigUsr1Handler )
59
+ import Ide.Types (PluginId (.. ))
60
+ import Language.LSP.Types (NormalizedFilePath ,
61
+ fromNormalizedFilePath )
62
+ import qualified ListT
63
+ import Numeric.Natural (Natural )
64
+ import OpenTelemetry.Eventlog (SpanInFlight (.. ), addEvent ,
65
+ beginSpan , endSpan ,
66
+ mkValueObserver , observe ,
67
+ setTag , withSpan , withSpan_ )
68
+ import qualified StmContainers.Map as STM
66
69
67
70
#if MIN_VERSION_ghc(8,8,0)
68
71
otTracedProvider :: MonadUnliftIO m => PluginId -> ByteString -> m a -> m a
@@ -174,16 +177,16 @@ otTracedProvider (PluginId pluginName) provider act
174
177
| otherwise = act
175
178
176
179
177
- startProfilingTelemetry :: Bool -> Logger -> Var Values -> IO ()
178
- startProfilingTelemetry allTheTime logger stateRef = do
180
+ startProfilingTelemetry :: Bool -> Logger -> Values -> IO ()
181
+ startProfilingTelemetry allTheTime logger state = do
179
182
instrumentFor <- getInstrumentCached
180
183
181
184
installSigUsr1Handler $ do
182
185
logInfo logger " SIGUSR1 received: performing memory measurement"
183
- performMeasurement logger stateRef instrumentFor
186
+ performMeasurement logger state instrumentFor
184
187
185
188
when allTheTime $ void $ regularly (1 * seconds) $
186
- performMeasurement logger stateRef instrumentFor
189
+ performMeasurement logger state instrumentFor
187
190
where
188
191
seconds = 1000000
189
192
@@ -193,17 +196,16 @@ startProfilingTelemetry allTheTime logger stateRef = do
193
196
194
197
performMeasurement ::
195
198
Logger ->
196
- Var Values ->
199
+ Values ->
197
200
(Maybe String -> IO OurValueObserver ) ->
198
201
IO ()
199
- performMeasurement logger stateRef instrumentFor = do
200
-
201
- values <- readVar stateRef
202
+ performMeasurement logger values instrumentFor = do
203
+ contents <- atomically $ ListT. toList $ STM. listT values
202
204
let keys = typeOf GhcSession
203
205
: typeOf GhcSessionDeps
204
206
-- TODO restore
205
207
: [ kty
206
- | k <- HMap. keys values
208
+ | (k,_) <- contents
207
209
, Just (kty,_) <- [fromKeyType k]
208
210
-- do GhcSessionIO last since it closes over stateRef itself
209
211
, kty /= typeOf GhcSession
@@ -212,7 +214,7 @@ performMeasurement logger stateRef instrumentFor = do
212
214
]
213
215
++ [typeOf GhcSessionIO ]
214
216
groupedForSharing <- evaluate (keys `using` seqList r0)
215
- measureMemory logger [groupedForSharing] instrumentFor stateRef
217
+ measureMemory logger [groupedForSharing] instrumentFor values
216
218
`catch` \ (e:: SomeException ) ->
217
219
logInfo logger (" MEMORY PROFILING ERROR: " <> fromString (show e))
218
220
@@ -243,12 +245,12 @@ measureMemory
243
245
:: Logger
244
246
-> [[TypeRep ]] -- ^ Grouping of keys for the sharing-aware analysis
245
247
-> (Maybe String -> IO OurValueObserver )
246
- -> Var Values
248
+ -> Values
247
249
-> IO ()
248
- measureMemory logger groups instrumentFor stateRef = withSpan_ " Measure Memory" $ do
249
- values <- readVar stateRef
250
+ measureMemory logger groups instrumentFor values = withSpan_ " Measure Memory" $ do
251
+ contents <- atomically $ ListT. toList $ STM. listT values
250
252
valuesSizeRef <- newIORef $ Just 0
251
- let ! groupsOfGroupedValues = groupValues values
253
+ let ! groupsOfGroupedValues = groupValues contents
252
254
logDebug logger " STARTING MEMORY PROFILING"
253
255
forM_ groupsOfGroupedValues $ \ groupedValues -> do
254
256
keepGoing <- readIORef valuesSizeRef
@@ -277,12 +279,12 @@ measureMemory logger groups instrumentFor stateRef = withSpan_ "Measure Memory"
277
279
logInfo logger " Memory profiling could not be completed: increase the size of your nursery (+RTS -Ax) and try again"
278
280
279
281
where
280
- groupValues :: Values -> [ [(String , [Value Dynamic ])] ]
281
- groupValues values =
282
+ -- groupValues :: Values -> [ [(String, [Value Dynamic])] ]
283
+ groupValues contents =
282
284
let ! groupedValues =
283
285
[ [ (show ty, vv)
284
286
| ty <- groupKeys
285
- , let vv = [ v | (fromKeyType -> Just (kty,_), ValueWithDiagnostics v _) <- HMap. toList values
287
+ , let vv = [ v | (fromKeyType -> Just (kty,_), ValueWithDiagnostics v _) <- contents
286
288
, kty == ty]
287
289
]
288
290
| groupKeys <- groups
0 commit comments