{-# LANGUAGE BangPatterns #-}
{-# LANGUAGE CPP #-}
{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE MagicHash #-}
{-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE TypeFamilies #-}
{-# LANGUAGE UnboxedTuples #-}
module Data.Prim.Ref
( Ref(..)
, IORef
, STRef
, newRef
, newDeepRef
, isSameRef
, readRef
, swapRef
, swapDeepRef
, writeRef
, writeDeepRef
, modifyRef
, modifyDeepRef
, modifyRef_
, modifyFetchNewRef
, modifyFetchOldRef
, modifyRefM
, modifyDeepRefM
, modifyRefM_
, modifyFetchNewRefM
, modifyFetchOldRefM
, atomicReadRef
, atomicSwapRef
, atomicWriteRef
, atomicModifyRef
, atomicModifyRef_
, atomicModifyFetchRef
, atomicModifyFetchNewRef
, atomicModifyFetchOldRef
, atomicModifyFetchBothRef
, casRef
, atomicModifyRef2
, atomicModifyRef2_
, atomicModifyFetchNewRef2
, atomicModifyFetchOldRef2
, atomicModifyFetchBothRef2
, atomicModifyFetchRef2
, newLazyRef
, writeLazyRef
, swapLazyRef
, modifyLazyRef
, modifyLazyRefM
, atomicWriteLazyRef
, atomicModifyLazyRef
, atomicModifyFetchNewLazyRef
, atomicModifyFetchOldLazyRef
, atomicModifyFetchBothLazyRef
, atomicModifyFetchLazyRef
, toSTRef
, fromSTRef
, toIORef
, fromIORef
, mkWeakRef
) where
import Control.DeepSeq
import Control.Prim.Monad
import Foreign.Prim
import Foreign.Prim.WeakPtr
import qualified GHC.IORef as IO
import qualified GHC.STRef as ST
data Ref a s = Ref (MutVar# s a)
instance Eq (Ref a s) where
== :: Ref a s -> Ref a s -> Bool
(==) = Ref a s -> Ref a s -> Bool
forall a s. Ref a s -> Ref a s -> Bool
isSameRef
type IORef a = Ref a RW
type STRef s a = Ref a s
isSameRef :: Ref a s -> Ref a s -> Bool
isSameRef :: Ref a s -> Ref a s -> Bool
isSameRef (Ref MutVar# s a
ref1#) (Ref MutVar# s a
ref2#) = Int# -> Bool
isTrue# (MutVar# s a -> MutVar# s a -> Int#
forall d a. MutVar# d a -> MutVar# d a -> Int#
sameMutVar# MutVar# s a
ref1# MutVar# s a
ref2#)
{-# INLINE isSameRef #-}
newRef :: MonadPrim s m => a -> m (Ref a s)
newRef :: a -> m (Ref a s)
newRef a
a = a
a a -> m (Ref a s) -> m (Ref a s)
`seq` a -> m (Ref a s)
forall s (m :: * -> *) a. MonadPrim s m => a -> m (Ref a s)
newLazyRef a
a
{-# INLINE newRef #-}
newDeepRef :: (NFData a, MonadPrim s m) => a -> m (Ref a s)
newDeepRef :: a -> m (Ref a s)
newDeepRef a
a = a
a a -> m (Ref a s) -> m (Ref a s)
forall a b. NFData a => a -> b -> b
`deepseq` a -> m (Ref a s)
forall s (m :: * -> *) a. MonadPrim s m => a -> m (Ref a s)
newLazyRef a
a
{-# INLINE newDeepRef #-}
newLazyRef :: MonadPrim s m => a -> m (Ref a s)
newLazyRef :: a -> m (Ref a s)
newLazyRef a
a =
(State# s -> (# State# s, Ref a s #)) -> m (Ref a s)
forall s (m :: * -> *) a.
MonadPrim s m =>
(State# s -> (# State# s, a #)) -> m a
prim ((State# s -> (# State# s, Ref a s #)) -> m (Ref a s))
-> (State# s -> (# State# s, Ref a s #)) -> m (Ref a s)
forall a b. (a -> b) -> a -> b
$ \State# s
s ->
case a -> State# s -> (# State# s, MutVar# s a #)
forall a d. a -> State# d -> (# State# d, MutVar# d a #)
newMutVar# a
a State# s
s of
(# State# s
s', MutVar# s a
ref# #) -> (# State# s
s', MutVar# s a -> Ref a s
forall a s. MutVar# s a -> Ref a s
Ref MutVar# s a
ref# #)
{-# INLINE newLazyRef #-}
readRef :: MonadPrim s m => Ref a s -> m a
readRef :: Ref a s -> m a
readRef (Ref MutVar# s a
ref#) = (State# s -> (# State# s, a #)) -> m a
forall s (m :: * -> *) a.
MonadPrim s m =>
(State# s -> (# State# s, a #)) -> m a
prim (MutVar# s a -> State# s -> (# State# s, a #)
forall d a. MutVar# d a -> State# d -> (# State# d, a #)
readMutVar# MutVar# s a
ref#)
{-# INLINE readRef #-}
swapRef :: MonadPrim s m => Ref a s -> a -> m a
swapRef :: Ref a s -> a -> m a
swapRef Ref a s
ref a
a = Ref a s -> m a
forall s (m :: * -> *) a. MonadPrim s m => Ref a s -> m a
readRef Ref a s
ref m a -> m () -> m a
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f a
<* Ref a s -> a -> m ()
forall s (m :: * -> *) a. MonadPrim s m => Ref a s -> a -> m ()
writeRef Ref a s
ref a
a
{-# INLINE swapRef #-}
swapLazyRef :: MonadPrim s m => Ref a s -> a -> m a
swapLazyRef :: Ref a s -> a -> m a
swapLazyRef Ref a s
ref a
a = Ref a s -> m a
forall s (m :: * -> *) a. MonadPrim s m => Ref a s -> m a
readRef Ref a s
ref m a -> m () -> m a
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f a
<* Ref a s -> a -> m ()
forall s (m :: * -> *) a. MonadPrim s m => Ref a s -> a -> m ()
writeLazyRef Ref a s
ref a
a
{-# INLINE swapLazyRef #-}
swapDeepRef :: (NFData a, MonadPrim s m) => Ref a s -> a -> m a
swapDeepRef :: Ref a s -> a -> m a
swapDeepRef Ref a s
ref a
a = Ref a s -> m a
forall s (m :: * -> *) a. MonadPrim s m => Ref a s -> m a
readRef Ref a s
ref m a -> m () -> m a
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f a
<* Ref a s -> a -> m ()
forall a s (m :: * -> *).
(NFData a, MonadPrim s m) =>
Ref a s -> a -> m ()
writeDeepRef Ref a s
ref a
a
{-# INLINE swapDeepRef #-}
writeRef :: MonadPrim s m => Ref a s -> a -> m ()
writeRef :: Ref a s -> a -> m ()
writeRef Ref a s
ref !a
a = Ref a s -> a -> m ()
forall s (m :: * -> *) a. MonadPrim s m => Ref a s -> a -> m ()
writeLazyRef Ref a s
ref a
a
{-# INLINE writeRef #-}
writeDeepRef :: (NFData a, MonadPrim s m) => Ref a s -> a -> m ()
writeDeepRef :: Ref a s -> a -> m ()
writeDeepRef Ref a s
ref a
a = a
a a -> m () -> m ()
forall a b. NFData a => a -> b -> b
`deepseq` Ref a s -> a -> m ()
forall s (m :: * -> *) a. MonadPrim s m => Ref a s -> a -> m ()
writeLazyRef Ref a s
ref a
a
{-# INLINE writeDeepRef #-}
writeLazyRef :: MonadPrim s m => Ref a s -> a -> m ()
writeLazyRef :: Ref a s -> a -> m ()
writeLazyRef (Ref MutVar# s a
ref#) a
a = (State# s -> State# s) -> m ()
forall s (m :: * -> *).
MonadPrim s m =>
(State# s -> State# s) -> m ()
prim_ (MutVar# s a -> a -> State# s -> State# s
forall d a. MutVar# d a -> a -> State# d -> State# d
writeMutVar# MutVar# s a
ref# a
a)
{-# INLINE writeLazyRef #-}
modifyRef :: MonadPrim s m => Ref a s -> (a -> (a, b)) -> m b
modifyRef :: Ref a s -> (a -> (a, b)) -> m b
modifyRef Ref a s
ref a -> (a, b)
f = Ref a s -> (a -> m (a, b)) -> m b
forall s (m :: * -> *) a b.
MonadPrim s m =>
Ref a s -> (a -> m (a, b)) -> m b
modifyRefM Ref a s
ref ((a, b) -> m (a, b)
forall (f :: * -> *) a. Applicative f => a -> f a
pure ((a, b) -> m (a, b)) -> (a -> (a, b)) -> a -> m (a, b)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. a -> (a, b)
f)
{-# INLINE modifyRef #-}
modifyDeepRef :: (NFData a, MonadPrim s m) => Ref a s -> (a -> (a, b)) -> m b
modifyDeepRef :: Ref a s -> (a -> (a, b)) -> m b
modifyDeepRef Ref a s
ref a -> (a, b)
f = Ref a s -> (a -> m (a, b)) -> m b
forall a s (m :: * -> *) b.
(NFData a, MonadPrim s m) =>
Ref a s -> (a -> m (a, b)) -> m b
modifyDeepRefM Ref a s
ref ((a, b) -> m (a, b)
forall (f :: * -> *) a. Applicative f => a -> f a
pure ((a, b) -> m (a, b)) -> (a -> (a, b)) -> a -> m (a, b)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. a -> (a, b)
f)
{-# INLINE modifyDeepRef #-}
modifyRef_ :: MonadPrim s m => Ref a s -> (a -> a) -> m ()
modifyRef_ :: Ref a s -> (a -> a) -> m ()
modifyRef_ Ref a s
ref a -> a
f = Ref a s -> (a -> m a) -> m ()
forall s (m :: * -> *) a.
MonadPrim s m =>
Ref a s -> (a -> m a) -> m ()
modifyRefM_ Ref a s
ref (a -> m a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (a -> m a) -> (a -> a) -> a -> m a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. a -> a
f)
{-# INLINE modifyRef_ #-}
modifyFetchNewRef :: MonadPrim s m => Ref a s -> (a -> a) -> m a
modifyFetchNewRef :: Ref a s -> (a -> a) -> m a
modifyFetchNewRef Ref a s
ref a -> a
f = Ref a s -> (a -> m a) -> m a
forall s (m :: * -> *) a.
MonadPrim s m =>
Ref a s -> (a -> m a) -> m a
modifyFetchNewRefM Ref a s
ref (a -> m a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (a -> m a) -> (a -> a) -> a -> m a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. a -> a
f)
{-# INLINE modifyFetchNewRef #-}
modifyFetchOldRef :: MonadPrim s m => Ref a s -> (a -> a) -> m a
modifyFetchOldRef :: Ref a s -> (a -> a) -> m a
modifyFetchOldRef Ref a s
ref a -> a
f = Ref a s -> (a -> m a) -> m a
forall s (m :: * -> *) a.
MonadPrim s m =>
Ref a s -> (a -> m a) -> m a
modifyFetchOldRefM Ref a s
ref (a -> m a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (a -> m a) -> (a -> a) -> a -> m a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. a -> a
f)
{-# INLINE modifyFetchOldRef #-}
modifyLazyRef :: MonadPrim s m => Ref a s -> (a -> (a, b)) -> m b
modifyLazyRef :: Ref a s -> (a -> (a, b)) -> m b
modifyLazyRef Ref a s
ref a -> (a, b)
f = Ref a s -> (a -> m (a, b)) -> m b
forall s (m :: * -> *) a b.
MonadPrim s m =>
Ref a s -> (a -> m (a, b)) -> m b
modifyLazyRefM Ref a s
ref ((a, b) -> m (a, b)
forall (f :: * -> *) a. Applicative f => a -> f a
pure ((a, b) -> m (a, b)) -> (a -> (a, b)) -> a -> m (a, b)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. a -> (a, b)
f)
{-# INLINE modifyLazyRef #-}
modifyRefM :: MonadPrim s m => Ref a s -> (a -> m (a, b)) -> m b
modifyRefM :: Ref a s -> (a -> m (a, b)) -> m b
modifyRefM Ref a s
ref a -> m (a, b)
f = do
(a
a', b
b) <- a -> m (a, b)
f (a -> m (a, b)) -> m a -> m (a, b)
forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< Ref a s -> m a
forall s (m :: * -> *) a. MonadPrim s m => Ref a s -> m a
readRef Ref a s
ref
b
b b -> m () -> m b
forall (f :: * -> *) a b. Functor f => a -> f b -> f a
<$ Ref a s -> a -> m ()
forall s (m :: * -> *) a. MonadPrim s m => Ref a s -> a -> m ()
writeRef Ref a s
ref a
a'
{-# INLINE modifyRefM #-}
modifyDeepRefM :: (NFData a, MonadPrim s m) => Ref a s -> (a -> m (a, b)) -> m b
modifyDeepRefM :: Ref a s -> (a -> m (a, b)) -> m b
modifyDeepRefM Ref a s
ref a -> m (a, b)
f = do
(a
a', b
b) <- a -> m (a, b)
f (a -> m (a, b)) -> m a -> m (a, b)
forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< Ref a s -> m a
forall s (m :: * -> *) a. MonadPrim s m => Ref a s -> m a
readRef Ref a s
ref
b
b b -> m () -> m b
forall (f :: * -> *) a b. Functor f => a -> f b -> f a
<$ Ref a s -> a -> m ()
forall a s (m :: * -> *).
(NFData a, MonadPrim s m) =>
Ref a s -> a -> m ()
writeDeepRef Ref a s
ref a
a'
{-# INLINE modifyDeepRefM #-}
modifyRefM_ :: MonadPrim s m => Ref a s -> (a -> m a) -> m ()
modifyRefM_ :: Ref a s -> (a -> m a) -> m ()
modifyRefM_ Ref a s
ref a -> m a
f = Ref a s -> m a
forall s (m :: * -> *) a. MonadPrim s m => Ref a s -> m a
readRef Ref a s
ref m a -> (a -> m a) -> m a
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= a -> m a
f m a -> (a -> m ()) -> m ()
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= Ref a s -> a -> m ()
forall s (m :: * -> *) a. MonadPrim s m => Ref a s -> a -> m ()
writeRef Ref a s
ref
{-# INLINE modifyRefM_ #-}
modifyFetchOldRefM :: MonadPrim s m => Ref a s -> (a -> m a) -> m a
modifyFetchOldRefM :: Ref a s -> (a -> m a) -> m a
modifyFetchOldRefM Ref a s
ref a -> m a
f = do
a
a <- Ref a s -> m a
forall s (m :: * -> *) a. MonadPrim s m => Ref a s -> m a
readRef Ref a s
ref
a
a a -> m () -> m a
forall (f :: * -> *) a b. Functor f => a -> f b -> f a
<$ (Ref a s -> a -> m ()
forall s (m :: * -> *) a. MonadPrim s m => Ref a s -> a -> m ()
writeRef Ref a s
ref (a -> m ()) -> m a -> m ()
forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< a -> m a
f a
a)
{-# INLINE modifyFetchOldRefM #-}
modifyFetchNewRefM :: MonadPrim s m => Ref a s -> (a -> m a) -> m a
modifyFetchNewRefM :: Ref a s -> (a -> m a) -> m a
modifyFetchNewRefM Ref a s
ref a -> m a
f = do
a
a <- Ref a s -> m a
forall s (m :: * -> *) a. MonadPrim s m => Ref a s -> m a
readRef Ref a s
ref
a
a' <- a -> m a
f a
a
a
a' a -> m () -> m a
forall (f :: * -> *) a b. Functor f => a -> f b -> f a
<$ Ref a s -> a -> m ()
forall s (m :: * -> *) a. MonadPrim s m => Ref a s -> a -> m ()
writeRef Ref a s
ref a
a'
{-# INLINE modifyFetchNewRefM #-}
modifyLazyRefM :: MonadPrim s m => Ref a s -> (a -> m (a, b)) -> m b
modifyLazyRefM :: Ref a s -> (a -> m (a, b)) -> m b
modifyLazyRefM Ref a s
ref a -> m (a, b)
f = do
a
a <- Ref a s -> m a
forall s (m :: * -> *) a. MonadPrim s m => Ref a s -> m a
readRef Ref a s
ref
(a
a', b
b) <- a -> m (a, b)
f a
a
b
b b -> m () -> m b
forall (f :: * -> *) a b. Functor f => a -> f b -> f a
<$ Ref a s -> a -> m ()
forall s (m :: * -> *) a. MonadPrim s m => Ref a s -> a -> m ()
writeLazyRef Ref a s
ref a
a'
{-# INLINE modifyLazyRefM #-}
atomicWriteRef :: MonadPrim s m => Ref e s -> e -> m ()
atomicWriteRef :: Ref e s -> e -> m ()
atomicWriteRef Ref e s
ref !e
x = Ref e s -> (e -> e) -> m ()
forall s (m :: * -> *) a.
MonadPrim s m =>
Ref a s -> (a -> a) -> m ()
atomicModifyRef_ Ref e s
ref (e -> e -> e
forall a b. a -> b -> a
const e
x)
{-# INLINE atomicWriteRef #-}
atomicReadRef :: MonadPrim s m => Ref e s -> m e
atomicReadRef :: Ref e s -> m e
atomicReadRef Ref e s
ref = Ref e s -> (e -> e) -> m e
forall s (m :: * -> *) a.
MonadPrim s m =>
Ref a s -> (a -> a) -> m a
atomicModifyFetchOldRef Ref e s
ref e -> e
forall a. a -> a
id
atomicSwapRef :: MonadPrim s m => Ref e s -> e -> m e
atomicSwapRef :: Ref e s -> e -> m e
atomicSwapRef Ref e s
ref e
x = Ref e s -> (e -> e) -> m e
forall s (m :: * -> *) a.
MonadPrim s m =>
Ref a s -> (a -> a) -> m a
atomicModifyFetchOldRef Ref e s
ref (e -> e -> e
forall a b. a -> b -> a
const e
x)
{-# INLINE atomicSwapRef #-}
numTriesCAS :: Int
numTriesCAS :: Int
numTriesCAS = Int
35
atomicModifyRef :: MonadPrim s m => Ref a s -> (a -> (a, b)) -> m b
atomicModifyRef :: Ref a s -> (a -> (a, b)) -> m b
atomicModifyRef Ref a s
ref a -> (a, b)
f = Ref a s -> m a
forall s (m :: * -> *) a. MonadPrim s m => Ref a s -> m a
readRef Ref a s
ref m a -> (a -> m b) -> m b
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= Int -> a -> m b
loop (Int
0 :: Int)
where
loop :: Int -> a -> m b
loop Int
i a
old
| Int
i Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
< Int
numTriesCAS = do
case a -> (a, b)
f a
old of
(!a
new, b
result) -> do
(Bool
success, a
current) <- Ref a s -> a -> a -> m (Bool, a)
forall s (m :: * -> *) a.
MonadPrim s m =>
Ref a s -> a -> a -> m (Bool, a)
casRef Ref a s
ref a
old a
new
if Bool
success
then b -> m b
forall (f :: * -> *) a. Applicative f => a -> f a
pure b
result
else Int -> a -> m b
loop (Int
i Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
1) a
current
| Bool
otherwise = Ref a s -> (a -> (a, b)) -> m b
forall s (m :: * -> *) a b.
MonadPrim s m =>
Ref a s -> (a -> (a, b)) -> m b
atomicModifyRef2 Ref a s
ref a -> (a, b)
f
{-# INLINE atomicModifyRef #-}
atomicModifyRef2 :: MonadPrim s m => Ref a s -> (a -> (a, b)) -> m b
atomicModifyRef2 :: Ref a s -> (a -> (a, b)) -> m b
atomicModifyRef2 (Ref MutVar# s a
ref#) a -> (a, b)
f =
#if __GLASGOW_HASKELL__ <= 806
let g prev =
case f prev of
r@(!_new, _result) -> r
in prim (atomicModifyMutVar# ref# g)
#else
(State# s -> (# State# s, b #)) -> m b
forall s (m :: * -> *) a.
MonadPrim s m =>
(State# s -> (# State# s, a #)) -> m a
prim ((State# s -> (# State# s, b #)) -> m b)
-> (State# s -> (# State# s, b #)) -> m b
forall a b. (a -> b) -> a -> b
$ \State# s
s ->
case MutVar# s a
-> (a -> (a, b)) -> State# s -> (# State# s, a, (a, b) #)
forall d a c.
MutVar# d a -> (a -> c) -> State# d -> (# State# d, a, c #)
atomicModifyMutVar2# MutVar# s a
ref# a -> (a, b)
f State# s
s of
(# State# s
s', a
_old, (!a
_new, b
result) #) -> (# State# s
s', b
result #)
#endif
{-# INLINE atomicModifyRef2 #-}
atomicModifyRef_ :: MonadPrim s m => Ref a s -> (a -> a) -> m ()
atomicModifyRef_ :: Ref a s -> (a -> a) -> m ()
atomicModifyRef_ Ref a s
ref a -> a
f = Ref a s -> m a
forall s (m :: * -> *) a. MonadPrim s m => Ref a s -> m a
readRef Ref a s
ref m a -> (a -> m ()) -> m ()
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= Int -> a -> m ()
loop (Int
0 :: Int)
where
loop :: Int -> a -> m ()
loop Int
i a
old
| Int
i Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
< Int
numTriesCAS = do
(Bool
success, a
current) <- Ref a s -> a -> a -> m (Bool, a)
forall s (m :: * -> *) a.
MonadPrim s m =>
Ref a s -> a -> a -> m (Bool, a)
casRef Ref a s
ref a
old (a -> m (Bool, a)) -> a -> m (Bool, a)
forall a b. (a -> b) -> a -> b
$! a -> a
f a
old
Bool -> m () -> m ()
forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
unless Bool
success (m () -> m ()) -> m () -> m ()
forall a b. (a -> b) -> a -> b
$ Int -> a -> m ()
loop (Int
i Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
1) a
current
| Bool
otherwise = Ref a s -> (a -> a) -> m ()
forall s (m :: * -> *) a.
MonadPrim s m =>
Ref a s -> (a -> a) -> m ()
atomicModifyRef2_ Ref a s
ref a -> a
f
{-# INLINE atomicModifyRef_ #-}
atomicModifyRef2_ :: MonadPrim s m => Ref a s -> (a -> a) -> m ()
atomicModifyRef2_ :: Ref a s -> (a -> a) -> m ()
atomicModifyRef2_ (Ref MutVar# s a
ref#) a -> a
f =
(State# s -> State# s) -> m ()
forall s (m :: * -> *).
MonadPrim s m =>
(State# s -> State# s) -> m ()
prim_ ((State# s -> State# s) -> m ()) -> (State# s -> State# s) -> m ()
forall a b. (a -> b) -> a -> b
$ \State# s
s ->
case MutVar# s a -> (a -> a) -> State# s -> (# State# s, a, a #)
forall d a.
MutVar# d a -> (a -> a) -> State# d -> (# State# d, a, a #)
atomicModifyMutVar_# MutVar# s a
ref# a -> a
f State# s
s of
(# State# s
s', a
_prev, !a
_cur #) -> State# s
s'
{-# INLINE atomicModifyRef2_ #-}
atomicModifyFetchOldRef :: MonadPrim s m => Ref a s -> (a -> a) -> m a
atomicModifyFetchOldRef :: Ref a s -> (a -> a) -> m a
atomicModifyFetchOldRef Ref a s
ref a -> a
f = Ref a s -> m a
forall s (m :: * -> *) a. MonadPrim s m => Ref a s -> m a
readRef Ref a s
ref m a -> (a -> m a) -> m a
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= Int -> a -> m a
loop (Int
0 :: Int)
where
loop :: Int -> a -> m a
loop Int
i a
old
| Int
i Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
< Int
numTriesCAS = do
(Bool
success, a
current) <- Ref a s -> a -> a -> m (Bool, a)
forall s (m :: * -> *) a.
MonadPrim s m =>
Ref a s -> a -> a -> m (Bool, a)
casRef Ref a s
ref a
old (a -> m (Bool, a)) -> a -> m (Bool, a)
forall a b. (a -> b) -> a -> b
$! a -> a
f a
old
if Bool
success
then a -> m a
forall (f :: * -> *) a. Applicative f => a -> f a
pure a
old
else Int -> a -> m a
loop (Int
i Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
1) a
current
| Bool
otherwise = Ref a s -> (a -> a) -> m a
forall s (m :: * -> *) a.
MonadPrim s m =>
Ref a s -> (a -> a) -> m a
atomicModifyFetchOldRef2 Ref a s
ref a -> a
f
{-# INLINE atomicModifyFetchNewRef #-}
atomicModifyFetchOldRef2 :: MonadPrim s m => Ref a s -> (a -> a) -> m a
atomicModifyFetchOldRef2 :: Ref a s -> (a -> a) -> m a
atomicModifyFetchOldRef2 (Ref MutVar# s a
ref#) a -> a
f =
(State# s -> (# State# s, a #)) -> m a
forall s (m :: * -> *) a.
MonadPrim s m =>
(State# s -> (# State# s, a #)) -> m a
prim ((State# s -> (# State# s, a #)) -> m a)
-> (State# s -> (# State# s, a #)) -> m a
forall a b. (a -> b) -> a -> b
$ \State# s
s ->
case MutVar# s a -> (a -> a) -> State# s -> (# State# s, a, a #)
forall d a.
MutVar# d a -> (a -> a) -> State# d -> (# State# d, a, a #)
atomicModifyMutVar_# MutVar# s a
ref# a -> a
f State# s
s of
(# State# s
s', a
_prev, !a
_cur #) -> (# State# s
s', a
_prev #)
{-# INLINE atomicModifyFetchOldRef2 #-}
atomicModifyFetchNewRef :: MonadPrim s m => Ref a s -> (a -> a) -> m a
atomicModifyFetchNewRef :: Ref a s -> (a -> a) -> m a
atomicModifyFetchNewRef Ref a s
ref a -> a
f = Ref a s -> m a
forall s (m :: * -> *) a. MonadPrim s m => Ref a s -> m a
readRef Ref a s
ref m a -> (a -> m a) -> m a
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= Int -> a -> m a
loop (Int
0 :: Int)
where
loop :: Int -> a -> m a
loop Int
i a
old
| Int
i Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
< Int
numTriesCAS = do
(Bool
success, a
current) <- Ref a s -> a -> a -> m (Bool, a)
forall s (m :: * -> *) a.
MonadPrim s m =>
Ref a s -> a -> a -> m (Bool, a)
casRef Ref a s
ref a
old (a -> m (Bool, a)) -> a -> m (Bool, a)
forall a b. (a -> b) -> a -> b
$! a -> a
f a
old
if Bool
success
then a -> m a
forall (f :: * -> *) a. Applicative f => a -> f a
pure a
current
else Int -> a -> m a
loop (Int
i Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
1) a
current
| Bool
otherwise = Ref a s -> (a -> a) -> m a
forall s (m :: * -> *) a.
MonadPrim s m =>
Ref a s -> (a -> a) -> m a
atomicModifyFetchNewRef2 Ref a s
ref a -> a
f
{-# INLINE atomicModifyFetchOldRef #-}
atomicModifyFetchNewRef2 :: MonadPrim s m => Ref a s -> (a -> a) -> m a
atomicModifyFetchNewRef2 :: Ref a s -> (a -> a) -> m a
atomicModifyFetchNewRef2 (Ref MutVar# s a
ref#) a -> a
f =
(State# s -> (# State# s, a #)) -> m a
forall s (m :: * -> *) a.
MonadPrim s m =>
(State# s -> (# State# s, a #)) -> m a
prim ((State# s -> (# State# s, a #)) -> m a)
-> (State# s -> (# State# s, a #)) -> m a
forall a b. (a -> b) -> a -> b
$ \State# s
s ->
case MutVar# s a -> (a -> a) -> State# s -> (# State# s, a, a #)
forall d a.
MutVar# d a -> (a -> a) -> State# d -> (# State# d, a, a #)
atomicModifyMutVar_# MutVar# s a
ref# a -> a
f State# s
s of
(# State# s
s', a
_prev, !a
cur #) -> (# State# s
s', a
cur #)
{-# INLINE atomicModifyFetchNewRef2 #-}
atomicModifyFetchBothRef :: MonadPrim s m => Ref a s -> (a -> a) -> m (a, a)
atomicModifyFetchBothRef :: Ref a s -> (a -> a) -> m (a, a)
atomicModifyFetchBothRef Ref a s
ref a -> a
f = Ref a s -> m a
forall s (m :: * -> *) a. MonadPrim s m => Ref a s -> m a
readRef Ref a s
ref m a -> (a -> m (a, a)) -> m (a, a)
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= Int -> a -> m (a, a)
loop (Int
0 :: Int)
where
loop :: Int -> a -> m (a, a)
loop Int
i a
old
| Int
i Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
< Int
numTriesCAS = do
(Bool
success, a
current) <- Ref a s -> a -> a -> m (Bool, a)
forall s (m :: * -> *) a.
MonadPrim s m =>
Ref a s -> a -> a -> m (Bool, a)
casRef Ref a s
ref a
old (a -> m (Bool, a)) -> a -> m (Bool, a)
forall a b. (a -> b) -> a -> b
$! a -> a
f a
old
if Bool
success
then (a, a) -> m (a, a)
forall (f :: * -> *) a. Applicative f => a -> f a
pure (a
old, a
current)
else Int -> a -> m (a, a)
loop (Int
i Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
1) a
current
| Bool
otherwise = Ref a s -> (a -> a) -> m (a, a)
forall s (m :: * -> *) a.
MonadPrim s m =>
Ref a s -> (a -> a) -> m (a, a)
atomicModifyFetchBothRef2 Ref a s
ref a -> a
f
{-# INLINE atomicModifyFetchBothRef #-}
atomicModifyFetchBothRef2 :: MonadPrim s m => Ref a s -> (a -> a) -> m (a, a)
atomicModifyFetchBothRef2 :: Ref a s -> (a -> a) -> m (a, a)
atomicModifyFetchBothRef2 (Ref MutVar# s a
ref#) a -> a
f =
(State# s -> (# State# s, (a, a) #)) -> m (a, a)
forall s (m :: * -> *) a.
MonadPrim s m =>
(State# s -> (# State# s, a #)) -> m a
prim ((State# s -> (# State# s, (a, a) #)) -> m (a, a))
-> (State# s -> (# State# s, (a, a) #)) -> m (a, a)
forall a b. (a -> b) -> a -> b
$ \State# s
s ->
case MutVar# s a -> (a -> a) -> State# s -> (# State# s, a, a #)
forall d a.
MutVar# d a -> (a -> a) -> State# d -> (# State# d, a, a #)
atomicModifyMutVar_# MutVar# s a
ref# a -> a
f State# s
s of
(# State# s
s', a
prev, !a
cur #) -> (# State# s
s', (a
prev, a
cur) #)
{-# INLINE atomicModifyFetchBothRef2 #-}
atomicModifyFetchRef :: MonadPrim s m => Ref a s -> (a -> (a, b)) -> m (a, a, b)
atomicModifyFetchRef :: Ref a s -> (a -> (a, b)) -> m (a, a, b)
atomicModifyFetchRef Ref a s
ref a -> (a, b)
f = Ref a s -> m a
forall s (m :: * -> *) a. MonadPrim s m => Ref a s -> m a
readRef Ref a s
ref m a -> (a -> m (a, a, b)) -> m (a, a, b)
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= Int -> a -> m (a, a, b)
loop (Int
0 :: Int)
where
loop :: Int -> a -> m (a, a, b)
loop Int
i a
old
| Int
i Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
< Int
numTriesCAS = do
case a -> (a, b)
f a
old of
(!a
new, b
result) -> do
(Bool
success, a
current) <- Ref a s -> a -> a -> m (Bool, a)
forall s (m :: * -> *) a.
MonadPrim s m =>
Ref a s -> a -> a -> m (Bool, a)
casRef Ref a s
ref a
old a
new
if Bool
success
then (a, a, b) -> m (a, a, b)
forall (f :: * -> *) a. Applicative f => a -> f a
pure (a
old, a
new, b
result)
else Int -> a -> m (a, a, b)
loop (Int
i Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
1) a
current
| Bool
otherwise = Ref a s -> (a -> (a, b)) -> m (a, a, b)
forall s (m :: * -> *) a b.
MonadPrim s m =>
Ref a s -> (a -> (a, b)) -> m (a, a, b)
atomicModifyFetchRef2 Ref a s
ref a -> (a, b)
f
{-# INLINE atomicModifyFetchRef #-}
atomicModifyFetchRef2 :: MonadPrim s m => Ref a s -> (a -> (a, b)) -> m (a, a, b)
atomicModifyFetchRef2 :: Ref a s -> (a -> (a, b)) -> m (a, a, b)
atomicModifyFetchRef2 Ref a s
ref a -> (a, b)
f =
Ref a s -> (a -> (a, b)) -> m (a, a, b)
forall s (m :: * -> *) a b.
MonadPrim s m =>
Ref a s -> (a -> (a, b)) -> m (a, a, b)
atomicModifyFetchLazyRef Ref a s
ref ((a -> (a, b)) -> m (a, a, b)) -> (a -> (a, b)) -> m (a, a, b)
forall a b. (a -> b) -> a -> b
$ \a
current ->
case a -> (a, b)
f a
current of
r :: (a, b)
r@(!a
_new, b
_res) -> (a, b)
r
{-# INLINE atomicModifyFetchRef2 #-}
atomicModifyFetchBothLazyRef :: MonadPrim s m => Ref a s -> (a -> a) -> m (a, a)
atomicModifyFetchBothLazyRef :: Ref a s -> (a -> a) -> m (a, a)
atomicModifyFetchBothLazyRef (Ref MutVar# s a
ref#) a -> a
f =
(State# s -> (# State# s, (a, a) #)) -> m (a, a)
forall s (m :: * -> *) a.
MonadPrim s m =>
(State# s -> (# State# s, a #)) -> m a
prim ((State# s -> (# State# s, (a, a) #)) -> m (a, a))
-> (State# s -> (# State# s, (a, a) #)) -> m (a, a)
forall a b. (a -> b) -> a -> b
$ \State# s
s ->
case MutVar# s a -> (a -> a) -> State# s -> (# State# s, a, a #)
forall d a.
MutVar# d a -> (a -> a) -> State# d -> (# State# d, a, a #)
atomicModifyMutVar_# MutVar# s a
ref# a -> a
f State# s
s of
(# State# s
s', a
prev, a
cur #) -> (# State# s
s', (a
prev, a
cur) #)
{-# INLINE atomicModifyFetchBothLazyRef #-}
casRef :: MonadPrim s m => Ref a s -> a -> a -> m (Bool, a)
casRef :: Ref a s -> a -> a -> m (Bool, a)
casRef (Ref MutVar# s a
ref#) a
expOld a
new =
(State# s -> (# State# s, (Bool, a) #)) -> m (Bool, a)
forall s (m :: * -> *) a.
MonadPrim s m =>
(State# s -> (# State# s, a #)) -> m a
prim ((State# s -> (# State# s, (Bool, a) #)) -> m (Bool, a))
-> (State# s -> (# State# s, (Bool, a) #)) -> m (Bool, a)
forall a b. (a -> b) -> a -> b
$ \State# s
s ->
case MutVar# s a -> a -> a -> State# s -> (# State# s, Int#, a #)
forall d a.
MutVar# d a -> a -> a -> State# d -> (# State# d, Int#, a #)
casMutVar# MutVar# s a
ref# a
expOld a
new State# s
s of
(# State# s
s', Int#
failed#, a
actualOld #) ->
(# State# s
s', (Int# -> Bool
isTrue# (Int#
failed# Int# -> Int# -> Int#
==# Int#
0#), a
actualOld) #)
{-# INLINE casRef #-}
atomicModifyFetchLazyRef :: MonadPrim s m => Ref a s -> (a -> (a, b)) -> m (a, a, b)
atomicModifyFetchLazyRef :: Ref a s -> (a -> (a, b)) -> m (a, a, b)
atomicModifyFetchLazyRef (Ref MutVar# s a
ref#) a -> (a, b)
f =
(State# s -> (# State# s, (a, a, b) #)) -> m (a, a, b)
forall s (m :: * -> *) a.
MonadPrim s m =>
(State# s -> (# State# s, a #)) -> m a
prim ((State# s -> (# State# s, (a, a, b) #)) -> m (a, a, b))
-> (State# s -> (# State# s, (a, a, b) #)) -> m (a, a, b)
forall a b. (a -> b) -> a -> b
$ \State# s
s ->
case MutVar# s a
-> (a -> (a, b)) -> State# s -> (# State# s, a, (a, b) #)
forall d a c.
MutVar# d a -> (a -> c) -> State# d -> (# State# d, a, c #)
atomicModifyMutVar2# MutVar# s a
ref# a -> (a, b)
f State# s
s of
(# State# s
s', a
old, ~(a
new, b
res) #) -> (# State# s
s', (a
old, a
new, b
res) #)
{-# INLINE atomicModifyFetchLazyRef #-}
atomicModifyLazyRef :: MonadPrim s m => Ref a s -> (a -> (a, b)) -> m b
atomicModifyLazyRef :: Ref a s -> (a -> (a, b)) -> m b
atomicModifyLazyRef (Ref MutVar# s a
ref#) a -> (a, b)
f = (State# s -> (# State# s, b #)) -> m b
forall s (m :: * -> *) a.
MonadPrim s m =>
(State# s -> (# State# s, a #)) -> m a
prim (MutVar# s a -> (a -> (a, b)) -> State# s -> (# State# s, b #)
forall s a b c.
MutVar# s a -> (a -> b) -> State# s -> (# State# s, c #)
atomicModifyMutVar# MutVar# s a
ref# a -> (a, b)
f)
{-# INLINE atomicModifyLazyRef #-}
atomicModifyLazyRef_ :: MonadPrim s m => Ref a s -> (a -> a) -> m ()
atomicModifyLazyRef_ :: Ref a s -> (a -> a) -> m ()
atomicModifyLazyRef_ (Ref MutVar# s a
ref#) a -> a
f =
(State# s -> State# s) -> m ()
forall s (m :: * -> *).
MonadPrim s m =>
(State# s -> State# s) -> m ()
prim_ ((State# s -> State# s) -> m ()) -> (State# s -> State# s) -> m ()
forall a b. (a -> b) -> a -> b
$ \State# s
s ->
case MutVar# s a -> (a -> a) -> State# s -> (# State# s, a, a #)
forall d a.
MutVar# d a -> (a -> a) -> State# d -> (# State# d, a, a #)
atomicModifyMutVar_# MutVar# s a
ref# a -> a
f State# s
s of
(# State# s
s', a
_prev, a
_cur #) -> State# s
s'
{-# INLINE atomicModifyLazyRef_ #-}
atomicModifyFetchOldLazyRef :: MonadPrim s m => Ref a s -> (a -> a) -> m a
atomicModifyFetchOldLazyRef :: Ref a s -> (a -> a) -> m a
atomicModifyFetchOldLazyRef (Ref MutVar# s a
ref#) a -> a
f =
(State# s -> (# State# s, a #)) -> m a
forall s (m :: * -> *) a.
MonadPrim s m =>
(State# s -> (# State# s, a #)) -> m a
prim ((State# s -> (# State# s, a #)) -> m a)
-> (State# s -> (# State# s, a #)) -> m a
forall a b. (a -> b) -> a -> b
$ \State# s
s ->
case MutVar# s a -> (a -> a) -> State# s -> (# State# s, a, a #)
forall d a.
MutVar# d a -> (a -> a) -> State# d -> (# State# d, a, a #)
atomicModifyMutVar_# MutVar# s a
ref# a -> a
f State# s
s of
(# State# s
s', a
prev, a
_cur #) -> (# State# s
s', a
prev #)
atomicModifyFetchNewLazyRef :: MonadPrim s m => Ref a s -> (a -> a) -> m a
atomicModifyFetchNewLazyRef :: Ref a s -> (a -> a) -> m a
atomicModifyFetchNewLazyRef (Ref MutVar# s a
ref#) a -> a
f =
(State# s -> (# State# s, a #)) -> m a
forall s (m :: * -> *) a.
MonadPrim s m =>
(State# s -> (# State# s, a #)) -> m a
prim ((State# s -> (# State# s, a #)) -> m a)
-> (State# s -> (# State# s, a #)) -> m a
forall a b. (a -> b) -> a -> b
$ \State# s
s ->
case MutVar# s a -> (a -> a) -> State# s -> (# State# s, a, a #)
forall d a.
MutVar# d a -> (a -> a) -> State# d -> (# State# d, a, a #)
atomicModifyMutVar_# MutVar# s a
ref# a -> a
f State# s
s of
(# State# s
s', a
_prev, a
cur #) -> (# State# s
s', a
cur #)
atomicWriteLazyRef :: MonadPrim s m => Ref b s -> b -> m ()
atomicWriteLazyRef :: Ref b s -> b -> m ()
atomicWriteLazyRef Ref b s
ref b
x = Ref b s -> (b -> b) -> m ()
forall s (m :: * -> *) a.
MonadPrim s m =>
Ref a s -> (a -> a) -> m ()
atomicModifyLazyRef_ Ref b s
ref (b -> b -> b
forall a b. a -> b -> a
const b
x)
toSTRef :: Ref a s -> ST.STRef s a
toSTRef :: Ref a s -> STRef s a
toSTRef (Ref MutVar# s a
ref#) = MutVar# s a -> STRef s a
forall s a. MutVar# s a -> STRef s a
ST.STRef MutVar# s a
ref#
{-# INLINE toSTRef #-}
fromSTRef :: ST.STRef s a -> Ref a s
fromSTRef :: STRef s a -> Ref a s
fromSTRef (ST.STRef MutVar# s a
ref#) = MutVar# s a -> Ref a s
forall a s. MutVar# s a -> Ref a s
Ref MutVar# s a
ref#
{-# INLINE fromSTRef #-}
toIORef :: Ref a RW -> IO.IORef a
toIORef :: Ref a RW -> IORef a
toIORef = STRef RW a -> IORef a
coerce (STRef RW a -> IORef a)
-> (Ref a RW -> STRef RW a) -> Ref a RW -> IORef a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Ref a RW -> STRef RW a
forall a s. Ref a s -> STRef s a
toSTRef
{-# INLINE toIORef #-}
fromIORef :: IO.IORef a -> Ref a RW
fromIORef :: IORef a -> Ref a RW
fromIORef = STRef RW a -> Ref a RW
forall s a. STRef s a -> Ref a s
fromSTRef (STRef RW a -> Ref a RW)
-> (IORef a -> STRef RW a) -> IORef a -> Ref a RW
forall b c a. (b -> c) -> (a -> b) -> a -> c
. IORef a -> STRef RW a
coerce
{-# INLINE fromIORef #-}
mkWeakRef ::
forall a b m. MonadUnliftPrim RW m
=> Ref a RW
-> m b
-> m (Weak (Ref a RW))
mkWeakRef :: Ref a RW -> m b -> m (Weak (Ref a RW))
mkWeakRef ref :: Ref a RW
ref@(Ref MutVar# RW a
ref#) !m b
finalizer =
m b
-> ((State# RW -> (# State# RW, b #))
-> State# RW -> (# State# RW, Weak (Ref a RW) #))
-> m (Weak (Ref a RW))
forall s (m :: * -> *) a b.
MonadUnliftPrim s m =>
m a
-> ((State# s -> (# State# s, a #))
-> State# s -> (# State# s, b #))
-> m b
runInPrimBase m b
finalizer (((State# RW -> (# State# RW, b #))
-> State# RW -> (# State# RW, Weak (Ref a RW) #))
-> m (Weak (Ref a RW)))
-> ((State# RW -> (# State# RW, b #))
-> State# RW -> (# State# RW, Weak (Ref a RW) #))
-> m (Weak (Ref a RW))
forall a b. (a -> b) -> a -> b
$ \State# RW -> (# State# RW, b #)
f# State# RW
s ->
case MutVar# RW a
-> Ref a RW
-> (State# RW -> (# State# RW, b #))
-> State# RW
-> (# State# RW, Weak# (Ref a RW) #)
forall a b c.
a
-> b
-> (State# RW -> (# State# RW, c #))
-> State# RW
-> (# State# RW, Weak# b #)
mkWeak# MutVar# RW a
ref# Ref a RW
ref State# RW -> (# State# RW, b #)
f# State# RW
s of
(# State# RW
s', Weak# (Ref a RW)
weak# #) -> (# State# RW
s', Weak# (Ref a RW) -> Weak (Ref a RW)
forall v. Weak# v -> Weak v
Weak Weak# (Ref a RW)
weak# #)
{-# INLINE mkWeakRef #-}