diff options
author | Kartik K. Agaram <vc@akkartik.com> | 2015-05-07 10:38:19 -0700 |
---|---|---|
committer | Kartik K. Agaram <vc@akkartik.com> | 2015-05-07 10:38:19 -0700 |
commit | 1179f0d456004bf0a7edd92fc083047ac8992801 (patch) | |
tree | 225e4887d8284ab359096a08a1896bf1ca77113a /039wait.cc | |
parent | c6e1041fa419461aacaf853c8040144bd52b0b5d (diff) | |
download | mu-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.cc | 24 |
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; } |