{-# LANGUAGE BangPatterns #-}
{-# LANGUAGE ConstraintKinds #-}
{-# LANGUAGE DuplicateRecordFields #-}
{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE KindSignatures #-}
{-# LANGUAGE MagicHash #-}
{-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE StrictData #-}
{-# LANGUAGE TypeOperators #-}
{-# LANGUAGE UnboxedTuples #-}
{-# LANGUAGE UnliftedFFITypes #-}
module OpenTelemetry.Util (
constructorName,
HasConstructor,
getThreadId,
bracketError,
casModifyIORef_,
casReadModifyIORef_,
AppendOnlyBoundedCollection,
emptyAppendOnlyBoundedCollection,
appendToBoundedCollection,
appendOnlyBoundedCollectionSize,
appendOnlyBoundedCollectionValues,
appendOnlyBoundedCollectionDroppedElementCount,
chunksOfV,
) where
import Control.Exception (SomeException)
import qualified Control.Exception as EUnsafe
import Control.Monad.IO.Unlift
import Data.IORef (IORef)
import Data.Kind
import qualified Data.Vector as V
import Foreign.C (CInt (..))
import GHC.Base (Addr#)
import GHC.Conc (ThreadId (ThreadId))
import GHC.Exts (unsafeCoerce#)
import qualified GHC.Exts as Exts
import GHC.Generics
import GHC.IO (IO (IO))
import GHC.IORef (IORef (IORef))
import GHC.STRef (STRef (STRef))
constructorName :: (HasConstructor (Rep a), Generic a) => a -> String
constructorName :: forall a. (HasConstructor (Rep a), Generic a) => a -> String
constructorName = Rep a (ZonkAny 0) -> String
forall x. Rep a x -> String
forall (f :: * -> *) x. HasConstructor f => f x -> String
genericConstrName (Rep a (ZonkAny 0) -> String)
-> (a -> Rep a (ZonkAny 0)) -> a -> String
forall b c a. (b -> c) -> (a -> b) -> a -> c
. a -> Rep a (ZonkAny 0)
forall x. a -> Rep a x
forall a x. Generic a => a -> Rep a x
from
class HasConstructor (f :: Type -> Type) where
genericConstrName :: f x -> String
instance (HasConstructor f) => HasConstructor (D1 c f) where
genericConstrName :: forall x. D1 c f x -> String
genericConstrName (M1 f x
x) = f x -> String
forall x. f x -> String
forall (f :: * -> *) x. HasConstructor f => f x -> String
genericConstrName f x
x
instance (HasConstructor x, HasConstructor y) => HasConstructor (x :+: y) where
genericConstrName :: forall x. (:+:) x y x -> String
genericConstrName (L1 x x
l) = x x -> String
forall x. x x -> String
forall (f :: * -> *) x. HasConstructor f => f x -> String
genericConstrName x x
l
genericConstrName (R1 y x
r) = y x -> String
forall x. y x -> String
forall (f :: * -> *) x. HasConstructor f => f x -> String
genericConstrName y x
r
instance (Constructor c) => HasConstructor (C1 c f) where
genericConstrName :: forall x. C1 c f x -> String
genericConstrName = M1 C c f x -> String
forall {k} (c :: k) k1 (t :: k -> (k1 -> *) -> k1 -> *)
(f :: k1 -> *) (a :: k1).
Constructor c =>
t c f a -> String
forall k1 (t :: Meta -> (k1 -> *) -> k1 -> *) (f :: k1 -> *)
(a :: k1).
t c f a -> String
conName
foreign import ccall unsafe "rts_getThreadId" c_getThreadId :: Addr# -> CInt
getThreadId :: ThreadId -> Int
getThreadId :: ThreadId -> Int
getThreadId (ThreadId ThreadId#
tid#) = CInt -> Int
forall a b. (Integral a, Num b) => a -> b
fromIntegral (CInt -> Int) -> CInt -> Int
forall a b. (a -> b) -> a -> b
$ Addr# -> CInt
c_getThreadId (ThreadId# -> Addr#
forall a b. a -> b
unsafeCoerce# ThreadId#
tid#)
{-# INLINE getThreadId #-}
casModifyIORef_ :: IORef a -> (a -> a) -> IO ()
casModifyIORef_ :: forall a. IORef a -> (a -> a) -> IO ()
casModifyIORef_ (IORef (STRef MutVar# RealWorld a
ref#)) a -> a
f = (State# RealWorld -> (# State# RealWorld, () #)) -> IO ()
forall a. (State# RealWorld -> (# State# RealWorld, a #)) -> IO a
IO State# RealWorld -> (# State# RealWorld, () #)
go#
where
go# :: State# RealWorld -> (# State# RealWorld, () #)
go# State# RealWorld
s0# =
case MutVar# RealWorld a
-> State# RealWorld -> (# State# RealWorld, a #)
forall d a. MutVar# d a -> State# d -> (# State# d, a #)
Exts.readMutVar# MutVar# RealWorld a
ref# State# RealWorld
s0# of
(# State# RealWorld
s1#, a
old #) ->
let !new :: a
new = a -> a
f a
old
in case MutVar# RealWorld a
-> a -> a -> State# RealWorld -> (# State# RealWorld, Int#, a #)
forall d a.
MutVar# d a -> a -> a -> State# d -> (# State# d, Int#, a #)
Exts.casMutVar# MutVar# RealWorld a
ref# a
old a
new State# RealWorld
s1# of
(# State# RealWorld
s2#, Int#
0#, a
_ #) -> (# State# RealWorld
s2#, () #)
(# State# RealWorld
s2#, Int#
_, a
_ #) -> State# RealWorld -> (# State# RealWorld, () #)
go# State# RealWorld
s2#
{-# NOINLINE casModifyIORef_ #-}
casReadModifyIORef_ :: IORef a -> (a -> a) -> IO a
casReadModifyIORef_ :: forall a. IORef a -> (a -> a) -> IO a
casReadModifyIORef_ (IORef (STRef MutVar# RealWorld a
ref#)) a -> a
f = (State# RealWorld -> (# State# RealWorld, a #)) -> IO a
forall a. (State# RealWorld -> (# State# RealWorld, a #)) -> IO a
IO State# RealWorld -> (# State# RealWorld, a #)
go#
where
go# :: State# RealWorld -> (# State# RealWorld, a #)
go# State# RealWorld
s0# =
case MutVar# RealWorld a
-> State# RealWorld -> (# State# RealWorld, a #)
forall d a. MutVar# d a -> State# d -> (# State# d, a #)
Exts.readMutVar# MutVar# RealWorld a
ref# State# RealWorld
s0# of
(# State# RealWorld
s1#, a
old #) ->
let !new :: a
new = a -> a
f a
old
in case MutVar# RealWorld a
-> a -> a -> State# RealWorld -> (# State# RealWorld, Int#, a #)
forall d a.
MutVar# d a -> a -> a -> State# d -> (# State# d, Int#, a #)
Exts.casMutVar# MutVar# RealWorld a
ref# a
old a
new State# RealWorld
s1# of
(# State# RealWorld
s2#, Int#
0#, a
_ #) -> (# State# RealWorld
s2#, a
old #)
(# State# RealWorld
s2#, Int#
_, a
_ #) -> State# RealWorld -> (# State# RealWorld, a #)
go# State# RealWorld
s2#
{-# NOINLINE casReadModifyIORef_ #-}
data AppendOnlyBoundedCollection a
= EmptyBounded
{-# UNPACK #-} !Int
| BoundedCollection
!([a] -> [a])
{-# UNPACK #-} !Int
{-# UNPACK #-} !Int
{-# UNPACK #-} !Int
instance forall a. (Show a) => Show (AppendOnlyBoundedCollection a) where
showsPrec :: Int -> AppendOnlyBoundedCollection a -> ShowS
showsPrec Int
d AppendOnlyBoundedCollection a
c =
let vec :: Vector a
vec = AppendOnlyBoundedCollection a -> Vector a
forall a. AppendOnlyBoundedCollection a -> Vector a
appendOnlyBoundedCollectionValues AppendOnlyBoundedCollection a
c
in Bool -> ShowS -> ShowS
showParen (Int
d Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
> Int
10) (ShowS -> ShowS) -> ShowS -> ShowS
forall a b. (a -> b) -> a -> b
$
String -> ShowS
showString String
"AppendOnlyBoundedCollection {collection = "
ShowS -> ShowS -> ShowS
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Vector a -> ShowS
forall a. Show a => a -> ShowS
shows Vector a
vec
ShowS -> ShowS -> ShowS
forall b c a. (b -> c) -> (a -> b) -> a -> c
. String -> ShowS
showString String
", maxSize = "
ShowS -> ShowS -> ShowS
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Int -> ShowS
forall a. Show a => a -> ShowS
shows (AppendOnlyBoundedCollection a -> Int
forall a. AppendOnlyBoundedCollection a -> Int
appendOnlyBoundedCollectionMaxSize AppendOnlyBoundedCollection a
c)
ShowS -> ShowS -> ShowS
forall b c a. (b -> c) -> (a -> b) -> a -> c
. String -> ShowS
showString String
", dropped = "
ShowS -> ShowS -> ShowS
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Int -> ShowS
forall a. Show a => a -> ShowS
shows (AppendOnlyBoundedCollection a -> Int
forall a. AppendOnlyBoundedCollection a -> Int
appendOnlyBoundedCollectionDroppedElementCount AppendOnlyBoundedCollection a
c)
ShowS -> ShowS -> ShowS
forall b c a. (b -> c) -> (a -> b) -> a -> c
. String -> ShowS
showString String
"}"
emptyAppendOnlyBoundedCollection
:: Int
-> AppendOnlyBoundedCollection a
emptyAppendOnlyBoundedCollection :: forall a. Int -> AppendOnlyBoundedCollection a
emptyAppendOnlyBoundedCollection !Int
s = Int -> AppendOnlyBoundedCollection a
forall a. Int -> AppendOnlyBoundedCollection a
EmptyBounded Int
s
{-# INLINE emptyAppendOnlyBoundedCollection #-}
appendOnlyBoundedCollectionValues :: AppendOnlyBoundedCollection a -> V.Vector a
appendOnlyBoundedCollectionValues :: forall a. AppendOnlyBoundedCollection a -> Vector a
appendOnlyBoundedCollectionValues (EmptyBounded Int
_) = Vector a
forall a. Vector a
V.empty
appendOnlyBoundedCollectionValues (BoundedCollection [a] -> [a]
dl Int
sz Int
_ Int
_) =
Int -> [a] -> Vector a
forall a. Int -> [a] -> Vector a
V.fromListN Int
sz ([a] -> [a]
dl [])
{-# INLINE appendOnlyBoundedCollectionValues #-}
appendOnlyBoundedCollectionSize :: AppendOnlyBoundedCollection a -> Int
appendOnlyBoundedCollectionSize :: forall a. AppendOnlyBoundedCollection a -> Int
appendOnlyBoundedCollectionSize (EmptyBounded Int
_) = Int
0
appendOnlyBoundedCollectionSize (BoundedCollection [a] -> [a]
_ Int
sz Int
_ Int
_) = Int
sz
{-# INLINE appendOnlyBoundedCollectionSize #-}
appendOnlyBoundedCollectionMaxSize :: AppendOnlyBoundedCollection a -> Int
appendOnlyBoundedCollectionMaxSize :: forall a. AppendOnlyBoundedCollection a -> Int
appendOnlyBoundedCollectionMaxSize (EmptyBounded Int
ms) = Int
ms
appendOnlyBoundedCollectionMaxSize (BoundedCollection [a] -> [a]
_ Int
_ Int
ms Int
_) = Int
ms
{-# INLINE appendOnlyBoundedCollectionMaxSize #-}
appendOnlyBoundedCollectionDroppedElementCount :: AppendOnlyBoundedCollection a -> Int
appendOnlyBoundedCollectionDroppedElementCount :: forall a. AppendOnlyBoundedCollection a -> Int
appendOnlyBoundedCollectionDroppedElementCount (EmptyBounded Int
_) = Int
0
appendOnlyBoundedCollectionDroppedElementCount (BoundedCollection [a] -> [a]
_ Int
_ Int
_ Int
d) = Int
d
{-# INLINE appendOnlyBoundedCollectionDroppedElementCount #-}
appendToBoundedCollection :: AppendOnlyBoundedCollection a -> a -> AppendOnlyBoundedCollection a
appendToBoundedCollection :: forall a.
AppendOnlyBoundedCollection a -> a -> AppendOnlyBoundedCollection a
appendToBoundedCollection (EmptyBounded Int
ms) a
x
| Int
ms Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
<= Int
0 = ([a] -> [a]) -> Int -> Int -> Int -> AppendOnlyBoundedCollection a
forall a.
([a] -> [a]) -> Int -> Int -> Int -> AppendOnlyBoundedCollection a
BoundedCollection [a] -> [a]
forall a. a -> a
id Int
0 Int
ms Int
1
| Bool
otherwise = ([a] -> [a]) -> Int -> Int -> Int -> AppendOnlyBoundedCollection a
forall a.
([a] -> [a]) -> Int -> Int -> Int -> AppendOnlyBoundedCollection a
BoundedCollection (a
x a -> [a] -> [a]
forall a. a -> [a] -> [a]
:) Int
1 Int
ms Int
0
appendToBoundedCollection (BoundedCollection [a] -> [a]
dl Int
sz Int
ms Int
d) a
x
| Int
sz Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
>= Int
ms = ([a] -> [a]) -> Int -> Int -> Int -> AppendOnlyBoundedCollection a
forall a.
([a] -> [a]) -> Int -> Int -> Int -> AppendOnlyBoundedCollection a
BoundedCollection [a] -> [a]
dl Int
sz Int
ms (Int
d Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
1)
| Bool
otherwise = ([a] -> [a]) -> Int -> Int -> Int -> AppendOnlyBoundedCollection a
forall a.
([a] -> [a]) -> Int -> Int -> Int -> AppendOnlyBoundedCollection a
BoundedCollection ([a] -> [a]
dl ([a] -> [a]) -> ([a] -> [a]) -> [a] -> [a]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (a
x a -> [a] -> [a]
forall a. a -> [a] -> [a]
:)) (Int
sz Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
1) Int
ms Int
d
{-# INLINE appendToBoundedCollection #-}
chunksOfV :: Int -> V.Vector a -> [V.Vector a]
chunksOfV :: forall a. Int -> Vector a -> [Vector a]
chunksOfV Int
n Vector a
v
| Vector a -> Bool
forall a. Vector a -> Bool
V.null Vector a
v = []
| Bool
otherwise =
let (Vector a
chunk, Vector a
rest) = Int -> Vector a -> (Vector a, Vector a)
forall a. Int -> Vector a -> (Vector a, Vector a)
V.splitAt Int
n Vector a
v
in Vector a
chunk Vector a -> [Vector a] -> [Vector a]
forall a. a -> [a] -> [a]
: Int -> Vector a -> [Vector a]
forall a. Int -> Vector a -> [Vector a]
chunksOfV Int
n Vector a
rest
bracketError :: (MonadUnliftIO m) => m a -> (Maybe SomeException -> a -> m b) -> (a -> m c) -> m c
{-# INLINEABLE bracketError #-}
bracketError :: forall (m :: * -> *) a b c.
MonadUnliftIO m =>
m a -> (Maybe SomeException -> a -> m b) -> (a -> m c) -> m c
bracketError m a
before Maybe SomeException -> a -> m b
after a -> m c
thing = ((forall a. m a -> IO a) -> IO c) -> m c
forall b. ((forall a. m a -> IO a) -> IO b) -> m b
forall (m :: * -> *) b.
MonadUnliftIO m =>
((forall a. m a -> IO a) -> IO b) -> m b
withRunInIO (((forall a. m a -> IO a) -> IO c) -> m c)
-> ((forall a. m a -> IO a) -> IO c) -> m c
forall a b. (a -> b) -> a -> b
$ \forall a. m a -> IO a
run -> ((forall a. IO a -> IO a) -> IO c) -> IO c
forall b. ((forall a. IO a -> IO a) -> IO b) -> IO b
EUnsafe.mask (((forall a. IO a -> IO a) -> IO c) -> IO c)
-> ((forall a. IO a -> IO a) -> IO c) -> IO c
forall a b. (a -> b) -> a -> b
$ \forall a. IO a -> IO a
restore -> do
x <- m a -> IO a
forall a. m a -> IO a
run m a
before
y <-
restore (run $ thing x) `EUnsafe.catch` \(SomeException
e1 :: SomeException) -> do
_ :: Either SomeException b <-
IO b -> IO (Either SomeException b)
forall e a. Exception e => IO a -> IO (Either e a)
EUnsafe.try (IO b -> IO (Either SomeException b))
-> IO b -> IO (Either SomeException b)
forall a b. (a -> b) -> a -> b
$ IO b -> IO b
forall a. IO a -> IO a
EUnsafe.uninterruptibleMask_ (IO b -> IO b) -> IO b -> IO b
forall a b. (a -> b) -> a -> b
$ m b -> IO b
forall a. m a -> IO a
run (m b -> IO b) -> m b -> IO b
forall a b. (a -> b) -> a -> b
$ Maybe SomeException -> a -> m b
after (SomeException -> Maybe SomeException
forall a. a -> Maybe a
Just SomeException
e1) a
x
EUnsafe.throwIO e1
_ <- EUnsafe.uninterruptibleMask_ $ run $ after Nothing x
return y