I'm not sure I totally understand your question about 'unpacking' an MVar,
but I'm going to assume you mean data structures that use the {-# UNPACK
#-} pragma, like in Control.Concurrent.Future [1] and
Control.Concurrent.NamedLock [2].

Here is how MVar is defined in GHC [3]:
    data MVar a = MVar (MVar# RealWorld a)

A "MVar# s a" is an unboxed pointer to a structure understood by the GHC
runtime.

So yes, you can imagine a MVar as a pointer-to-pointer.  The structure it
points at likely has another pointer to the embedded boxed "a", so it may
even be pointer-to-pointer-to-pointer.

The MVar data structure exists to allow laziness; for example

   let x = unsafePerformIO (newMVar ()) in ()

is likely to not allocate an MVar#, just a thunk that would create an MVar
if it was evaluated.  Unboxed objects (represented by convetion with # in
GHC), on the other hand, are strict, so if you have an MVar# RealWorld (),
you know it points to a valid MVar#.

>From [2] we have
data NLItem = NLItem {-# UNPACK #-} !Int
                     {-# UNPACK #-} !(MVar ())

All the {-# UNPACK #-} pragma does is embed the contents of a strict
single-constructor data declaration *directly* into the structure
containing it; it's like you declared NLItem as such:

    data NLItem = NLItem Word# (MVar# RealWorld ())

except that if you call functions that want an Int or MVar thunk, the
compiler will automatically re-box them in a new I#/MVar constructor.

Many copies of pointers to the same MVar# may exist; they are all
'identical' MVars; equality is defined as such:
    instance Eq (MVar a) where
            (MVar mvar1#) == (MVar mvar2#) = sameMVar# mvar1# mvar2#

where sameMVar# is a primitive that is probably just raw pointer equality.

Because of this, boxed MVars can be garbage collected without necessarily
garbage-collecting the MVar# it holds, if a live reference to that MVar#
still exists elsewhere.

  -- ryan

[1]
http://hackage.haskell.org/packages/archive/future/2.0.0/doc/html/src/Control-Concurrent-Future.html
[2]
http://hackage.haskell.org/packages/archive/named-lock/0.1/doc/html/src/Control-Concurrent-NamedLock.html
[3]
http://www.haskell.org/ghc/docs/7.4.1/html/libraries/base/src/GHC-MVar.html#MVar

On Mon, Jul 30, 2012 at 9:25 PM, Leon Smith <[email protected]> wrote:

> I admit I don't know exactly how MVars are implemented,  but given that
> they can be aliased and have indefinite extent,   I would think that they
> look something vaguely like a  cdatatype ** var,  basically a pointer to an
> MVar (which is itself a pointer,  modulo some other things such as a thread
> queue.)
>
> And,  I would think that "unpacking" such an structure would basically be
> eliminating one layer of indirection,  so it would then look vague like a
> cdatatype * var.    But again,  given aliasing and indefinite extent, this
> would seem to be a difficult thing to do.
>
> Actually this isn't too difficult if an MVar only exists in a single
> unpacked structure:   other references to the MVar can simply be pointers
> into the structure.   But the case where an MVar is unpacked into two
> different structures suggests that,  at least in some cases,  an "unpacked"
> MVar is still a cdatatype ** var;
>
> So, is my understanding more or less correct?  Does anybody have a good,
> succinct explanation of how MVars are implemented,  and how they are
> unpacked?
>
> One final question,   assuming that unpacking an MVar really does
> eliminate a layer of indirection,  and that other references to that MVar
> are simply pointers into a larger structure,   what happens to that larger
> structure when there are no more references to it (but still some
> references to the MVar?)    Given the complications that must arise out of
> a doubly "unpacked" MVar,  I'm going to guess that the larger structure
> does get garbage collected in this case,  and that the MVar becomes
> dislodged from this structure.   Would that MVar then be placed directly
> inside another unpacked reference, if one is available?
>
> Best,
> Leon
>
> _______________________________________________
> Haskell-Cafe mailing list
> [email protected]
> http://www.haskell.org/mailman/listinfo/haskell-cafe
>
>
_______________________________________________
Haskell-Cafe mailing list
[email protected]
http://www.haskell.org/mailman/listinfo/haskell-cafe

Reply via email to