- Scheduler completed.
- Added a wizard just for show, but there is no interesting cpu-scheduling policy to test it with - Better textual output. git-svn-id: svn://svn.gna.org/svn/sgpemv2/trunk@842 3ecf2c5c-341e-0410-92b4-d18e462d057c
This commit is contained in:
parent
436e401ae8
commit
69c8341384
4 changed files with 364 additions and 103 deletions
|
@ -28,7 +28,7 @@
|
|||
#include "singleton.tcc"
|
||||
|
||||
#include <glibmm/thread.h>
|
||||
|
||||
#include <iostream>
|
||||
#include <cassert>
|
||||
#include <memory>
|
||||
|
||||
|
@ -103,14 +103,13 @@ update_future_processes(unsigned int front, auto_ptr<ConcreteEnvironment>& next_
|
|||
DynamicProcess& dp = dynamic_cast<DynamicProcess&>(**it_ps);
|
||||
if(dp.get_arrival_time() == front)
|
||||
{
|
||||
front = dp.get_elapsed_time(); // == 0
|
||||
assert(front == 0);
|
||||
assert(dp.get_elapsed_time() == 0);
|
||||
typedef std::vector<DynamicThread*> DynamicThreads;
|
||||
DynamicThreads dts = dp.get_dynamic_threads();
|
||||
for(DynamicThreads::const_iterator it_dts = dts.begin(); it_dts != dts.end(); it_dts++)
|
||||
{
|
||||
DynamicThread& dt = **it_dts;
|
||||
if(dt.get_arrival_time() == front)
|
||||
if(dt.get_arrival_time() == dp.get_elapsed_time())
|
||||
{
|
||||
dt.set_state(Schedulable::state_ready);
|
||||
// in this way we will never have threads ready having remaining time == 0
|
||||
|
@ -195,7 +194,7 @@ advance_running_process_and_thread(unsigned int front, auto_ptr<ConcreteEnvironm
|
|||
}
|
||||
}
|
||||
|
||||
// Introduces newly arrived threads.
|
||||
// Introduces newly arrived for(unsigned int i = 0; i < queue.size(); i++)
|
||||
// Postcondition:
|
||||
// for each process p in next_snapshot
|
||||
// (
|
||||
|
@ -475,13 +474,15 @@ build_ready_queue(unsigned int front, auto_ptr<ConcreteEnvironment>& next_snapsh
|
|||
{
|
||||
DynamicThread& dt = **it_dts;
|
||||
if(dt.get_state() == Schedulable::state_ready)
|
||||
{
|
||||
queue.append(dt);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// returns false if and only if the snapshot contains a candidate running thread,
|
||||
// returns true if and only if the snapshot contains a candidate running thread,
|
||||
// the thread's state is state_running.
|
||||
static bool
|
||||
find_a_candidate(unsigned int front, auto_ptr<ConcreteEnvironment>& next_snapshot)
|
||||
|
@ -500,21 +501,21 @@ find_a_candidate(unsigned int front, auto_ptr<ConcreteEnvironment>& next_snapsho
|
|||
{
|
||||
DynamicThread& dt = **it_dts;
|
||||
if(dt.get_state() == Schedulable::state_running)
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
// if no process has been found, select the first on the ready queue.
|
||||
ReadyQueue& queue = next_snapshot->get_sorted_queue();
|
||||
if (queue.size() == 0)
|
||||
return true;
|
||||
return false;
|
||||
DynamicThread& candidate = dynamic_cast<DynamicThread&>(queue.get_item_at(0));
|
||||
candidate.set_state(Schedulable::state_running);
|
||||
// HACK HACK HACK
|
||||
// we do not remove the candidate from the ready queue. this information is useful
|
||||
// since we chose to set the last_aquisition and the last_release just after a
|
||||
// successful selection. see try_to_run().
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
|
@ -541,6 +542,16 @@ check_if_simulation_is_terminated(unsigned int front, auto_ptr<ConcreteEnvironme
|
|||
}
|
||||
|
||||
|
||||
static void
|
||||
print_queue(unsigned int front, auto_ptr<ConcreteEnvironment>& next_snapshot)
|
||||
{
|
||||
ReadyQueue& queue = next_snapshot->get_sorted_queue();
|
||||
for(unsigned int i = 0; i < queue.size(); i++)
|
||||
{
|
||||
std::cout << queue.get_item_at(i).get_name();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
@ -549,8 +560,7 @@ check_if_simulation_is_terminated(unsigned int front, auto_ptr<ConcreteEnvironme
|
|||
static bool
|
||||
try_to_run(unsigned int front, auto_ptr<ConcreteEnvironment>& next_snapshot)
|
||||
{
|
||||
printf("trying to run");
|
||||
bool success = true;
|
||||
bool success = false;
|
||||
typedef std::vector<Process*> Processes;
|
||||
Processes ps = next_snapshot->get_processes();
|
||||
for(Processes::const_iterator it_ps = ps.begin(); it_ps != ps.end(); it_ps++)
|
||||
|
@ -565,15 +575,17 @@ try_to_run(unsigned int front, auto_ptr<ConcreteEnvironment>& next_snapshot)
|
|||
DynamicThread& dt = **it_dts;
|
||||
if(dt.get_state() == Schedulable::state_running)
|
||||
{
|
||||
// this is our candidate
|
||||
success = true;
|
||||
// let's see if it is runnable or if it blocks:
|
||||
typedef std::vector<DynamicRequest*> DynamicRequests;
|
||||
DynamicRequests drs = dt.get_dynamic_requests();
|
||||
for(DynamicRequests::const_iterator it_drs = drs.begin(); it_drs != drs.end(); it_drs++)
|
||||
{
|
||||
printf("checking all requests");
|
||||
DynamicRequest& dr = **it_drs;
|
||||
// if it's time to do it, raise a request
|
||||
if(dr.get_state() == Request::state_future && dr.get_instant() == dt.get_elapsed_time())
|
||||
{
|
||||
printf("found a new request");
|
||||
typedef std::vector<DynamicSubRequest*> DynamicSubRequests;
|
||||
DynamicSubRequests dsrs = dr.get_dynamic_subrequests();
|
||||
for(DynamicSubRequests::const_iterator it_dsrs = dsrs.begin(); it_dsrs != dsrs.end(); it_dsrs++)
|
||||
|
@ -583,7 +595,6 @@ try_to_run(unsigned int front, auto_ptr<ConcreteEnvironment>& next_snapshot)
|
|||
Environment::SubRequestQueue& queue = next_snapshot->get_request_queue(dsr.get_resource_key());
|
||||
/// Enqueue the subrequest at the back of the queue.
|
||||
queue.push_back(&dsr);
|
||||
printf("pushing back a request");
|
||||
|
||||
/// TODO: right here, right now we should call the resource policy to
|
||||
/// update the queue. Updates the state of the subrequest depending
|
||||
|
@ -601,39 +612,44 @@ try_to_run(unsigned int front, auto_ptr<ConcreteEnvironment>& next_snapshot)
|
|||
dsr.set_state(Request::state_allocated);
|
||||
}
|
||||
}
|
||||
}
|
||||
} // end of request raising
|
||||
// if it does exist at least one unallocable request, the thread may not run!
|
||||
if (dr.get_state() == Request::state_unallocable)
|
||||
{
|
||||
dt.set_state(Schedulable::state_blocked);
|
||||
success = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
// HACK HACK HACK
|
||||
// this check is legal, since all pointers in the sorted queue should be valid.
|
||||
// if the current thread is the first in the ready queue, we need to remove it
|
||||
if (next_snapshot->get_sorted_queue().size() != 0 &&
|
||||
&next_snapshot->get_sorted_queue().get_item_at(0) == &dt)
|
||||
{
|
||||
// in case of success in allocating the cpu, we must update the last_aquisition
|
||||
if (success)
|
||||
dt.set_last_acquisition(front);
|
||||
next_snapshot->get_sorted_queue().erase_first();
|
||||
}
|
||||
// if the current thread was the one that was previously running
|
||||
else
|
||||
{
|
||||
// we must update the last_release
|
||||
if (!success)
|
||||
dt.set_last_release(front);
|
||||
//cpu_policy.sort_queue();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return success;
|
||||
}
|
||||
} // end for loop over all running thread requests
|
||||
|
||||
// HACK HACK HACK
|
||||
// this check is legal, since all pointers in the sorted queue should be valid.
|
||||
// if the current thread is the first in the ready queue, we need to remove it
|
||||
if (next_snapshot->get_sorted_queue().size() != 0 &&
|
||||
&next_snapshot->get_sorted_queue().get_item_at(0) == &dt)
|
||||
{
|
||||
// in case of success in allocating the cpu, we must update the last_aquisition
|
||||
if (success)
|
||||
dt.set_last_acquisition(front);
|
||||
next_snapshot->get_sorted_queue().erase_first();
|
||||
} // if the current thread was the one that was previously running
|
||||
else
|
||||
{
|
||||
// we must update the last_release
|
||||
if (!success)
|
||||
dt.set_last_release(front);
|
||||
else
|
||||
return success;
|
||||
//cpu_policy.sort_queue();
|
||||
}
|
||||
|
||||
|
||||
|
||||
} // end things to do if thread was running
|
||||
} // end for loop over all threads of a running process
|
||||
} // end if process is running
|
||||
} // end for loop over all processes
|
||||
return false;
|
||||
}// end main loop
|
||||
|
||||
//.............................................................................
|
||||
//.............................................................................
|
||||
|
@ -686,32 +702,25 @@ Scheduler::step_forward(ConcreteHistory& concrete_history, CPUPolicy& cpu_policy
|
|||
build_ready_queue(next_instant, next_snapshot);
|
||||
|
||||
// and pass it to the policy itself
|
||||
if (next_snapshot->get_sorted_queue().size() != 0)
|
||||
cpu_policy.sort_queue();
|
||||
// if (next_snapshot->get_sorted_queue().size() != 0)
|
||||
// cpu_policy.sort_queue();
|
||||
|
||||
|
||||
bool found = false;
|
||||
bool none_ready_or_running = false;
|
||||
bool simulation_terminated = false;
|
||||
bool running = false;
|
||||
bool idle = false;
|
||||
bool terminated = false;
|
||||
|
||||
do
|
||||
{
|
||||
// If no thread is in running state, select a new thread to be
|
||||
// executed (so it changes its state from ready to running).
|
||||
// However, in case it hasn't to run for a strictly positive
|
||||
// amount of time, put it into terminated state. (??) Then try to
|
||||
// select a new schedulable, by jumping (??) to the point about
|
||||
// building the ready queue.
|
||||
none_ready_or_running = find_a_candidate(next_instant, next_snapshot);
|
||||
if (none_ready_or_running)
|
||||
simulation_terminated = check_if_simulation_is_terminated(next_instant, next_snapshot);
|
||||
if (find_a_candidate(next_instant, next_snapshot))
|
||||
running = try_to_run(next_instant, next_snapshot);
|
||||
else
|
||||
// Check pending requests for the running thread. If in the
|
||||
// current instant the thread does a new unfulfillable request,
|
||||
// put it in blocked state and jump (??) to the point about building
|
||||
// the ready queue
|
||||
found = try_to_run(next_instant, next_snapshot);
|
||||
if (check_if_simulation_is_terminated(next_instant, next_snapshot))
|
||||
terminated = true;
|
||||
else
|
||||
idle = true;
|
||||
}
|
||||
while (!found && !none_ready_or_running && !simulation_terminated);
|
||||
while (!running && !idle && !terminated);
|
||||
|
||||
// append the new snapshot, releasing the auto_ptr!
|
||||
concrete_history.append_new_environment(next_snapshot.release());
|
||||
|
@ -720,7 +729,7 @@ Scheduler::step_forward(ConcreteHistory& concrete_history, CPUPolicy& cpu_policy
|
|||
_policy = NULL;
|
||||
_ready_queue = NULL;
|
||||
|
||||
return !simulation_terminated; // watch out for the !
|
||||
return !terminated; // watch out for the !
|
||||
}
|
||||
catch(UserInterruptException& e)
|
||||
{
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue