- Correctly set release time for candidate threads that try to

run and immediately block
- Use modulo to check the end of the time slice instead than a
simple equality


git-svn-id: svn://svn.gna.org/svn/sgpemv2/trunk@976 3ecf2c5c-341e-0410-92b4-d18e462d057c
This commit is contained in:
tchernobog 2006-08-31 18:57:09 +00:00
parent 5b7130a9a0
commit ba9b28b0c8
1 changed files with 18 additions and 17 deletions

View File

@ -19,7 +19,7 @@
// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA // Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
/* DISCLAIMER FOR THE RAMPANT CODER: */ // DISCLAIMER FOR THE RAMPANT CODER:
// ----------------------------------------------------\\ // ----------------------------------------------------\\
// ``If you touch this code, your ass is grass, \\ // ``If you touch this code, your ass is grass, \\
// and I'm the lawnmover.'' \\ // and I'm the lawnmover.'' \\
@ -503,13 +503,14 @@ Scheduler::step_forward(History& history, CPUPolicy& cpu_policy, ResourcePolicy&
// This happens when the policy makes use of preemptability by // This happens when the policy makes use of preemptability by
// priority, or when a time slice ended // priority, or when a time slice ended
if (running_thread != NULL && running_thread->get_state() == Schedulable::state_running && if (running_thread != NULL && running_thread->get_state() == Schedulable::state_running &&
(preemptible_policy || (preemptible_policy || (time_slice > 0 &&
time_slice == current_instant - running_thread->get_last_acquisition()) ) // A process can be preempted every n-th time-slice, so we use the modulo operator
(current_instant - running_thread->get_last_acquisition()) % time_slice == 0) ))
{ {
running_thread->set_state(Schedulable::state_ready); running_thread->set_state(Schedulable::state_ready);
// We don't set the last_release parameter here. If necessary, // We don't set the last_release parameter here. If necessary,
// we'll do that below, when selecting a new running thread, // we'll do that below, when selecting a new running thread,
// if it's different from the previous one. // only if it's different from the previous one.
} }
@ -561,6 +562,18 @@ Scheduler::step_forward(History& history, CPUPolicy& cpu_policy, ResourcePolicy&
continue; continue;
} }
// If the new running is different from the old one,
// remember to release our old pal, and to acquire our
// new runner.
// It'll sufficit that *one* candidate is different from
// the old running to trigger this, and it's rightly so.
if(&candidate != running_thread)
{
if(running_thread != NULL)
running_thread->set_last_release(current_instant);
candidate.set_last_acquisition(current_instant);
}
// Now we check if our candidate blocks on a new request // Now we check if our candidate blocks on a new request
raise_new_requests(candidate, *new_snapshot, resource_policy); raise_new_requests(candidate, *new_snapshot, resource_policy);
if(candidate.get_state() != Schedulable::state_blocked) if(candidate.get_state() != Schedulable::state_blocked)
@ -568,12 +581,10 @@ Scheduler::step_forward(History& history, CPUPolicy& cpu_policy, ResourcePolicy&
we_ve_got_a_winner /*!hurrah!*/ = true; we_ve_got_a_winner /*!hurrah!*/ = true;
else // if blocked, we've to remove it from the ready queue else // if blocked, we've to remove it from the ready queue
{ {
candidate.set_last_acquisition(current_instant);
_ready_queue->erase_first(); _ready_queue->erase_first();
alive_threads--; alive_threads--;
} }
} }
// ?. Finally select the new thread (if appropriate); now we're sure // ?. Finally select the new thread (if appropriate); now we're sure
// the one we have can run // the one we have can run
@ -582,16 +593,6 @@ Scheduler::step_forward(History& history, CPUPolicy& cpu_policy, ResourcePolicy&
// Fix fields of running thread // Fix fields of running thread
DynamicThread& new_running = (DynamicThread&) _ready_queue->get_item_at(0); DynamicThread& new_running = (DynamicThread&) _ready_queue->get_item_at(0);
new_running.set_state(Schedulable::state_running); new_running.set_state(Schedulable::state_running);
// If the new running is different from the old one,
// remember to release our old pal, and to acquire our
// new runner.
if(&new_running != running_thread)
{
if(running_thread != NULL)
running_thread->set_last_release(current_instant);
new_running.set_last_acquisition(current_instant);
}
} }
} }