- Catch UserInterruptException launched from

PythonPolicy in Scheduler, but it cheerfully 
segfaults python...


git-svn-id: svn://svn.gna.org/svn/sgpemv2/trunk@464 3ecf2c5c-341e-0410-92b4-d18e462d057c
This commit is contained in:
tchernobog 2006-02-26 23:38:25 +00:00
parent 8c39173c2f
commit 0a6b34d6ab
3 changed files with 112 additions and 85 deletions

View File

@ -156,12 +156,13 @@ PythonPolicy::get_time_slice() const throw(UserInterruptException) {
void void
PythonPolicy::wait_unlock() const throw(UserInterruptException) PythonPolicy::wait_unlock() const throw(UserInterruptException)
{ {
PyThreadState *_save; PyThreadState* _save;
int i = 0; // We give the sort_queue() three seconds max time, then... int i = 0; // We give the sort_queue() three seconds max time, then...
// we shot it stone dead! Bang. // we shot it stone dead! Bang.
bool still_locked; bool still_locked;
do { do
{
Py_UNBLOCK_THREADS; Py_UNBLOCK_THREADS;
usleep(25000); // hack'a'ton! magggggiccc nummmbeeerrrrrs!! usleep(25000); // hack'a'ton! magggggiccc nummmbeeerrrrrs!!
Py_BLOCK_THREADS; Py_BLOCK_THREADS;
@ -171,9 +172,12 @@ PythonPolicy::wait_unlock() const throw(UserInterruptException)
Py_DECREF(retval); Py_DECREF(retval);
if(i++ > 120) if(i++ > 120)
{
throw UserInterruptException("User-defined policy is " throw UserInterruptException("User-defined policy is "
"taking too long to terminate."); "taking too long to terminate.");
} while(still_locked); }
}
while(still_locked);
// What we should really do here: // What we should really do here:

View File

@ -21,6 +21,9 @@
#include "policy.hh" #include "policy.hh"
#include "scheduler.hh" #include "scheduler.hh"
#include "policy_manager.hh" #include "policy_manager.hh"
#include "user_interrupt_exception.hh"
#include <iostream>
using namespace std; using namespace std;
using namespace sgpem; using namespace sgpem;
using namespace memory; using namespace memory;
@ -79,113 +82,131 @@ Scheduler::get_policy()
void void
Scheduler::step_forward() Scheduler::step_forward()
{ {
Policy& policy = get_policy(); try
{
Policy& policy = get_policy();
History& h = History::get_instance(); History& h = History::get_instance();
//****************** //******************
//check for arrivals and prepare the queue //check for arrivals and prepare the queue
//****************** //******************
smart_ptr<SchedulableList> initial = h.get_simulation_status_at(h.get_current_time()); smart_ptr<SchedulableList> initial = h.get_simulation_status_at(h.get_current_time());
if (!initial) if (!initial)
{ {
cout << _("\nNo initial state inserted!!\n"); cout << _("\nNo initial state inserted!!\n");
return; return;
} }
_ready_queue.clear(); _ready_queue.clear();
//adds running schedulable //adds running schedulable
smart_ptr<SchedulableStatus> running_ptr = h.get_scheduled_at(h.get_current_time()); smart_ptr<SchedulableStatus> running_ptr = h.get_scheduled_at(h.get_current_time());
if (running_ptr) if (running_ptr)
_ready_queue.add_at_top(*running_ptr); _ready_queue.add_at_top(*running_ptr);
//adds the READY ones //adds the READY ones
for(uint rea=0; rea < initial->size(); rea++) for(uint rea=0; rea < initial->size(); rea++)
if (initial->get_item_at(rea)->get_state() == SchedulableStatus::state_ready) if (initial->get_item_at(rea)->get_state() == SchedulableStatus::state_ready)
_ready_queue.add_at_bottom(*initial->get_item_at(rea)); _ready_queue.add_at_bottom(*initial->get_item_at(rea));
//adds each new ready schedulable and sorts the queue //adds each new ready schedulable and sorts the queue
for(uint i=0; i < initial->size(); i++) for(uint i=0; i < initial->size(); i++)
if (initial->get_item_at(i)->get_state() == SchedulableStatus::state_future 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()) && (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(); //cout << "\nnuovo running: " << initial->get_item_at(i)->get_schedulable()->get_name();
//restore the old running schedulable //restore the old running schedulable
if (policy.is_pre_emptive() == false && running_ptr) if (policy.is_pre_emptive() == false && running_ptr)
_ready_queue.remove(0); _ready_queue.remove(0);
//adds the NEW one //adds the NEW one
_ready_queue.add_at_bottom(*initial->get_item_at(i)); _ready_queue.add_at_bottom(*initial->get_item_at(i));
_ready_queue.get_item_at(_ready_queue.size()-1)->set_state(SchedulableStatus::state_ready); _ready_queue.get_item_at(_ready_queue.size()-1)->set_state(SchedulableStatus::state_ready);
initial->get_item_at(i)->set_state(SchedulableStatus::state_ready); initial->get_item_at(i)->set_state(SchedulableStatus::state_ready);
// Sort the queue // Sort the queue
policy.sort_queue(event_schedulable_arrival); policy.sort_queue(event_schedulable_arrival);
//restore the old running schedulable //restore the old running schedulable
if (policy.is_pre_emptive() == false && running_ptr) if (policy.is_pre_emptive() == false && running_ptr)
_ready_queue.add_at_top(*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 //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++) for(uint i=0; i < _ready_queue.size(); i++)
if (*_ready_queue.get_item_at(i) == *running_ptr) if (*_ready_queue.get_item_at(i) == *running_ptr)
{ {
_ready_queue.add_at_bottom(*_ready_queue.get_item_at(i)); _ready_queue.add_at_bottom(*_ready_queue.get_item_at(i));
_ready_queue.remove(i); _ready_queue.remove(i);
_ready_queue.get_item_at(_ready_queue.size()-1)->set_state(SchedulableStatus::state_terminated); _ready_queue.get_item_at(_ready_queue.size()-1)->set_state(SchedulableStatus::state_terminated);
break; break;
} }
//cout << "\nTERMINATO!!"; //cout << "\nTERMINATO!!";
running_ptr = NULL; running_ptr = NULL;
//IF _ready_queue.size() == 0 sort_queue(...) is called but has no effect!! //IF _ready_queue.size() == 0 sort_queue(...) is called but has no effect!!
policy.sort_queue(event_schedulable_termination); policy.sort_queue(event_schedulable_termination);
} }
//***************** //*****************
// Check for time slice // Check for time slice
//***************** //*****************
if (policy.get_time_slice() != numeric_limits<int>::max()) //time-slice if (policy.get_time_slice() != numeric_limits<int>::max()) //time-slice
policy.sort_queue(event_end_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 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)) || _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) //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)->set_state(SchedulableStatus::state_running);
_ready_queue.get_item_at(0)->give_cpu_time(1); _ready_queue.get_item_at(0)->give_cpu_time(1);
} }
//all the others are ready //all the others are ready
for (uint i = 1; i < _ready_queue.size(); i++) for (uint i = 1; i < _ready_queue.size(); i++)
if (_ready_queue.get_item_at(i)->get_state() == SchedulableStatus::state_running) if (_ready_queue.get_item_at(i)->get_state() == SchedulableStatus::state_running)
_ready_queue.get_item_at(i)->set_state(SchedulableStatus::state_ready); _ready_queue.get_item_at(i)->set_state(SchedulableStatus::state_ready);
//append blocked, future, and terminated schedulables //append blocked, future, and terminated schedulables
for (uint i = 0; i < initial->size(); i++) for (uint i = 0; i < initial->size(); i++)
if(initial->get_item_at(i)->get_state() == SchedulableStatus::state_blocked 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_future
|| initial->get_item_at(i)->get_state() == SchedulableStatus::state_terminated) || initial->get_item_at(i)->get_state() == SchedulableStatus::state_terminated)
_ready_queue.add_at_bottom(*initial->get_item_at(i)); _ready_queue.add_at_bottom(*initial->get_item_at(i));
cout << "\n"; cout << "\n";
/* for (uint i = 0; i < _ready_queue.size(); i++) /* for (uint i = 0; i < _ready_queue.size(); i++)
cout << " " << _ready_queue.get_item_at(i)->get_schedulable()->get_name() cout << " " << _ready_queue.get_item_at(i)->get_schedulable()->get_name()
<<"_" << _ready_queue.get_item_at(i)->get_state(); <<"_" << _ready_queue.get_item_at(i)->get_state();
*/ */
h.enqueue_slice(_ready_queue); 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
}
} }

View File

@ -15,6 +15,8 @@ class fcfs(Policy) :
return -1 return -1
def sort_queue(self, event, queue): def sort_queue(self, event, queue):
#while True:
# pass
cmpf = lambda a, b: \ cmpf = lambda a, b: \
a.get_schedulable().get_arrival_time() < \ a.get_schedulable().get_arrival_time() < \
b.get_schedulable().get_arrival_time() b.get_schedulable().get_arrival_time()