<div dir="ltr">This would make MonadFix's implementation much nicer, I think :)</div><div class="gmail_extra"><br><div class="gmail_quote">On Fri, Jun 29, 2018 at 9:14 AM, Oleg Grenrus <span dir="ltr"><<a href="mailto:oleg.grenrus@iki.fi" target="_blank">oleg.grenrus@iki.fi</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">I have wanted something like that! Also similiar STM TQVar would be nice<br>
to have. For example `async` uses TMVar where the value is written only<br>
once. if once filled the QVar cannot be empty is useful property.<br>
<br>
For STM variant, I'd actually like to have<br>
<br>
putTQVar' :: QTVar a -> a -> STM (TVar a)<br>
<br>
i.e. giving me back a `TVar a`, for which I now the value is already<br>
there (i.e. reading won't block). Not sure what the would be such for<br>
IO, IORef doesn't feel right.<br>
<span class="HOEnZb"><font color="#888888"><br>
- Oleg<br>
</font></span><div class="HOEnZb"><div class="h5"><br>
On 29.06.2018 08:28, David Feuer wrote:<br>
> IVars (write-once variables) can be useful for various purposes. In Haskell, they can be implemented using MVars. But MVars are not the lightest things in the world. I'm wondering if it might pay to implement something much lighter primitively. Here's a sketch of some things I'll tentatively call QVars.<br>
><br>
> A QVar has two fields: a value (possibly null) and a stack (no need for a queue) of waiting threads.<br>
><br>
> newEmptyQVar: Create a QVar with a null value and an empty queue.<br>
><br>
> tryReadQVar: Just look at the value.<br>
><br>
> readQVar: Check if the value is null (simple memory read). If not, use it. If so, push yourself onto the waiting stack (CAS loop). The code that will run when you're awakened will try to awaken the next thread if there is one (CAS loop).<br>
><br>
> putQVar: Install a new value and get the old one (exchange). If the old value was null, mark the QVar dirty. Awaken the first thread if there is one (CAS loop). Return the old value if it was non-null (this can be used in library code to make duplicate writes, or non-equal duplicate writes, an error).<br>
><br>
> I think we'd probably also want atomic modification operations, but I haven't figured out which ones yet.<br>
><br>
> Implementation differences from MVars:<br>
><br>
> * We have two fields instead of three (because we can get away with a stack instead of a queue).<br>
><br>
> * We never need to lock the QVar closure. MVars do: they can change freely between empty and full, so it's necessary to coordinate between value and queue modifications.<br>
> ______________________________<wbr>_________________<br>
> ghc-devs mailing list<br>
> <a href="mailto:ghc-devs@haskell.org">ghc-devs@haskell.org</a><br>
> <a href="http://mail.haskell.org/cgi-bin/mailman/listinfo/ghc-devs" rel="noreferrer" target="_blank">http://mail.haskell.org/cgi-<wbr>bin/mailman/listinfo/ghc-devs</a><br>
<br>
<br>
______________________________<wbr>_________________<br>
ghc-devs mailing list<br>
<a href="mailto:ghc-devs@haskell.org">ghc-devs@haskell.org</a><br>
<a href="http://mail.haskell.org/cgi-bin/mailman/listinfo/ghc-devs" rel="noreferrer" target="_blank">http://mail.haskell.org/cgi-<wbr>bin/mailman/listinfo/ghc-devs</a><br>
</div></div></blockquote></div><br></div>