From 899e20323aaccc01b606fe364bdd1fa949b22798 Mon Sep 17 00:00:00 2001 From: tchernobog Date: Tue, 4 Jul 2006 09:30:45 +0000 Subject: [PATCH] - Write some more of Scheduler::step_forward() - Noted some design lackings, warning the designers git-svn-id: svn://svn.gna.org/svn/sgpemv2/trunk@706 3ecf2c5c-341e-0410-92b4-d18e462d057c --- src/backend/dynamic_request.cc | 2 +- src/backend/dynamic_request.hh | 2 +- src/backend/request.hh | 2 +- src/backend/scheduler.cc | 121 ++++++++++++++++++++++++--------- src/backend/scheduler.hh | 4 +- 5 files changed, 94 insertions(+), 37 deletions(-) diff --git a/src/backend/dynamic_request.cc b/src/backend/dynamic_request.cc index 5c7dd62..b5cc072 100644 --- a/src/backend/dynamic_request.cc +++ b/src/backend/dynamic_request.cc @@ -83,7 +83,7 @@ DynamicRequest::get_instant() const } Request::state -DynamicRequest::get_current_state() const +DynamicRequest::get_state() const { return _state; } diff --git a/src/backend/dynamic_request.hh b/src/backend/dynamic_request.hh index b32a947..48fe48a 100644 --- a/src/backend/dynamic_request.hh +++ b/src/backend/dynamic_request.hh @@ -52,7 +52,7 @@ namespace sgpem unsigned int get_instant() const; - state get_current_state() const; + state get_state() const; void serialize(SerializeVisitor& translator) const; diff --git a/src/backend/request.hh b/src/backend/request.hh index a814113..ad332f9 100644 --- a/src/backend/request.hh +++ b/src/backend/request.hh @@ -45,7 +45,7 @@ namespace sgpem virtual std::vector get_subrequests() = 0; virtual unsigned int get_instant() const = 0; - virtual state get_current_state() const = 0; + virtual state get_state() const = 0; virtual void serialize(SerializeVisitor& translator) const = 0; }; diff --git a/src/backend/scheduler.cc b/src/backend/scheduler.cc index aa9f2d1..3ad872d 100644 --- a/src/backend/scheduler.cc +++ b/src/backend/scheduler.cc @@ -30,7 +30,7 @@ // Do not include full template definition in the header file #include "singleton.tcc" -#include +#include using namespace std; using namespace sgpem; @@ -47,18 +47,31 @@ collect_threads(const std::vector& procs, std::vector& collected_threads) { typedef std::vector Processes; - typedef std::vector Threads; + typedef std::vector Threads; collected_threads.clear(); for(Processes::const_iterator it1 = procs.begin(); it1 != procs.end(); it1++) { - const Threads& ts = (*it1)->get_threads(); - for(Threads::const_iterator it2 = ts.begin(); it2 != ts.end(); it2++) - collected_threads.push_back((DynamicThread*) *it2); + const Threads& ts = ((DynamicProcess&) **it1).get_dynamic_threads(); + collected_threads.insert(collected_threads.end(), ts.begin(), ts.end()); } } +static void +free_all_resources_of(DynamicThread& ended_thread) +{ + typedef std::vector Requests; + typedef std::vector SubRequests; + Requests& reqs = ended_thread.get_dynamic_requests(); + + for(Requests::iterator it = reqs.begin(); it != reqs.end(); it++) + { + // FIXME : write me + // Where is "state_fulfilled" or similar in Request::state? + } +} + // --------------------------------------------------------- @@ -108,66 +121,106 @@ Scheduler::step_forward(History& history, Policy& cpu_policy) throw(UserInterrup bool simulation_ended = true; // Assume we've finished. Then prove me wrong. ConcreteHistory& concrete_history = (ConcreteHistory&) history; - ConcreteEnvironment* new_snapshot = new ConcreteEnvironment(concrete_history.get_last_environment()); - typedef std::vector Processes; - typedef std::vector Threads; + // Use an auto_ptr since we've some exceptions in the coming... + auto_ptr new_snapshot(new ConcreteEnvironment(concrete_history.get_last_environment())); + + typedef std::vector Processes; + typedef std::vector Requests; + typedef std::vector SubRequests; + typedef std::vector Threads; Threads all_threads; + DynamicThread* running_thread = NULL; collect_threads(new_snapshot->get_processes(), all_threads); // designer + implementer (Matteo) comment follows: - // FIXME: decreasing the time elapsed of the running thread + process - // should maybe be done here as the first thing, instead than - // directly when selecting them - // 1. mark future threads as ready, if appropriate - // 2. mark ended threads as terminated for(Threads::iterator it = all_threads.begin(); it != all_threads.end(); it++) { - if((*it)->get_state() == Schedulable::state_future) + DynamicThread& current = **it; + + // 1. mark future threads as ready, if appropriate + if(current.get_state() == Schedulable::state_future) { - Process& parent = (*it)->get_process(); - if(parent.get_elapsed_time() == (*it)->get_arrival_time()) - (*it)->set_state(Schedulable::state_ready); + Process& parent = current.get_process(); + if(parent.get_elapsed_time() == current.get_arrival_time()) + current.set_state(Schedulable::state_ready); } - - if((*it)->get_total_cpu_time() - (*it)->get_elapsed_time() == 0) - (*it)->set_state(Schedulable::state_terminated); - - // 3. check for simulation termination (we can directly use threads) - // for this check, since processes' state is based upon theirs) + + // Save the current running thread for future usage, if it hasn't ended + // its allotted time + if(current.get_state() == Schedulable::state_running) + { + running_thread = ¤t; // Even if we change its state to terminated + // 2. mark threads that used all their allotted time as terminated + if(current.get_total_cpu_time() - current.get_elapsed_time() == 0) + current.set_state(Schedulable::state_terminated); + } + + // 3. check for simulation termination (we can directly use threads + // for this check, since processes' state is based upon threads' one) if(simulation_ended && ((*it)->get_state() & (Schedulable::state_blocked | Schedulable::state_terminated)) == 0) simulation_ended = false; } + // FIXME: increasing the time elapsed of the running thread + process + // should maybe be done here as the first thing, instead than + // directly when selecting them + if(running_thread != NULL) + { + running_thread->decrease_remaining_time(); + running_thread->get_process().decrease_remaining_time(); + } + + // 4a. Requests for the running thread exhausted + if(running_thread != NULL) { + Requests& reqs = running_thread->get_dynamic_requests(); + + // FIXME we lack a way to tell and/or remember for how + // much a subrequest has been being fulfilled + // THIS MEANS this part is NOT complete + // We should check if a request has been fulfilled + + // FIXME If a request was being fulfilled to the running thread, + // we should decrease the request remaining time here. + + // This is why we kept a ref to the old running thread, + // even if it was terminated + if(running_thread->get_state() == Schedulable::state_terminated) + free_all_resources_of(*running_thread); // this function isn't complete + + } + // / // / // / // (I'M HERE) < * * * * * * * * * * * - // \ + // \ // \ // \ // // (is it visible enough for you?) + + ReadyQueue& ready_queue = new_snapshot->get_sorted_queue(); + prepare_ready_queue(ready_queue); try { - // call the policy to sort the queue - // ... + // ?. Use the policy to sort the queue + + // FIXME: how does it get the queue? + cpu_policy.sort_queue(); } - catch( UserInterruptException e ) + catch(UserInterruptException& e) { _policy_manager.init(); - - //TODO Do we need to perform some other cleanup operation here? - delete new_snapshot; - - // Do we need to update something? + // ^^^^^ + // Do we need to update something else? // Going up unwinding the stack, tell: // - the user that the policy sucks @@ -175,5 +228,7 @@ Scheduler::step_forward(History& history, Policy& cpu_policy) throw(UserInterrup throw; } - concrete_history.append_new_environment(new_snapshot); + // append the new snapshot... + // ...and remember to release the auto_ptr! + concrete_history.append_new_environment(new_snapshot.release()); } diff --git a/src/backend/scheduler.hh b/src/backend/scheduler.hh index d0e5dfe..3c61c42 100644 --- a/src/backend/scheduler.hh +++ b/src/backend/scheduler.hh @@ -91,9 +91,11 @@ namespace sgpem Policy& get_policy(); private: + void prepare_ready_queue(ReadyQueue& queue); + Scheduler(); //private constructor. - ReadyQueue _ready_queue; + ReadyQueue _ready_queue; PolicyManager& _policy_manager; };