[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