Edward Z. Yang | 10 Jul 11:20 2013
Picon

Proposal: replace readMVar with atomicReadMVar, breaking BC

GHC HEAD recently got a new primitive: atomicReadMVar#, which allows you
to read MVars without first taking and then putting back (removing a
nasty race where readMVar only works properly when there are no waiting
putters).

atomicReadMVar behaves differently from readMVar.  The key
differences are:

    - An atomicReadMVar op never causes an MVar to become "empty" at any point.
      This means less programs deadlock now.

    - An blocked atomicReadMVar is always served by the *first* putMVar
      to arrive (it cuts to the head of the queue), whereas readMVar
      obeyed the FIFO ordering.  This means this program behaves differently:

        m <- newEmptyMVar
        forkIO $ takeMVar m
        threadDelay 100
        forkIO $ print =<< readMVar m {- atomicReadMVar m -}
        threadDelay 100
        putMVar m 1
        putMVar m 2
        -- readMVar: outputs 2
        -- atomicReadMVar: outputs 1

      It actually would not be too difficult to add support for atomicReadMVar
      which *does* respect the FIFO ordering but I don't have a sense when
      that would be useful.

The general feeling Simon and I have is that everyone really wanted
(Continue reading)

Simon Peyton-Jones | 10 Jul 12:47 2013
Picon

RE: Proposal: replace readMVar with atomicReadMVar, breaking BC

Good!  Are the new semantics clearly documented?

Simon

| -----Original Message-----
| From: libraries-bounces <at> haskell.org [mailto:libraries-
| bounces <at> haskell.org] On Behalf Of Edward Z. Yang
| Sent: 10 July 2013 10:20
| To: libraries
| Subject: Proposal: replace readMVar with atomicReadMVar, breaking BC
| 
| GHC HEAD recently got a new primitive: atomicReadMVar#, which allows you
| to read MVars without first taking and then putting back (removing a
| nasty race where readMVar only works properly when there are no waiting
| putters).
| 
| atomicReadMVar behaves differently from readMVar.  The key
| differences are:
| 
|     - An atomicReadMVar op never causes an MVar to become "empty" at any
| point.
|       This means less programs deadlock now.
| 
|     - An blocked atomicReadMVar is always served by the *first* putMVar
|       to arrive (it cuts to the head of the queue), whereas readMVar
|       obeyed the FIFO ordering.  This means this program behaves
| differently:
| 
|         m <- newEmptyMVar
|         forkIO $ takeMVar m
(Continue reading)

Edward Z. Yang | 10 Jul 19:08 2013
Picon

RE: Proposal: replace readMVar with atomicReadMVar, breaking BC

I only realized that the ordering semantics were different when I
was writing this email.  I'll go add them to the Haddock docs.

Excerpts from Simon Peyton-Jones's message of Wed Jul 10 03:47:27 -0700 2013:
> Good!  Are the new semantics clearly documented?
> 
> Simon
> 
> | -----Original Message-----
> | From: libraries-bounces <at> haskell.org [mailto:libraries-
> | bounces <at> haskell.org] On Behalf Of Edward Z. Yang
> | Sent: 10 July 2013 10:20
> | To: libraries
> | Subject: Proposal: replace readMVar with atomicReadMVar, breaking BC
> | 
> | GHC HEAD recently got a new primitive: atomicReadMVar#, which allows you
> | to read MVars without first taking and then putting back (removing a
> | nasty race where readMVar only works properly when there are no waiting
> | putters).
> | 
> | atomicReadMVar behaves differently from readMVar.  The key
> | differences are:
> | 
> |     - An atomicReadMVar op never causes an MVar to become "empty" at any
> | point.
> |       This means less programs deadlock now.
> | 
> |     - An blocked atomicReadMVar is always served by the *first* putMVar
> |       to arrive (it cuts to the head of the queue), whereas readMVar
> |       obeyed the FIFO ordering.  This means this program behaves
(Continue reading)

Edward Z. Yang | 10 Jul 21:31 2013
Picon

RE: Proposal: replace readMVar with atomicReadMVar, breaking BC

Clever me, I already described this behavior:

-- |Atomically read the contents of an 'MVar'.  If the 'MVar' is
-- currently empty, 'atomicReadMVar' will wait until its full.
-- 'atomicReadMVar' is guaranteed to receive the next 'putMVar'.
--
-- 'atomicReadMVar' is multiple-wakeup, so when multiple readers are
-- blocked on an 'MVar', all of them are woken up at the same time.

Emphasis on "guaranteed to receive the next 'putMVar' :)

Edward

Excerpts from Edward Z. Yang's message of Wed Jul 10 10:08:17 -0700 2013:
> I only realized that the ordering semantics were different when I
> was writing this email.  I'll go add them to the Haddock docs.
> 
> Excerpts from Simon Peyton-Jones's message of Wed Jul 10 03:47:27 -0700 2013:
> > Good!  Are the new semantics clearly documented?
> > 
> > Simon
> > 
> > | -----Original Message-----
> > | From: libraries-bounces <at> haskell.org [mailto:libraries-
> > | bounces <at> haskell.org] On Behalf Of Edward Z. Yang
> > | Sent: 10 July 2013 10:20
> > | To: libraries
> > | Subject: Proposal: replace readMVar with atomicReadMVar, breaking BC
> > | 
> > | GHC HEAD recently got a new primitive: atomicReadMVar#, which allows you
(Continue reading)

Tom Murphy | 10 Jul 14:45 2013
Picon

Re: Proposal: replace readMVar with atomicReadMVar, breaking BC

Is there a reason why as I programmer I should prefer the non-FIFO
semantics, or is it implemented that way for efficiency?

Tom

El Jul 10, 2013, a las 5:20, "Edward Z. Yang" <ezyang <at> MIT.EDU> escribió:

> GHC HEAD recently got a new primitive: atomicReadMVar#, which allows you
> to read MVars without first taking and then putting back (removing a
> nasty race where readMVar only works properly when there are no waiting
> putters).
>
> atomicReadMVar behaves differently from readMVar.  The key
> differences are:
>
>    - An atomicReadMVar op never causes an MVar to become "empty" at any point.
>      This means less programs deadlock now.
>
>    - An blocked atomicReadMVar is always served by the *first* putMVar
>      to arrive (it cuts to the head of the queue), whereas readMVar
>      obeyed the FIFO ordering.  This means this program behaves differently:
>
>        m <- newEmptyMVar
>        forkIO $ takeMVar m
>        threadDelay 100
>        forkIO $ print =<< readMVar m {- atomicReadMVar m -}
>        threadDelay 100
>        putMVar m 1
>        putMVar m 2
>        -- readMVar: outputs 2
(Continue reading)

Edward Z. Yang | 10 Jul 19:07 2013
Picon

Re: Proposal: replace readMVar with atomicReadMVar, breaking BC

Excerpts from Tom Murphy's message of Wed Jul 10 05:45:36 -0700 2013:
> Is there a reason why as I programmer I should prefer the non-FIFO
> semantics, or is it implemented that way for efficiency?

Timely delivery of reads.  Ordinary takeMVar is FIFO for fairness
reasons: so long as an MVar is not held indefinitely, all takeMVars
will be serviced.  For reads, we can service them immediately without
worrying about fairness, since they don't block anyone.

It is literally trivial to do either FIFO and non-FIFO implementation
wise.

Edward
amindfv | 11 Jul 02:24 2013
Picon

Re: Proposal: replace readMVar with atomicReadMVar, breaking BC

+1 definitely.

Tom

El Jul 10, 2013, a las 13:07, "Edward Z. Yang" <ezyang <at> MIT.EDU> escribió:

> Excerpts from Tom Murphy's message of Wed Jul 10 05:45:36 -0700 2013:
>> Is there a reason why as I programmer I should prefer the non-FIFO
>> semantics, or is it implemented that way for efficiency?
> 
> Timely delivery of reads.  Ordinary takeMVar is FIFO for fairness
> reasons: so long as an MVar is not held indefinitely, all takeMVars
> will be serviced.  For reads, we can service them immediately without
> worrying about fairness, since they don't block anyone.
> 
> It is literally trivial to do either FIFO and non-FIFO implementation
> wise.
> 
> Edward

_______________________________________________
Libraries mailing list
Libraries <at> haskell.org
http://www.haskell.org/mailman/listinfo/libraries
Joey Adams | 11 Jul 06:13 2013
Picon

Re: Proposal: replace readMVar with atomicReadMVar, breaking BC

+1 for changing readMVar to be atomic, but we should probably mention the change in the doc for readMVar, something like the following (perhaps in fewer words):

    -- | ...
    --
    -- /Compatibility note:/ prior to base 4.7, 'readMVar' was a combination
    -- of 'takeMVar' and 'putMVar', resulting in two drawbacks:
    --
    --  * 'readMVar' was not atomic in the presence of multiple producers.
    --    Between taking the value and putting it back, another thread
    --    calling 'putMVar' could win, causing 'readMVar' to block after
    --    retrieving a value.
    --
    -- * 'readMVar' was not multiple wakeup, meaning each consumer had to
    --   wake up the next.
_______________________________________________
Libraries mailing list
Libraries <at> haskell.org
http://www.haskell.org/mailman/listinfo/libraries
Simon Marlow | 15 Jul 21:49 2013
Picon

Re: Proposal: replace readMVar with atomicReadMVar, breaking BC

On 10/07/13 13:45, Tom Murphy wrote:
> Is there a reason why as I programmer I should prefer the non-FIFO
> semantics, or is it implemented that way for efficiency?

You might prefer the FIFO semantics if you want to take advantage of the 
fact that the RTS implements a double-ended queue of threads in such a 
way that threads can be removed from the middle in O(1) time if they 
receive an exception from throwTo.  However, the only person I know that 
does this sort of thing is Chris Kuklewicz, and I can never understand 
his code. :-)

I expect the readMVar-jumps-to-the-front-of-the-queue semantics will be 
more useful in most cases.  We could have both, but I doubt it's worth it.

Cheers,
	Simon

> Tom
>
>
> El Jul 10, 2013, a las 5:20, "Edward Z. Yang" <ezyang <at> MIT.EDU> escribió:
>
>> GHC HEAD recently got a new primitive: atomicReadMVar#, which allows you
>> to read MVars without first taking and then putting back (removing a
>> nasty race where readMVar only works properly when there are no waiting
>> putters).
>>
>> atomicReadMVar behaves differently from readMVar.  The key
>> differences are:
>>
>>     - An atomicReadMVar op never causes an MVar to become "empty" at any point.
>>       This means less programs deadlock now.
>>
>>     - An blocked atomicReadMVar is always served by the *first* putMVar
>>       to arrive (it cuts to the head of the queue), whereas readMVar
>>       obeyed the FIFO ordering.  This means this program behaves differently:
>>
>>         m <- newEmptyMVar
>>         forkIO $ takeMVar m
>>         threadDelay 100
>>         forkIO $ print =<< readMVar m {- atomicReadMVar m -}
>>         threadDelay 100
>>         putMVar m 1
>>         putMVar m 2
>>         -- readMVar: outputs 2
>>         -- atomicReadMVar: outputs 1
>>
>>       It actually would not be too difficult to add support for atomicReadMVar
>>       which *does* respect the FIFO ordering but I don't have a sense when
>>       that would be useful.
>>
>> The general feeling Simon and I have is that everyone really wanted
>> to make believe readMVar was atomicReadMVar, and so maybe we should
>> break BC and make readMVar do the right thing.  But it is probably
>> worth some discussion, and I entreat you to think about the second
>> point more carefully.
>>
>> Thanks,
>> Edward
>>
>> _______________________________________________
>> Libraries mailing list
>> Libraries <at> haskell.org
>> http://www.haskell.org/mailman/listinfo/libraries
>
> _______________________________________________
> Libraries mailing list
> Libraries <at> haskell.org
> http://www.haskell.org/mailman/listinfo/libraries
>
Bertram Felgenhauer | 10 Jul 19:21 2013

Re: Proposal: replace readMVar with atomicReadMVar, breaking BC

Edward Z. Yang wrote:
> GHC HEAD recently got a new primitive: atomicReadMVar#, which allows you
> to read MVars without first taking and then putting back

Great, thanks a lot!

> The general feeling Simon and I have is that everyone really wanted
> to make believe readMVar was atomicReadMVar, and so maybe we should
> break BC and make readMVar do the right thing.

I agree completely. In my experience, the current non-atomic behaviour
of readMVar has only lead to confusion; I don't see any use for this
behaviour. Besides, if anybody really wants that behaviour they should
probably invoke takeMVar and putMVar separately and add a comment or
two.

I also agree with the reasoning behind processing atomicReadMVar
eagerly.

Best regards,

Bertram
Austin Seipp | 10 Jul 21:28 2013
Picon

Re: Proposal: replace readMVar with atomicReadMVar, breaking BC

After reading some of the background and seeing this, +1 (Frankly, I
didn't even know before this that readMVar had the race condition you
described, and from my point of view, it should simply be fixed!)

Also: If you add a small release note blurb for the changes `base`,
that would be wonderful too. :)

On Wed, Jul 10, 2013 at 4:20 AM, Edward Z. Yang <ezyang <at> mit.edu> wrote:
> GHC HEAD recently got a new primitive: atomicReadMVar#, which allows you
> to read MVars without first taking and then putting back (removing a
> nasty race where readMVar only works properly when there are no waiting
> putters).
>
> atomicReadMVar behaves differently from readMVar.  The key
> differences are:
>
>     - An atomicReadMVar op never causes an MVar to become "empty" at any point.
>       This means less programs deadlock now.
>
>     - An blocked atomicReadMVar is always served by the *first* putMVar
>       to arrive (it cuts to the head of the queue), whereas readMVar
>       obeyed the FIFO ordering.  This means this program behaves differently:
>
>         m <- newEmptyMVar
>         forkIO $ takeMVar m
>         threadDelay 100
>         forkIO $ print =<< readMVar m {- atomicReadMVar m -}
>         threadDelay 100
>         putMVar m 1
>         putMVar m 2
>         -- readMVar: outputs 2
>         -- atomicReadMVar: outputs 1
>
>       It actually would not be too difficult to add support for atomicReadMVar
>       which *does* respect the FIFO ordering but I don't have a sense when
>       that would be useful.
>
> The general feeling Simon and I have is that everyone really wanted
> to make believe readMVar was atomicReadMVar, and so maybe we should
> break BC and make readMVar do the right thing.  But it is probably
> worth some discussion, and I entreat you to think about the second
> point more carefully.
>
> Thanks,
> Edward
>
> _______________________________________________
> Libraries mailing list
> Libraries <at> haskell.org
> http://www.haskell.org/mailman/listinfo/libraries

--

-- 
Regards,
Austin - PGP: 4096R/0x91384671
Edward Z. Yang | 10 Jul 22:38 2013
Picon

Re: Proposal: replace readMVar with atomicReadMVar, breaking BC

Where do these release notes live?

Excerpts from Austin Seipp's message of Wed Jul 10 12:28:48 -0700 2013:
> After reading some of the background and seeing this, +1 (Frankly, I
> didn't even know before this that readMVar had the race condition you
> described, and from my point of view, it should simply be fixed!)
> 
> Also: If you add a small release note blurb for the changes `base`,
> that would be wonderful too. :)
> 
> On Wed, Jul 10, 2013 at 4:20 AM, Edward Z. Yang <ezyang <at> mit.edu> wrote:
> > GHC HEAD recently got a new primitive: atomicReadMVar#, which allows you
> > to read MVars without first taking and then putting back (removing a
> > nasty race where readMVar only works properly when there are no waiting
> > putters).
> >
> > atomicReadMVar behaves differently from readMVar.  The key
> > differences are:
> >
> >     - An atomicReadMVar op never causes an MVar to become "empty" at any point.
> >       This means less programs deadlock now.
> >
> >     - An blocked atomicReadMVar is always served by the *first* putMVar
> >       to arrive (it cuts to the head of the queue), whereas readMVar
> >       obeyed the FIFO ordering.  This means this program behaves differently:
> >
> >         m <- newEmptyMVar
> >         forkIO $ takeMVar m
> >         threadDelay 100
> >         forkIO $ print =<< readMVar m {- atomicReadMVar m -}
> >         threadDelay 100
> >         putMVar m 1
> >         putMVar m 2
> >         -- readMVar: outputs 2
> >         -- atomicReadMVar: outputs 1
> >
> >       It actually would not be too difficult to add support for atomicReadMVar
> >       which *does* respect the FIFO ordering but I don't have a sense when
> >       that would be useful.
> >
> > The general feeling Simon and I have is that everyone really wanted
> > to make believe readMVar was atomicReadMVar, and so maybe we should
> > break BC and make readMVar do the right thing.  But it is probably
> > worth some discussion, and I entreat you to think about the second
> > point more carefully.
> >
> > Thanks,
> > Edward
> >
> > _______________________________________________
> > Libraries mailing list
> > Libraries <at> haskell.org
> > http://www.haskell.org/mailman/listinfo/libraries
> 
Edward Z. Yang | 10 Jul 22:38 2013
Picon

Re: Proposal: replace readMVar with atomicReadMVar, breaking BC

Oh, found it.

Excerpts from Austin Seipp's message of Wed Jul 10 12:28:48 -0700 2013:
> After reading some of the background and seeing this, +1 (Frankly, I
> didn't even know before this that readMVar had the race condition you
> described, and from my point of view, it should simply be fixed!)
> 
> Also: If you add a small release note blurb for the changes `base`,
> that would be wonderful too. :)
> 
> On Wed, Jul 10, 2013 at 4:20 AM, Edward Z. Yang <ezyang <at> mit.edu> wrote:
> > GHC HEAD recently got a new primitive: atomicReadMVar#, which allows you
> > to read MVars without first taking and then putting back (removing a
> > nasty race where readMVar only works properly when there are no waiting
> > putters).
> >
> > atomicReadMVar behaves differently from readMVar.  The key
> > differences are:
> >
> >     - An atomicReadMVar op never causes an MVar to become "empty" at any point.
> >       This means less programs deadlock now.
> >
> >     - An blocked atomicReadMVar is always served by the *first* putMVar
> >       to arrive (it cuts to the head of the queue), whereas readMVar
> >       obeyed the FIFO ordering.  This means this program behaves differently:
> >
> >         m <- newEmptyMVar
> >         forkIO $ takeMVar m
> >         threadDelay 100
> >         forkIO $ print =<< readMVar m {- atomicReadMVar m -}
> >         threadDelay 100
> >         putMVar m 1
> >         putMVar m 2
> >         -- readMVar: outputs 2
> >         -- atomicReadMVar: outputs 1
> >
> >       It actually would not be too difficult to add support for atomicReadMVar
> >       which *does* respect the FIFO ordering but I don't have a sense when
> >       that would be useful.
> >
> > The general feeling Simon and I have is that everyone really wanted
> > to make believe readMVar was atomicReadMVar, and so maybe we should
> > break BC and make readMVar do the right thing.  But it is probably
> > worth some discussion, and I entreat you to think about the second
> > point more carefully.
> >
> > Thanks,
> > Edward
> >
> > _______________________________________________
> > Libraries mailing list
> > Libraries <at> haskell.org
> > http://www.haskell.org/mailman/listinfo/libraries
> 
John Lato | 11 Jul 01:43 2013
Picon

Re: Proposal: replace readMVar with atomicReadMVar, breaking BC

+1 from me.  I don't think anyone really wants the current readMVar semantics anyway, and if somebody really does they can define their own non-atomic readMVar.  Thanks for working on this!


On Thu, Jul 11, 2013 at 4:38 AM, Edward Z. Yang <ezyang <at> mit.edu> wrote:
Oh, found it.

Excerpts from Austin Seipp's message of Wed Jul 10 12:28:48 -0700 2013:
> After reading some of the background and seeing this, +1 (Frankly, I
> didn't even know before this that readMVar had the race condition you
> described, and from my point of view, it should simply be fixed!)
>
> Also: If you add a small release note blurb for the changes `base`,
> that would be wonderful too. :)
>
> On Wed, Jul 10, 2013 at 4:20 AM, Edward Z. Yang <ezyang <at> mit.edu> wrote:
> > GHC HEAD recently got a new primitive: atomicReadMVar#, which allows you
> > to read MVars without first taking and then putting back (removing a
> > nasty race where readMVar only works properly when there are no waiting
> > putters).
> >
> > atomicReadMVar behaves differently from readMVar.  The key
> > differences are:
> >
> >     - An atomicReadMVar op never causes an MVar to become "empty" at any point.
> >       This means less programs deadlock now.
> >
> >     - An blocked atomicReadMVar is always served by the *first* putMVar
> >       to arrive (it cuts to the head of the queue), whereas readMVar
> >       obeyed the FIFO ordering.  This means this program behaves differently:
> >
> >         m <- newEmptyMVar
> >         forkIO $ takeMVar m
> >         threadDelay 100
> >         forkIO $ print =<< readMVar m {- atomicReadMVar m -}
> >         threadDelay 100
> >         putMVar m 1
> >         putMVar m 2
> >         -- readMVar: outputs 2
> >         -- atomicReadMVar: outputs 1
> >
> >       It actually would not be too difficult to add support for atomicReadMVar
> >       which *does* respect the FIFO ordering but I don't have a sense when
> >       that would be useful.
> >
> > The general feeling Simon and I have is that everyone really wanted
> > to make believe readMVar was atomicReadMVar, and so maybe we should
> > break BC and make readMVar do the right thing.  But it is probably
> > worth some discussion, and I entreat you to think about the second
> > point more carefully.
> >
> > Thanks,
> > Edward
> >
> > _______________________________________________
> > Libraries mailing list
> > Libraries <at> haskell.org
> > http://www.haskell.org/mailman/listinfo/libraries
>

_______________________________________________
Libraries mailing list
Libraries <at> haskell.org
http://www.haskell.org/mailman/listinfo/libraries

_______________________________________________
Libraries mailing list
Libraries <at> haskell.org
http://www.haskell.org/mailman/listinfo/libraries
Milan Straka | 10 Jul 21:46 2013
Picon

Re: Proposal: replace readMVar with atomicReadMVar, breaking BC

> -----Original message-----
> From: "Edward Z. Yang" <ezyang <at> MIT.EDU>
> Sent: 10 Jul 2013, 02:20
>
> GHC HEAD recently got a new primitive: atomicReadMVar#, which allows you
> to read MVars without first taking and then putting back (removing a
> nasty race where readMVar only works properly when there are no waiting
> putters).

That is great, I have been missing such a primitive.

> The general feeling Simon and I have is that everyone really wanted
> to make believe readMVar was atomicReadMVar, and so maybe we should
> break BC and make readMVar do the right thing.  But it is probably
> worth some discussion, and I entreat you to think about the second
> point more carefully.

+1 from me. Even though it is a BC and a change in semantics, it is
a change to the behaviour people expect or hope for when using readMVar.

Cheers,
Milan
Ian Lynagh | 10 Jul 22:25 2013

Re: Proposal: replace readMVar with atomicReadMVar, breaking BC

On Wed, Jul 10, 2013 at 02:20:14AM -0700, Edward Z. Yang wrote:
> 
> The general feeling Simon and I have is that everyone really wanted
> to make believe readMVar was atomicReadMVar, and so maybe we should
> break BC and make readMVar do the right thing.

I don't think this breaks backwards compatibility. The haddocks say:

    Fairness 

    No thread can be blocked indefinitely on an MVar unless another
    thread holds that MVar indefinitely. One usual implementation of
    this fairness guarantee is that threads blocked on an MVar are
    served in a first-in-first-out fashion, but this is not guaranteed
    in the semantics.

Thanks
Ian
--

-- 
Ian Lynagh, Haskell Consultant
Well-Typed LLP, http://www.well-typed.com/
Edward Kmett | 11 Jul 10:08 2013
Picon

Re: Proposal: replace readMVar with atomicReadMVar, breaking BC

+1 


I agree that changing this is more likely to give users the functionality that they expected from the API in the first place.

On Wed, Jul 10, 2013 at 4:20 AM, Edward Z. Yang <ezyang <at> mit.edu> wrote:
GHC HEAD recently got a new primitive: atomicReadMVar#, which allows you
to read MVars without first taking and then putting back (removing a
nasty race where readMVar only works properly when there are no waiting
putters).

atomicReadMVar behaves differently from readMVar.  The key
differences are:

    - An atomicReadMVar op never causes an MVar to become "empty" at any point.
      This means less programs deadlock now.

    - An blocked atomicReadMVar is always served by the *first* putMVar
      to arrive (it cuts to the head of the queue), whereas readMVar
      obeyed the FIFO ordering.  This means this program behaves differently:

        m <- newEmptyMVar
        forkIO $ takeMVar m
        threadDelay 100
        forkIO $ print =<< readMVar m {- atomicReadMVar m -}
        threadDelay 100
        putMVar m 1
        putMVar m 2
        -- readMVar: outputs 2
        -- atomicReadMVar: outputs 1

      It actually would not be too difficult to add support for atomicReadMVar
      which *does* respect the FIFO ordering but I don't have a sense when
      that would be useful.

The general feeling Simon and I have is that everyone really wanted
to make believe readMVar was atomicReadMVar, and so maybe we should
break BC and make readMVar do the right thing.  But it is probably
worth some discussion, and I entreat you to think about the second
point more carefully.

Thanks,
Edward

_______________________________________________
Libraries mailing list
Libraries <at> haskell.org
http://www.haskell.org/mailman/listinfo/libraries

_______________________________________________
Libraries mailing list
Libraries <at> haskell.org
http://www.haskell.org/mailman/listinfo/libraries
David Luposchainsky | 11 Jul 10:57 2013

Re: Proposal: replace readMVar with atomicReadMVar, breaking BC

On 2013-07-10 11:20, Edward Z. Yang wrote:
> GHC HEAD recently got a new primitive: atomicReadMVar#, which allows you
> to read MVars without first taking and then putting back (removing a
> nasty race where readMVar only works properly when there are no waiting
> putters).

+1

I avoided readMVar for that reason in the past, effectively doing the
take/put manually. I agree with others that the atomic operation is the
desired behavior.

David
Edward Z. Yang | 12 Jul 23:44 2013
Picon

Re: Proposal: replace readMVar with atomicReadMVar, breaking BC

OK, it looks like the consensus is to change the old readMVar.  I will
go and implement this.

Edward

Excerpts from Edward Z. Yang's message of Wed Jul 10 02:20:14 -0700 2013:
> GHC HEAD recently got a new primitive: atomicReadMVar#, which allows you
> to read MVars without first taking and then putting back (removing a
> nasty race where readMVar only works properly when there are no waiting
> putters).
> 
> atomicReadMVar behaves differently from readMVar.  The key
> differences are:
> 
>     - An atomicReadMVar op never causes an MVar to become "empty" at any point.
>       This means less programs deadlock now.
> 
>     - An blocked atomicReadMVar is always served by the *first* putMVar
>       to arrive (it cuts to the head of the queue), whereas readMVar
>       obeyed the FIFO ordering.  This means this program behaves differently:
> 
>         m <- newEmptyMVar
>         forkIO $ takeMVar m
>         threadDelay 100
>         forkIO $ print =<< readMVar m {- atomicReadMVar m -}
>         threadDelay 100
>         putMVar m 1
>         putMVar m 2
>         -- readMVar: outputs 2
>         -- atomicReadMVar: outputs 1
> 
>       It actually would not be too difficult to add support for atomicReadMVar
>       which *does* respect the FIFO ordering but I don't have a sense when
>       that would be useful.
> 
> The general feeling Simon and I have is that everyone really wanted
> to make believe readMVar was atomicReadMVar, and so maybe we should
> break BC and make readMVar do the right thing.  But it is probably
> worth some discussion, and I entreat you to think about the second
> point more carefully.
> 
> Thanks,
> Edward
> 

Gmane