1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65
|
{-# LANGUAGE MagicHash, UnboxedTuples, DeriveDataTypeable #-}
-- |
-- Module : Data.Primitive.MutVar
-- Copyright : (c) Justin Bonnar 2011, Roman Leshchinskiy 2011-2012
-- License : BSD-style
--
-- Maintainer : Roman Leshchinskiy <rl@cse.unsw.edu.au>
-- Portability : non-portable
--
-- Primitive boxed mutable variables
--
module Data.Primitive.MutVar (
MutVar(..),
newMutVar,
readMutVar,
writeMutVar,
atomicModifyMutVar,
modifyMutVar
) where
import Control.Monad.Primitive ( PrimMonad(..), primitive_ )
import GHC.Prim ( MutVar#, sameMutVar#, newMutVar#,
readMutVar#, writeMutVar#, atomicModifyMutVar# )
import Data.Typeable ( Typeable )
-- | A 'MutVar' behaves like a single-element mutable array associated
-- with a primitive state token.
data MutVar s a = MutVar (MutVar# s a)
deriving ( Typeable )
instance Eq (MutVar s a) where
MutVar mva# == MutVar mvb# = sameMutVar# mva# mvb#
-- | Create a new 'MutVar' with the specified initial value
newMutVar :: PrimMonad m => a -> m (MutVar (PrimState m) a)
{-# INLINE newMutVar #-}
newMutVar initialValue = primitive $ \s# ->
case newMutVar# initialValue s# of
(# s'#, mv# #) -> (# s'#, MutVar mv# #)
-- | Read the value of a 'MutVar'
readMutVar :: PrimMonad m => MutVar (PrimState m) a -> m a
{-# INLINE readMutVar #-}
readMutVar (MutVar mv#) = primitive (readMutVar# mv#)
-- | Write a new value into a 'MutVar'
writeMutVar :: PrimMonad m => MutVar (PrimState m) a -> a -> m ()
{-# INLINE writeMutVar #-}
writeMutVar (MutVar mv#) newValue = primitive_ (writeMutVar# mv# newValue)
-- | Atomically mutate the contents of a 'MutVar'
atomicModifyMutVar :: PrimMonad m => MutVar (PrimState m) a -> (a -> (a,b)) -> m b
{-# INLINE atomicModifyMutVar #-}
atomicModifyMutVar (MutVar mv#) f = primitive $ atomicModifyMutVar# mv# f
-- | Mutate the contents of a 'MutVar'
modifyMutVar :: PrimMonad m => MutVar (PrimState m) a -> (a -> a) -> m ()
{-# INLINE modifyMutVar #-}
modifyMutVar (MutVar mv#) g = primitive_ $ \s# ->
case readMutVar# mv# s# of
(# s'#, a #) -> writeMutVar# mv# (g a) s'#
|