I am working on a complete rewrite of my Masking package (the original was too bulky and dependant on creating hundreds of shreds), and was wondering just how something is scheduled in ChucK. Basically, I am trying to create a single shred that handles the updating of various parameters (as opposed to the original which had a shred for each parameter), and in doing so, I would like to create a "locking" mechanism around an array used to control which parameters get updated, and when. On one shred, there is the code that controlls the updating of parameters, this shred runs for the life of the program (or some portion of). On the second shred (most likely the main shred), the array containing the references to the parameters to be updated needs to be locked to prevent having a new reference added while the first shred is actually updating the parameters. (Does this make sense?) So, what I would like to know is how the following code would execute. now + 0::ms => now; Would this push the execution of the code to follow to the end of the current time slice? Or is this functionality undefined, and would it execute these shreds in an arbitrary fashion? In a nut shell, this is the code from the updating shred that locks the array... (this is embedded in an object) false => int locked; false => int keepGoing; MController @ controllers[]; // this gets initialized to match the number of controlled parameters fun void helper(....) { true => keepGoing; while(keepGoing) { while(locked) { now + 0::ms => now; } true => locked; for(0 => int i; i < controllers.cap(); i++) { if (controllers[i] != null) { <<< "do something with this controller", "" >>>; } } false => locked; } } The variable 'locked' controlls the access to the 'for' loop, and the variable 'keepGoing' controlls the outer loop. 'keepGoing' is set to true at the top of this code, but will be set to false by another shred to force the 'helper' function to exit as needed. The array 'controllers' is accessed by both this shred, as well as the main shred to add extra parameters to the 'helper' shred. Wow, this was probably a roundabout way to ask this question, but I hope it is comprehensible... Thanks, Mike -- Help the Environment, Plant a Bush back in Texas!
Howdy, On Jun 12, 2006, at 2:44 PM, Mike McGonagle wrote:
So, what I would like to know is how the following code would execute.
now + 0::ms => now;
Would this push the execution of the code to follow to the end of the current time slice? Or is this functionality undefined, and would it execute these shreds in an arbitrary fashion?
Im not sure what that would do, but check out me.yield(), I think that serves exactly such a purpose.
(this is embedded in an object) false => int locked; false => int keepGoing; MController @ controllers[]; // this gets initialized to match the number of controlled parameters
fun void helper(....) { true => keepGoing; while(keepGoing) { while(locked) { now + 0::ms => now; } true => locked; for(0 => int i; i < controllers.cap(); i++) { if (controllers[i] != null) { <<< "do something with this controller", "" >>>; } } false => locked; } }
Hmm, i see a few potential issues here. helper() never allows for the passage of time, which might be a problem, unless keepGoing is set to false relatively quickly. If time doesnt advance within the helper shred, time cant advance for other shreds. Secondly, I dont think your locking mechanism is guaranteed to work all of the time. In this code:
while(locked) { now + 0::ms => now; } // point A true => locked;
what if another shred is scheduled to execute at point A? Say this shred is also waiting on locked; when it is scheduled to execute, locked is false, so it exits from the while loop. Both shreds would then proceed as if they had acquired the lock, which is probably undesirable. Its not really possible to write a reliable mutex using standard control structures and variables. It might be possible using Events, but I think they are really something that should be provided by the ChucK language (feature request!). Until that happens, I would recommend trying to use Events somehow... spencer
Thank you, Spencer, while my post was probably a little disjointed,
and my code example did have the missing time settings (I forgot it in
my haste), I think you are right about looking into using events.
Guess it is time for a little more study on events.
And as far as the request for the mutex stuff in ChucK, might the
"synchronize" keyword from Java do the trick? (Yes, I know it is not
that simple, but at least it is a model to follow).
Thanks again,
Mike
On 6/12/06, Spencer Salazar
Howdy,
On Jun 12, 2006, at 2:44 PM, Mike McGonagle wrote:
So, what I would like to know is how the following code would execute.
now + 0::ms => now;
Would this push the execution of the code to follow to the end of the current time slice? Or is this functionality undefined, and would it execute these shreds in an arbitrary fashion?
Im not sure what that would do, but check out me.yield(), I think that serves exactly such a purpose.
(this is embedded in an object) false => int locked; false => int keepGoing; MController @ controllers[]; // this gets initialized to match the number of controlled parameters
fun void helper(....) { true => keepGoing; while(keepGoing) { while(locked) { now + 0::ms => now; } true => locked; for(0 => int i; i < controllers.cap(); i++) { if (controllers[i] != null) { <<< "do something with this controller", "" >>>; } } false => locked; } }
Hmm, i see a few potential issues here. helper() never allows for the passage of time, which might be a problem, unless keepGoing is set to false relatively quickly. If time doesnt advance within the helper shred, time cant advance for other shreds.
Secondly, I dont think your locking mechanism is guaranteed to work all of the time. In this code:
while(locked) { now + 0::ms => now; } // point A true => locked;
what if another shred is scheduled to execute at point A? Say this shred is also waiting on locked; when it is scheduled to execute, locked is false, so it exits from the while loop. Both shreds would then proceed as if they had acquired the lock, which is probably undesirable.
Its not really possible to write a reliable mutex using standard control structures and variables. It might be possible using Events, but I think they are really something that should be provided by the ChucK language (feature request!). Until that happens, I would recommend trying to use Events somehow...
spencer
_______________________________________________ chuck-users mailing list chuck-users@lists.cs.princeton.edu https://lists.cs.princeton.edu/mailman/listinfo/chuck-users
-- Help the Environment, Plant a Bush back in Texas!
Hello all, I have read through the stuff on events (and it seems quite limited in documentation and examples), and thought that there was no way that I could use events to handle the scheduling of additional mask controls. But, it kind of dawned on me, that MAYBE, if I put a call to 'me.yield()' at the top of the control shreds loop that it would delay the execution of the body of the loop to the end of the time-slice. So, now the 'helper' function would look like... fun void helper(....) { true => keepGoing; while(keepGoing) { me.yield(); for(0 => int i; i < controllers.cap(); i++) { if (controllers[i] != null) { <<< "do something with this controller", "" >>>; } } now + control_period => now; } } (control_period is assumed to be some arbitrary duration value) Would this still be too much of an assumption that there wouldn't be any data-collisions between shreds? The reason that I am having a hard time with this, is that I can't figure out how to send an event to another shred, without forcing the receiving shred to "wait" on that event. The control shred needs to be able to continue execution to handle the actual changing of the parameters used by the masks. Are there any examples of using events that do not require a shred to 'wait' on a scheduled event? Thanks, Mike -- Help the Environment, Plant a Bush back in Texas! "I place economy among the first and most important republican virtues, and public debt as the greatest of the dangers to be feared. To preserve our independence, we must not let our rulers load us with perpetual debt." -- Thomas Jefferson, third US president, architect and author (1743-1826)
participants (2)
-
Mike McGonagle
-
Spencer Salazar