about summary refs log tree commit diff stats
path: root/039wait.cc
diff options
context:
space:
mode:
authorKartik K. Agaram <vc@akkartik.com>2015-05-07 10:38:19 -0700
committerKartik K. Agaram <vc@akkartik.com>2015-05-07 10:38:19 -0700
commit1179f0d456004bf0a7edd92fc083047ac8992801 (patch)
tree225e4887d8284ab359096a08a1896bf1ca77113a /039wait.cc
parentc6e1041fa419461aacaf853c8040144bd52b0b5d (diff)
downloadmu-1179f0d456004bf0a7edd92fc083047ac8992801.tar.gz
1295 - broken snapshot
I spent a couple of hours debugging this because routine-state only
sometimes writes to its product. This is unacceptable. Fix this first.
Diffstat (limited to '039wait.cc')
-rw-r--r--039wait.cc24
1 files changed, 17 insertions, 7 deletions
diff --git a/039wait.cc b/039wait.cc
index 940cba89..b6d4fc18 100644
--- a/039wait.cc
+++ b/039wait.cc
@@ -41,6 +41,7 @@ case WAIT_FOR_LOCATION: {
   Current_routine->waiting_on_location = loc.value;
   Current_routine->old_value_of_wating_location = Memory[loc.value];
   trace("run") << "waiting for location " << loc.value << " to change from " << Memory[loc.value];
+  trace("schedule") << Current_routine->id << ": waiting for location " << loc.value << " to change from " << Memory[loc.value];
   break;
 }
 
@@ -48,16 +49,21 @@ case WAIT_FOR_LOCATION: {
 
 :(before "End Scheduler State Transitions")
 for (index_t i = 0; i < Routines.size(); ++i) {
+  trace("schedule") << "wake up loop 1: routine " << Routines[i]->id << " has state " << Routines[i]->state;
   if (Routines[i]->state != WAITING) continue;
-  if (Memory[Routines[i]->waiting_on_location] &&
+  trace("schedule") << "waiting on location: " << Routines[i]->waiting_on_location;
+  if (Routines[i]->waiting_on_location)
+    trace("schedule") << "checking routine " << Routines[i]->id << " waiting on location "
+      << Routines[i]->waiting_on_location << ": " << Memory[Routines[i]->waiting_on_location] << " vs " << Routines[i]->old_value_of_wating_location;
+  if (Routines[i]->waiting_on_location &&
       Memory[Routines[i]->waiting_on_location] != Routines[i]->old_value_of_wating_location) {
-    trace("schedule") << "waking up routine\n";
+    trace("schedule") << Current_routine->id << ": waking up routine " << Routines[i]->id << " waiting on location " << Routines[i]->waiting_on_location;
     Routines[i]->state = RUNNING;
     Routines[i]->waiting_on_location = Routines[i]->old_value_of_wating_location = 0;
   }
 }
 
-//: also allow waiting on a routine
+//: also allow waiting on a routine to stop running
 
 :(scenario wait_for_routine)
 recipe f1 [
@@ -89,18 +95,22 @@ case WAIT_FOR_ROUTINE: {
   Current_routine->state = WAITING;
   Current_routine->waiting_on_routine = loc.value;
   trace("run") << "waiting for routine " << loc.value;
+  trace("schedule") << Current_routine->id << ": waiting for routine " << loc.value;
   break;
 }
 
 :(before "End Scheduler State Transitions")
+// Wake up any routines waiting for other routines to go to sleep.
+// Important: this must come after the scheduler loop above giving routines
+// waiting for locations to change a chance to wake up.
 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);
+  index_t target = Routines[i]->waiting_on_routine;
+  assert(target != 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";
+    if (Routines[j]->id == target && Routines[j]->state != RUNNING) {
+      trace("schedule") << "waking up routine " << Routines[i]->id << " waiting on routine " << target;
       Routines[i]->state = RUNNING;
       Routines[i]->waiting_on_routine = 0;
     }