- 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:
parent
0c3ecf3bcb
commit
1bc33d37ec
|
@ -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 = ¤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
|
// 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 = ¤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
|
// 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);
|
||||||
|
|
Loading…
Reference in New Issue