[Haskell-cafe] Re: Using tiny (atomic) mutables between multiple threads

Simon Marlow marlowsd at gmail.com
Wed Sep 16 11:05:04 EDT 2009

On 13/09/2009 07:45, Belka wrote:
> Hello, Haskell Cafe!
> I used an MVar to signalize to many threads, when it's time to finish their
> business (I called it a LoopBreaker). Recently I realized, that it might be
> too expensive (to use MVar) for cases when threads are many and all of them
> read my LoopBreaker intensively. This assumption appeared in a case, where I
> widely (in many threads) used my stopableThreadDelay, which checks
> LoopBreaker every d = 100 milliseconds.
> So I decided that I don't really need all the great features, that MVar
> provides, and that a simpler memory usage concept might be applied here. In
> a most (machinely) reduced view, all I need is a mutable byte. It would be
> thread safe, since reading and writing are atomic operations. I then wrote a
> simple experimental module (my first experience with Ptr in Haskell):
> -----------------
> import Control.Monad
> import Foreign.Marshal.Utils
> import Foreign.Ptr
> import Foreign.Storable
> newtype MyVar a = MyVar { mvPtr :: Ptr a }
> newMyVar :: Storable a =>  a ->  IO (MyVar a)
> newMyVar val = MyVar `liftM` new val
> readMyVar :: Storable a =>  (MyVar a) ->  IO a
> readMyVar val = peek $ mvPtr val
> writeMyVar :: Storable a =>  (MyVar a) ->  a ->  IO ()
> writeMyVar var val = poke (mvPtr var) val
> -----------------
> Now, please, help me to answer few questions about all it:
> 1. Might readMVar really be computationally expensive under heavy load,
> (with all it's wonderful blocking features)? How much (approximately) more
> expensive, comparing to a assembler's "mov"?

Probably 10-100 times more expensive than a mov, depending on the cache 

> 2. Are the above readMyVar and writeMyVar really atomic? Or are they atomic
> only if I apply them to<MyVar Word8>  type?

It depends what you mean by atomic.  If you mean is readMyVar atomic 
with respect to writeMyVar, then it depends on which type you're 
instantiating MyVar with, and what machine you're running on.  e.g. a 
MyVar Word32 will probably be atomic, but MyVar Word64 might only be 
atomic on a 64-bit platform.  You'd also have to check your machine's 
architecture manuals to be sure.  MyVar Word8 is atomic on some 
platforms but not others.

The upshot is that it's not a good idea to rely on atomicity here.

I'd recommend using IORef and atomicModifyIORef when you need atomicity.

> 3. Are the above readMyVar and writeMyVar safe against asynchronous
> exceptions? Or again, only if I use<MyVar Word8>  type?

It depends what you mean by "safe", but probably you're worried about 
atomicity again.

It's pretty unusual to want just a mutable variable for communication 
between threads, normally you need *some* kind of synchronisation. 
What's your application?


More information about the Haskell-Cafe mailing list