- 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
|
// 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,13 +581,11 @@ 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
|
||||||
if (we_ve_got_a_winner)
|
if (we_ve_got_a_winner)
|
||||||
|
@ -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);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue