- Fix one of two Scheduler's bugs. Now the state of the running thread

is update separately by the state of future or blocked ones at the
beginning of step_forward() (since else it didn't influence the state of
threads coming before it in the global thread list)


git-svn-id: svn://svn.gna.org/svn/sgpemv2/trunk@974 3ecf2c5c-341e-0410-92b4-d18e462d057c
This commit is contained in:
tchernobog 2006-08-31 17:15:41 +00:00
parent 0c3ecf3bcb
commit 1bc33d37ec
1 changed files with 44 additions and 31 deletions

View File

@ -403,28 +403,16 @@ Scheduler::step_forward(History& history, CPUPolicy& cpu_policy, ResourcePolicy&
collect_threads(new_snapshot->get_processes(), all_threads); collect_threads(new_snapshot->get_processes(), all_threads);
// When a new instant cames, we could have to update the state of future // The first thing we've to do is to update the state of the old
// threads to make them ready, or running threads to make them terminated // running thread, if there's one.
// We also update the other properties of the running thread, and keep a
// count of the alive threads
for (Iseq<Threads::iterator> it = iseq(all_threads); it; ++it) for (Iseq<Threads::iterator> it = iseq(all_threads); it; ++it)
{ {
DynamicThread& current = **it; DynamicThread& current = **it;
// 1. mark future threads as ready, if appropriate
if (current.get_state() == Schedulable::state_future)
{
Process& parent = current.get_process();
if ((long) parent.get_arrival_time() <= current_instant &&
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 // Save the current running thread for future usage, if it hasn't ended
// its allotted time // its allotted time
if (current.get_state() == Schedulable::state_running) if (current.get_state() == Schedulable::state_running)
{ {
assert(running_thread == NULL); // ... only one thread must be running at a time.
running_thread = &current; // Even if we can change its state to terminate running_thread = &current; // Even if we can change its state to terminate
// increasing the time elapsed of the running thread + process // increasing the time elapsed of the running thread + process
@ -443,6 +431,28 @@ Scheduler::step_forward(History& history, CPUPolicy& cpu_policy, ResourcePolicy&
current.set_state(Schedulable::state_terminated); current.set_state(Schedulable::state_terminated);
terminate_all_requests_of(current, *new_snapshot); 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. We also keep a count of alive threads
for (Iseq<Threads::iterator> it = iseq(all_threads); it; ++it)
{
DynamicThread& current = **it;
// 1. mark future threads as ready, if appropriate
if (current.get_state() == Schedulable::state_future)
{
Process& parent = current.get_process();
if ((long) parent.get_arrival_time() <= current_instant &&
parent.get_elapsed_time() == current.get_arrival_time())
current.set_state(Schedulable::state_ready);
} }
// 3. check for simulation termination (we can directly use threads // 3. check for simulation termination (we can directly use threads
@ -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 // Else, it's time to see if the first candidate can run
DynamicThread& candidate = (DynamicThread&) _ready_queue->get_item_at(0); DynamicThread& candidate = (DynamicThread&) _ready_queue->get_item_at(0);
candidate.set_last_acquisition(current_instant); 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 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 // if you think it's safe, you can change this condition with an assert
// and delete the body of the ``if''. // and delete the body of the ``if''.
if(candidate.get_total_cpu_time() - candidate.get_elapsed_time() == 0) if(candidate.get_total_cpu_time() - candidate.get_elapsed_time() == 0)
{ {
candidate.set_last_release(current_instant);
candidate.set_state(Schedulable::state_terminated); candidate.set_state(Schedulable::state_terminated);
// Put every request of this thread to state_exhausted // Put every request of this thread to state_exhausted
terminate_all_requests_of(candidate, *new_snapshot); terminate_all_requests_of(candidate, *new_snapshot);