about summary refs log blame commit diff stats
path: root/cpp/038scheduler.cc
blob: d35d853d5633a416071f6a1cff68590d8658213d (plain) (tree)
1
2
3
4
5
6
7
8
9
10
11
12
13

                                                                           
 
                     








                             
 

                                                                                               

                                           
                                                                                                          
                   
                                                             

                                  




                                                    

                          











                                                    
                           





















                                                                                                    





















                                          
//: Run a second routine concurrently using fork, without any guarantees on
//: how the operations in each are interleaved with each other.

:(scenario scheduler)
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(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)")
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;
:(before "End Setup")
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);
    Current_routine = NULL;
  }
}

:(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;
}

:(scenario scheduler_interleaves_routines)
% Scheduling_interval = 1;
recipe f1 [
  run f2:recipe
  1:integer <- copy 0:literal
  2:integer <- copy 0:literal
]
recipe f2 [
  3:integer <- copy 4:literal
  4:integer <- copy 4:literal
]
+schedule: f1
+run: instruction f1/0
+schedule: f2
+run: instruction f2/0
+schedule: f1
+run: instruction f1/1
+schedule: f2
+run: instruction f2/1
+schedule: f1
+run: instruction f1/2