diff options
Diffstat (limited to 'cpp/038scheduler')
-rw-r--r-- | cpp/038scheduler | 65 |
1 files changed, 53 insertions, 12 deletions
diff --git a/cpp/038scheduler b/cpp/038scheduler index 08be7821..7645a315 100644 --- a/cpp/038scheduler +++ b/cpp/038scheduler @@ -1,17 +1,19 @@ -//: Run multiple routines concurrently, without any guarantees on how the -//: operations in each are interleaved with each other. +//: Run a second routine concurrently using fork, without any guarantees on +//: how the operations in each are interleaved with each other. -:(before "End Globals") -size_t Scheduling_interval = 500; +:(scenario run) +recipe f1 [ + run f2:recipe + 1:integer <- copy 3:literal +] +recipe f2 [ + 2:integer <- copy 4:literal +] ++schedule: f1 ++schedule: f2 -//: first, add a deadline to run() -//: todo: these changes are ugly and brittle -:(replace{} "void run(recipe_number r)") -void run(recipe_number r) { - routine rr(r); - Current_routine = &rr; - run_current_routine(Scheduling_interval); -} +//: first, add a deadline to run(routine) +//: these changes are ugly and brittle; just close your nose and get through the next few lines :(replace "void run_current_routine()") void run_current_routine(size_t time_slice) :(replace "while (!Current_routine->completed())" following "void run_current_routine(size_t time_slice)") @@ -19,3 +21,42 @@ size_t ninstrs = 0; while (!Current_routine->completed() && ninstrs < time_slice) :(after "Running One Instruction") ninstrs++; + +//: now the rest of the scheduler is clean +:(before "End Globals") +list<routine*> Running_routines, Completed_routines; +size_t Scheduling_interval = 500; +:(replace{} "void run(recipe_number r)") +void run(recipe_number r) { + Running_routines.push_back(new routine(r)); + while (!Running_routines.empty()) { + Current_routine = Running_routines.front(); + Running_routines.pop_front(); + trace("schedule") << current_recipe_name(); + run_current_routine(Scheduling_interval); + if (Current_routine->calls.empty()) + Completed_routines.push_back(Current_routine); + else + Running_routines.push_back(Current_routine); + } +} + +:(before "End Teardown") +for (list<routine*>::iterator p = Running_routines.begin(); p != Running_routines.end(); ++p) + delete *p; +Running_routines.clear(); +for (list<routine*>::iterator p = Completed_routines.begin(); p != Completed_routines.end(); ++p) + delete *p; +Completed_routines.clear(); + +:(before "End Primitive Recipe Declarations") +RUN, +:(before "End Primitive Recipe Numbers") +Recipe_number["run"] = RUN; +:(before "End Primitive Recipe Implementations") +case RUN: { + trace("run") << "ingredient 0 is " << current_instruction().ingredients[0].name; + assert(!current_instruction().ingredients[0].initialized); + Running_routines.push_back(new routine(Recipe_number[current_instruction().ingredients[0].name])); + break; +} |