// 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::set_policy(Policy* p) { _policy = p; } Policy* Scheduler::get_policy() { return _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()); if (!initial) { cout << _("\nNo initial state inserted!!\n"); return; } _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 the READY ones for(uint rea=0; rea < initial->size(); rea++) if (initial->get_item_at(rea)->get_state() == SchedulableStatus::state_ready) _ready_queue.add_at_bottom(*initial->get_item_at(rea)); //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_future && (int)initial->get_item_at(i)->get_schedulable()->get_arrival_time() == h.get_current_time()) { //cout << "\nnuovo running: " << initial->get_item_at(i)->get_schedulable()->get_name(); //restore the old running schedulable if (_policy->is_pre_emptive() == false && running_ptr) _ready_queue.remove(0); //adds the NEW one _ready_queue.add_at_bottom(*initial->get_item_at(i)); _ready_queue.get_item_at(_ready_queue.size()-1)->set_state(SchedulableStatus::state_ready); initial->get_item_at(i)->set_state(SchedulableStatus::state_ready); // 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 is a running schedulable and it's terminated. Append at the bottom with the state TERMINATED for(uint i=0; i < _ready_queue.size(); i++) if (*_ready_queue.get_item_at(i) == *running_ptr) { _ready_queue.add_at_bottom(*_ready_queue.get_item_at(i)); _ready_queue.remove(i); _ready_queue.get_item_at(_ready_queue.size()-1)->set_state(SchedulableStatus::state_terminated); break; } //cout << "\nTERMINATO!!"; running_ptr = NULL; //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 //****************** if (_ready_queue.size() != 0 && (_ready_queue.get_item_at(0)->get_state() == SchedulableStatus::state_ready || _ready_queue.get_item_at(0)->get_state() == SchedulableStatus::state_running)) { //the first ready element IS the running one (if != *running_ptr then there is a CONTEXT SWICH) _ready_queue.get_item_at(0)->set_state(SchedulableStatus::state_running); _ready_queue.get_item_at(0)->give_cpu_time(1); } //all the others are ready for (uint i = 1; i < _ready_queue.size(); i++) if (_ready_queue.get_item_at(i)->get_state() == SchedulableStatus::state_running) _ready_queue.get_item_at(i)->set_state(SchedulableStatus::state_ready); //append blocked, future, and terminated 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) _ready_queue.add_at_bottom(*initial->get_item_at(i)); cout << "\n"; /* for (uint i = 0; i < _ready_queue.size(); i++) cout << " " << _ready_queue.get_item_at(i)->get_schedulable()->get_name() <<"_" << _ready_queue.get_item_at(i)->get_state(); */ h.enqueue_slice(_ready_queue); }