{-# LANGUAGE MagicHash, UnboxedTuples, BangPatterns #-}
module System.Random.Mersenne.Pure64.MTBlock (
MTBlock,
seedBlock,
nextBlock,
lookupBlock,
blockLen,
mixWord64,
) where
import GHC.Exts
#if __GLASGOW_HASKELL__ >= 706
import GHC.IO
#else
import GHC.IOBase
#endif
import GHC.Word
import System.Random.Mersenne.Pure64.Base
import System.Random.Mersenne.Pure64.Internal
allocateBlock :: IO MTBlock
allocateBlock :: IO MTBlock
allocateBlock =
(State# RealWorld -> (# State# RealWorld, MTBlock #)) -> IO MTBlock
forall a. (State# RealWorld -> (# State# RealWorld, a #)) -> IO a
IO ((State# RealWorld -> (# State# RealWorld, MTBlock #))
-> IO MTBlock)
-> (State# RealWorld -> (# State# RealWorld, MTBlock #))
-> IO MTBlock
forall a b. (a -> b) -> a -> b
$ \State# RealWorld
s0 -> case Int#
-> State# RealWorld
-> (# State# RealWorld, MutableByteArray# RealWorld #)
forall d. Int# -> State# d -> (# State# d, MutableByteArray# d #)
newPinnedByteArray# Int#
blockSize# State# RealWorld
s0 of
(# State# RealWorld
s1, MutableByteArray# RealWorld
b0 #) -> case MutableByteArray# RealWorld
-> State# RealWorld -> (# State# RealWorld, ByteArray# #)
forall d.
MutableByteArray# d -> State# d -> (# State# d, ByteArray# #)
unsafeFreezeByteArray# MutableByteArray# RealWorld
b0 State# RealWorld
s1 of
(# State# RealWorld
s2, ByteArray#
b1 #) -> (# State# RealWorld
s2, ByteArray# -> MTBlock
MTBlock ByteArray#
b1 #)
where
!(I# Int#
blockSize#) = Int
blockSize
blockAsPtr :: MTBlock -> Ptr a
blockAsPtr :: forall a. MTBlock -> Ptr a
blockAsPtr (MTBlock ByteArray#
b) = Addr# -> Ptr a
forall a. Addr# -> Ptr a
Ptr (ByteArray# -> Addr#
byteArrayContents# ByteArray#
b)
seedBlock :: Word64 -> MTBlock
seedBlock :: Word64 -> MTBlock
seedBlock Word64
seed = IO MTBlock -> MTBlock
forall a. IO a -> a
unsafeDupablePerformIO (IO MTBlock -> MTBlock) -> IO MTBlock -> MTBlock
forall a b. (a -> b) -> a -> b
$ do
b <- IO MTBlock
allocateBlock
c_seed_genrand64_block (blockAsPtr b) seed
c_next_genrand64_block (blockAsPtr b) (blockAsPtr b)
touch b
return b
{-# NOINLINE seedBlock #-}
nextBlock :: MTBlock -> MTBlock
nextBlock :: MTBlock -> MTBlock
nextBlock MTBlock
b = IO MTBlock -> MTBlock
forall a. IO a -> a
unsafeDupablePerformIO (IO MTBlock -> MTBlock) -> IO MTBlock -> MTBlock
forall a b. (a -> b) -> a -> b
$ do
new <- IO MTBlock
allocateBlock
c_next_genrand64_block (blockAsPtr b) (blockAsPtr new)
touch b
touch new
return new
{-# NOINLINE nextBlock #-}
touch :: a -> IO ()
touch :: forall a. a -> IO ()
touch 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
s0 -> case a -> State# RealWorld -> State# RealWorld
forall a d. a -> State# d -> State# d
touch# a
r State# RealWorld
s0 of State# RealWorld
s1 -> (# State# RealWorld
s1, () #)
lookupBlock :: MTBlock -> Int -> Word64
lookupBlock :: MTBlock -> Int -> Word64
lookupBlock (MTBlock ByteArray#
b) (I# Int#
i) = Word64# -> Word64
W64# (ByteArray# -> Int# -> Word64#
indexWord64Array# ByteArray#
b Int#
i)
mixWord64 :: Word64 -> Word64
mixWord64 :: Word64 -> Word64
mixWord64 = Word64 -> Word64
c_mix_word64