RE: atomic MVar overwrite (was RE: [Haskell-cafe] How to use QSem?)
On 23 June 2004 17:46, S. Alexander Jacobson wrote: > Basically, what I want is a tryReadSampleVar > function. > > Or, if we stick with MVars, I don't want another > thread to operate between the tryTakeMVar and the > putMVar. In particular, I don't want another > thread to believe (mistakenly) that the mvar is > empty when it is simply being updated. > > I suppose I could define a new abstraction where I > have a second mvar that acts as an exclusive lock > on the the first MVar. e.g. > >data XMVar a = XMVar (MVar ()) MVar a > >overWriteXMVar (XMVar lock mvar) val = > withMVar lock (\_->tryTakeMVar mvar >> putMVar mvar val) >tryTakeXMVar (XMVar lock mvar) val = > withMVar lock (\_->tryTakeMVar mvar) > > But, I think it would be more sane simply to > have a tryReadSampleVar somewhere. If you send me code for tryReadSampleVar, I'll incorporate it. Unfortunately SampleVar is abstract, so you'll need to take the source for that library (libraries/base/Control/Concurrent/SampleVar.hs in a GHC distribution) and modify it to create your own version. Cheers, Simon ___ Haskell-Cafe mailing list [EMAIL PROTECTED] http://www.haskell.org/mailman/listinfo/haskell-cafe
RE: atomic MVar overwrite (was RE: [Haskell-cafe] How to use QSem?)
Basically, what I want is a tryReadSampleVar function. Or, if we stick with MVars, I don't want another thread to operate between the tryTakeMVar and the putMVar. In particular, I don't want another thread to believe (mistakenly) that the mvar is empty when it is simply being updated. I suppose I could define a new abstraction where I have a second mvar that acts as an exclusive lock on the the first MVar. e.g. data XMVar a = XMVar (MVar ()) MVar a overWriteXMVar (XMVar lock mvar) val = withMVar lock (\_->tryTakeMVar mvar >> putMVar mvar val) tryTakeXMVar (XMVar lock mvar) val = withMVar lock (\_->tryTakeMVar mvar) But, I think it would be more sane simply to have a tryReadSampleVar somewhere. -Alex- _ S. Alexander Jacobson mailto:[EMAIL PROTECTED] tel:917-770-6565 http://alexjacobson.com On Wed, 23 Jun 2004, Simon Marlow wrote: > On 23 June 2004 17:13, S. Alexander Jacobson wrote: > > > Ah, that worked. Thank you. The MVar > > documentation is also very brief. > > > > I would also like to overwrite the contents of an > > MVar atomically regardless of whether it is full > > or empty. I am current using. > > > > overWrite mvar val = tryTakeMVar mvar >> putMVar mvar val > > > > But it is not atomic :-( The lib functions > > (modifyMVar and tryPutMVar) are atomic but seem to > > require that you know in advance the MVar's state. > > The question to ask here is "atomic with respect to what?". modifyMVar > is atomic only with respect to other threads performing modifyMVar-type > operations on the MVar (i.e. take followed by put). If another thread > is doing repeated puts into the MVar, then modifyMVar's atomicity is > defeated. > > There isn't really a problem here, you just need to be sure that you use > your MVars in a consistent way - you can always define a new abstraction > that doesn't permit operations to be performed in the wrong order. > > So in order to tell you how to write your overWrite function, we need to > know what other operations are being concurrently performed on the MVar, > and what invariants you expect to hold. > > Cheers, > Simon > ___ Haskell-Cafe mailing list [EMAIL PROTECTED] http://www.haskell.org/mailman/listinfo/haskell-cafe
RE: atomic MVar overwrite (was RE: [Haskell-cafe] How to use QSem?)
On 23 June 2004 17:13, S. Alexander Jacobson wrote: > Ah, that worked. Thank you. The MVar > documentation is also very brief. > > I would also like to overwrite the contents of an > MVar atomically regardless of whether it is full > or empty. I am current using. > > overWrite mvar val = tryTakeMVar mvar >> putMVar mvar val > > But it is not atomic :-( The lib functions > (modifyMVar and tryPutMVar) are atomic but seem to > require that you know in advance the MVar's state. The question to ask here is "atomic with respect to what?". modifyMVar is atomic only with respect to other threads performing modifyMVar-type operations on the MVar (i.e. take followed by put). If another thread is doing repeated puts into the MVar, then modifyMVar's atomicity is defeated. There isn't really a problem here, you just need to be sure that you use your MVars in a consistent way - you can always define a new abstraction that doesn't permit operations to be performed in the wrong order. So in order to tell you how to write your overWrite function, we need to know what other operations are being concurrently performed on the MVar, and what invariants you expect to hold. Cheers, Simon ___ Haskell-Cafe mailing list [EMAIL PROTECTED] http://www.haskell.org/mailman/listinfo/haskell-cafe
atomic MVar overwrite (was RE: [Haskell-cafe] How to use QSem?)
Ah, that worked. Thank you. The MVar documentation is also very brief. I would also like to overwrite the contents of an MVar atomically regardless of whether it is full or empty. I am current using. overWrite mvar val = tryTakeMVar mvar >> putMVar mvar val But it is not atomic :-( The lib functions (modifyMVar and tryPutMVar) are atomic but seem to require that you know in advance the MVar's state. Is there a solution to this or do I have to refactor? -Alex- _ S. Alexander Jacobson mailto:[EMAIL PROTECTED] tel:917-770-6565 http://alexjacobson.com On Wed, 23 Jun 2004, Simon Marlow wrote: > On 22 June 2004 21:44, S. Alexander Jacobson wrote: > > > The GHC documentation on QSem is very sparse. I > > would like to give a thread exclusive access to a > > resource. > > > > My *guess* based on the documentation is that I > > can create an exclusive lock using: > > > >logSem <- newQSem 1 > > If the maximum value of your QSem is 1, then an MVar will do. That is, > an MVar can be used as a simple semaphore, and a QSem is necessary if > you need a quantity semaphore (there are > 1 units of the resource). > > > And then any thread that wants to lock the > > resource uses: > > > >withLogSem x = do waitQSem logSem; y <- x; signalQSem logSem; > > return y > > > > as follows: > > > >withLogSem $ rotate curLogPos > > import Control.Concurrent, create the semaphore like this: > >m <- newMVar () > > and use it like this: > >withMVar m $ \_ -> ... critical section ... > > If you are using the semaphore to protect a mutable variable, then you > can handily merge the two ideas into an MVar, which behaves like a > thread-safe mutable variable. > > Cheers, > Simon > ___ Haskell-Cafe mailing list [EMAIL PROTECTED] http://www.haskell.org/mailman/listinfo/haskell-cafe