RE: atomic MVar overwrite (was RE: [Haskell-cafe] How to use QSem?)

2004-06-24 Thread Simon Marlow
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?)

2004-06-23 Thread S. Alexander Jacobson
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?)

2004-06-23 Thread Simon Marlow
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?)

2004-06-23 Thread S. Alexander Jacobson
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