{-# LANGUAGE CPP #-}
{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE MagicHash #-}
{-# LANGUAGE UnboxedTuples #-}
-- |
-- Module      : Foreign.Prim.Ptr
-- Copyright   : (c) Alexey Kuleshevich 2020
-- License     : BSD3
-- Maintainer  : Alexey Kuleshevich <alexey@kuleshevi.ch>
-- Stability   : experimental
-- Portability : non-portable
--
module Foreign.Prim.Ptr
  ( module GHC.Ptr
  , plusOffPtr
  , plusByteOffPtr
  , minusOffPtr
  , minusOffRemPtr
  , minusByteOffPtr
  , readPtr
  , readOffPtr
  , readByteOffPtr
  , writePtr
  , writeOffPtr
  , writeByteOffPtr
  , setOffPtr
  , copyPtrToPtr
  , copyByteOffPtrToPtr
  , movePtrToPtr
  , moveByteOffPtrToPtr
  , comparePtrToPtr
  , compareByteOffPtrToPtr
  , freeHaskellFunPtr
  , module X
  , WordPtr(..)
  , ptrToWordPtr
  , wordPtrToPtr
  , IntPtr(..)
  , ptrToIntPtr
  , intPtrToPtr
  -- * Atomic
  , casOffPtr
  , atomicModifyOffPtr
  , atomicModifyOffPtr_
  , atomicModifyFetchOldOffPtr
  , atomicModifyFetchNewOffPtr
  -- ** Numeric
  , atomicAddFetchOldOffPtr
  , atomicAddFetchNewOffPtr
  , atomicSubFetchOldOffPtr
  , atomicSubFetchNewOffPtr
  -- ** Binary
  , atomicAndFetchOldOffPtr
  , atomicAndFetchNewOffPtr
  , atomicNandFetchOldOffPtr
  , atomicNandFetchNewOffPtr
  , atomicOrFetchOldOffPtr
  , atomicOrFetchNewOffPtr
  , atomicXorFetchOldOffPtr
  , atomicXorFetchNewOffPtr
  , atomicNotFetchOldOffPtr
  , atomicNotFetchNewOffPtr
  -- * Prefetch
  , prefetchPtr0
  , prefetchPtr1
  , prefetchPtr2
  , prefetchPtr3
  , prefetchOffPtr0
  , prefetchOffPtr1
  , prefetchOffPtr2
  , prefetchOffPtr3
  ) where

import Control.Prim.Monad
import Control.Prim.Monad.Unsafe
import Data.Prim
import Data.Prim.Atomic
import Data.Prim.Class
import Foreign.Marshal.Utils (copyBytes)
import Foreign.Prim
import qualified Foreign.Ptr as GHC (freeHaskellFunPtr)
import Foreign.Ptr as X hiding (IntPtr, WordPtr, freeHaskellFunPtr, intPtrToPtr,
                         ptrToIntPtr, ptrToWordPtr, wordPtrToPtr)
import GHC.Ptr

setOffPtr ::
     (MonadPrim s m, Prim e)
  => Ptr e -- ^ Chunk of memory to fill
  -> Off e -- ^ Offset in number of elements
  -> Count e -- ^ Number of cells to fill
  -> e -- ^ A value to fill the cells with
  -> m ()
setOffPtr :: Ptr e -> Off e -> Count e -> e -> m ()
setOffPtr (Ptr Addr#
addr#) (Off (I# Int#
o#)) (Count (I# Int#
n#)) e
a = (State# s -> State# s) -> m ()
forall s (m :: * -> *).
MonadPrim s m =>
(State# s -> State# s) -> m ()
prim_ (Addr# -> Int# -> Int# -> e -> State# s -> State# s
forall a s.
Prim a =>
Addr# -> Int# -> Int# -> a -> State# s -> State# s
setOffAddr# Addr#
addr# Int#
o# Int#
n# e
a)
{-# INLINE setOffPtr #-}


readOffPtr :: (MonadPrim s m, Prim e) => Ptr e -> Off e -> m e
readOffPtr :: Ptr e -> Off e -> m e
readOffPtr (Ptr Addr#
addr#) (Off (I# Int#
i#)) = (State# s -> (# State# s, e #)) -> m e
forall s (m :: * -> *) a.
MonadPrim s m =>
(State# s -> (# State# s, a #)) -> m a
prim (Addr# -> Int# -> State# s -> (# State# s, e #)
forall a s.
Prim a =>
Addr# -> Int# -> State# s -> (# State# s, a #)
readOffAddr# Addr#
addr# Int#
i#)
{-# INLINE readOffPtr #-}


readByteOffPtr :: (MonadPrim s m, Prim e) => Ptr e -> Off Word8 -> m e
readByteOffPtr :: Ptr e -> Off Word8 -> m e
readByteOffPtr Ptr e
ptr (Off Int
i) =
  case Ptr e
ptr Ptr e -> Int -> Ptr Any
forall a b. Ptr a -> Int -> Ptr b
`plusPtr` Int
i of
    Ptr Addr#
addr# -> (State# s -> (# State# s, e #)) -> m e
forall s (m :: * -> *) a.
MonadPrim s m =>
(State# s -> (# State# s, a #)) -> m a
prim (Addr# -> Int# -> State# s -> (# State# s, e #)
forall a s.
Prim a =>
Addr# -> Int# -> State# s -> (# State# s, a #)
readOffAddr# Addr#
addr# Int#
0#)
{-# INLINE readByteOffPtr #-}

writeOffPtr :: (MonadPrim s m, Prim e) => Ptr e -> Off e -> e -> m ()
writeOffPtr :: Ptr e -> Off e -> e -> m ()
writeOffPtr (Ptr Addr#
addr#) (Off (I# Int#
i#)) e
a = (State# s -> State# s) -> m ()
forall s (m :: * -> *).
MonadPrim s m =>
(State# s -> State# s) -> m ()
prim_ (Addr# -> Int# -> e -> State# s -> State# s
forall a s. Prim a => Addr# -> Int# -> a -> State# s -> State# s
writeOffAddr# Addr#
addr# Int#
i# e
a)
{-# INLINE writeOffPtr #-}

writeByteOffPtr :: (MonadPrim s m, Prim e) => Ptr e -> Off Word8 -> e -> m ()
writeByteOffPtr :: Ptr e -> Off Word8 -> e -> m ()
writeByteOffPtr Ptr e
ptr (Off Int
i) e
a =
  case Ptr e
ptr Ptr e -> Int -> Ptr Any
forall a b. Ptr a -> Int -> Ptr b
`plusPtr` Int
i of
    Ptr Addr#
addr# -> (State# s -> State# s) -> m ()
forall s (m :: * -> *).
MonadPrim s m =>
(State# s -> State# s) -> m ()
prim_ (Addr# -> Int# -> e -> State# s -> State# s
forall a s. Prim a => Addr# -> Int# -> a -> State# s -> State# s
writeOffAddr# Addr#
addr# Int#
0# e
a)
{-# INLINE writeByteOffPtr #-}

readPtr :: (MonadPrim s m, Prim e) => Ptr e -> m e
readPtr :: Ptr e -> m e
readPtr (Ptr Addr#
addr#) = (State# s -> (# State# s, e #)) -> m e
forall s (m :: * -> *) a.
MonadPrim s m =>
(State# s -> (# State# s, a #)) -> m a
prim (Addr# -> Int# -> State# s -> (# State# s, e #)
forall a s.
Prim a =>
Addr# -> Int# -> State# s -> (# State# s, a #)
readOffAddr# Addr#
addr# Int#
0#)
{-# INLINE readPtr #-}

writePtr :: (MonadPrim s m, Prim e) => Ptr e -> e -> m ()
writePtr :: Ptr e -> e -> m ()
writePtr (Ptr Addr#
addr#) e
a = (State# s -> State# s) -> m ()
forall s (m :: * -> *).
MonadPrim s m =>
(State# s -> State# s) -> m ()
prim_ (Addr# -> Int# -> e -> State# s -> State# s
forall a s. Prim a => Addr# -> Int# -> a -> State# s -> State# s
writeOffAddr# Addr#
addr# Int#
0# e
a)
{-# INLINE writePtr #-}

plusByteOffPtr :: Ptr e -> Off Word8 -> Ptr e
plusByteOffPtr :: Ptr e -> Off Word8 -> Ptr e
plusByteOffPtr (Ptr Addr#
addr#) (Off (I# Int#
off#)) = Addr# -> Ptr e
forall a. Addr# -> Ptr a
Ptr (Addr#
addr# Addr# -> Int# -> Addr#
`plusAddr#` Int#
off#)
{-# INLINE plusByteOffPtr #-}


plusOffPtr :: Prim e => Ptr e -> Off e -> Ptr e
plusOffPtr :: Ptr e -> Off e -> Ptr e
plusOffPtr (Ptr Addr#
addr#) Off e
off = Addr# -> Ptr e
forall a. Addr# -> Ptr a
Ptr (Addr#
addr# Addr# -> Int# -> Addr#
`plusAddr#` Off e -> Int#
forall e. Prim e => Off e -> Int#
unOffBytes# Off e
off)
{-# INLINE plusOffPtr #-}

-- | Find the offset in bytes that is between the two pointers by subtracting one address
-- from another.
--
-- @since 0.1.0
minusByteOffPtr :: Ptr e -> Ptr e -> Off Word8
minusByteOffPtr :: Ptr e -> Ptr e -> Off Word8
minusByteOffPtr (Ptr Addr#
xaddr#) (Ptr Addr#
yaddr#) = Int -> Off Word8
forall e. Int -> Off e
Off (Int# -> Int
I# (Addr#
xaddr# Addr# -> Addr# -> Int#
`minusAddr#` Addr#
yaddr#))
{-# INLINE minusByteOffPtr #-}

-- | Find the offset in number of elements that is between the two pointers by subtracting
-- one address from another and dividing the result by the size of an element.
--
-- @since 0.1.0
minusOffPtr :: Prim e => Ptr e -> Ptr e -> Off e
minusOffPtr :: Ptr e -> Ptr e -> Off e
minusOffPtr (Ptr Addr#
xaddr#) (Ptr Addr#
yaddr#) =
  Off Word8 -> Off e
forall e. Prim e => Off Word8 -> Off e
fromByteOff (Int -> Off Word8
forall e. Int -> Off e
Off (Int# -> Int
I# (Addr#
xaddr# Addr# -> Addr# -> Int#
`minusAddr#` Addr#
yaddr#)))
{-# INLINE minusOffPtr #-}

-- | Same as `minusOffPtr`, but will also return the remainder in bytes that is left over.
--
-- @since 0.1.0
minusOffRemPtr :: Prim e => Ptr e -> Ptr e -> (Off e, Off Word8)
minusOffRemPtr :: Ptr e -> Ptr e -> (Off e, Off Word8)
minusOffRemPtr (Ptr Addr#
xaddr#) (Ptr Addr#
yaddr#) =
  Off Word8 -> (Off e, Off Word8)
forall e. Prim e => Off Word8 -> (Off e, Off Word8)
fromByteOffRem (Int -> Off Word8
forall e. Int -> Off e
Off (Int# -> Int
I# (Addr#
xaddr# Addr# -> Addr# -> Int#
`minusAddr#` Addr#
yaddr#)))
{-# INLINE minusOffRemPtr #-}

copyPtrToPtr :: (MonadPrim s m, Prim e) => Ptr e -> Off e -> Ptr e -> Off e -> Count e -> m ()
copyPtrToPtr :: Ptr e -> Off e -> Ptr e -> Off e -> Count e -> m ()
copyPtrToPtr Ptr e
srcPtr Off e
srcOff Ptr e
dstPtr Off e
dstOff Count e
c =
  IO () -> m ()
forall s (m :: * -> *) a. MonadPrim s m => IO a -> m a
unsafeIOToPrim (IO () -> m ()) -> IO () -> m ()
forall a b. (a -> b) -> a -> b
$
  Ptr e -> Ptr e -> Int -> IO ()
forall a. Ptr a -> Ptr a -> Int -> IO ()
copyBytes
    (Ptr e
dstPtr Ptr e -> Off e -> Ptr e
forall e. Prim e => Ptr e -> Off e -> Ptr e
`plusOffPtr` Off e
dstOff)
    (Ptr e
srcPtr Ptr e -> Off e -> Ptr e
forall e. Prim e => Ptr e -> Off e -> Ptr e
`plusOffPtr` Off e
srcOff)
    (Count e -> Int
forall e. Prim e => Count e -> Int
unCountBytes Count e
c)
{-# INLINE copyPtrToPtr #-}

copyByteOffPtrToPtr ::
     (MonadPrim s m, Prim e)
  => Ptr e
  -> Off Word8
  -> Ptr e
  -> Off Word8
  -> Count e
  -> m ()
copyByteOffPtrToPtr :: Ptr e -> Off Word8 -> Ptr e -> Off Word8 -> Count e -> m ()
copyByteOffPtrToPtr Ptr e
srcPtr (Off Int
srcOff) Ptr e
dstPtr (Off Int
dstOff) Count e
c =
  IO () -> m ()
forall s (m :: * -> *) a. MonadPrim s m => IO a -> m a
unsafeIOToPrim (IO () -> m ()) -> IO () -> m ()
forall a b. (a -> b) -> a -> b
$
  Ptr Any -> Ptr Any -> Int -> IO ()
forall a. Ptr a -> Ptr a -> Int -> IO ()
copyBytes
    (Ptr e
dstPtr Ptr e -> Int -> Ptr Any
forall a b. Ptr a -> Int -> Ptr b
`plusPtr` Int
dstOff)
    (Ptr e
srcPtr Ptr e -> Int -> Ptr Any
forall a b. Ptr a -> Int -> Ptr b
`plusPtr` Int
srcOff)
    (Count e -> Int
forall e. Prim e => Count e -> Int
unCountBytes Count e
c)
{-# INLINE copyByteOffPtrToPtr #-}

movePtrToPtr :: (MonadPrim s m, Prim e) => Ptr e -> Off e -> Ptr e -> Off e -> Count e -> m ()
movePtrToPtr :: Ptr e -> Off e -> Ptr e -> Off e -> Count e -> m ()
movePtrToPtr Ptr e
src Off e
srcOff Ptr e
dst Off e
dstOff =
  Ptr e -> Off Word8 -> Ptr e -> Off Word8 -> Count e -> m ()
forall s (m :: * -> *) e.
(MonadPrim s m, Prim e) =>
Ptr e -> Off Word8 -> Ptr e -> Off Word8 -> Count e -> m ()
moveByteOffPtrToPtr Ptr e
src (Off e -> Off Word8
forall e. Prim e => Off e -> Off Word8
toByteOff Off e
srcOff) Ptr e
dst (Off e -> Off Word8
forall e. Prim e => Off e -> Off Word8
toByteOff Off e
dstOff)
{-# INLINE movePtrToPtr #-}

moveByteOffPtrToPtr ::
     (MonadPrim s m, Prim e)
  => Ptr e
  -> Off Word8
  -> Ptr e
  -> Off Word8
  -> Count e
  -> m ()
moveByteOffPtrToPtr :: Ptr e -> Off Word8 -> Ptr e -> Off Word8 -> Count e -> m ()
moveByteOffPtrToPtr (Ptr Addr#
srcAddr#) (Off (I# Int#
srcOff#)) (Ptr Addr#
dstAddr#) (Off (I# Int#
dstOff#)) Count e
c =
  IO () -> m ()
forall s (m :: * -> *) a. MonadPrim s m => IO a -> m a
unsafeIOToPrim (IO () -> m ()) -> IO () -> m ()
forall a b. (a -> b) -> a -> b
$ Addr# -> Int# -> Addr# -> Int# -> Int# -> IO ()
memmoveAddr# Addr#
srcAddr# Int#
srcOff# Addr#
dstAddr# Int#
dstOff# (Count e -> Int#
forall e. Prim e => Count e -> Int#
unCountBytes# Count e
c)
{-# INLINE moveByteOffPtrToPtr #-}

-- | Compare memory between two pointers. Offsets and count is in number of elements,
-- instead of byte count. Use `compareByteOffPtrToPtr` when offset in bytes is required.
comparePtrToPtr :: Prim e => Ptr e -> Off e -> Ptr e -> Off e -> Count e -> Ordering
comparePtrToPtr :: Ptr e -> Off e -> Ptr e -> Off e -> Count e -> Ordering
comparePtrToPtr (Ptr Addr#
addr1#) Off e
off1 (Ptr Addr#
addr2#) Off e
off2 Count e
c =
  Int# -> Ordering
toOrdering# (Addr# -> Int# -> Addr# -> Int# -> Int# -> Int#
memcmpAddr# Addr#
addr1# (Off e -> Int#
forall e. Prim e => Off e -> Int#
unOffBytes# Off e
off1) Addr#
addr2# (Off e -> Int#
forall e. Prim e => Off e -> Int#
unOffBytes# Off e
off2) (Count e -> Int#
forall e. Prim e => Count e -> Int#
unCountBytes# Count e
c))
{-# INLINE comparePtrToPtr #-}

-- | Same as `comparePtrToPtr`, except offset is in bytes instead of number of elements.
compareByteOffPtrToPtr ::
     Prim e => Ptr e -> Off Word8 -> Ptr e -> Off Word8 -> Count e -> Ordering
compareByteOffPtrToPtr :: Ptr e -> Off Word8 -> Ptr e -> Off Word8 -> Count e -> Ordering
compareByteOffPtrToPtr (Ptr Addr#
addr1#) (Off (I# Int#
off1#)) (Ptr Addr#
addr2#) (Off (I# Int#
off2#)) Count e
c =
  Int# -> Ordering
toOrdering# (Addr# -> Int# -> Addr# -> Int# -> Int# -> Int#
memcmpAddr# Addr#
addr1# Int#
off1# Addr#
addr2# Int#
off2# (Count e -> Int#
forall e. Prim e => Count e -> Int#
unCountBytes# Count e
c))
{-# INLINE compareByteOffPtrToPtr #-}




-- | Perform atomic modification of an element in the `Ptr` at the supplied
-- index. Returns the artifact of computation @__b__@.  Offset is in number of elements,
-- rather than bytes. Implies a full memory barrier.
--
-- /Note/ - Bounds are not checked, therefore this function is unsafe.
--
-- @since 0.1.0
casOffPtr ::
     (MonadPrim s m, Atomic e)
  => Ptr e -- ^ Array to be mutated
  -> Off e -- ^ Index is in elements of @__a__@, rather than bytes.
  -> e -- ^ Expected old value
  -> e -- ^ New value
  -> m e
casOffPtr :: Ptr e -> Off e -> e -> e -> m e
casOffPtr (Ptr Addr#
addr#) (Off (I# Int#
i#)) e
old e
new = (State# s -> (# State# s, e #)) -> m e
forall s (m :: * -> *) a.
MonadPrim s m =>
(State# s -> (# State# s, a #)) -> m a
prim ((State# s -> (# State# s, e #)) -> m e)
-> (State# s -> (# State# s, e #)) -> m e
forall a b. (a -> b) -> a -> b
$ Addr# -> Int# -> e -> e -> State# s -> (# State# s, e #)
forall a s.
Atomic a =>
Addr# -> Int# -> a -> a -> State# s -> (# State# s, a #)
casOffAddr# Addr#
addr# Int#
i# e
old e
new
{-# INLINE casOffPtr #-}

-- | Perform atomic modification of an element in the `Ptr` at the supplied
-- index. Returns the artifact of computation @__b__@.  Offset is in number of elements,
-- rather than bytes. Implies a full memory barrier.
--
-- /Note/ - Bounds are not checked, therefore this function is unsafe.
--
-- @since 0.1.0
atomicModifyOffPtr ::
     (MonadPrim s m, Atomic e)
  => Ptr e -- ^ Array to be mutated
  -> Off e -- ^ Index is in elements of @__a__@, rather than bytes.
  -> (e -> (e, b)) -- ^ Function that is applied to the old value and returns new value
                   -- and some artifact of computation @__b__@
  -> m b
atomicModifyOffPtr :: Ptr e -> Off e -> (e -> (e, b)) -> m b
atomicModifyOffPtr (Ptr Addr#
addr#) (Off (I# Int#
i#)) e -> (e, b)
f =
  (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
$
  Addr# -> Int# -> (e -> (# e, b #)) -> State# s -> (# State# s, b #)
forall a b s.
Atomic a =>
Addr# -> Int# -> (a -> (# a, b #)) -> State# s -> (# State# s, b #)
atomicModifyOffAddr# Addr#
addr# Int#
i# ((e -> (# e, b #)) -> State# s -> (# State# s, b #))
-> (e -> (# e, b #)) -> State# s -> (# State# s, b #)
forall a b. (a -> b) -> a -> b
$ \e
a ->
    case e -> (e, b)
f e
a of
      (e
a', b
b) -> (# e
a', b
b #)
{-# INLINE atomicModifyOffPtr #-}

-- | Perform atomic modification of an element in the `Ptr` at the supplied
-- index.  Offset is in number of elements, rather than bytes. Implies a full memory
-- barrier.
--
-- /Note/ - Bounds are not checked, therefore this function is unsafe.
--
-- @since 0.1.0
atomicModifyOffPtr_ ::
     (MonadPrim s m, Atomic e)
  => Ptr e -- ^ Array to be mutated
  -> Off e -- ^ Index is in elements of @__a__@, rather than bytes.
  -> (e -> e) -- ^ Function that is applied to the old value and returns new value.
  -> m ()
atomicModifyOffPtr_ :: Ptr e -> Off e -> (e -> e) -> m ()
atomicModifyOffPtr_ (Ptr Addr#
addr#) (Off (I# Int#
i#)) e -> e
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
$ Addr# -> Int# -> (e -> e) -> State# s -> State# s
forall a s.
Atomic a =>
Addr# -> Int# -> (a -> a) -> State# s -> State# s
atomicModifyOffAddr_# Addr#
addr# Int#
i# e -> e
f
{-# INLINE atomicModifyOffPtr_ #-}


-- | Perform atomic modification of an element in the `Ptr` at the supplied
-- index. Returns the previous value.  Offset is in number of elements, rather than
-- bytes. Implies a full memory barrier.
--
-- /Note/ - Bounds are not checked, therefore this function is unsafe.
--
-- @since 0.1.0
atomicModifyFetchOldOffPtr ::
     (MonadPrim s m, Atomic e)
  => Ptr e -- ^ Array to be mutated
  -> Off e -- ^ Index is in elements of @__a__@, rather than bytes.
  -> (e -> e) -- ^ Function that is applied to the old value and returns the new value
  -> m e
atomicModifyFetchOldOffPtr :: Ptr e -> Off e -> (e -> e) -> m e
atomicModifyFetchOldOffPtr (Ptr Addr#
addr#) (Off (I# Int#
i#)) e -> e
f =
  (State# s -> (# State# s, e #)) -> m e
forall s (m :: * -> *) a.
MonadPrim s m =>
(State# s -> (# State# s, a #)) -> m a
prim ((State# s -> (# State# s, e #)) -> m e)
-> (State# s -> (# State# s, e #)) -> m e
forall a b. (a -> b) -> a -> b
$ Addr# -> Int# -> (e -> e) -> State# s -> (# State# s, e #)
forall a s.
Atomic a =>
Addr# -> Int# -> (a -> a) -> State# s -> (# State# s, a #)
atomicModifyFetchOldOffAddr# Addr#
addr# Int#
i# e -> e
f
{-# INLINE atomicModifyFetchOldOffPtr #-}


-- | Perform atomic modification of an element in the `Ptr` at the supplied
-- index.  Offset is in number of elements, rather than bytes. Implies a full memory
-- barrier.
--
-- /Note/ - Bounds are not checked, therefore this function is unsafe.
--
-- @since 0.1.0
atomicModifyFetchNewOffPtr ::
     (MonadPrim s m, Atomic e)
  => Ptr e -- ^ Array to be mutated
  -> Off e -- ^ Index is in elements of @__a__@, rather than bytes.
  -> (e -> e) -- ^ Function that is applied to the old value and returns the new value
  -> m e
atomicModifyFetchNewOffPtr :: Ptr e -> Off e -> (e -> e) -> m e
atomicModifyFetchNewOffPtr (Ptr Addr#
addr#) (Off (I# Int#
i#)) e -> e
f =
  (State# s -> (# State# s, e #)) -> m e
forall s (m :: * -> *) a.
MonadPrim s m =>
(State# s -> (# State# s, a #)) -> m a
prim ((State# s -> (# State# s, e #)) -> m e)
-> (State# s -> (# State# s, e #)) -> m e
forall a b. (a -> b) -> a -> b
$ Addr# -> Int# -> (e -> e) -> State# s -> (# State# s, e #)
forall a s.
Atomic a =>
Addr# -> Int# -> (a -> a) -> State# s -> (# State# s, a #)
atomicModifyFetchNewOffAddr# Addr#
addr# Int#
i# e -> e
f
{-# INLINE atomicModifyFetchNewOffPtr #-}



-- | Add a numeric value to an element of a `Ptr`, corresponds to @(`+`)@ done
-- atomically. Returns the previous value.  Offset is in number of elements, rather
-- than bytes. Implies a full memory barrier.
--
-- /Note/ - Bounds are not checked, therefore this function is unsafe.
--
-- @since 0.1.0
atomicAddFetchOldOffPtr ::
     (MonadPrim s m, AtomicCount e)
  => Ptr e
  -> Off e
  -> e
  -> m e
atomicAddFetchOldOffPtr :: Ptr e -> Off e -> e -> m e
atomicAddFetchOldOffPtr (Ptr Addr#
addr#) (Off (I# Int#
i#)) e
a =
  (State# s -> (# State# s, e #)) -> m e
forall s (m :: * -> *) a.
MonadPrim s m =>
(State# s -> (# State# s, a #)) -> m a
prim (Addr# -> Int# -> e -> State# s -> (# State# s, e #)
forall a s.
AtomicCount a =>
Addr# -> Int# -> a -> State# s -> (# State# s, a #)
atomicAddFetchOldOffAddr# Addr#
addr# Int#
i# e
a)
{-# INLINE atomicAddFetchOldOffPtr #-}

-- | Add a numeric value to an element of a `Ptr`, corresponds to @(`+`)@ done
-- atomically. Returns the new value.  Offset is in number of elements, rather
-- than bytes. Implies a full memory barrier.
--
-- /Note/ - Bounds are not checked, therefore this function is unsafe.
--
-- @since 0.1.0
atomicAddFetchNewOffPtr ::
     (MonadPrim s m, AtomicCount e)
  => Ptr e
  -> Off e
  -> e
  -> m e
atomicAddFetchNewOffPtr :: Ptr e -> Off e -> e -> m e
atomicAddFetchNewOffPtr (Ptr Addr#
addr#) (Off (I# Int#
i#)) e
a =
  (State# s -> (# State# s, e #)) -> m e
forall s (m :: * -> *) a.
MonadPrim s m =>
(State# s -> (# State# s, a #)) -> m a
prim (Addr# -> Int# -> e -> State# s -> (# State# s, e #)
forall a s.
AtomicCount a =>
Addr# -> Int# -> a -> State# s -> (# State# s, a #)
atomicAddFetchNewOffAddr# Addr#
addr# Int#
i# e
a)
{-# INLINE atomicAddFetchNewOffPtr #-}



-- | Subtract a numeric value from an element of a `Ptr`, corresponds to
-- @(`-`)@ done atomically. Returns the previous value.  Offset is in number of elements, rather
-- than bytes. Implies a full memory barrier.
--
-- /Note/ - Bounds are not checked, therefore this function is unsafe.
--
-- @since 0.1.0
atomicSubFetchOldOffPtr ::
     (MonadPrim s m, AtomicCount e)
  => Ptr e
  -> Off e
  -> e
  -> m e
atomicSubFetchOldOffPtr :: Ptr e -> Off e -> e -> m e
atomicSubFetchOldOffPtr (Ptr Addr#
addr#) (Off (I# Int#
i#)) e
a =
  (State# s -> (# State# s, e #)) -> m e
forall s (m :: * -> *) a.
MonadPrim s m =>
(State# s -> (# State# s, a #)) -> m a
prim (Addr# -> Int# -> e -> State# s -> (# State# s, e #)
forall a s.
AtomicCount a =>
Addr# -> Int# -> a -> State# s -> (# State# s, a #)
atomicSubFetchOldOffAddr# Addr#
addr# Int#
i# e
a)
{-# INLINE atomicSubFetchOldOffPtr #-}

-- | Subtract a numeric value from an element of a `Ptr`, corresponds to
-- @(`-`)@ done atomically. Returns the new value. Offset is in number of elements, rather
-- than bytes. Implies a full memory barrier.
--
-- /Note/ - Bounds are not checked, therefore this function is unsafe.
--
-- @since 0.1.0
atomicSubFetchNewOffPtr ::
     (MonadPrim s m, AtomicCount e)
  => Ptr e
  -> Off e
  -> e
  -> m e
atomicSubFetchNewOffPtr :: Ptr e -> Off e -> e -> m e
atomicSubFetchNewOffPtr (Ptr Addr#
addr#) (Off (I# Int#
i#)) e
a =
  (State# s -> (# State# s, e #)) -> m e
forall s (m :: * -> *) a.
MonadPrim s m =>
(State# s -> (# State# s, a #)) -> m a
prim (Addr# -> Int# -> e -> State# s -> (# State# s, e #)
forall a s.
AtomicCount a =>
Addr# -> Int# -> a -> State# s -> (# State# s, a #)
atomicSubFetchNewOffAddr# Addr#
addr# Int#
i# e
a)
{-# INLINE atomicSubFetchNewOffPtr #-}



-- | Binary conjunction (AND) of an element of a `Ptr` with the supplied value,
-- corresponds to @(`Data.Bits..&.`)@ done atomically. Returns the previous value. Offset
-- is in number of elements, rather than bytes. Implies a full memory barrier.
--
-- /Note/ - Bounds are not checked, therefore this function is unsafe.
--
-- @since 0.1.0
atomicAndFetchOldOffPtr ::
     (MonadPrim s m, AtomicBits e)
  => Ptr e
  -> Off e
  -> e
  -> m e
atomicAndFetchOldOffPtr :: Ptr e -> Off e -> e -> m e
atomicAndFetchOldOffPtr (Ptr Addr#
addr#) (Off (I# Int#
i#)) e
a =
  (State# s -> (# State# s, e #)) -> m e
forall s (m :: * -> *) a.
MonadPrim s m =>
(State# s -> (# State# s, a #)) -> m a
prim (Addr# -> Int# -> e -> State# s -> (# State# s, e #)
forall a s.
AtomicBits a =>
Addr# -> Int# -> a -> State# s -> (# State# s, a #)
atomicAndFetchOldOffAddr# Addr#
addr# Int#
i# e
a)
{-# INLINE atomicAndFetchOldOffPtr #-}

-- | Binary conjunction (AND) of an element of a `Ptr` with the supplied value,
-- corresponds to @(`Data.Bits..&.`)@ done atomically. Returns the new value. Offset is
-- in number of elements, rather than bytes. Implies a full memory barrier.
--
-- /Note/ - Bounds are not checked, therefore this function is unsafe.
--
-- @since 0.1.0
atomicAndFetchNewOffPtr ::
     (MonadPrim s m, AtomicBits e)
  => Ptr e
  -> Off e
  -> e
  -> m e
atomicAndFetchNewOffPtr :: Ptr e -> Off e -> e -> m e
atomicAndFetchNewOffPtr (Ptr Addr#
addr#) (Off (I# Int#
i#)) e
a =
  (State# s -> (# State# s, e #)) -> m e
forall s (m :: * -> *) a.
MonadPrim s m =>
(State# s -> (# State# s, a #)) -> m a
prim (Addr# -> Int# -> e -> State# s -> (# State# s, e #)
forall a s.
AtomicBits a =>
Addr# -> Int# -> a -> State# s -> (# State# s, a #)
atomicAndFetchNewOffAddr# Addr#
addr# Int#
i# e
a)
{-# INLINE atomicAndFetchNewOffPtr #-}



-- | Negation of binary conjunction (NAND) of an element of a `Ptr` with the
-- supplied value, corresponds to @\\x y -> `Data.Bits.complement` (x `Data.Bits..&.` y)@
-- done atomically. Returns the previous value. Offset is in number of elements, rather
-- than bytes. Implies a full memory barrier.
--
-- /Note/ - Bounds are not checked, therefore this function is unsafe.
--
-- @since 0.1.0
atomicNandFetchOldOffPtr ::
     (MonadPrim s m, AtomicBits e)
  => Ptr e
  -> Off e
  -> e
  -> m e
atomicNandFetchOldOffPtr :: Ptr e -> Off e -> e -> m e
atomicNandFetchOldOffPtr (Ptr Addr#
addr#) (Off (I# Int#
i#)) e
a =
  (State# s -> (# State# s, e #)) -> m e
forall s (m :: * -> *) a.
MonadPrim s m =>
(State# s -> (# State# s, a #)) -> m a
prim (Addr# -> Int# -> e -> State# s -> (# State# s, e #)
forall a s.
AtomicBits a =>
Addr# -> Int# -> a -> State# s -> (# State# s, a #)
atomicNandFetchOldOffAddr# Addr#
addr# Int#
i# e
a)
{-# INLINE atomicNandFetchOldOffPtr #-}

-- | Negation of binary conjunction (NAND)  of an element of a `Ptr` with the supplied
-- value, corresponds to @\\x y -> `Data.Bits.complement` (x `Data.Bits..&.` y)@ done
-- atomically. Returns the new value. Offset is in number of elements, rather than
-- bytes. Implies a full memory barrier.
--
-- /Note/ - Bounds are not checked, therefore this function is unsafe.
--
-- @since 0.1.0
atomicNandFetchNewOffPtr ::
     (MonadPrim s m, AtomicBits e)
  => Ptr e
  -> Off e
  -> e
  -> m e
atomicNandFetchNewOffPtr :: Ptr e -> Off e -> e -> m e
atomicNandFetchNewOffPtr (Ptr Addr#
addr#) (Off (I# Int#
i#)) e
a =
  (State# s -> (# State# s, e #)) -> m e
forall s (m :: * -> *) a.
MonadPrim s m =>
(State# s -> (# State# s, a #)) -> m a
prim (Addr# -> Int# -> e -> State# s -> (# State# s, e #)
forall a s.
AtomicBits a =>
Addr# -> Int# -> a -> State# s -> (# State# s, a #)
atomicNandFetchNewOffAddr# Addr#
addr# Int#
i# e
a)
{-# INLINE atomicNandFetchNewOffPtr #-}




-- | Binary disjunction (OR) of an element of a `Ptr` with the supplied value,
-- corresponds to @(`Data.Bits..|.`)@ done atomically. Returns the previous value. Offset
-- is in number of elements, rather than bytes. Implies a full memory barrier.
--
-- /Note/ - Bounds are not checked, therefore this function is unsafe.
--
-- @since 0.1.0
atomicOrFetchOldOffPtr ::
     (MonadPrim s m, AtomicBits e)
  => Ptr e
  -> Off e
  -> e
  -> m e
atomicOrFetchOldOffPtr :: Ptr e -> Off e -> e -> m e
atomicOrFetchOldOffPtr (Ptr Addr#
addr#) (Off (I# Int#
i#)) e
a =
  (State# s -> (# State# s, e #)) -> m e
forall s (m :: * -> *) a.
MonadPrim s m =>
(State# s -> (# State# s, a #)) -> m a
prim (Addr# -> Int# -> e -> State# s -> (# State# s, e #)
forall a s.
AtomicBits a =>
Addr# -> Int# -> a -> State# s -> (# State# s, a #)
atomicOrFetchOldOffAddr# Addr#
addr# Int#
i# e
a)
{-# INLINE atomicOrFetchOldOffPtr #-}

-- | Binary disjunction (OR) of an element of a `Ptr` with the supplied value,
-- corresponds to @(`Data.Bits..|.`)@ done atomically. Returns the new value. Offset is
-- in number of elements, rather than bytes. Implies a full memory barrier.
--
-- /Note/ - Bounds are not checked, therefore this function is unsafe.
--
-- @since 0.1.0
atomicOrFetchNewOffPtr ::
     (MonadPrim s m, AtomicBits e)
  => Ptr e
  -> Off e
  -> e
  -> m e
atomicOrFetchNewOffPtr :: Ptr e -> Off e -> e -> m e
atomicOrFetchNewOffPtr (Ptr Addr#
addr#) (Off (I# Int#
i#)) e
a =
  (State# s -> (# State# s, e #)) -> m e
forall s (m :: * -> *) a.
MonadPrim s m =>
(State# s -> (# State# s, a #)) -> m a
prim (Addr# -> Int# -> e -> State# s -> (# State# s, e #)
forall a s.
AtomicBits a =>
Addr# -> Int# -> a -> State# s -> (# State# s, a #)
atomicOrFetchNewOffAddr# Addr#
addr# Int#
i# e
a)
{-# INLINE atomicOrFetchNewOffPtr #-}



-- | Binary exclusive disjunction (XOR) of an element of a `Ptr` with the supplied value,
-- corresponds to @`Data.Bits.xor`@ done atomically. Returns the previous value. Offset
-- is in number of elements, rather than bytes. Implies a full memory barrier.
--
-- /Note/ - Bounds are not checked, therefore this function is unsafe.
--
-- @since 0.1.0
atomicXorFetchOldOffPtr ::
     (MonadPrim s m, AtomicBits e)
  => Ptr e
  -> Off e
  -> e
  -> m e
atomicXorFetchOldOffPtr :: Ptr e -> Off e -> e -> m e
atomicXorFetchOldOffPtr (Ptr Addr#
addr#) (Off (I# Int#
i#)) e
a =
  (State# s -> (# State# s, e #)) -> m e
forall s (m :: * -> *) a.
MonadPrim s m =>
(State# s -> (# State# s, a #)) -> m a
prim (Addr# -> Int# -> e -> State# s -> (# State# s, e #)
forall a s.
AtomicBits a =>
Addr# -> Int# -> a -> State# s -> (# State# s, a #)
atomicXorFetchOldOffAddr# Addr#
addr# Int#
i# e
a)
{-# INLINE atomicXorFetchOldOffPtr #-}

-- | Binary exclusive disjunction (XOR) of an element of a `Ptr` with the supplied value,
-- corresponds to @`Data.Bits.xor`@ done atomically. Returns the new value. Offset is
-- in number of elements, rather than bytes. Implies a full memory barrier.
--
-- /Note/ - Bounds are not checked, therefore this function is unsafe.
--
-- @since 0.1.0
atomicXorFetchNewOffPtr ::
     (MonadPrim s m, AtomicBits e)
  => Ptr e
  -> Off e
  -> e
  -> m e
atomicXorFetchNewOffPtr :: Ptr e -> Off e -> e -> m e
atomicXorFetchNewOffPtr (Ptr Addr#
addr#) (Off (I# Int#
i#)) e
a =
  (State# s -> (# State# s, e #)) -> m e
forall s (m :: * -> *) a.
MonadPrim s m =>
(State# s -> (# State# s, a #)) -> m a
prim (Addr# -> Int# -> e -> State# s -> (# State# s, e #)
forall a s.
AtomicBits a =>
Addr# -> Int# -> a -> State# s -> (# State# s, a #)
atomicXorFetchNewOffAddr# Addr#
addr# Int#
i# e
a)
{-# INLINE atomicXorFetchNewOffPtr #-}





-- | Binary negation (NOT) of an element of a `Ptr`, corresponds to
-- @(`Data.Bits.complement`)@ done atomically. Returns the previous value. Offset is in
-- number of elements, rather than bytes. Implies a full memory barrier.
--
-- /Note/ - Bounds are not checked, therefore this function is unsafe.
--
-- @since 0.1.0
atomicNotFetchOldOffPtr ::
     (MonadPrim s m, AtomicBits e)
  => Ptr e
  -> Off e
  -> m e
atomicNotFetchOldOffPtr :: Ptr e -> Off e -> m e
atomicNotFetchOldOffPtr (Ptr Addr#
addr#) (Off (I# Int#
i#)) =
  (State# s -> (# State# s, e #)) -> m e
forall s (m :: * -> *) a.
MonadPrim s m =>
(State# s -> (# State# s, a #)) -> m a
prim (Addr# -> Int# -> State# s -> (# State# s, e #)
forall a s.
AtomicBits a =>
Addr# -> Int# -> State# s -> (# State# s, a #)
atomicNotFetchOldOffAddr# Addr#
addr# Int#
i#)
{-# INLINE atomicNotFetchOldOffPtr #-}

-- | Binary negation (NOT) of an element of a `Ptr`, corresponds to
-- @(`Data.Bits.complement`)@ done atomically. Returns the new value. Offset is in number
-- of elements, rather than bytes. Implies a full memory barrier.
--
-- /Note/ - Bounds are not checked, therefore this function is unsafe.
--
-- @since 0.1.0
atomicNotFetchNewOffPtr ::
     (MonadPrim s m, AtomicBits e)
  => Ptr e
  -> Off e
  -> m e
atomicNotFetchNewOffPtr :: Ptr e -> Off e -> m e
atomicNotFetchNewOffPtr (Ptr Addr#
addr#) (Off (I# Int#
i#)) =
  (State# s -> (# State# s, e #)) -> m e
forall s (m :: * -> *) a.
MonadPrim s m =>
(State# s -> (# State# s, a #)) -> m a
prim (Addr# -> Int# -> State# s -> (# State# s, e #)
forall a s.
AtomicBits a =>
Addr# -> Int# -> State# s -> (# State# s, a #)
atomicNotFetchNewOffAddr# Addr#
addr# Int#
i#)
{-# INLINE atomicNotFetchNewOffPtr #-}





prefetchPtr0 :: MonadPrim s m => Ptr e -> m ()
prefetchPtr0 :: Ptr e -> m ()
prefetchPtr0 (Ptr Addr#
b#) = (State# s -> State# s) -> m ()
forall s (m :: * -> *).
MonadPrim s m =>
(State# s -> State# s) -> m ()
prim_ (Addr# -> Int# -> State# s -> State# s
forall d. Addr# -> Int# -> State# d -> State# d
prefetchAddr0# Addr#
b# Int#
0#)
{-# INLINE prefetchPtr0 #-}

prefetchPtr1 :: MonadPrim s m => Ptr a -> m ()
prefetchPtr1 :: Ptr a -> m ()
prefetchPtr1 (Ptr Addr#
b#) = (State# s -> State# s) -> m ()
forall s (m :: * -> *).
MonadPrim s m =>
(State# s -> State# s) -> m ()
prim_ (Addr# -> Int# -> State# s -> State# s
forall d. Addr# -> Int# -> State# d -> State# d
prefetchAddr1# Addr#
b# Int#
0#)
{-# INLINE prefetchPtr1 #-}

prefetchPtr2 :: MonadPrim s m => Ptr e -> m ()
prefetchPtr2 :: Ptr e -> m ()
prefetchPtr2 (Ptr Addr#
b#) = (State# s -> State# s) -> m ()
forall s (m :: * -> *).
MonadPrim s m =>
(State# s -> State# s) -> m ()
prim_ (Addr# -> Int# -> State# s -> State# s
forall d. Addr# -> Int# -> State# d -> State# d
prefetchAddr2# Addr#
b# Int#
0#)
{-# INLINE prefetchPtr2 #-}

prefetchPtr3 :: MonadPrim s m => Ptr e -> m ()
prefetchPtr3 :: Ptr e -> m ()
prefetchPtr3 (Ptr Addr#
b#) = (State# s -> State# s) -> m ()
forall s (m :: * -> *).
MonadPrim s m =>
(State# s -> State# s) -> m ()
prim_ (Addr# -> Int# -> State# s -> State# s
forall d. Addr# -> Int# -> State# d -> State# d
prefetchAddr3# Addr#
b# Int#
0#)
{-# INLINE prefetchPtr3 #-}

prefetchOffPtr0 :: (MonadPrim s m, Prim e) => Ptr e -> Off e -> m ()
prefetchOffPtr0 :: Ptr e -> Off e -> m ()
prefetchOffPtr0 (Ptr Addr#
b#) Off e
off = (State# s -> State# s) -> m ()
forall s (m :: * -> *).
MonadPrim s m =>
(State# s -> State# s) -> m ()
prim_ (Addr# -> Int# -> State# s -> State# s
forall d. Addr# -> Int# -> State# d -> State# d
prefetchAddr0# Addr#
b# (Off e -> Int#
forall e. Prim e => Off e -> Int#
unOffBytes# Off e
off))
{-# INLINE prefetchOffPtr0 #-}

prefetchOffPtr1 :: (MonadPrim s m, Prim e) => Ptr e -> Off e -> m ()
prefetchOffPtr1 :: Ptr e -> Off e -> m ()
prefetchOffPtr1 (Ptr Addr#
b#) Off e
off = (State# s -> State# s) -> m ()
forall s (m :: * -> *).
MonadPrim s m =>
(State# s -> State# s) -> m ()
prim_ (Addr# -> Int# -> State# s -> State# s
forall d. Addr# -> Int# -> State# d -> State# d
prefetchAddr1# Addr#
b# (Off e -> Int#
forall e. Prim e => Off e -> Int#
unOffBytes# Off e
off))
{-# INLINE prefetchOffPtr1 #-}

prefetchOffPtr2 :: (MonadPrim s m, Prim e) => Ptr e -> Off e -> m ()
prefetchOffPtr2 :: Ptr e -> Off e -> m ()
prefetchOffPtr2 (Ptr Addr#
b#) Off e
off = (State# s -> State# s) -> m ()
forall s (m :: * -> *).
MonadPrim s m =>
(State# s -> State# s) -> m ()
prim_ (Addr# -> Int# -> State# s -> State# s
forall d. Addr# -> Int# -> State# d -> State# d
prefetchAddr2# Addr#
b# (Off e -> Int#
forall e. Prim e => Off e -> Int#
unOffBytes# Off e
off))
{-# INLINE prefetchOffPtr2 #-}

prefetchOffPtr3 :: (MonadPrim s m, Prim e) => Ptr e -> Off e -> m ()
prefetchOffPtr3 :: Ptr e -> Off e -> m ()
prefetchOffPtr3 (Ptr Addr#
b#) Off e
off = (State# s -> State# s) -> m ()
forall s (m :: * -> *).
MonadPrim s m =>
(State# s -> State# s) -> m ()
prim_ (Addr# -> Int# -> State# s -> State# s
forall d. Addr# -> Int# -> State# d -> State# d
prefetchAddr3# Addr#
b# (Off e -> Int#
forall e. Prim e => Off e -> Int#
unOffBytes# Off e
off))
{-# INLINE prefetchOffPtr3 #-}

-- | Same as `GHC.freeHaskellFunPtr`
--
-- @since 0.1.0
freeHaskellFunPtr :: MonadPrim s m => FunPtr a -> m ()
freeHaskellFunPtr :: FunPtr a -> m ()
freeHaskellFunPtr = IO () -> m ()
forall s (m :: * -> *) a. MonadPrim s m => IO a -> m a
unsafeIOToPrim (IO () -> m ()) -> (FunPtr a -> IO ()) -> FunPtr a -> m ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. FunPtr a -> IO ()
forall a. FunPtr a -> IO ()
GHC.freeHaskellFunPtr