Hi folks! Riddle me this... This destroys poor Chuck after a short time: ----- class Forkable { // I am a process fun void run() { // sporkable code here... SinOsc s => dac; 100::ms => now; me.yield(); } } class Forker { // I fork a process (Forkable) fun Shred fork( Forkable f ) { // code that forks a Forkable spork ~ f.run() @=> Shred @ offspring; // RETURNING A SHRED OBJECT me.yield(); return offspring; } } Forkable forkable; Forker forker; while( true ) { forker.fork( forkable ); 50::ms => now; } ----- This, however, does not: ----- class Forkable { // I am a process fun void run() { // sporkable code here... SinOsc s => dac; 100::ms => now; me.yield(); } } class Forker { // I fork a process (Forkable) fun void fork( Forkable f ) { // code that forks a Forkable spork ~ f.run(); // NOT RETURNING THE SHRED OBJECT HERE me.yield(); } } Forkable forkable; Forker forker; while( true ) { forker.fork( forkable ); 50::ms => now; } ----- What gives? It apparently doesn't like the return of the Shred object. I'm not sure what's happening here. It's not *really* that important to me, but it would be nice to have the option of killing that process later. Any ideas? Am I doing something wrong??? Cheers, Mike -- http://semiotech.org http://deadlylittlepills.com/michael
Mike;
What gives? It apparently doesn't like the return of the Shred object. I'm not sure what's happening here. It's not *really* that important to me, but it would be nice to have the option of killing that process later.
Any ideas? Am I doing something wrong???
Weird. Adding a single line like this; class Forkable { // I am a process fun void run() { // sporkable code here... SinOsc s => dac; 100::ms => now; //unchuck! s =< dac; me.yield(); } } Makes the first example behave as well. The difference seems to be that the SinOsc's aren't automatically unchucked from the dac when the their shred exits in the first example.... and this seems due to the existance of that reference. This leads to clipping and a high cpu load, resulting in that weird noise because you are still creating 20 SinOsc's per second. My bet would be that this might be a case of reference counting gone wrong. At least it's fixable with a manual unchuck though it's quite odd that SinOsc's that aren't attached to a Shred can keep running. In fact; with my edit of the Forkable class I can start your code, stop it, and often a tone will keep sounding without a single shred running (!!!). Strange stuff, good catch! Yours, Kas.
In fact; with my edit of the Forkable class I can start your code, stop it, and often a tone will keep sounding without a single shred running (!!!).
Yes, I forgot to mention that! Crazy... I guess I'll manually
unchuck the SinOsc for now. I'll have to check if that happens with
other UGens...
Meanwhile, if I unchuck that SinOsc from the dac it works in the sense
that the SinOsc objects don't add up, however, only if the shreds
finish executing. If I remove the parent while one of the sporked
shreds is still running, one sine keeps going. Ostensibly because the
last shred hasn't finished and the unchuck line hasn't run. This
makes me really wish I could define code that would be called when a
shred exits. That would be a neat feature...
Strange stuff indeed!
Thanks!
-Mike
On Fri, Jun 13, 2008 at 7:40 AM, Kassen
Mike;
What gives? It apparently doesn't like the return of the Shred object. I'm not sure what's happening here. It's not *really* that important to me, but it would be nice to have the option of killing that process later.
Any ideas? Am I doing something wrong???
Weird. Adding a single line like this;
class Forkable { // I am a process fun void run() { // sporkable code here... SinOsc s => dac; 100::ms => now;
//unchuck! s =< dac; me.yield(); } }
Makes the first example behave as well. The difference seems to be that the SinOsc's aren't automatically unchucked from the dac when the their shred exits in the first example.... and this seems due to the existance of that reference. This leads to clipping and a high cpu load, resulting in that weird noise because you are still creating 20 SinOsc's per second.
My bet would be that this might be a case of reference counting gone wrong. At least it's fixable with a manual unchuck though it's quite odd that SinOsc's that aren't attached to a Shred can keep running. In fact; with my edit of the Forkable class I can start your code, stop it, and often a tone will keep sounding without a single shred running (!!!).
Strange stuff, good catch!
Yours, Kas.
_______________________________________________ chuck-users mailing list chuck-users@lists.cs.princeton.edu https://lists.cs.princeton.edu/mailman/listinfo/chuck-users
-- http://semiotech.org http://deadlylittlepills.com/michael
2008/6/13 mike clemow
Yes, I forgot to mention that! Crazy... I guess I'll manually unchuck the SinOsc for now. I'll have to check if that happens with other UGens...
Unchucking unused Ugens it good form anyway. Wherever you can afford to I'd do that because it saves CPU. IT tisn0/t alway appropriate because with some Ugens or systems of Ugens the code need not be aware of when the Ugen is "done", for example with the physical models in the STK.
Meanwhile, if I unchuck that SinOsc from the dac it works in the sense that the SinOsc objects don't add up, however, only if the shreds finish executing. If I remove the parent while one of the sporked shreds is still running, one sine keeps going. Ostensibly because the last shred hasn't finished and the unchuck line hasn't run. This makes me really wish I could define code that would be called when a shred exits. That would be a neat feature...
Yes, quite weird and I can't remember this being like that in the past. This is truely arcane stuff and likely only Ge knows.... But I have a suspicion. Clearly a outside reference to a shred affects how it deals with cleanup. I suspect this has to do with Ge having been working at garbage collection (which also works with references... or at least will). I suspect what we are seeing might be a trace of the start of a GC framework. In that case we found a bug in a feature that's not even here yet... That would be quite funny. Disclaimer; this is complete speculation and not of any practical use. Code to be run when a shred exits is a interesting idea but I suspect it's asking for trouble. Because a shred has it's own namespace which is obviously gone when the shred is such code would probably need to be run *before* it exits and after it get's it's exit notice.... but then what if this code does stuff like advance time or (worse yet!) call for the exit of the same shred? I suspect this would be asking for stuck VM's and confused shredulers. I'd rather have proper cleanup. I'd also be quite interested in Shred type objects giving access to that shred's name-space like this; fun void foo() { 3 => int value; while (second => now) <<< value >>>>; } spork ~ foo() @=> Shred bar; 4::second => now; //modest proposal starts here 5 => bar.value; hour => now; This would also enable us to run manual cleanup; either from the last lines of the shred's code (asuming it's not a infinite loop) or from the shred that calls for it's exit, right before the exit call. Kas.
I'd also be quite interested in Shred type objects giving access to that shred's name-space
I guess even using the public keyword for sporked shreds (if functions
ever become objects ;-) for some kind of global access to the
namespace, maybe?
public fun void foo()
{
5 => int value;
while (second => now) <<< value >>>>;
}
spork ~ foo() @=> Shred bar;
4::second => now;
3 => bar.value;
week => now;
Of course, we'd have to distinguish between a "public" and a "fun" first. ;-)
-Mike
On Fri, Jun 13, 2008 at 11:17 AM, Kassen
2008/6/13 mike clemow
: Yes, I forgot to mention that! Crazy... I guess I'll manually unchuck the SinOsc for now. I'll have to check if that happens with other UGens...
Unchucking unused Ugens it good form anyway. Wherever you can afford to I'd do that because it saves CPU. IT tisn0/t alway appropriate because with some Ugens or systems of Ugens the code need not be aware of when the Ugen is "done", for example with the physical models in the STK.
Meanwhile, if I unchuck that SinOsc from the dac it works in the sense that the SinOsc objects don't add up, however, only if the shreds finish executing. If I remove the parent while one of the sporked shreds is still running, one sine keeps going. Ostensibly because the last shred hasn't finished and the unchuck line hasn't run. This makes me really wish I could define code that would be called when a shred exits. That would be a neat feature...
Yes, quite weird and I can't remember this being like that in the past. This is truely arcane stuff and likely only Ge knows.... But I have a suspicion. Clearly a outside reference to a shred affects how it deals with cleanup. I suspect this has to do with Ge having been working at garbage collection (which also works with references... or at least will). I suspect what we are seeing might be a trace of the start of a GC framework. In that case we found a bug in a feature that's not even here yet... That would be quite funny.
Disclaimer; this is complete speculation and not of any practical use.
Code to be run when a shred exits is a interesting idea but I suspect it's asking for trouble. Because a shred has it's own namespace which is obviously gone when the shred is such code would probably need to be run *before* it exits and after it get's it's exit notice.... but then what if this code does stuff like advance time or (worse yet!) call for the exit of the same shred? I suspect this would be asking for stuck VM's and confused shredulers. I'd rather have proper cleanup. I'd also be quite interested in Shred type objects giving access to that shred's name-space like this;
fun void foo() { 3 => int value; while (second => now) <<< value >>>>; }
spork ~ foo() @=> Shred bar;
4::second => now;
//modest proposal starts here 5 => bar.value; hour => now;
This would also enable us to run manual cleanup; either from the last lines of the shred's code (asuming it's not a infinite loop) or from the shred that calls for it's exit, right before the exit call.
Kas.
_______________________________________________ chuck-users mailing list chuck-users@lists.cs.princeton.edu https://lists.cs.princeton.edu/mailman/listinfo/chuck-users
-- http://semiotech.org http://deadlylittlepills.com/michael
mike clemow:
I guess even using the public keyword for sporked shreds (if functions ever become objects ;-) for some kind of global access to the namespace, maybe?
Well... A "Shred" is already a class and a object... ====================== public class Foo extends Shred { //stuff } =============== ...is entirely legal, it just won't do anything useful, more or less like extending a Ugen; it'll parse and compile as a class but gives errors once you try using it.
Of course, we'd have to distinguish between a "public" and a "fun" first. ;-)
Yeah... and garbage collection, and....
There's this rhyme my father used to say to me. It's untranslatable to English but 'd summarise it as "desire keeps one going" (or maybe "keeps us going"). ;¬) Have a nice weekend, Kas.
participants (2)
-
Kassen
-
mike clemow