// src/backend/scheduler.cc - Copyright 2005, 2006, University // of Padova, dept. of Pure and Applied // Mathematics // // This file is part of SGPEMv2. // // This is free software; you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation; either version 2 of the License, or // (at your option) any later version. // // SGPEMv2 is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with SGPEMv2; if not, write to the Free Software // Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA #include "policy.hh" #include "scheduler.hh" using namespace std; using namespace sgpem; using namespace memory; //static object Scheduler Scheduler::_instance(10); //dummy parameter /** */ Scheduler::Scheduler(int) //private constructor. The parameter is discarded {} Scheduler& Scheduler::get_instance() { return _instance; } SchedulableList* Scheduler::get_ready_queue() { return &_ready_queue; } /** \note E' fondamentale che questo metodo memorizzi localmente qualora la politica attuale sia a prerilascio o meno, e la durata del quanto di tempo, in quanto la politica e' libera di variare questi parametri a piacere durante l'esecuzione della simulazione */ void Scheduler::reset_status() { _ready_queue.clear(); History::get_instance().truncate_at(0); // restore the policy } void Scheduler::step_forward() { History& h = History::get_instance(); //****************** //check for arrivals and prepare the queue //****************** smart_ptr initial = h.get_simulation_status_at(h.get_current_time()); _ready_queue.clear(); //adds running schedulable smart_ptr running_ptr = h.get_scheduled_at(h.get_current_time()); if (running_ptr) _ready_queue.add_at_top(*running_ptr); //adds each new ready schedulable and sorts the queue for(uint i=0; i < initial->size(); i++) if (initial->get_item_at(i)->get_state() == SchedulableStatus::state_ready && (int)initial->get_item_at(i)->get_schedulable()->get_arrival_time() == h.get_current_time()) { _ready_queue.add_at_bottom(*initial->get_item_at(i)); //pops the running schedulable only if the policy is not preemptive if (_policy->is_pre_emptive() == false && running_ptr) _ready_queue.remove(0); // Sort the queue _policy->sort_queue(event_schedulable_arrival); //restore the old running schedulable if (_policy->is_pre_emptive() == false && running_ptr) _ready_queue.add_at_top(*running_ptr); } //**************** // Check for termination //**************** if (running_ptr && running_ptr->get_cpu_time_left() == 0) { //there was a running schedulable and it's terminated. Remove it! for(uint i=0; i < _ready_queue.size(); i++) if (*_ready_queue.get_item_at(i) == *running_ptr) { _ready_queue.remove(i); break; } //IF _ready_queue.size() == 0 sort_queue(...) is called but has no effect!! _policy->sort_queue(event_schedulable_termination); } //***************** // Check for time slice //***************** if (_policy->get_time_slice() != numeric_limits::max()) //time-slice _policy->sort_queue(event_end_time_slice); //****************** // Create the final list of schedulable //****************** SchedulableList final = _ready_queue; if (final.size() != 0) //the firs element IS the running one (if != *running_ptr then there is a CONTEXT SWICH) final.get_item_at(0)->set_state(SchedulableStatus::state_running); //all the others are ready for (uint i = 1; i < final.size(); i++) if (final.get_item_at(i)->get_state() == SchedulableStatus::state_running) final.get_item_at(i)->set_state(SchedulableStatus::state_ready); //append blocked, future, terminated and the old running schedulables for (uint i = 0; i < initial->size(); i++) if(initial->get_item_at(i)->get_state() == SchedulableStatus::state_blocked || initial->get_item_at(i)->get_state() == SchedulableStatus::state_future || initial->get_item_at(i)->get_state() == SchedulableStatus::state_terminated || (initial->get_item_at(i)->get_state() == SchedulableStatus::state_ready && (int)initial->get_item_at(i)->get_schedulable()->get_arrival_time() != h.get_current_time()) ) final.add_at_bottom(*initial->get_item_at(i)); h.enqueue_slice(final); }