diff options
author | Kartik K. Agaram <vc@akkartik.com> | 2015-04-27 01:42:07 -0700 |
---|---|---|
committer | Kartik K. Agaram <vc@akkartik.com> | 2015-04-27 01:42:07 -0700 |
commit | c76b49e74ad8b66ac2c077dc0da62c2846131585 (patch) | |
tree | 758505eb3b1200fd07a7228b8f55b36e8e7a18cd /cpp/039wait.cc | |
parent | 08004ec84b755291e5b177748a659b7200c5b5a6 (diff) | |
download | mu-c76b49e74ad8b66ac2c077dc0da62c2846131585.tar.gz |
1206 - 'wait' state for synchronizing routines
I think I have enough now to port channels over.
Diffstat (limited to 'cpp/039wait.cc')
-rw-r--r-- | cpp/039wait.cc | 57 |
1 files changed, 57 insertions, 0 deletions
diff --git a/cpp/039wait.cc b/cpp/039wait.cc new file mode 100644 index 00000000..eba3a437 --- /dev/null +++ b/cpp/039wait.cc @@ -0,0 +1,57 @@ +//: Routines can be put in a 'waiting' state, from which it will be ready to +//: run again when a specific memory location changes its value. This is mu's +//: basic technique for orchestrating the order in which different routines +//: operate. + +:(scenario "stalled_routine") +recipe f1 [ + 1:integer <- copy 0:literal + run f2:recipe + wait-for-location 1:integer + # now wait for f2 to run and modify location 1 before using its value + 2:integer <- copy 1:integer +] +recipe f2 [ + 1:integer <- copy 34:literal +] +# if we got the synchronization wrong we'd be storing 0 in location 2 ++mem: storing 34 in location 2 + +//: define the new state that all routines can be in + +:(before "End routine States") +WAITING, +:(before "End routine Fields") +// only if state == WAITING +size_t waiting_on_location; +int old_value_of_wating_location; +:(before "End routine Constructor") +waiting_on_location = old_value_of_wating_location = 0; + +//: primitive recipe to put routines in that state + +:(before "End Primitive Recipe Declarations") +WAIT_FOR_LOCATION, +:(before "End Primitive Recipe Numbers") +Recipe_number["wait-for-location"] = WAIT_FOR_LOCATION; +:(before "End Primitive Recipe Implementations") +case WAIT_FOR_LOCATION: { + reagent loc = canonize(current_instruction().ingredients[0]); + Current_routine->state = WAITING; + Current_routine->waiting_on_location = loc.value; + Current_routine->old_value_of_wating_location = Memory[loc.value]; + trace("run") << "waiting for " << loc.value << " to change from " << Memory[loc.value]; + break; +} + +//: scheduler tweak to get routines out of that state + +:(before "End Scheduler State Transitions") +for (size_t i = 0; i < Routines.size(); ++i) { + if (Routines[i]->state != WAITING) continue; + if (Memory[Routines[i]->waiting_on_location] != Routines[i]->old_value_of_wating_location) { + trace("schedule") << "waking up routine\n"; + Routines[i]->state = RUNNING; + Routines[i]->waiting_on_location = Routines[i]->old_value_of_wating_location = 0; + } +} |