- 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:
matrevis 2006-08-03 00:30:36 +00:00
parent 10091d7a16
commit 96055b4cf1
1 changed files with 68 additions and 13 deletions

View File

@ -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();
} }