[PD] variable receive objects?

Ivica Ico Bukvic ico at vt.edu
Wed Jun 20 23:23:02 CEST 2012

On 06/20/2012 01:53 PM, Miller Puckette wrote:
> Hi Ico and list -
> On Tue, Jun 19, 2012 at 10:20:07PM -0400, Ivica Ico Bukvic wrote:
>>> -----Original Message-----
>>> From: Miller Puckette [mailto:msp at ucsd.edu]
>>> Sent: Tuesday, June 19, 2012 5:11 PM
>>> To: Ivica Ico Bukvic
>>> Cc: 'Claude Heiland-Allen'; Hans-Christoph Steiner; pd-list at iem.at
>>> Subject: Re: [PD] variable receive objects?
>>> I don't think your patch works in every case (I think you simply have to
>> check
>>> every e->e_who inside functions like bindlist_bang() before dereferencing
>>> them since someone could clear one of them while inside a previous one).
>> Thanks for the update, Miller. Is there a way you could give me an example
>> patch that would fail this way? I ask this simply because I am unable to
>> imagine one you describe here. Namely, even if a parent's send has been
>> changed by the child-of-a-child object this way, this change would only make
>> specific instance point to null object but its pointer would be still valid
>> until its entire sub-tree has been navigated, and only after its entire
>> sub-tree has been navigated would it be actually dereferencing stuff and
>> fixing the pointers accordingly before the next incoming wave of calls.
> I don't have an example handy but here's a stack pseudo-trace:
> ...
> bindlist_bang()
> pd_bang(first item in bindlist)
> ...
> toggle_receive()<--- zeros out second item in bindlist
You're right, there should be one more check before calling pd_bang or 
pd_whatever simply stating

if (e->e_who != NULL) pd_whatever(e->e_who);

Beyond that, it should work as only
e structs that have been slated for deallocation will have that one set 
to NULL while still having a valid pointer to the rest of the list so as 
to avoid the crash.
> then when pd_bang returns, bindlist_bang proceeds to dereference second
> item in bindlist and... not bang but more like 'boom'.
>>> Also, there are declarations after functional lines, e.g.,
>>> +	change_bindlist_via_graph = 1;
>>>       t_bindelem *e;
>>> which is not standard C - something I frequently have to clean up in
>> people's
>>> patches :)
>> You mean declaration of a global variable needs to be placed at the top of
>> the source file? Sure, that is an easy fix. It's been placed here in
>> proximity to make the patch more legible.
> It's an automatic variable whose declaration should be at the beginning of a
> block.  Otherwise Visual C++ seems to get offended (and I don't find out
> until I crank up my stupid windows machine :)

But it is declared as a global variable at the beginning of the diff so 
it is not an automatic variable that is destroyed after function exits:

+static int change_bindlist_via_graph = 0;
+static void bindlist_cleanup(t_bindlist *x)

Are you saying that I need to re-declare it within the function? If so, 
that is the first time I would've seen anything like it and it is 
something certainly the rest of the Pd code does not conform to, either 
(or at least pd-extended).

>>> I think something like what you proposed could work; there would still be
>> a
>>> performance hit which I'd probably want to measure before committing to
>>> doing this... since after all we're just talking about a wierd and
>> obnoxious
>>> 'feature'
>>> in IEMGUIs that I would simply take out if I could :)
>> I am not so sure there is a performance hit since in both cases
>> dereferencing happens in exactly the same way, except in this one the
>> referencing is delayed and in the interim structs destined to be
>> dereferenced are made to point to null and then skipped if a subsequent call
>> trips over a null-pointing struct before it has been dereferenced. As such
>> its performance impact should be minimal.
> Main performance hit would be that every time anyone traverses a bindlist
> (many send/receive messages, perhaps most) there's all that extra code in
> bindlist_bang(), etc. needed to make the extra tests (possible zero receiver
> and possible cleanup needed afterward).
Clean-up afterward is already implemented and is done within 
bindlist_cleanup() call which is nearly identical in terms of its 
workload to what was originally placed within pd_unbind, so I seriously 
doubt this will make much if any difference.

What will potentially add a bit of an overhead is the call above that I 
forgot to add:

if (e->e_who != NULL) pd_whatever(e->e_who);

I honestly have no idea how much a single if statement checking for a 
null pointer requires in terms of CPU usage. That said, FWIW I seriously 
doubt that this one if would cause that much of cpu overhead even if 
executed on a large number of calls.
> cheers
> M

Ivica Ico Bukvic, D.M.A
Composition, Music Technology
Director, DISIS Interactive Sound&  Intermedia Studio
Director, L2Ork Linux Laptop Orchestra
Head, ICAT IMPACT Studio
Virginia Tech
Department of Music
Blacksburg, VA 24061-0240
(540) 231-6139
(540) 231-5034 (fax)

More information about the Pd-list mailing list