No subject
Thu Jul 5 12:38:43 CEST 2012
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 <leon.p.smith at gmail.com> 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
> Haskell-Cafe at haskell.org
> http://www.haskell.org/mailman/listinfo/haskell-cafe
>
>
--e89a8f23494bda1bb604c6191d44
Content-Type: text/html; charset=ISO-8859-1
Content-Transfer-Encoding: quoted-printable
I'm not sure I totally understand your question about 'unpacking=
9; an MVar, but I'm going to assume you mean data structures that use t=
he {-# UNPACK #-} pragma, like in Control.Concurrent.Future [1] and Control=
.Concurrent.NamedLock [2].<br>
<br>Here is how MVar is defined in GHC [3]:<br>=A0=A0=A0 data MVar a =3D MV=
ar (MVar# RealWorld a)<br><br>A "MVar# s a" is an unboxed pointer=
to a structure understood by the GHC runtime.<br><br>So yes, you can imagi=
ne a MVar as a pointer-to-pointer.=A0 The structure it points at likely has=
another pointer to the embedded boxed "a", so it may even be poi=
nter-to-pointer-to-pointer.<br>
<br>The MVar data structure exists to allow laziness; for example<br>
<br>
=A0=A0 let x =3D unsafePerformIO (newMVar ()) in ()<br>
<br>
is likely to not allocate an MVar#, just a thunk that would create an=20
MVar if it was evaluated.=A0 Unboxed objects (represented by convetion=20
with # in GHC), on the other hand, are strict, so if you have an MVar#=20
RealWorld (), you know it points to a valid MVar#.<br><br>From [2] we have<=
br>data NLItem =3D NLItem {-# UNPACK #-} !Int<br>=A0=A0=A0=A0=A0=A0=A0=A0=
=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 {-# UNPACK #-} !(MVar ())<br><br>All t=
he {-# UNPACK #-} pragma does is embed the contents of a strict single-cons=
tructor data declaration *directly* into the structure containing it; it=
9;s like you declared NLItem as such:<br>
<br>=A0=A0=A0 data NLItem =3D NLItem Word# (MVar# RealWorld ())<br><br>exce=
pt 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.<br><br>Many co=
pies of pointers to the same MVar# may exist; they are all 'identical&#=
39; MVars; equality is defined as such:<br>
=A0=A0=A0 instance Eq (MVar a) where<br>=A0 =A0=A0 =A0=A0=A0=A0=A0=A0 (MVar=
mvar1#) =3D=3D (MVar mvar2#) =3D sameMVar# mvar1# mvar2#<br><br>where same=
MVar# is a primitive that is probably just raw pointer equality.<br><br>Bec=
ause of this, boxed MVars can be garbage collected without necessarily garb=
age-collecting the MVar# it holds, if a live reference to that MVar# still =
exists elsewhere.<br>
<br>=A0 -- ryan<br><br>[1] <a href=3D"http://hackage.haskell.org/packages/a=
rchive/future/2.0.0/doc/html/src/Control-Concurrent-Future.html">http://hac=
kage.haskell.org/packages/archive/future/2.0.0/doc/html/src/Control-Concurr=
ent-Future.html</a><br>
[2] <a href=3D"http://hackage.haskell.org/packages/archive/named-lock/0.1/d=
oc/html/src/Control-Concurrent-NamedLock.html">http://hackage.haskell.org/p=
ackages/archive/named-lock/0.1/doc/html/src/Control-Concurrent-NamedLock.ht=
ml</a><br>
[3] <a href=3D"http://www.haskell.org/ghc/docs/7.4.1/html/libraries/base/sr=
c/GHC-MVar.html#MVar">http://www.haskell.org/ghc/docs/7.4.1/html/libraries/=
base/src/GHC-MVar.html#MVar</a><br><br><div class=3D"gmail_quote">On Mon, J=
ul 30, 2012 at 9:25 PM, Leon Smith <span dir=3D"ltr"><<a href=3D"mailto:=
leon.p.smith at gmail.com" target=3D"_blank">leon.p.smith at gmail.com</a>></s=
pan> wrote:<br>
<blockquote class=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;border-left:1p=
x #ccc solid;padding-left:1ex"><div>I admit I don't know exactly how MV=
ars are implemented, =A0but given that they can be aliased and have indefin=
ite extent, =A0 I would think that they look something vaguely like a =A0cd=
atatype ** var, =A0basically a pointer to an MVar (which is itself a pointe=
r, =A0modulo some other things such as a thread queue.)</div>
<div><br></div><div>And, =A0I would think that "unpacking" such a=
n structure would basically be eliminating one layer of indirection, =A0so =
it would then look vague like a cdatatype * var. =A0 =A0But again, =A0given=
aliasing and indefinite extent, this would seem to be a difficult thing to=
do.</div>
<div><br></div><div>Actually this isn't too difficult if an MVar only e=
xists in a single unpacked structure: =A0 other references to the MVar can =
simply be pointers into the structure. =A0 But the case where an MVar is un=
packed into two different structures suggests that, =A0at least in some cas=
es, =A0an "unpacked" MVar is still a cdatatype ** var;</div>
<div><br></div><div>So, is my understanding more or less correct? =A0Does a=
nybody have a good, succinct explanation of how MVars are implemented, =A0a=
nd how they are unpacked?</div><div><br></div><div>One final question, =A0 =
assuming that unpacking an MVar really does eliminate a layer of indirectio=
n, =A0and that other references to that MVar are simply pointers into a lar=
ger structure, =A0 what happens to that larger structure when there are no =
more references to it (but still some references to the MVar?) =A0 =A0Given=
the complications that must arise out of a doubly "unpacked" MVa=
r, =A0I'm going to guess that the larger structure does get garbage col=
lected in this case, =A0and that the MVar becomes dislodged from this struc=
ture. =A0 Would that MVar then be placed directly inside another unpacked r=
eference, if one is available?</div>
<div><br></div><div>Best,</div><div>Leon</div>
<br>_______________________________________________<br>
Haskell-Cafe mailing list<br>
<a href=3D"mailto:Haskell-Cafe at haskell.org">Haskell-Cafe at haskell.org</a><br=
>
<a href=3D"http://www.haskell.org/mailman/listinfo/haskell-cafe" target=3D"=
_blank">http://www.haskell.org/mailman/listinfo/haskell-cafe</a><br>
<br></blockquote></div><br>
--e89a8f23494bda1bb604c6191d44--
More information about the Haskell-Cafe
mailing list