about summary refs log tree commit diff stats
path: root/cpp/038scheduler
diff options
context:
space:
mode:
Diffstat (limited to 'cpp/038scheduler')
-rw-r--r--cpp/038scheduler65
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;
+}