
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 state.
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? Cheers, Simon