diff --git a/src/backend/scheduler.cc b/src/backend/scheduler.cc index fe0c374..f41c8bc 100644 --- a/src/backend/scheduler.cc +++ b/src/backend/scheduler.cc @@ -403,10 +403,45 @@ Scheduler::step_forward(History& history, CPUPolicy& cpu_policy, ResourcePolicy& collect_threads(new_snapshot->get_processes(), all_threads); + // The first thing we've to do is to update the state of the old + // running thread, if there's one. + for (Iseq it = iseq(all_threads); it; ++it) + { + DynamicThread& current = **it; + + // Save the current running thread for future usage, if it hasn't ended + // its allotted time + if (current.get_state() == Schedulable::state_running) + { + running_thread = ¤t; // Even if we can change its state to terminate + + // increasing the time elapsed of the running thread + process + // should be done here as the first thing, instead than + // directly after selecting them + if (current.get_total_cpu_time() - current.get_elapsed_time() > 0) + current.decrease_remaining_time(); + + // 4a. Look for exhausted requests for the running thread + update_allocated_requests(current, *new_snapshot); + + // 2. mark threads that used all their allotted time as terminated, + // and put their requests as exhausted + if (current.get_total_cpu_time() - current.get_elapsed_time() == 0) + { + current.set_state(Schedulable::state_terminated); + terminate_all_requests_of(current, *new_snapshot); + } + + // if we found the running thread, there isn't another one, + // so we can safely exit the for loop. + break; + + } //~ if state == running + } //~ for over all threads + + // When a new instant cames, we could have to update the state of future - // threads to make them ready, or running threads to make them terminated - // We also update the other properties of the running thread, and keep a - // count of the alive threads + // threads to make them ready. We also keep a count of alive threads for (Iseq it = iseq(all_threads); it; ++it) { DynamicThread& current = **it; @@ -419,32 +454,7 @@ Scheduler::step_forward(History& history, CPUPolicy& cpu_policy, ResourcePolicy& parent.get_elapsed_time() == current.get_arrival_time()) current.set_state(Schedulable::state_ready); } - - // Save the current running thread for future usage, if it hasn't ended - // its allotted time - if (current.get_state() == Schedulable::state_running) - { - assert(running_thread == NULL); // ... only one thread must be running at a time. - running_thread = ¤t; // Even if we can change its state to terminate - - // increasing the time elapsed of the running thread + process - // should be done here as the first thing, instead than - // directly after selecting them - if (current.get_total_cpu_time() - current.get_elapsed_time() > 0) - current.decrease_remaining_time(); - - // 4a. Look for exhausted requests for the running thread - update_allocated_requests(current, *new_snapshot); - - // 2. mark threads that used all their allotted time as terminated, - // and put their requests as exhausted - if (current.get_total_cpu_time() - current.get_elapsed_time() == 0) - { - current.set_state(Schedulable::state_terminated); - terminate_all_requests_of(current, *new_snapshot); - } - } - + // 3. check for simulation termination (we can directly use threads // for this check, since processes' state is based upon threads' one) Schedulable::state cur_state = current.get_state(); @@ -453,7 +463,7 @@ Scheduler::step_forward(History& history, CPUPolicy& cpu_policy, ResourcePolicy& { alive_threads++; } - + } //~ for over all_threads // ?. Time to see if some unallocable request became allocable, so @@ -523,13 +533,16 @@ Scheduler::step_forward(History& history, CPUPolicy& cpu_policy, ResourcePolicy& // Else, it's time to see if the first candidate can run DynamicThread& candidate = (DynamicThread&) _ready_queue->get_item_at(0); candidate.set_last_acquisition(current_instant); + // Even if it can run, we anyhow sets its release time to now, because + // it means its release time is *at least* the current_instant. This + // is needed for RR policies. + candidate.set_last_release(current_instant); // If a thread has been created with duration "0" (silly, but possible); // if you think it's safe, you can change this condition with an assert // and delete the body of the ``if''. if(candidate.get_total_cpu_time() - candidate.get_elapsed_time() == 0) { - candidate.set_last_release(current_instant); candidate.set_state(Schedulable::state_terminated); // Put every request of this thread to state_exhausted terminate_all_requests_of(candidate, *new_snapshot);