module GHC.Stack.Profiler.Internal.SymbolTable (
  -- * 'StackSymbolTable' type
  StackSymbolTable,
  emptySymbolTable,
  emptySymbolTableIO,
  readSymbolTable,
  writeSymbolTable,
) where

import Control.Concurrent.STM
import GHC.Generics (Generic)
import GHC.Stack.Profiler.Core

-- | A @'SymbolTableWriter' 'MapTable'@ guarded by a lock for mutable, concurrent access.
--
-- The lock is an 'MVar', but this is considered an implementation detail that may change without warning.
newtype StackSymbolTable = MkStackSymbolTable
  { StackSymbolTable -> TVar (SymbolTableWriter MapTable)
writerSymbolTable :: TVar (SymbolTableWriter MapTable)
  }
  deriving ((forall x. StackSymbolTable -> Rep StackSymbolTable x)
-> (forall x. Rep StackSymbolTable x -> StackSymbolTable)
-> Generic StackSymbolTable
forall x. Rep StackSymbolTable x -> StackSymbolTable
forall x. StackSymbolTable -> Rep StackSymbolTable x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
$cfrom :: forall x. StackSymbolTable -> Rep StackSymbolTable x
from :: forall x. StackSymbolTable -> Rep StackSymbolTable x
$cto :: forall x. Rep StackSymbolTable x -> StackSymbolTable
to :: forall x. Rep StackSymbolTable x -> StackSymbolTable
Generic, StackSymbolTable -> StackSymbolTable -> Bool
(StackSymbolTable -> StackSymbolTable -> Bool)
-> (StackSymbolTable -> StackSymbolTable -> Bool)
-> Eq StackSymbolTable
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: StackSymbolTable -> StackSymbolTable -> Bool
== :: StackSymbolTable -> StackSymbolTable -> Bool
$c/= :: StackSymbolTable -> StackSymbolTable -> Bool
/= :: StackSymbolTable -> StackSymbolTable -> Bool
Eq)

-- | Create an empty 'StackSymbolTable'
emptySymbolTableIO :: IO StackSymbolTable
emptySymbolTableIO :: IO StackSymbolTable
emptySymbolTableIO = STM StackSymbolTable -> IO StackSymbolTable
forall a. STM a -> IO a
atomically STM StackSymbolTable
emptySymbolTable

emptySymbolTable :: STM StackSymbolTable
emptySymbolTable :: STM StackSymbolTable
emptySymbolTable =
  TVar (SymbolTableWriter MapTable) -> StackSymbolTable
MkStackSymbolTable
    (TVar (SymbolTableWriter MapTable) -> StackSymbolTable)
-> STM (TVar (SymbolTableWriter MapTable)) -> STM StackSymbolTable
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> SymbolTableWriter MapTable
-> STM (TVar (SymbolTableWriter MapTable))
forall a. a -> STM (TVar a)
newTVar SymbolTableWriter MapTable
emptyMapSymbolTableWriter

readSymbolTable :: StackSymbolTable -> STM (SymbolTableWriter MapTable)
readSymbolTable :: StackSymbolTable -> STM (SymbolTableWriter MapTable)
readSymbolTable =
  TVar (SymbolTableWriter MapTable)
-> STM (SymbolTableWriter MapTable)
forall a. TVar a -> STM a
readTVar (TVar (SymbolTableWriter MapTable)
 -> STM (SymbolTableWriter MapTable))
-> (StackSymbolTable -> TVar (SymbolTableWriter MapTable))
-> StackSymbolTable
-> STM (SymbolTableWriter MapTable)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. StackSymbolTable -> TVar (SymbolTableWriter MapTable)
writerSymbolTable

writeSymbolTable :: SymbolTableWriter MapTable -> StackSymbolTable -> STM ()
writeSymbolTable :: SymbolTableWriter MapTable -> StackSymbolTable -> STM ()
writeSymbolTable SymbolTableWriter MapTable
newWriterTbl StackSymbolTable
symTbl =
  TVar (SymbolTableWriter MapTable)
-> SymbolTableWriter MapTable -> STM ()
forall a. TVar a -> a -> STM ()
writeTVar (StackSymbolTable -> TVar (SymbolTableWriter MapTable)
writerSymbolTable StackSymbolTable
symTbl) SymbolTableWriter MapTable
newWriterTbl