- 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:
parent
5b7130a9a0
commit
ba9b28b0c8
|
@ -19,7 +19,7 @@
|
|||
// 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, \\
|
||||
// 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
|
||||
// priority, or when a time slice ended
|
||||
if (running_thread != NULL && running_thread->get_state() == Schedulable::state_running &&
|
||||
(preemptible_policy ||
|
||||
time_slice == current_instant - running_thread->get_last_acquisition()) )
|
||||
(preemptible_policy || (time_slice > 0 &&
|
||||
// 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);
|
||||
// We don't set the last_release parameter here. If necessary,
|
||||
// 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;
|
||||
}
|
||||
|
||||
// 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
|
||||
raise_new_requests(candidate, *new_snapshot, resource_policy);
|
||||
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;
|
||||
else // if blocked, we've to remove it from the ready queue
|
||||
{
|
||||
candidate.set_last_acquisition(current_instant);
|
||||
_ready_queue->erase_first();
|
||||
alive_threads--;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// ?. Finally select the new thread (if appropriate); now we're sure
|
||||
// the one we have can run
|
||||
|
@ -582,16 +593,6 @@ Scheduler::step_forward(History& history, CPUPolicy& cpu_policy, ResourcePolicy&
|
|||
// Fix fields of running thread
|
||||
DynamicThread& new_running = (DynamicThread&) _ready_queue->get_item_at(0);
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue