[chuck-users] implementing a "wait for signal with timeout"

Robert Poor rdpoor at gmail.com
Mon Jun 8 17:34:06 EDT 2009


Mike:

Kudos to Spencer for a nice bit of code.  Unless I'm reading it wrong,  
it does exactly the opposite of what I need: the main Forkable blocks  
until all of its children have finished.

As for

> ...solace in programming as if the memory leaks and performance
> issues don't exist and I get more real work done this way.

Trust me -- I am NOT one to do "premature optimization".  Rather, I  
was forced find a real solution once I realized I was consistently  
filling up memory during live performances.  (Do you know how long it  
takes ChucK to respond even to ^C when that happens?  The rest of the  
band was through a verse and the final chorus before I could regain  
control of my laptop!)

I'll explain my approach in the next mail...

- Rob

On 8 Jun 2009, at 12:40, mike clemow wrote:

> Hey Robert,
>
>>> ... The problem with killing the
>>> thread is that you leak 88K with each thread (!!!).
>
> Normally, I feel like I'm the guy complaining about this kind of
> thing.  ;-)  I've decided that, despite the memory and performance
> issues surrounding shreds, sporking them, & cetera, I have decided
> that the ChucKian way of solving these types of problems is better
> than trying to program around them in ChucK.  Programming around
> ChucK's issues in any other language would not be terribly hard, but
> in ChucK, it is hard.  The thing is that ChucK provides a way of doing
> this stuff in a small amount of code and it takes an amount of code
> multiple orders of magnitude larger to solve the same problem in an
> performance/memory-optimized way.
>
> The attached piece of code is something that Spencer Salazar whipped
> up for me one day in response to my gripe about shreds dying without
> finishing.  It combines the idea of a shred and an event and I've
> based a lot of my frameworks around this one piece of code (thank you
> Spencer!).  To use it, you subclass it and override the run() method
> with your sporkable shred code, instantiate your subclass and spawn
> the shred with yourForkable.start().  It would not be difficult to
> subclass this in such a way as to incorporate the concept of "wait for
> a signal (e.g. event.broadcast()) OR for a specific time to elapse,
> whichever comes first."  Or it might be that your code wouldn't need
> such a thing, if you use this--I honestly don't know.
>
> While this implementation doesn't explicitly reuse shreds, I have
> found solace in programming as if the memory leaks and performance
> issues don't exist and I get more real work done this way.  One day,
> these problems will no longer exist and all our code will run much
> smoother.  Until then, I've used this code as a basis for a granular
> synthesis implementation in which every grain is at least one (if not
> more) shred(s) and there's still a lot it can do before it breaks.
> I've tried programming around these issues, however, and I end up with
> code I can't even read, let alone understand or debug.
>
> It's like there's a path-of-least-resistance that ChucK's system
> provides.  Yes, if you travel that path you will run into certain
> issues, however, if you don't travel that path, you might as well be
> using something else, because you're missing out on the revolution
> that this path represents.
>
> This is just my 2 cents.
>
> _mike
>
>
> On Mon, Jun 8, 2009 at 1:59 PM, dan trueman<dtrueman at princeton.edu>  
> wrote:
>> jah, i've requested something like this before:
>>
>> myEvent  ||  1::minute => now; //time advances to whichever comes  
>> first....
>>
>> i've programmed around it using secondary timing shreds, but it  
>> would be
>> much nicer to be able to do something like the above...
>>
>> dt
>>
>> On Jun 8, 2009, at 1:53 PM, Robert Poor wrote:
>>
>>> Gang:
>>>
>>> In real-time music making, sometimes you want to wait for a signal  
>>> (e.g.
>>> event.broadcast()) OR for a specific time to elapse, whichever  
>>> comes first.
>>>  I've implemented ways to do this, but I'm not really satisfied  
>>> with the
>>> code.
>>>
>>> Here's the problem: Lets say that your music is slaved to a  
>>> metronome, and
>>> the metronome is allowed to change speed.  You want your music to  
>>> stay
>>> sync'd to the metronome.  If you simply do:
>>>        now + (1/tempo)::second => time next_beat;
>>>        next_beat => now;
>>>        play_note();
>>> you'll be in trouble if the metronome speeds up while you're  
>>> waiting: your
>>> note will be late.  The fundamental problem is that once you execute
>>> "next_beat => now;", you're committed to waiting and there's now  
>>> way to
>>> break out of it, short of killing the thread.  The problem with  
>>> killing the
>>> thread is that you leak 88K with each thread (!!!).
>>>
>>> So here's the programming challenge: how would you implement a  
>>> "wait for
>>> signal with timeout" that will block until it gets a signal OR a  
>>> specified
>>> time has elapsed?  Since each thread costs 88K in non-reclaimed  
>>> memory, you
>>> may create threads, but your solution must re-use them.
>>>
>>> As I said, I have implementations which I'm happy to share, but  
>>> I'd like
>>> to see how you would do this first.  Most of all, this is likely  
>>> to turn
>>> into a feature request for the next version of ChucK.
>>>
>>> - Rob
>>> _______________________________________________
>>> chuck-users mailing list
>>> chuck-users at lists.cs.princeton.edu
>>> https://lists.cs.princeton.edu/mailman/listinfo/chuck-users
>> _______________________________________________
>> chuck-users mailing list
>> chuck-users at lists.cs.princeton.edu
>> https://lists.cs.princeton.edu/mailman/listinfo/chuck-users
>> -- 
> http://michaelclemow.com
> http://semiotech.org
> <Forkable.ck>_______________________________________________
> chuck-users mailing list
> chuck-users at lists.cs.princeton.edu
> https://lists.cs.princeton.edu/mailman/listinfo/chuck-users



More information about the chuck-users mailing list