[Haskell-cafe] Does the TMVar and TChan really obey STM rules?

5 views
Skip to first unread message

Andrey Sisoyev

unread,
Dec 24, 2009, 10:03:38 AM12/24/09
to haskel...@haskell.org

Hi everyone,

>isEmptyTMVar :: TMVar a -> STM Bool Source
>
>Check whether a given TMVar is empty.
>
>Notice that the boolean value returned is just a snapshot
>of the state of the TMVar. By the time you get to react on its result,
>the TMVar may have been filled (or emptied) - so be extremely careful
>when using this operation. Use tryTakeTMVar instead if possible.

When I read this in the haddock to Control.Concurrent.STM.TMVar, I started
to suspect that the behavior of TMVar and TChan might be worse than I
imagined.

Few questions on TMVar and TChan:
(1) If 2 threads are sleeping-waiting for the output of TChan, and it gets
filled, do they both wakeup, or just one?
(2) Similar question about reading/writing TMVar.
(3) If a thread is sleeping-waiting for the output of TChan, but transaction
wants to restart due to the change in any of touched TVar, then does the
thread wakeup and restart the transaction?
(4) Similar question about TMVar.

Also, if there is some paper on this, please, give me a link on it.

Please help,
Andrey
--
View this message in context: http://old.nabble.com/Does-the-TMVar-and-TChan-really-obey-STM-rules--tp26914707p26914707.html
Sent from the Haskell - Haskell-Cafe mailing list archive at Nabble.com.

_______________________________________________
Haskell-Cafe mailing list
Haskel...@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe

Neil Brown

unread,
Dec 24, 2009, 11:45:47 AM12/24/09
to Andrey Sisoyev, haskel...@haskell.org
Andrey Sisoyev wrote:
> Hi everyone,
>
>
>> isEmptyTMVar :: TMVar a -> STM Bool Source
>>
>> Check whether a given TMVar is empty.
>>
>> Notice that the boolean value returned is just a snapshot
>> of the state of the TMVar. By the time you get to react on its result,
>> the TMVar may have been filled (or emptied) - so be extremely careful
>> when using this operation. Use tryTakeTMVar instead if possible.
>>
>
> When I read this in the haddock to Control.Concurrent.STM.TMVar, I started
> to suspect that the behavior of TMVar and TChan might be worse than I
> imagined.
>
That warning seems a little paranoid to me. The state of the TMVar must
persist to the end of the transaction (from the point of view of the
process executing a transaction), so isEmptyTMVar seems fine as long as
you act on it in the same transaction. What would be bad would be
something like:

do b <- atomically $ isEmptyTMVar tv
if b ....

Where you act on the value in a later transaction. (Unless I've missed
something?)


> Few questions on TMVar and TChan:
> (1) If 2 threads are sleeping-waiting for the output of TChan, and it gets
> filled, do they both wakeup, or just one?
> (2) Similar question about reading/writing TMVar.
> (3) If a thread is sleeping-waiting for the output of TChan, but transaction
> wants to restart due to the change in any of touched TVar, then does the
> thread wakeup and restart the transaction?
> (4) Similar question about TMVar.
>
> Also, if there is some paper on this, please, give me a link on it.
>

I believe, 1 and 2: both wake up and retry the transaction, but only the
process that completes the transaction first will succeed, the other
will end up going back to sleep. 3 and 4: yes. I think the rule is
simply, if you call retry, you'll wait until any TVar you've read from
so far changes, then you'll wake up and redo the transaction. To see
how that affects TMVar and TChan, read their source code to see what
they are actually doing with TVars and retry.

Neil.

Svein Ove Aas

unread,
Dec 24, 2009, 4:54:53 PM12/24/09
to Andrey Sisoyev, haskel...@haskell.org
On Thu, Dec 24, 2009 at 4:03 PM, Andrey Sisoyev
<Andrejs....@nextmail.ru> wrote:
>
> Hi everyone,
>
>>isEmptyTMVar :: TMVar a -> STM Bool    Source
>>
>>Check whether a given TMVar is empty.
>>
>>Notice that the boolean value returned is just a snapshot
>>of the state of the TMVar. By the time you get to react on its result,
>>the TMVar may have been filled (or emptied) - so be extremely careful
>>when using this operation. Use tryTakeTMVar instead if possible.
>
> When I read this in the haddock to Control.Concurrent.STM.TMVar, I started
> to suspect that the behavior of TMVar and TChan might be worse than I
> imagined.
>
That looks like it was copied and pasted from the MVar documentation.
It's not in the least correct; in fact, TMVar a is implemented as TVar
(Maybe a), so it is just as atomic.

> Few questions on TMVar and TChan:
> (1) If 2 threads are sleeping-waiting for the output of TChan, and it gets
> filled, do they both wakeup, or just one?

You will only see one react. It's just about possible that both in
fact wake, but one will go back to sleep; the abstraction doesn't
leak.

> (2) Similar question about reading/writing TMVar.

Same answer.

> (3) If a thread is sleeping-waiting for the output of TChan, but transaction
> wants to restart due to the change in any of touched TVar, then does the
> thread wakeup and restart the transaction?

If an STM transaction blocks, the runtime keeps track of all cells
(TVars) that have been read until the point in the transaction at
which it called retry, and restarts it - from the beginning - if any
of them change.

This could be optimized. It may even have been optimized. But tose are
the semantics; it'll behave like that's true.

> (4) Similar question about TMVar.
>

It's all implemented by TVars, so all your questions are about those.

--
Svein Ove Aas

Andrey Sisoyev

unread,
Dec 26, 2009, 10:29:47 AM12/26/09
to haskel...@haskell.org

Thank you, Svein Ove Aas and Neil Brown, for your replies !
I really should have checked the stm sources before panicking here! =)

Regards,
Andrey
--
View this message in context: http://old.nabble.com/Does-the-TMVar-and-TChan-really-obey-STM-rules--tp26914707p26927805.html


Sent from the Haskell - Haskell-Cafe mailing list archive at Nabble.com.

_______________________________________________

Reply all
Reply to author
Forward
0 new messages