diff options
author | Kartik K. Agaram <vc@akkartik.com> | 2015-05-02 11:49:11 -0700 |
---|---|---|
committer | Kartik K. Agaram <vc@akkartik.com> | 2015-05-02 11:49:11 -0700 |
commit | d9a7e6abc7dba8e84a5e80a6593145f1aaeb6f6c (patch) | |
tree | af2345c92315d623124d5612931914c54042a42b | |
parent | 981cc9e8e9fd2f76b4dced8b88f3dac41c87d761 (diff) | |
download | mu-d9a7e6abc7dba8e84a5e80a6593145f1aaeb6f6c.tar.gz |
1239 - scheduler bugfix
In the process, some extra unit tests as well. The final scenario is newly fixed. Between the earlier support for '%' escaping C code inside scenarios, and the previous commit, we now actually have the ability to setup the Routines data structure just so to simulate different situations. One unanticipated but happy consequence of ignoring run(""): I can interleave '+' lines with '-' lines to avoid making any ordering assertions between '+' lines. So the '+' lines here are checked in order: +layer1: a +layer3: c But here they will pass even if present out of order: +layer1: a -layer2: b +layer3: c This might be too confusing. In general, relying on run("") is just a temporary hack. It might well have even worse counter-intuitive effects. At least I'm not seeing any string-escaping issues so far.
-rw-r--r-- | cpp/.traces/scheduler_runs_single_routine | 21 | ||||
-rw-r--r-- | cpp/.traces/scheduler_skips_completed_routines | 28 | ||||
-rw-r--r-- | cpp/.traces/scheduler_starts_at_middle_of_routines | 20 | ||||
-rw-r--r-- | cpp/038scheduler.cc | 49 |
4 files changed, 117 insertions, 1 deletions
diff --git a/cpp/.traces/scheduler_runs_single_routine b/cpp/.traces/scheduler_runs_single_routine new file mode 100644 index 00000000..8f5d7102 --- /dev/null +++ b/cpp/.traces/scheduler_runs_single_routine @@ -0,0 +1,21 @@ +parse/0: instruction: copy +parse/0: ingredient: {name: "0", value: 0, type: 0, properties: ["0": "literal"]} +parse/0: product: {name: "1", value: 0, type: 1, properties: ["1": "integer"]} +parse/0: instruction: copy +parse/0: ingredient: {name: "0", value: 0, type: 0, properties: ["0": "literal"]} +parse/0: product: {name: "2", value: 0, type: 1, properties: ["2": "integer"]} +after-brace/0: recipe f1 +after-brace/0: copy ... +after-brace/0: copy ... +new/0: routine allocated memory from 1000 to 101000 +schedule/0: f1 +run/0: instruction f1/0 +run/0: {name: "1", value: 1, type: 1, properties: ["1": "integer"]} <- copy {name: "0", value: 0, type: 0, properties: ["0": "literal"]} +run/0: ingredient 0 is 0 +mem/0: storing 0 in location 1 +schedule/0: f1 +run/0: instruction f1/1 +run/0: {name: "2", value: 2, type: 1, properties: ["2": "integer"]} <- copy {name: "0", value: 0, type: 0, properties: ["0": "literal"]} +run/0: ingredient 0 is 0 +mem/0: storing 0 in location 2 +schedule/0: f1 diff --git a/cpp/.traces/scheduler_skips_completed_routines b/cpp/.traces/scheduler_skips_completed_routines new file mode 100644 index 00000000..9e609d02 --- /dev/null +++ b/cpp/.traces/scheduler_skips_completed_routines @@ -0,0 +1,28 @@ +parse/0: instruction: copy +parse/0: ingredient: {name: "0", value: 0, type: 0, properties: ["0": "literal"]} +parse/0: product: {name: "1", value: 0, type: 1, properties: ["1": "integer"]} +parse/0: instruction: copy +parse/0: ingredient: {name: "0", value: 0, type: 0, properties: ["0": "literal"]} +parse/0: product: {name: "2", value: 0, type: 1, properties: ["2": "integer"]} +new/0: routine allocated memory from 1000 to 101000 +new/0: routine allocated memory from 101000 to 201000 +parse/0: instruction: copy +parse/0: ingredient: {name: "0", value: 0, type: 0, properties: ["0": "literal"]} +parse/0: product: {name: "3", value: 0, type: 1, properties: ["3": "integer"]} +after-brace/0: recipe f1 +after-brace/0: copy ... +after-brace/0: recipe f2 +after-brace/0: copy ... +after-brace/0: recipe f3 +after-brace/0: copy ... +new/0: routine allocated memory from 201000 to 301000 +schedule/0: f3 +run/0: instruction f3/0 +run/0: {name: "3", value: 3, type: 1, properties: ["3": "integer"]} <- copy {name: "0", value: 0, type: 0, properties: ["0": "literal"]} +run/0: ingredient 0 is 0 +mem/0: storing 0 in location 3 +schedule/0: f1 +run/0: instruction f1/0 +run/0: {name: "1", value: 1, type: 1, properties: ["1": "integer"]} <- copy {name: "0", value: 0, type: 0, properties: ["0": "literal"]} +run/0: ingredient 0 is 0 +mem/0: storing 0 in location 1 diff --git a/cpp/.traces/scheduler_starts_at_middle_of_routines b/cpp/.traces/scheduler_starts_at_middle_of_routines new file mode 100644 index 00000000..2c35f427 --- /dev/null +++ b/cpp/.traces/scheduler_starts_at_middle_of_routines @@ -0,0 +1,20 @@ +new/0: routine allocated memory from 1000 to 101000 +parse/0: instruction: copy +parse/0: ingredient: {name: "0", value: 0, type: 0, properties: ["0": "literal"]} +parse/0: product: {name: "1", value: 0, type: 1, properties: ["1": "integer"]} +parse/0: instruction: copy +parse/0: ingredient: {name: "0", value: 0, type: 0, properties: ["0": "literal"]} +parse/0: product: {name: "2", value: 0, type: 1, properties: ["2": "integer"]} +after-brace/0: recipe f1 +after-brace/0: copy ... +after-brace/0: copy ... +new/0: routine allocated memory from 101000 to 201000 +schedule/0: f1 +run/0: instruction f1/0 +run/0: {name: "1", value: 1, type: 1, properties: ["1": "integer"]} <- copy {name: "0", value: 0, type: 0, properties: ["0": "literal"]} +run/0: ingredient 0 is 0 +mem/0: storing 0 in location 1 +run/0: instruction f1/1 +run/0: {name: "2", value: 2, type: 1, properties: ["2": "integer"]} <- copy {name: "0", value: 0, type: 0, properties: ["0": "literal"]} +run/0: ingredient 0 is 0 +mem/0: storing 0 in location 2 diff --git a/cpp/038scheduler.cc b/cpp/038scheduler.cc index 3550ff1f..6e3f74b8 100644 --- a/cpp/038scheduler.cc +++ b/cpp/038scheduler.cc @@ -46,6 +46,8 @@ void run(recipe_number r) { Routines.push_back(new routine(r)); Current_routine_index = 0, Current_routine = Routines[0]; while (!all_routines_done()) { + skip_to_next_routine(); +//? cout << "scheduler: " << Current_routine_index << '\n'; //? 1 assert(Current_routine); assert(Current_routine->state == RUNNING); trace("schedule") << current_recipe_name(); @@ -53,13 +55,14 @@ void run(recipe_number r) { if (Current_routine->completed()) Current_routine->state = COMPLETED; // End Scheduler State Transitions - skip_to_next_routine(); } +//? cout << "done with run\n"; //? 1 } :(code) bool all_routines_done() { for (size_t i = 0; i < Routines.size(); ++i) { +//? cout << "routine " << i << ' ' << Routines[i]->state << '\n'; //? 1 if (Routines[i]->state == RUNNING) { return false; } @@ -73,11 +76,13 @@ void skip_to_next_routine() { assert(Current_routine_index < Routines.size()); for (size_t i = (Current_routine_index+1)%Routines.size(); i != Current_routine_index; i = (i+1)%Routines.size()) { if (Routines[i]->state == RUNNING) { +//? cout << "switching to " << i << '\n'; //? 1 Current_routine_index = i; Current_routine = Routines[i]; return; } } +//? cout << "all done\n"; //? 1 } :(before "End Teardown") @@ -97,6 +102,17 @@ case START_RUNNING: { break; } +:(scenario scheduler_runs_single_routine) +% Scheduling_interval = 1; +recipe f1 [ + 1:integer <- copy 0:literal + 2:integer <- copy 0:literal +] ++schedule: f1 ++run: instruction f1/0 ++schedule: f1 ++run: instruction f1/1 + :(scenario scheduler_interleaves_routines) % Scheduling_interval = 1; recipe f1 [ @@ -118,3 +134,34 @@ recipe f2 [ +run: instruction f2/1 +schedule: f1 +run: instruction f1/2 + +:(scenario scheduler_skips_completed_routines) +# this scenario will require some careful setup in escaped C++ +# (straining our tangle capabilities to near-breaking point) +% recipe_number f1 = load("recipe f1 [\n1:integer <- copy 0:literal\n]").front(); +% recipe_number f2 = load("recipe f2 [\n2:integer <- copy 0:literal\n]").front(); +% Routines.push_back(new routine(f1)); // f1 meant to run +% Routines.push_back(new routine(f2)); +% Routines.back()->state = COMPLETED; // f2 not meant to run +#? % Trace_stream->dump_layer = "all"; +# must have at least one routine without escaping +recipe f3 [ + 3:integer <- copy 0:literal +] +# by interleaving '+' lines with '-' lines, we allow f1 and f3 to run in any order ++schedule: f1 ++mem: storing 0 in location 1 +-schedule: f2 +-mem: storing 0 in location 2 ++schedule: f3 ++mem: storing 0 in location 3 + +:(scenario scheduler_starts_at_middle_of_routines) +% Routines.push_back(new routine(COPY)); +% Routines.back()->state = COMPLETED; +recipe f1 [ + 1:integer <- copy 0:literal + 2:integer <- copy 0:literal +] ++schedule: f1 +-run: idle |