{-# LANGUAGE MagicHash #-}
{-# LANGUAGE TupleSections #-}
{-# LANGUAGE UnboxedTuples #-}
{-# OPTIONS_HADDOCK hide #-}
module Data.Array.Accelerate.Lifetime (
Lifetime(..),
newLifetime, withLifetime, touchLifetime,
addFinalizer, finalize, mkWeak, mkWeakPtr,
unsafeGetValue,
) where
import Data.Function ( on )
import Data.IORef ( mkWeakIORef, atomicModifyIORef' )
import Prelude
import GHC.Base ( touch#, IO(..))
import GHC.IORef ( IORef(.. ), newIORef )
import GHC.Prim ( mkWeak# )
import GHC.STRef ( STRef(..) )
import GHC.Weak ( Weak(..) )
type LTF = IORef [IO ()]
data Lifetime a = Lifetime {-# UNPACK #-} !LTF
{-# UNPACK #-} !(Weak LTF)
a
instance Eq a => Eq (Lifetime a) where
== :: Lifetime a -> Lifetime a -> Bool
(==) = a -> a -> Bool
forall a. Eq a => a -> a -> Bool
(==) (a -> a -> Bool)
-> (Lifetime a -> a) -> Lifetime a -> Lifetime a -> Bool
forall b c a. (b -> b -> c) -> (a -> b) -> a -> a -> c
`on` Lifetime a -> a
forall a. Lifetime a -> a
unsafeGetValue
{-# INLINE newLifetime #-}
newLifetime :: a -> IO (Lifetime a)
newLifetime :: a -> IO (Lifetime a)
newLifetime a
a = do
IORef [IO ()]
ref <- [IO ()] -> IO (IORef [IO ()])
forall a. a -> IO (IORef a)
newIORef []
Weak (IORef [IO ()])
weak <- IORef [IO ()] -> IO () -> IO (Weak (IORef [IO ()]))
forall a. IORef a -> IO () -> IO (Weak (IORef a))
mkWeakIORef IORef [IO ()]
ref (IORef [IO ()] -> IO ()
finalizer IORef [IO ()]
ref)
Lifetime a -> IO (Lifetime a)
forall (m :: * -> *) a. Monad m => a -> m a
return (Lifetime a -> IO (Lifetime a)) -> Lifetime a -> IO (Lifetime a)
forall a b. (a -> b) -> a -> b
$! IORef [IO ()] -> Weak (IORef [IO ()]) -> a -> Lifetime a
forall a. IORef [IO ()] -> Weak (IORef [IO ()]) -> a -> Lifetime a
Lifetime IORef [IO ()]
ref Weak (IORef [IO ()])
weak a
a
{-# INLINE withLifetime #-}
withLifetime :: Lifetime a -> (a -> IO b) -> IO b
withLifetime :: Lifetime a -> (a -> IO b) -> IO b
withLifetime (Lifetime IORef [IO ()]
ref Weak (IORef [IO ()])
_ a
a) a -> IO b
f = do
b
r <- a -> IO b
f a
a
IORef [IO ()] -> IO ()
forall a. IORef a -> IO ()
touchIORef IORef [IO ()]
ref
b -> IO b
forall (m :: * -> *) a. Monad m => a -> m a
return b
r
{-# INLINE touchLifetime #-}
touchLifetime :: Lifetime a -> IO ()
touchLifetime :: Lifetime a -> IO ()
touchLifetime (Lifetime IORef [IO ()]
ref Weak (IORef [IO ()])
_ a
_) = IORef [IO ()] -> IO ()
forall a. IORef a -> IO ()
touchIORef IORef [IO ()]
ref
addFinalizer :: Lifetime a -> IO () -> IO ()
addFinalizer :: Lifetime a -> IO () -> IO ()
addFinalizer (Lifetime IORef [IO ()]
ref Weak (IORef [IO ()])
_ a
_) IO ()
f =
IORef [IO ()] -> ([IO ()] -> ([IO ()], ())) -> IO ()
forall a b. IORef a -> (a -> (a, b)) -> IO b
atomicModifyIORef' IORef [IO ()]
ref (\[IO ()]
fs -> (IO ()
fIO () -> [IO ()] -> [IO ()]
forall a. a -> [a] -> [a]
:[IO ()]
fs,()))
finalize :: Lifetime a -> IO ()
finalize :: Lifetime a -> IO ()
finalize (Lifetime IORef [IO ()]
ref Weak (IORef [IO ()])
_ a
_) = IORef [IO ()] -> IO ()
finalizer IORef [IO ()]
ref
mkWeak :: Lifetime k -> v -> IO (Weak v)
mkWeak :: Lifetime k -> v -> IO (Weak v)
mkWeak (Lifetime ref :: IORef [IO ()]
ref@(IORef (STRef MutVar# RealWorld [IO ()]
r#)) Weak (IORef [IO ()])
_ k
_) v
v = IO () -> IO (Weak v)
forall c. IO c -> IO (Weak v)
go (IORef [IO ()] -> IO ()
finalizer IORef [IO ()]
ref)
where
go :: IO c -> IO (Weak v)
go (IO State# RealWorld -> (# State# RealWorld, c #)
f) =
(State# RealWorld -> (# State# RealWorld, Weak v #)) -> IO (Weak v)
forall a. (State# RealWorld -> (# State# RealWorld, a #)) -> IO a
IO ((State# RealWorld -> (# State# RealWorld, Weak v #))
-> IO (Weak v))
-> (State# RealWorld -> (# State# RealWorld, Weak v #))
-> IO (Weak v)
forall a b. (a -> b) -> a -> b
$ \State# RealWorld
s -> case MutVar# RealWorld [IO ()]
-> v
-> (State# RealWorld -> (# State# RealWorld, c #))
-> State# RealWorld
-> (# State# RealWorld, Weak# v #)
forall a b c.
a
-> b
-> (State# RealWorld -> (# State# RealWorld, c #))
-> State# RealWorld
-> (# State# RealWorld, Weak# b #)
mkWeak# MutVar# RealWorld [IO ()]
r# v
v State# RealWorld -> (# State# RealWorld, c #)
f State# RealWorld
s of
(# State# RealWorld
s', Weak# v
w# #) -> (# State# RealWorld
s', Weak# v -> Weak v
forall v. Weak# v -> Weak v
Weak Weak# v
w# #)
mkWeakPtr :: Lifetime a -> IO (Weak (Lifetime a))
mkWeakPtr :: Lifetime a -> IO (Weak (Lifetime a))
mkWeakPtr Lifetime a
l = Lifetime a -> Lifetime a -> IO (Weak (Lifetime a))
forall k v. Lifetime k -> v -> IO (Weak v)
mkWeak Lifetime a
l Lifetime a
l
{-# INLINE unsafeGetValue #-}
unsafeGetValue :: Lifetime a -> a
unsafeGetValue :: Lifetime a -> a
unsafeGetValue (Lifetime IORef [IO ()]
_ Weak (IORef [IO ()])
_ a
a) = a
a
finalizer :: IORef [IO ()] -> IO ()
finalizer :: IORef [IO ()] -> IO ()
finalizer IORef [IO ()]
ref = do
[IO ()]
fins <- IORef [IO ()] -> ([IO ()] -> ([IO ()], [IO ()])) -> IO [IO ()]
forall a b. IORef a -> (a -> (a, b)) -> IO b
atomicModifyIORef' IORef [IO ()]
ref ([],)
[IO ()] -> IO ()
forall (t :: * -> *) (m :: * -> *) a.
(Foldable t, Monad m) =>
t (m a) -> m ()
sequence_ [IO ()]
fins
{-# INLINE touchIORef #-}
touchIORef :: IORef a -> IO ()
touchIORef :: IORef a -> IO ()
touchIORef IORef a
r = (State# RealWorld -> (# State# RealWorld, () #)) -> IO ()
forall a. (State# RealWorld -> (# State# RealWorld, a #)) -> IO a
IO ((State# RealWorld -> (# State# RealWorld, () #)) -> IO ())
-> (State# RealWorld -> (# State# RealWorld, () #)) -> IO ()
forall a b. (a -> b) -> a -> b
$ \State# RealWorld
s -> case IORef a -> State# RealWorld -> State# RealWorld
forall a. a -> State# RealWorld -> State# RealWorld
touch# IORef a
r State# RealWorld
s of State# RealWorld
s' -> (# State# RealWorld
s', () #)