- Only schedule Threads. Ditch support for Policies deciding

if they want to schedule Threads or Processes altogether
- Move setter methods for last_acquisition/last_release from
DynamicSchedulable to DynamicThread
- Rewrite aforesaid methods, along with the respective getter
methods, into Dynamic(Thread|Process)


git-svn-id: svn://svn.gna.org/svn/sgpemv2/trunk@708 3ecf2c5c-341e-0410-92b4-d18e462d057c
This commit is contained in:
tchernobog 2006-07-04 10:46:15 +00:00
parent 736aa25456
commit a378239d60
17 changed files with 119 additions and 194 deletions

View File

@ -82,32 +82,6 @@ class ScriptAdapter :
self._ret_val = self._policy.is_preemptive() self._ret_val = self._policy.is_preemptive()
self._g_mutex.unlock() self._g_mutex.unlock()
## @brief Asynchronously call Policy.get_time_slice()
#
# @param self The caller object
def async_get_time_slice(self):
self._g_mutex.lock(ScriptAdapter._wrap_get_time_slice, self)
def _wrap_get_time_slice(self):
thread.start_new_thread(ScriptAdapter._wrap_get_time_slice_callback, (self,))
def _wrap_get_time_slice_callback(self):
self._ret_val = self._policy.get_time_slice()
self._g_mutex.unlock()
## @brief Asynchronously call Policy.wants()
#
# @param self The caller object
def async_wants(self):
self._g_mutex.lock(ScriptAdapter._wrap_wants, self)
def _wrap_wants(self):
thread.start_new_thread(ScriptAdapter._wrap_wants_callback, (self,))
def _wrap_wants_callback(self):
self._ret_val = self._policy.wants()
self._g_mutex.unlock()
## @brief Return the global shared variable with the methods' last return value ## @brief Return the global shared variable with the methods' last return value
def get_return_value(self): def get_return_value(self):
return self._ret_val return self._ret_val

View File

@ -36,9 +36,6 @@ class fcfs(Policy) :
def get_time_slice(self): def get_time_slice(self):
return -2 return -2
def wants(self):
return policy_sorts_processes
def sort_queue(self, queue): def sort_queue(self, queue):
cmpf = lambda a, b: \ cmpf = lambda a, b: \
a.get_arrival_time() < \ a.get_arrival_time() < \

View File

@ -36,9 +36,6 @@ class sjf(Policy) :
def get_time_slice(self): def get_time_slice(self):
return -1 return -1
def wants(self):
return policy_sorts_processes
def sort_queue(self, queue): def sort_queue(self, queue):
cmpf = lambda a, b: \ cmpf = lambda a, b: \
a.get_remaining_time() < \ a.get_remaining_time() < \

View File

@ -160,27 +160,6 @@ PythonPolicy::get_time_slice() const throw(UserInterruptException)
return tmp < 0 ? numeric_limits<int>::max() : static_cast<int>(tmp); return tmp < 0 ? numeric_limits<int>::max() : static_cast<int>(tmp);
} }
policy_sorts_type
PythonPolicy::wants() const throw(UserInterruptException)
{
PyObject* retval = PyObject_CallMethod(_adapter, "async_wants", NULL);
Py_DECREF(retval);
wait_unlock();
// Parse return value stored in global Python object
retval = PyObject_CallMethod(_adapter, "get_return_value", NULL);
assert(retval);
long tmp = PyInt_AsLong(retval);
Py_DECREF(retval);
//FIXME add the MalformedPolicyException class and throw it the else
// branch instead
if(tmp == policy_sorts_threads || tmp == policy_sorts_processes)
return static_cast<policy_sorts_type>(tmp);
else
return policy_sorts_processes;
}
void void
PythonPolicy::wait_unlock() const throw(UserInterruptException) PythonPolicy::wait_unlock() const throw(UserInterruptException)

View File

@ -76,8 +76,6 @@ namespace sgpem
*/ */
int get_time_slice() const throw(UserInterruptException); int get_time_slice() const throw(UserInterruptException);
policy_sorts_type wants() const throw(UserInterruptException);
void activate() void activate()
{ {
//FIXME write code for me //FIXME write code for me

View File

@ -47,9 +47,6 @@ namespace std {
namespace sgpem { namespace sgpem {
/** Don't get worried, order is not important! */
enum policy_sorts_type { policy_sorts_threads, policy_sorts_processes };
class Policy { class Policy {
public: public:
virtual ~Policy() = 0; virtual ~Policy() = 0;
@ -154,7 +151,7 @@ namespace sgpem {
}; };
virtual unsigned int get_arrival_time() const = 0; virtual unsigned int get_arrival_time() const = 0;
virtual unsigned int get_remaining_time() const = 0; virtual unsigned int get_elapsed_time() const = 0;
virtual int get_base_priority() const = 0; virtual int get_base_priority() const = 0;
virtual int get_current_priority() const = 0; virtual int get_current_priority() const = 0;
virtual unsigned int get_total_cpu_time() const = 0; virtual unsigned int get_total_cpu_time() const = 0;
@ -198,25 +195,7 @@ namespace sgpem {
size_t size() const; size_t size() const;
// Dynamic cast to Process or to Thread so sgpem::Thread* get_item_at(position index);
// that Python code sees the extra-methods
%typename(out) sgpem::Schedulable*;
{
// OMG, Ponies!!
Process* proc;
Thread* thread;
if((proc = dynamic_cast<Process*>($1)) != NULL)
$result = SWIG_NewPointerObj(SWIG_as_voidptr(proc),
SWIGTYPE_p_sgpem__Process, 0 | 0 );
else if((thread = dynamic_cast<Thread*>($1)) != NULL)
$result = SWIG_NewPointerObj(SWIG_as_voidptr(thread),
SWIGTYPE_p_sgpem__Thread, 0 | 0 );
else // Fall back to Schedulable* if no dynamic_cast went well:
$result = SWIG_NewPointerObj(SWIG_as_voidptr(thread),
$1_descriptor, 0 | 0 );
}
sgpem::Schedulable* get_item_at(position index);
%typename(out) sgpem::Schedulable*; %typename(out) sgpem::Schedulable*;

View File

@ -155,3 +155,44 @@ DynamicProcess::get_dynamic_threads()
{ {
return _dynamic_threads; return _dynamic_threads;
} }
unsigned int
DynamicProcess::get_elapsed_time() const
{
unsigned int result = 0;
for(std::vector<DynamicThread*>::const_iterator it = _dynamic_threads.begin();
it != _dynamic_threads.end(); it++)
{
result += (*it)->get_elapsed_time();
}
return result;
}
int
DynamicProcess::get_last_acquisition() const
{
int result = -1;
for(std::vector<DynamicThread*>::const_iterator it = _dynamic_threads.begin();
it != _dynamic_threads.end(); it++)
{
int acq = (*it)->get_last_acquisition();
if(result < acq)
result = acq;
}
return result;
}
int
DynamicProcess::get_last_release() const
{
int result = -1;
for(std::vector<DynamicThread*>::const_iterator it = _dynamic_threads.begin();
it != _dynamic_threads.end(); it++)
{
int acq = (*it)->get_last_release();
if(result < acq)
result = acq;
}
return result;
}

View File

@ -53,6 +53,10 @@ namespace sgpem
void serialize(SerializeVisitor& translator) const; void serialize(SerializeVisitor& translator) const;
int get_last_acquisition() const;
int get_last_release() const;
unsigned int get_elapsed_time() const;
virtual StaticProcess& get_core(); virtual StaticProcess& get_core();
virtual const StaticProcess& get_core() const; virtual const StaticProcess& get_core() const;

View File

@ -28,8 +28,7 @@ using namespace sgpem;
using namespace std; using namespace std;
DynamicSchedulable::DynamicSchedulable() DynamicSchedulable::DynamicSchedulable()
: _ran_for(0), _last_acquisition(-1), : _priority_push(0)
_last_release(-1), _priority_push(0)
{} {}
bool bool
@ -63,60 +62,9 @@ DynamicSchedulable::get_total_cpu_time() const
return get_core().get_total_cpu_time(); return get_core().get_total_cpu_time();
} }
int
DynamicSchedulable::get_priority_push() const
{
return _priority_push;
}
int
DynamicSchedulable::set_priority_push(int new_value)
{
int temp = _priority_push;
_priority_push = new_value;
return temp;
}
int int
DynamicSchedulable::get_current_priority() const DynamicSchedulable::get_current_priority() const
{ {
return get_base_priority() + get_priority_push(); return get_base_priority() + get_priority_push();
} }
unsigned int
DynamicSchedulable::get_elapsed_time() const
{
return _ran_for;
}
void
DynamicSchedulable::decrease_remaining_time()
{
_ran_for++;
}
int
DynamicSchedulable::get_last_acquisition() const
{
return _last_acquisition;
}
void
DynamicSchedulable::set_last_acquisition(int instant)
{
_last_acquisition = instant;
}
int
DynamicSchedulable::get_last_release() const
{
return _last_release;
}
void
DynamicSchedulable::set_last_release(int instant)
{
_last_release = instant;
}

View File

@ -68,17 +68,11 @@ namespace sgpem
virtual int get_current_priority() const; virtual int get_current_priority() const;
virtual unsigned int get_elapsed_time() const; virtual unsigned int get_elapsed_time() const = 0;
virtual void decrease_remaining_time(); virtual int get_last_acquisition() const = 0;
virtual int get_last_acquisition() const; virtual int get_last_release() const = 0;
virtual void set_last_acquisition(int instant);
virtual int get_last_release() const;
virtual void set_last_release(int instant);
/** \brief Returns a pointer to the schedulable object /** \brief Returns a pointer to the schedulable object
* *
@ -89,9 +83,6 @@ namespace sgpem
virtual const StaticSchedulable& get_core() const = 0; virtual const StaticSchedulable& get_core() const = 0;
private: private:
int _ran_for;
int _last_acquisition;
int _last_release;
int _priority_push; int _priority_push;
}; };
} }

View File

@ -33,7 +33,8 @@ using namespace std;
DynamicThread::DynamicThread(StaticThread* core, DynamicProcess* parent) DynamicThread::DynamicThread(StaticThread* core, DynamicProcess* parent)
: DynamicSchedulable(), _core(core), _state(state_future), _parent(parent) : DynamicSchedulable(), _core(core), _state(state_future), _parent(parent),
_ran_for(0), _last_acquisition(-1), _last_release(-1)
{ {
parent->get_threads().push_back(this); parent->get_threads().push_back(this);
} }
@ -109,3 +110,41 @@ DynamicThread::get_dynamic_requests()
{ {
return _dynamic_requests; return _dynamic_requests;
} }
unsigned int
DynamicThread::get_elapsed_time() const
{
return _ran_for;
}
void
DynamicThread::decrease_remaining_time()
{
_ran_for++;
}
int
DynamicThread::get_last_acquisition() const
{
return _last_acquisition;
}
void
DynamicThread::set_last_acquisition(int instant)
{
_last_acquisition = instant;
}
int
DynamicThread::get_last_release() const
{
return _last_release;
}
void
DynamicThread::set_last_release(int instant)
{
_last_release = instant;
}

View File

@ -50,9 +50,17 @@ namespace sgpem
DynamicProcess& get_process(); DynamicProcess& get_process();
state get_state() const; state get_state() const;
state set_state(state new_state); state set_state(state new_state);
int get_last_acquisition() const;
void set_last_acquisition(int instant);
int get_last_release() const;
void set_last_release(int instant);
unsigned int get_elapsed_time() const;
void decrease_remaining_time();
std::vector<Request*> get_requests(); std::vector<Request*> get_requests();
void serialize(SerializeVisitor& translator) const; void serialize(SerializeVisitor& translator) const;
@ -68,6 +76,10 @@ namespace sgpem
state _state; state _state;
std::vector<DynamicRequest*> _dynamic_requests; std::vector<DynamicRequest*> _dynamic_requests;
DynamicProcess* _parent; DynamicProcess* _parent;
int _ran_for;
int _last_acquisition;
int _last_release;
}; };
} }

View File

@ -25,12 +25,6 @@ using namespace sgpem;
Policy::~Policy() Policy::~Policy()
{} {}
int
Policy::get_id() const
{
return _id;
}
PolicyParameters& PolicyParameters&
Policy::get_parameters() Policy::get_parameters()

View File

@ -32,13 +32,6 @@
namespace sgpem namespace sgpem
{ {
enum policy_sorts_type
{
policy_sorts_threads,
policy_sorts_processes
};
class Policy; class Policy;
/** \brief /** \brief
@ -50,7 +43,6 @@ namespace sgpem
class SG_DLLEXPORT Policy class SG_DLLEXPORT Policy
{ {
public: public:
virtual ~Policy(); virtual ~Policy();
/** /**
@ -70,12 +62,6 @@ namespace sgpem
*/ */
virtual void sort_queue() const throw(UserInterruptException) = 0; virtual void sort_queue() const throw(UserInterruptException) = 0;
/**
Gets the unique identifier (id) of this Policy.
\return The Policy id.
*/
int get_id() const;
/** /**
Gets a string description of the policy. Gets a string description of the policy.
@ -105,16 +91,6 @@ namespace sgpem
*/ */
virtual int get_time_slice() const throw(UserInterruptException) = 0; virtual int get_time_slice() const throw(UserInterruptException) = 0;
/**
Tell what kind of entities are scheduled by this policy.
Because it's a pure virtual method, must be re-implemented
in concrete derived classes.
\return A SortsType value identifying the desired type for the objects
composing the queue passed to the sort_queue method.
*/
virtual policy_sorts_type wants() const throw(UserInterruptException) = 0;
virtual void activate() = 0; virtual void activate() = 0;
virtual void deactivate() = 0; virtual void deactivate() = 0;
@ -130,7 +106,6 @@ namespace sgpem
protected: protected:
PolicyParameters _parameters; PolicyParameters _parameters;
int _id;
}; };
}//~ namespace sgpem }//~ namespace sgpem

View File

@ -36,7 +36,7 @@ ReadyQueue::swap(position a, position b)
// Once we've done the check once, we // Once we've done the check once, we
// can assume it's safe to use "[]"; // can assume it's safe to use "[]";
// this for performance reasons. // this for performance reasons.
Schedulable* temp = _scheds.at(a); Thread* temp = _scheds.at(a);
_scheds[a] = _scheds.at(b); _scheds[a] = _scheds.at(b);
_scheds[b] = temp; _scheds[b] = temp;
} }
@ -49,7 +49,7 @@ ReadyQueue::size() const
} }
sgpem::Schedulable& sgpem::Thread&
ReadyQueue::get_item_at(position index) ReadyQueue::get_item_at(position index)
throw (std::out_of_range) throw (std::out_of_range)
{ {
@ -59,7 +59,7 @@ ReadyQueue::get_item_at(position index)
void void
ReadyQueue::append(Schedulable& schedulable) ReadyQueue::append(Thread& thread)
{ {
_scheds.push_back(&schedulable); _scheds.push_back(&thread);
} }

View File

@ -29,7 +29,7 @@
namespace sgpem namespace sgpem
{ {
class ReadyQueue; class ReadyQueue;
class Schedulable; class Thread;
class SG_DLLEXPORT ReadyQueue class SG_DLLEXPORT ReadyQueue
{ {
@ -39,12 +39,12 @@ namespace sgpem
void swap(position a, position b) throw (std::out_of_range); void swap(position a, position b) throw (std::out_of_range);
size_t size() const; size_t size() const;
Schedulable& get_item_at(position index) throw (std::out_of_range); Thread& get_item_at(position index) throw (std::out_of_range);
void append(Schedulable& schedulable); void append(Thread& schedulable);
private: private:
typedef std::vector<Schedulable*> Schedulables; typedef std::vector<Thread*> Threads;
Schedulables _scheds; Threads _scheds;
}; };
} }

View File

@ -182,10 +182,7 @@ Scheduler::step_forward(History& history, Policy& cpu_policy) throw(UserInterrup
// should maybe be done here as the first thing, instead than // should maybe be done here as the first thing, instead than
// directly when selecting them // directly when selecting them
if(running_thread != NULL) if(running_thread != NULL)
{
running_thread->decrease_remaining_time(); running_thread->decrease_remaining_time();
running_thread->get_process().decrease_remaining_time();
}
// 4a. Requests for the running thread exhausted // 4a. Requests for the running thread exhausted
if(running_thread != NULL) { if(running_thread != NULL) {