- minor bugfix: scheduler was terminating subrequests before decreasing
their elapsed time - requests are now behaving nicely, since they are raised at the correct instant, and terminated at the right instant - the ready queues are still not ready, tough :(, anyway, now there is really nothing else to do before them. - stepforward is looking much more uglier (if possible). git-svn-id: svn://svn.gna.org/svn/sgpemv2/trunk@816 3ecf2c5c-341e-0410-92b4-d18e462d057c
This commit is contained in:
parent
10091d7a16
commit
96055b4cf1
|
@ -90,14 +90,6 @@ update_requests_for_old_running_thread(DynamicThread& running_thread)
|
||||||
{
|
{
|
||||||
DynamicRequest& rq = **r_it;
|
DynamicRequest& rq = **r_it;
|
||||||
|
|
||||||
// If the running thread terminated uncoditionally put them in exhausted state
|
|
||||||
if(running_terminated)
|
|
||||||
{
|
|
||||||
SubRequests& subreqs = rq.get_dynamic_subrequests();
|
|
||||||
for(SubRequests::iterator s_it = subreqs.begin(); s_it != subreqs.end(); s_it++)
|
|
||||||
(*s_it)->set_state(Request::state_exhausted);
|
|
||||||
continue; // go to next request
|
|
||||||
}
|
|
||||||
|
|
||||||
if(rq.get_state() == Request::state_allocated)
|
if(rq.get_state() == Request::state_allocated)
|
||||||
{
|
{
|
||||||
|
@ -121,6 +113,14 @@ update_requests_for_old_running_thread(DynamicThread& running_thread)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
// If the running thread terminated uncoditionally put them in exhausted state
|
||||||
|
if(running_terminated)
|
||||||
|
{
|
||||||
|
SubRequests& subreqs = rq.get_dynamic_subrequests();
|
||||||
|
for(SubRequests::iterator s_it = subreqs.begin(); s_it != subreqs.end(); s_it++)
|
||||||
|
(*s_it)->set_state(Request::state_exhausted);
|
||||||
|
continue; // go to next request
|
||||||
|
}
|
||||||
} //~ for(over requests)
|
} //~ for(over requests)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -276,12 +276,39 @@ Scheduler::step_forward(History& history, CPUPolicy& cpu_policy) throw(UserInter
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// Try to continue running the current running thread
|
||||||
|
if (running_thread != NULL && running_thread->get_state() == Schedulable::state_running)
|
||||||
|
{
|
||||||
|
// the thread may block on raising a request
|
||||||
|
Requests& reqs = running_thread->get_dynamic_requests();
|
||||||
|
for(Requests::iterator r_it = reqs.begin(); r_it != reqs.end(); r_it++)
|
||||||
|
{
|
||||||
|
DynamicRequest& rq = **r_it;
|
||||||
|
if (rq.get_state() == Request::state_future
|
||||||
|
&& rq.get_instant() == running_thread->get_elapsed_time())
|
||||||
|
{
|
||||||
|
SubRequests& subreqs = rq.get_dynamic_subrequests();
|
||||||
|
for(SubRequests::iterator s_it = subreqs.begin(); s_it != subreqs.end(); s_it++)
|
||||||
|
{
|
||||||
|
DynamicSubRequest& subr = **s_it;
|
||||||
|
// FIXME: allocation is always granted, by now. We'll need queues to
|
||||||
|
// implement it correctly
|
||||||
|
if(subr.get_state() == Request::state_future)
|
||||||
|
subr.set_state(Request::state_allocated);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// ?. Ask the policy to sort the queue. We do this multiple time if we must select
|
// ?. Ask the policy to sort the queue. We do this multiple time if we must select
|
||||||
// a new thread and it can't run for some reason (goes blocked, or terminates).
|
// a new thread and it can't run for some reason (goes blocked, or terminates).
|
||||||
bool selected_cant_run;
|
bool found = true;
|
||||||
do
|
do
|
||||||
{
|
{
|
||||||
selected_cant_run = false;
|
printf("\n looking for a running one");
|
||||||
|
found = true;
|
||||||
prepare_ready_queue(*new_snapshot, all_threads);
|
prepare_ready_queue(*new_snapshot, all_threads);
|
||||||
|
|
||||||
if(_ready_queue->size() == 0)
|
if(_ready_queue->size() == 0)
|
||||||
|
@ -291,21 +318,47 @@ Scheduler::step_forward(History& history, CPUPolicy& cpu_policy) throw(UserInter
|
||||||
|
|
||||||
DynamicThread& candidate = (DynamicThread&) _ready_queue->get_item_at(0);
|
DynamicThread& candidate = (DynamicThread&) _ready_queue->get_item_at(0);
|
||||||
|
|
||||||
|
|
||||||
|
// the thread may block on raising a request
|
||||||
|
Requests& reqs = candidate.get_dynamic_requests();
|
||||||
|
for(Requests::iterator r_it = reqs.begin(); r_it != reqs.end(); r_it++)
|
||||||
|
{
|
||||||
|
DynamicRequest& rq = **r_it;
|
||||||
|
if (rq.get_state() == Request::state_future
|
||||||
|
&& rq.get_instant() == candidate.get_elapsed_time())
|
||||||
|
{
|
||||||
|
SubRequests& subreqs = rq.get_dynamic_subrequests();
|
||||||
|
for(SubRequests::iterator s_it = subreqs.begin(); s_it != subreqs.end(); s_it++)
|
||||||
|
{
|
||||||
|
DynamicSubRequest& subr = **s_it;
|
||||||
|
// FIXME: allocation is always granted, by now. We'll need queues to
|
||||||
|
// implement it correctly
|
||||||
|
if(subr.get_state() == Request::state_future)
|
||||||
|
subr.set_state(Request::state_allocated);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// We could have threads with 0 duration. Silly, but possible.
|
// We could have threads with 0 duration. Silly, but possible.
|
||||||
|
// the silly thing was to permit the user to do this :P
|
||||||
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_acquisition(current_instant);
|
candidate.set_last_acquisition(current_instant);
|
||||||
candidate.set_last_release(current_instant);
|
candidate.set_last_release(current_instant);
|
||||||
candidate.set_state(Schedulable::state_terminated);
|
candidate.set_state(Schedulable::state_terminated);
|
||||||
// FIXME : check requests for thread at instant 0?
|
// FIXED : check requests for thread at instant 0?
|
||||||
selected_cant_run = true;
|
// the real question is: should we check for requests raised at
|
||||||
|
// the thread last instant? the answer is: who cares?
|
||||||
|
// doing it or not is a matter of cut-n-paste
|
||||||
|
found = false;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
// FIXME : check if the first thread of the queue blocks
|
// FIXME : check if the first thread of the queue blocks
|
||||||
|
|
||||||
}
|
}
|
||||||
while(selected_cant_run);
|
while(!found);
|
||||||
|
|
||||||
// ?. Finally select the new thread (if appropriate); now we're sure it can run
|
// ?. Finally select the new thread (if appropriate); now we're sure it can run
|
||||||
if(_ready_queue->size() > 0 && (running_thread == NULL || running_thread->get_state() != Schedulable::state_running))
|
if(_ready_queue->size() > 0 && (running_thread == NULL || running_thread->get_state() != Schedulable::state_running))
|
||||||
|
@ -317,6 +370,8 @@ Scheduler::step_forward(History& history, CPUPolicy& cpu_policy) throw(UserInter
|
||||||
// removes running element from the ready queue
|
// removes running element from the ready queue
|
||||||
// since no method was provided to erase an item in the queue, we should rebuild it.
|
// since no method was provided to erase an item in the queue, we should rebuild it.
|
||||||
// this is pointless. I just added the method.
|
// this is pointless. I just added the method.
|
||||||
|
// rebuilding the ready queue may corrupt the order set by the policy:
|
||||||
|
// this is not acceptable, nor it is asking the policy to resort it.
|
||||||
_ready_queue->erase_first();
|
_ready_queue->erase_first();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue