develooper Front page | perl.ithreads | Postings from May 2008

Re: p5p summary: Improving threads::shared ?

Thread Previous | Thread Next
Dean Arnold
May 5, 2008 12:36
Re: p5p summary: Improving threads::shared ?
Message ID:
Jerry D. Hedden wrote:
> erry D. Hedden wrote:
>>     Look at $x:
>>     REF(0x144f8f0)
>>     REF(0x144f8f0)
>>     REF(0x144f8f0)
>>     REF(0x144f8f0)
>>     REF(0x144f8f0)
>>     REF(0x144f8f0)
>>     First look at $y:
>>     SCALAR(0x1423c70)
>>     SCALAR(0x1423ad8)
>>     SCALAR(0x14bd968)
>>     SCALAR(0x14bd980)
>>     SCALAR(0x14bd998)
>>     SCALAR(0x14bd9b0)
>>     Second look at $y:
>>     REF(0x1423c70)
>>     REF(0x1423ad8)
>>     REF(0x14bd968)
>>     REF(0x14bd980)
>>     REF(0x14bd998)
>>     SCALAR(0x14bd9b0)
>>  Seems to me that this is a bug.  It shows that
>>  threads::shared isn't detecting that it's dealing with a
>>  circular reference.  With each level that the app traverses,
>>  threads::shared "unrolls" another version of the shared
>>  variable.
>>  The more I think about it, the more I'm convinced this needs
>>  to be fixed.  The original variable $x is a circular
>>  reference, and it's finiteness is detectable.  The copy made
>>  to $y has become an infinitely deep reference with lazy
>>  evaluation.
> I've been looking at how to fix this, but know understanding
> of the internals of threads::shared is weak.
> Conceptually, I think it would require keeping a weak
> reference of each private SV associated with a shared SV.
> This would need to be done on a per-thread basis.  Then when
> a thread tries to reference a shared SV, a lookup would be
> made to see if a private SV already exists (and still
> exists) for that thread.  If so, that is returned (and the
> ref count of the weak ref is incremented?).  If not, a new
> private SV is created, and a weak ref to it is appropriately
> stored.
> Is this a logical approach?  If so, is it doable?

By coincidence, I've been doing related
work on Thread::Sociable's STM implementation.
It has to keep a "shadow" proxy of each variable
in order to avoid the same referencing issue
(otherwise, it could create multiple different
transactional versions of the same referenced variable)

For threads::shared, the only solution I can think of is
adding a fieldhash to the thread-private my_ctx structure
keyed by the address of the referent variable's
shared version. Then each attempt to create a new proxy
would lookup any existing persistent proxy for the shared
SV, and return it if found (currently, each new reference
to a shared variable creates a new proxy, which is what causes
this mess).

It may create refcounting issues; the private proxy
would need to be refcounted every time the shared
variable was refcounted in the same thread. (Alternately,
the thread could refcount only the proxy, and then decrement
the shared versions refcount only when the private proxy's
refcount dropped to zero)

I also don't know how it would effect taking ref's of
shared array/hash elements.

And this will probably slow things down even further.

- Dean

Thread Previous | Thread Next Perl Programming lists via nntp and http.
Comments to Ask Bjørn Hansen at | Group listing | About