diff options
Diffstat (limited to 'cpp/039wait.cc')
-rw-r--r-- | cpp/039wait.cc | 56 |
1 files changed, 54 insertions, 2 deletions
diff --git a/cpp/039wait.cc b/cpp/039wait.cc index b9208590..940cba89 100644 --- a/cpp/039wait.cc +++ b/cpp/039wait.cc @@ -40,7 +40,7 @@ case WAIT_FOR_LOCATION: { 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]; + trace("run") << "waiting for location " << loc.value << " to change from " << Memory[loc.value]; break; } @@ -49,9 +49,61 @@ case WAIT_FOR_LOCATION: { :(before "End Scheduler State Transitions") for (index_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) { + if (Memory[Routines[i]->waiting_on_location] && + 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; } } + +//: also allow waiting on a routine + +:(scenario wait_for_routine) +recipe f1 [ + 1:integer <- copy 0:literal + 2:integer/routine <- start-running f2:recipe + wait-for-routine 2:integer/routine + # now wait for f2 to run and modify location 1 before using its value + 3:integer <- copy 1:integer +] +recipe f2 [ + 1:integer <- copy 34:literal +] +# if we got the synchronization wrong we'd be storing 0 in location 3 ++mem: storing 34 in location 3 + +:(before "End routine Fields") +// only if state == WAITING +index_t waiting_on_routine; +:(before "End routine Constructor") +waiting_on_routine = 0; + +:(before "End Primitive Recipe Declarations") +WAIT_FOR_ROUTINE, +:(before "End Primitive Recipe Numbers") +Recipe_number["wait-for-routine"] = WAIT_FOR_ROUTINE; +:(before "End Primitive Recipe Implementations") +case WAIT_FOR_ROUTINE: { + reagent loc = canonize(current_instruction().ingredients[0]); + Current_routine->state = WAITING; + Current_routine->waiting_on_routine = loc.value; + trace("run") << "waiting for routine " << loc.value; + break; +} + +:(before "End Scheduler State Transitions") +for (index_t i = 0; i < Routines.size(); ++i) { + if (Routines[i]->state != WAITING) continue; + if (!Routines[i]->waiting_on_routine) continue; + index_t id = Routines[i]->waiting_on_routine; + assert(id != i); + for (index_t j = 0; j < Routines.size(); ++j) { + if (Routines[j]->id == id && Routines[j]->state != WAITING) { + trace("schedule") << "waking up routine\n"; + Routines[i]->state = RUNNING; + Routines[i]->waiting_on_routine = 0; + } + } +} + |