diff --git a/src/backend/pyloader/python_policy.cc b/src/backend/pyloader/python_policy.cc index 6fab705..5199159 100644 --- a/src/backend/pyloader/python_policy.cc +++ b/src/backend/pyloader/python_policy.cc @@ -156,12 +156,13 @@ PythonPolicy::get_time_slice() const throw(UserInterruptException) { void PythonPolicy::wait_unlock() const throw(UserInterruptException) { - PyThreadState *_save; + PyThreadState* _save; int i = 0; // We give the sort_queue() three seconds max time, then... // we shot it stone dead! Bang. bool still_locked; - do { + do + { Py_UNBLOCK_THREADS; usleep(25000); // hack'a'ton! magggggiccc nummmbeeerrrrrs!! Py_BLOCK_THREADS; @@ -171,9 +172,12 @@ PythonPolicy::wait_unlock() const throw(UserInterruptException) Py_DECREF(retval); if(i++ > 120) + { throw UserInterruptException("User-defined policy is " "taking too long to terminate."); - } while(still_locked); + } + } + while(still_locked); // What we should really do here: diff --git a/src/backend/scheduler.cc b/src/backend/scheduler.cc index 54117ba..71c03ee 100644 --- a/src/backend/scheduler.cc +++ b/src/backend/scheduler.cc @@ -21,6 +21,9 @@ #include "policy.hh" #include "scheduler.hh" #include "policy_manager.hh" +#include "user_interrupt_exception.hh" + +#include using namespace std; using namespace sgpem; using namespace memory; @@ -79,113 +82,131 @@ Scheduler::get_policy() void Scheduler::step_forward() { - Policy& policy = get_policy(); + try + { + Policy& policy = get_policy(); - 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) + 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; + cout << _("\nNo initial state inserted!!\n"); + return; } - _ready_queue.clear(); + _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 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 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(); + //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); + //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); + //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); + // 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); - } + //restore the old running schedulable + if (policy.is_pre_emptive() == false && running_ptr) + _ready_queue.add_at_top(*running_ptr); + } - //**************** - // Check for termination - //**************** + //**************** + // Check for termination + //**************** - if (running_ptr && running_ptr->get_cpu_time_left() == 0) + 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; + //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); + //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); + //***************** + // 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 - //****************** + //****************** + // 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)) + 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); + //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); + //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)); + //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 << "\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); + <<"_" << _ready_queue.get_item_at(i)->get_state(); + */ + h.enqueue_slice(_ready_queue); + } + catch( UserInterruptException e ) + { + // FIXME : Naive. + cerr << "Exception: " << e.what() << endl; + + // Errrrr.... you won't like this: + _policy_manager.init(); + // https://sourceforge.net/tracker/?func=detail&atid=105470&aid=1165761&group_id=5470 + // maybe it's that??? oh, damn. + // or maybe not. see http://www.python.org/doc/2.4.2/api/initialization.html + + // Tell: + // - the user that the policy sucks + // - SimulationController that everything stopped + } } diff --git a/src/builtin-policies/fcfs.py b/src/builtin-policies/fcfs.py index 13a4216..cf9269a 100644 --- a/src/builtin-policies/fcfs.py +++ b/src/builtin-policies/fcfs.py @@ -15,6 +15,8 @@ class fcfs(Policy) : return -1 def sort_queue(self, event, queue): + #while True: + # pass cmpf = lambda a, b: \ a.get_schedulable().get_arrival_time() < \ b.get_schedulable().get_arrival_time()