- 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,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 = ¤t; // Even if we can change its state to terminate
|
running_thread = ¤t; // 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);
|
||||||
|
|
Loading…
Reference in New Issue