- 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,10 +403,45 @@ 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);
// The first thing we've to do is to update the state of the old
// running thread, if there's one.
for (Iseq<Threads::iterator> 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 = &current; // 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 // 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 // threads to make them ready. We also keep a count of alive threads
// 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;
@ -419,32 +454,7 @@ Scheduler::step_forward(History& history, CPUPolicy& cpu_policy, ResourcePolicy&
parent.get_elapsed_time() == current.get_arrival_time()) parent.get_elapsed_time() == current.get_arrival_time())
current.set_state(Schedulable::state_ready); 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 = &current; // 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 // 3. check for simulation termination (we can directly use threads
// for this check, since processes' state is based upon threads' one) // for this check, since processes' state is based upon threads' one)
Schedulable::state cur_state = current.get_state(); Schedulable::state cur_state = current.get_state();
@ -453,7 +463,7 @@ Scheduler::step_forward(History& history, CPUPolicy& cpu_policy, ResourcePolicy&
{ {
alive_threads++; alive_threads++;
} }
} //~ for over all_threads } //~ for over all_threads
// ?. Time to see if some unallocable request became allocable, so // ?. 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 // 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);